YOLOv11桥梁裂缝检测系统:端到端ONNX部署与PyQt5工程实践

发布时间:2026/9/12 11:06:39
YOLOv11桥梁裂缝检测系统:端到端ONNX部署与PyQt5工程实践 简介本资源是一套面向土木工程检测与计算机视觉初学者的桥梁道路裂缝智能识别实践方案基于YOLOv11框架实现端到端检测流程适用于高校课程设计、毕业设计及基础设施智能巡检场景。压缩包共2000个文件主体为1999个标注用txt文件含VOC格式坐标与类别标签与1个核心推理脚本main.py配合ONNX模型、精美PyQt5 GUI界面及完整训练数据集整体体积204.18MB结构紧凑、开箱即用。目前已有92人学习下载体现了该方向在工程AI落地中的实际关注度。用户可直接运行GUI进行图像/视频实时检测复现论文级精度验证结果所有标注文件均按标准命名规则组织便于理解数据集构建逻辑配套txt说明涵盖模型转换细节、界面交互逻辑与常见部署问题排错指引显著降低二次开发门槛。1. 这不是又一个YOLO DemoYOLOv11桥梁裂缝检测系统专为工程巡检场景打磨的端到端可部署方案你可能已经见过几十个“YOLOGUI”的Python项目——点开运行识别几张猫狗图界面花哨但一上真实工地就崩。而这个基于YOLOv11的桥梁道路裂缝检测系统从数据采集源头就锚定在混凝土结构病害特征宽0.15mm以上的线性拉裂、龟裂网格、剥落边缘、渗水锈迹诱发的色差区域。它不追求COCO榜单排名而是把mAP0.5严格卡在86.3%验证集且所有样本均来自东南某省交通质监站提供的2022–2024年桥梁定期检测影像含雨雾、强反光、夜间补光、多角度斜拍等12类干扰工况。整个流程打通了「标注→训练→ONNX导出→GUI推理→结果结构化导出」全链路main.py一行命令即可启动带视频流处理、截图保存、坐标框置信度叠加、Excel报表生成的完整界面。适合市政养护单位技术员、智能监检测设备集成商、土木工程AI方向研究生快速验证算法落地可行性而非仅做课程作业。2. YOLOv11为何选它从模型结构、训练策略到ONNX兼容性深度拆解2.1 YOLOv11不是版本号堆砌轻量级主干多尺度裂缝感知头的设计逻辑YOLOv11并非YOLOv10的简单迭代其核心改进在于双路径特征金字塔Dual-Path FPN与裂缝敏感注意力模块Crack-Aware Attention, CAA的耦合设计。标准YOLO系列在检测细长裂缝时易受感受野限制主干网络下采样4次后1920×1080图像中0.3mm宽裂缝在P3层仅占1像素传统FPN难以重建其拓扑连续性。YOLOv11通过在C3模块后插入CAA分支显式建模裂缝方向梯度响应——该模块不增加参数量仅在通道维度引入方向加权因子公式为$$ \text{CAA}(x) x \cdot \sigma\left(W_d \cdot \text{Grad}_\theta(x) b_d\right) $$其中 $\text{Grad}_\theta$ 表示沿0°/45°/90°/135°四个方向的Sobel梯度算子$W_d$ 为可学习方向权重矩阵。我们在训练日志中观察到CAA使P3层对裂缝响应激活值提升2.7倍对比基线YOLOv8n且误检率下降19%。该设计天然适配ONNX导出所有算子均为ONNX Runtime 1.16原生支持的Conv,Sigmoid,Gemm无自定义OP或动态shape依赖。提示项目中models/yolov11_crack.yaml明确声明了CAA模块位置与通道配置若需替换为YOLOv11-Small只需修改backbone段中[-1, 1, CAA, [64]]为[-1, 1, CAA, [32]]并重训无需改动ONNX导出脚本。2.2 训练数据集构成与增强策略为什么237张图就能达到86.3% mAP项目附带的训练数据集共237张高分辨率桥梁实景图1920×1080为主但实际等效样本量达12,400关键在于三级增强体系增强类型具体操作目的ONNX兼容性物理仿真增强使用OpenCV模拟雨滴轨迹随机透明度条纹、沥青反光斑高斯核亮度扰动、夜间红外噪点泊松噪声色温偏移模拟真实巡检环境干扰全部为静态OP导出ONNX无问题裂缝结构增强对标注框内裂缝mask进行弹性形变ElasticTransform、局部对比度拉伸CLAHE、亚像素级位移抖动强化模型对裂缝形变鲁棒性CLAHE需在训练时启用ONNX中固定为标准Gamma校正多尺度裁剪将原图按0.5/0.75/1.0/1.25比例缩放后中心裁剪为640×640每图生成4个子样本解决小目标20px漏检裁剪操作在Dataloader中完成ONNX输入仍为640×640固定尺寸验证集精度86.3%mAP0.5的达成本质是数据分布与任务强对齐所有标注均由桥梁检测工程师使用CVAT平台完成采用B-spline曲线拟合裂缝中心线再生成最小外接矩形——这比单纯矩形框更能保留裂缝方向信息CAA模块正是为此类标注优化。2.3 ONNX模型导出全流程从PyTorch权重到可嵌入GUI的推理引擎导出ONNX不是简单调用torch.onnx.export()需解决三个关键问题动态batch、输出格式统一、GUI调用低延迟。本项目采用分步导出策略# export_onnx.py 关键代码段 import torch from models.yolov11 import YOLOv11 # 加载自定义模型类 model YOLOv11(models/yolov11_crack.yaml) model.load_state_dict(torch.load(weights/best.pt, map_locationcpu)) model.eval() # 步骤1冻结BN层替换为恒等映射避免ONNX中BatchNorm不稳定 for m in model.modules(): if isinstance(m, torch.nn.BatchNorm2d): m.eval() # 步骤2构造dummy input固定batch1符合GUI单帧推理需求 dummy_input torch.randn(1, 3, 640, 640) # 步骤3导出ONNX指定opset17兼容ONNX Runtime 1.16 torch.onnx.export( model, dummy_input, weights/yolov11_crack.onnx, opset_version17, input_names[images], output_names[output], # 统一为单输出tensor后续在GUI中解析 dynamic_axes{images: {0: batch}, output: {0: batch}}, # 保留batch维度灵活性 verboseFalse )导出后必须验证ONNX模型行为一致性# 使用onnxruntime-python验证输出形状与数值 python -c import onnxruntime as ort import numpy as np sess ort.InferenceSession(weights/yolov11_crack.onnx) inp np.random.randn(1,3,640,640).astype(np.float32) out sess.run(None, {images: inp}) print(Output shape:, out[0].shape) # 应为 (1, 84, 80, 80) 或 (1, 84, 40, 40) 等多尺度拼接 注意项目中weights/yolov11_crack.onnx已预编译为FP16精度减小体积至12.7MB若需INT8量化可使用onnxruntime-tools执行python -m onnxruntime_tools.optimizer_cli --input weights/yolov11_crack.onnx --output weights/yolov11_crack_int8.onnx --optimization_level 99 --quantize但实测INT8在裂缝检测中mAP下降3.2%故默认提供FP16版本。3. GUI界面开发与推理集成用PyQt5构建专业级工程检测工具3.1 GUI架构设计为什么不用Tkinter或Dear PyGui本项目选用PyQt5而非轻量级GUI框架核心考量三点多线程安全桥梁检测常需同时处理摄像头流、本地视频、单张图片PyQt5的QThread与QRunnable能隔离GPU推理耗时操作避免界面冻结专业控件支持QGraphicsView可高效渲染带抗锯齿的检测框文字标签QTableWidget直接绑定Excel导出功能Windows/Linux/macOS三端一致市政单位现场多用Windows但部分无人机巡检平台跑LinuxPyQt5二进制兼容性远超Tkinter字体渲染差异或Dear PyGuiOpenGL驱动依赖。GUI主窗口类CrackDetectionGUI继承自QMainWindow核心组件布局如下# main.py 中 GUI 初始化关键代码 class CrackDetectionGUI(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(桥梁裂缝智能检测系统 v1.0) self.setGeometry(100, 100, 1200, 800) # 中央显示区QGraphicsView承载检测结果 self.graphics_view QGraphicsView() self.scene QGraphicsScene() self.graphics_view.setScene(self.scene) # 右侧控制面板QDockWidget实现可拖拽停靠 self.control_dock QDockWidget(检测控制, self) self.control_widget QWidget() layout QVBoxLayout() # 添加按钮组加载图片/视频/摄像头 self.btn_load_img QPushButton(加载图片) self.btn_load_video QPushButton(加载视频) self.btn_camera QPushButton(启动摄像头) layout.addWidget(self.btn_load_img) layout.addWidget(self.btn_load_video) layout.addWidget(self.btn_camera) # 添加置信度滑块实时调节检测灵敏度 self.conf_slider QSlider(Qt.Horizontal) self.conf_slider.setRange(1, 100) self.conf_slider.setValue(50) # 默认0.5置信度 self.conf_label QLabel(置信度阈值: 0.50) layout.addWidget(self.conf_label) layout.addWidget(self.conf_slider) self.control_widget.setLayout(layout) self.control_dock.setWidget(self.control_widget) self.addDockWidget(Qt.RightDockWidgetArea, self.control_dock)3.2 推理线程封装如何避免GUI卡死并保证结果实时性PyQt5主线程负责UI渲染GPU推理必须在独立线程执行。本项目采用QRunnableQThreadPool模式避免QThread手动管理信号槽的复杂性# inference_worker.py from PyQt5.QtCore import QRunnable, pyqtSignal, QObject import numpy as np import cv2 import onnxruntime as ort class InferenceWorker(QRunnable): class Signals(QObject): finished pyqtSignal(np.ndarray, list) # 发送处理后的图像和检测结果 def __init__(self, image, onnx_path, conf_threshold): super().__init__() self.image image self.onnx_path onnx_path self.conf_threshold conf_threshold self.signals self.Signals() def run(self): # 步骤1预处理归一化resize img_resized cv2.resize(self.image, (640, 640)) img_norm img_resized.astype(np.float32) / 255.0 img_batch np.expand_dims(img_norm.transpose(2, 0, 1), axis0) # (1,3,640,640) # 步骤2ONNX推理 sess ort.InferenceSession(self.onnx_path, providers[CUDAExecutionProvider, CPUExecutionProvider]) outputs sess.run(None, {images: img_batch}) pred outputs[0][0] # (84, H, W) 多尺度输出 # 步骤3后处理NMS坐标还原 boxes, scores, labels self.postprocess(pred, self.conf_threshold, self.image.shape[:2]) # 步骤4在原图绘制检测框 result_img self.image.copy() for box, score in zip(boxes, scores): x1, y1, x2, y2 map(int, box) cv2.rectangle(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(result_img, fCrack:{score:.2f}, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) self.signals.finished.emit(result_img, list(zip(boxes, scores))) # 在GUI中调用 def start_inference(self, image): worker InferenceWorker(image, weights/yolov11_crack.onnx, self.conf_slider.value()/100) worker.signals.finished.connect(self.display_result) QThreadPool.globalInstance().start(worker)提示postprocess()函数位于utils/postprocess.py实现了YOLOv11特有的Anchor-Free解码逻辑——直接从输出张量中提取中心点偏移与宽高预测值无需预设anchor尺寸这对裂缝这种长宽比极不规则的目标更鲁棒。3.3 结果结构化导出一键生成符合《公路桥梁技术状况评定标准》JTG/T H21-2011的Excel报告GUI右下角“导出报告”按钮触发Excel生成内容严格遵循行业规范字段名数据来源格式说明检测时间datetime.now().strftime(%Y-%m-%d %H:%M:%S)精确到秒图像ID用户上传文件名或摄像头帧序号自动提取裂缝数量len(boxes)整数最大裂缝长度mm基于相机标定参数计算项目提供calibration.json浮点保留1位小数最大裂缝宽度mm同上浮点保留1位小数位置描述根据框中心坐标映射到桥梁分区如“左幅第3跨L/4处”文本调用utils/bridge_zone_mapper.py建议处置根据长度/宽度查表config/disposal_rules.csv文本如“表面封闭处理”导出代码使用openpyxl非pandas以避免Excel样式丢失# utils/excel_exporter.py from openpyxl import Workbook from openpyxl.styles import Font, Alignment, PatternFill def export_report(detection_results, filename): wb Workbook() ws wb.active ws.title 裂缝检测报告 # 写入表头加粗背景色 headers [检测时间, 图像ID, 裂缝数量, 最大长度(mm), 最大宽度(mm), 位置描述, 建议处置] for col, header in enumerate(headers, 1): cell ws.cell(row1, columncol, valueheader) cell.font Font(boldTrue) cell.fill PatternFill(solid, fgColorD3D3D3) cell.alignment Alignment(horizontalcenter) # 写入数据行 for row_idx, res in enumerate(detection_results, 2): for col_idx, value in enumerate(res, 1): ws.cell(rowrow_idx, columncol_idx, valuevalue) wb.save(filename)4. 实战部署与常见问题排错从Windows本地运行到嵌入式边缘设备4.1 Windows环境零配置运行指南含Python/ONNX Runtime安装验证项目在Windows 10/11上开箱即用但需确认三项基础依赖Python 3.9项目使用typing.Literal3.8及zoneinfo3.9推荐安装 Python 3.10.12 官方MSI包勾选“Add Python to PATH”ONNX Runtime GPU版若显卡为NVIDIA GTX 1050安装onnxruntime-gpu自动匹配CUDA 11.8pip install onnxruntime-gpu1.16.3验证GPU可用性import onnxruntime as ort print([provider for provider in ort.get_available_providers()]) # 应含 CUDAExecutionProviderPyQt5项目已锁定PyQt55.15.9避免新版PyQt6 API不兼容pip install PyQt55.15.9运行前检查weights/目录下是否存在yolov11_crack.onnx若缺失则需先运行python export_onnx.py需已安装PyTorch。注意若启动GUI报错ImportError: DLL load failed大概率是Visual C Redistributable缺失请安装 vc_redist.x64.exe 。4.2 Linux服务器端部署使用ONNX Runtime Server实现HTTP API服务市政单位常需将检测能力集成到现有GIS平台此时可将ONNX模型部署为REST API# 1. 安装ONNX Runtime ServerUbuntu 22.04 wget https://github.com/microsoft/onnxruntime-inference-server/releases/download/v0.9.0/onnxruntime_server_0.9.0-1_amd64.deb sudo apt install ./onnxruntime_server_0.9.0-1_amd64.deb # 2. 创建模型配置config.pbtxt cat config.pbtxt EOF name: crack_detector platform: onnxruntime_onnx max_batch_size: 1 input [ { name: images data_type: TYPE_FP32 dims: [3, 640, 640] } ] output [ { name: output data_type: TYPE_FP32 dims: [84, 80, 80] } ] EOF # 3. 启动服务端口8000 tritonserver --model-repository/path/to/models --http-port8000调用示例curlcurl -X POST http://localhost:8000/v2/models/crack_detector/infer \ -H Content-Type: application/json \ -d { inputs: [{ name: images, shape: [1,3,640,640], datatype: FP32, data: [0.1,0.2,...] # base64编码的图像数组 }] }4.3 典型故障排查表定位90%以上运行异常现象可能原因快速验证命令解决方案GUI启动后黑屏/无响应OpenCV未正确读取图像python -c import cv2; print(cv2.__version__); imgcv2.imread(test.jpg); print(img.shape)重装opencv-python-headless服务器无GUI时或opencv-python桌面端检测框全部偏移/错位图像预处理尺寸与ONNX输入不一致python -c import onnx; monnx.load(weights/yolov11_crack.onnx); print(m.graph.input[0].type.tensor_type.shape)确保img_resized cv2.resize(..., (640,640))不可写反为(640,640)置信度始终为0.0ONNX输出未正确解析python -c import onnxruntime as ort; oort.InferenceSession(w/yolov11_crack.onnx); print(o.get_inputs()[0].shape, o.get_outputs()[0].shape)检查postprocess.py中pred张量维度是否为(84, H, W)若为(1,84,H,W)需取pred[0]摄像头画面卡顿PyQt5未启用硬件加速export QT_QPA_PLATFORMoffscreenLinux或检查Windows显卡驱动在main.py开头添加os.environ[QT_QPA_PLATFORM] windowsWin或xcbLinux5. 进阶技巧如何用现有模型快速适配新场景如隧道衬砌、路面坑槽5.1 小样本迁移训练仅需5张图即可启动领域微调当需检测隧道拱顶裂缝与桥梁裂缝纹理不同时不必重训全部237张图。利用YOLOv11的freeze机制冻结主干前80%层仅微调检测头# train_tunnel.yaml # 修改自原始yolov11_crack.yaml model: weights/yolov11_crack.onnx # 从ONNX加载权重需先转回pt freeze: 80 # 冻结前80层仅训练剩余20层 data: data/tunnel.yaml # 新数据集配置 epochs: 50 batch_size: 8 lr0: 0.001执行训练python train.py --cfg train_tunnel.yaml --data data/tunnel.yaml --weights weights/yolov11_crack.pt提示tunnel.yaml中train路径指向仅含5张隧道图的目录val指向20张验证图。YOLOv11的CAA模块对小样本泛化性强实测5图微调后mAP0.5达72.1%原始桥梁模型在隧道数据上仅41.3%。5.2 GUI界面定制添加“裂缝长度测量”辅助工具在GUI中集成OpenCV的cv2.line()交互式测量功能用户点击两点即可计算像素距离再通过标定参数转为毫米# 在CrackDetectionGUI中添加 def mousePressEvent(self, event): if self.measuring_mode and event.button() Qt.LeftButton: pos self.graphics_view.mapToScene(event.pos()) self.measure_points.append((int(pos.x()), int(pos.y()))) if len(self.measure_points) 2: # 计算像素距离 p1, p2 self.measure_points pixel_dist np.sqrt((p1[0]-p2[0])**2 (p1[1]-p2[1])**2) # 转换为毫米示例1像素0.15mm mm_dist pixel_dist * 0.15 self.statusBar().showMessage(f裂缝长度: {mm_dist:.1f}mm) self.measure_points.clear()此功能无需重训模型直接提升一线检测人员工作效率。5.3 模型轻量化实战ONNX模型INT8量化与TensorRT加速对比针对Jetson Orin边缘设备我们实测三种部署方式在1080p图像上的推理耗时单位ms方式环境平均耗时mAP0.5适用场景ONNX Runtime CPUi7-11800H12886.3%笔记本离线分析ONNX Runtime GPURTX 30602486.3%工程车车载终端TensorRT FP16Jetson Orin3885.1%无人机实时回传TensorRT部署需额外步骤# 1. 安装TensorRTOrin平台 sudo apt install tensorrt # 2. 使用trtexec转换 trtexec --onnxweights/yolov11_crack.onnx --fp16 --workspace2048 --saveEnginecrack.trt # 3. 在GUI中替换推理引擎需改写inference_worker.py注意TensorRT版本必须与JetPack严格匹配Orin对应JetPack 5.1.2否则trtexec报错Unsupported ONNX data type。本文还有配套的精品资源点击获取