拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Python+YOLOv5路面桥梁裂缝检测:从数据集准备到模型部署全流程

简介基于Python与Yolov5构建的路面桥梁裂缝检测识别项目面向高校学生、工程技术人员及具备一定深度学习基础的开发者可支撑毕业设计、课程设计、期末大作业和项目原型快速验证。项目聚焦道路与桥梁表面裂缝的自动定位与识别能够对裂缝形态、大小和位置作出较准确判断为基础设施安全巡检提供有效参考并曾获98分评审成绩。压缩包共49个文件包含YAML配置、Python源码、Pyc编译文件、Shell脚本以及示例图片、Dockerfile分别对应模型结构参数配置、算法逻辑、编译缓存、权重下载和容器化部署包体仅1.98MB轻量易用。目前已有98人学习浏览。源码与模型经过本地编译验证可直接运行省去从零搭建的繁琐过程配套的训练说明与部署文档有助于理解Yolov5完整流程并可根据实际场景调整检测精度与推理效率是学习与工程落地兼顾的实用资源。1. 路面桥梁裂缝检测项目为什么选择 YOLOv5 作为识别模型路面桥梁裂缝检测识别项目如果只看效果用现在更高精度的实例分割模型也能做但放到毕业设计里YOLOv5 依然是最容易把“源代码 模型 数据集”三个交付物串在一起的方案。它把检测任务收敛成 detect 和 train 两条命令行models/yolov5s.yaml 一类的配置文件直接暴露网络深度和宽度答辩时能对着结构讲清楚特征提取、特征融合和输出头同时裂缝目标在图像里细长、分布零散恰好适合用这类 anchor 敏感的目标检测模型做定位。标题里的 Python YOLOv5本质是一条完整链路准备 Python 环境、配置裂缝数据集、训练检测权重、验证指标、再导出模型供演示程序调用。下面按这个顺序展开使用 640 像素输入、矩形推理和切片补丁来弥补小裂缝漏检问题最后给出一个可以写进毕业设计说明书的量化评估方法。2. 用 Python 3.9 虚拟环境跑通 YOLOv5 的 detect.py2.1 读懂 YOLOv5 源代码骨架入口脚本与配置文件拿到一个基于 PythonYOLOv5 的路面桥梁裂缝检测项目包压缩包里通常有 detect.py、train.py、val.py、export.py 这类入口脚本。它们和 YOLOv5 官方仓库的组织方式一致models/ 目录存放 yolov5s.yaml、yolov5m.yaml 等网络结构定义data/ 目录存放数据集配置weights/ 或 runs/ 目录放训练好的模型文件。先跑通这条链路再替换数据是处理这类代码最省事的方式。yolov5-crack/ ├── detect.py ├── train.py ├── val.py ├── export.py ├── requirements.txt ├── models/ │ ├── yolov5s.yaml │ └── yolov5m.yaml ├── data/ │ └── crack.yaml ├── weights/ │ └── crack.pt └── runs/说明训练脚本 train.py 只读取 models/ 下的 yaml 和 data/ 下的数据配置不直接关心图像放哪detect.py 只关心 --weights 和 --source 两个路径。如果你是第一次接手这种源码包先把目录层级截图放进毕业设计文档里后面写“系统模块设计”时能直接复用。2.2 Python 环境配置用 conda 隔离避免系统依赖互相干扰YOLOv5 项目依赖 torch、torchvision、opencv-python、pyyaml、tqdm 等常用库。常见组合是 Python 3.9、torch 1.13 左右、torchvision 与 torch 保持同版本。为了避免实验室机器已有 Python 版本混乱、numpy 版本冲突我一般会新建独立的虚拟环境conda create -n crack python3.9 -y conda activate crack pip install -r requirements.txt如果 requirements.txt 里没有锁版本或者安装之后 detect.py 报 ImportError再手动补装核心依赖。下面是这个项目里最常用的依赖对应表按顺序核对即可。依赖常见版本作用python3.8 或 3.9运行入口脚本torch1.13.1 或 2.0训练与推理后端torchvision与 torch 同版本图像变换与数据集读取opencv-python4.5 以上读图、视频处理pyyaml5.4 以上读取 yaml 配置提示安装 torch 时不必先装 CPU 版再换 GPU 版。直接在指令里指定对应 CUDA 版本的 index-url 会更省时间如果做毕设的机器只有 CPUpip 默认安装的 CPU 版同样能跑 detect.py只是训练速度明显慢。2.3 第一次用模型做路面桥梁裂缝检测虚拟环境配置好之后先用包里的 crack.pt 做一次推理验证图像读取链路、模型权重和输出目录都能正常工作python detect.py \ --weights weights/crack.pt \ --source data/images/bridge_crack.jpg \ --imgsz 640 \ --conf-thres 0.25 \ --iou-thres 0.45 \ --project runs/detect \ --name bridge_demo \ --exist-ok \ --save-txt--imgsz 640是输入网络的边长YOLOv5 会等比例缩放到 640 并补灰边--conf-thres 0.25是置信度阈值低于阈值的框直接丢弃--iou-thres 0.45是 NMS 的 IoU 阈值控制两个重叠框是否合并。裂缝项目里如果背景噪声大我会把 conf-thres 调高到 0.35如果目标是细小裂缝调低到 0.15 更稳妥。detect.py 的常用参数还有很多一张表能说清参数传入值作用--source图片路径 / 视频路径 / 文件夹 / 摄像头编号指定输入来源--classes0 或 0 1只检测固定类别--device0、0,1、cpu选择显卡或 CPU--save-txt无需值保存 txt 标注文件--save-crop无需值把每个目标裁剪成单独图片运行成功后结果写在runs/detect/bridge_demo/下。如果加了--save-txt同名 txt 文件里每行是class cx cy w h conf这些 txt 文件可以为后面的 val.py 指标计算和答辩演示页的“结果导出”功能复用。3. 裂缝数据集准备从标注格式到场景级划分3.1 YOLO 标注文件与数据配置YOLOv5 训练自己的数据集格式是每个 jpg 配一个同名 txt 文件。txt 每一行代表一个目标框0 0.492187 0.667316 0.023455 0.008912 0 0.132812 0.845703 0.045312 0.011123第一个数字是类别编号本项目中 0 对应 crack后四个数字分别是归一化的中心点 x、归一化的中心点 y、归一化的宽度 w、归一化的高度 h。除以图像宽度和高度之后所有值都在 0 到 1 之间。裂缝文本往往占行数不多因为每条裂缝一般对应一个或两个长条框不要把同一个连续裂缝拆成几十个小块否则训练时正样本比例会失衡。数据目录按 YOLOv5 约定组织如下datasets/crack/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/data/crack.yaml指向该目录即可path: ../datasets/crack train: images/train val: images/val test: images/test nc: 1 names: [crack]path一般写相对于训练脚本的位置train和val会自动拼接成完整目录。如果图像和标签结构不匹配训练时会报No labels found in ...需要先去检查 images 和 labels 下的文件名是否完全一致包括后缀。3.2 半自动标注用初始模型预标注再人工修正做一个裂缝检测项目纯手工标注过 1000 张 4K 桥面照片会把时间耗完。常见做法是先用已有模型给一批未标注图片生成候选框再导入标注工具修改。预标注的生成命令仍然是 detect.py只是同时保留 txt 和置信度python detect.py \ --weights weights/crack_v0.pt \ --source data/raw_images/ \ --classes 0 \ --conf-thres 0.3 \ --save-txt \ --save-conf \ --project data/pre_labels--classes 0限定输出 crack 这一类避免模型把它认识的其它目标也写进 txt--save-conf会把置信度附在第 5 位之后但最终进入训练的 txt 文件要去掉置信度那一列。人工校正时用 LabelImg 或 X-AnyLabeling 打开原图和预标注 txt重点做两件事把误检的桥梁伸缩缝、青苔、水渍删掉把断裂的裂纹片段合并成一个完整框或两个相邻框。半自动标注不必追求一开始就准确第一次先做 100 张训练出的权重马上可以用于下一个循环。3.3 训练/验证集划分按桥洞场景分组避免数据泄漏检测模型的验证指标只有在“验证集和训练集不重叠”时才有意义。路面和桥梁图像常常同一场景连续拍摄几十帧如果直接整体随机分成 train 和 val同一桥洞的不同角度会同时出现在两边val 的 mAP 会虚高答辩时拿真实图片一测就露馅。我一般先用文件名前缀代表场景按场景分组后切分import glob, random random.seed(42) scene_map {} for jpg in glob.glob(data/raw/*.jpg): name jpg.split(/)[-1] scene name.split(_)[0] # 例如 bridge_07.jpg - bridge scene_map.setdefault(scene, []).append(name) scene_list sorted(scene_map.keys()) random.shuffle(scene_list) val_scenes set(scene_list[:len(scene_list) // 5]) for scene, files in scene_map.items(): destination val if scene in val_scenes else train print(scene, destination, len(files))这段脚本先把文件名按场景聚合再决定场景归属 train 或 val同场景的帧会进入同一集合。需要额外留一份 test 时可以从 val_scenes 中再取一半做 test但选择 best.pt 不要用 test 结果。数据划分建议比例用途train70%训练参数val20%选 checkpoint 和调超参test10%最终演示与报告测试对路面桥梁裂缝这类弱纹理目标数据增强参数先从 YOLOv5 自带的 hyp.scratch-low.yaml 起步mosaic 和 fliplr 默认开启足够不要一上来就把旋转角度调到 90 度。裂缝是近似线性的过强旋转会让框的含义变得不稳定先训练一版看漏检率再决定增强强度。4. 训练自己的裂缝模型从 YOLOv5 网络结构到超参数设置4.1 YOLOv5 网络结构s/m/l/x 与显存取舍YOLOv5 网络结构由 Backbone、Neck、Head 三部分组成。Backbone 用 CSPDarknet 提取特征Neck 用 PANet 做多尺度融合Head 输出 3 个尺寸的预测矩阵分别对应小目标、中目标、大目标。models/yolov5s.yaml 里的 depth_multiple 和 width_multiple 控制层重复次数和通道倍数因此同一个 YOLOv5 网络结构可以有四种量级配置depth_multiplewidth_multiple常见适用显存yolov5s0.330.508GB 左右yolov5m0.670.7512GB 左右yolov5l1.001.0016GB 左右yolov5x1.331.2524GB 以上路面桥梁裂缝是相对细长的目标不是极小的行人目标。用 640 输入时YOLOv5s 的 Head 最小分支 stride 8已经能覆盖常见的裂缝宽度。如果标注框的宽度只有 10 像素左右则不要让 width_multiple 过大优先提高 imgsz 到 960或者采取第 6 章会讲到的切片推理都比直接换大模型更有效。4.2 yolov5 超参数与自己的数据集训练命令拿到整理好的数据集后训练命令会这样写python train.py \ --data data/crack.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --epochs 150 \ --batch-size 16 \ --imgsz 640 \ --workers 8 \ --cache ram \ --hyp data/hyps/hyp.scratch-low.yaml \ --project runs/train \ --name crack_v1 \ --exist-ok--cfg指定网络结构--weights指定预训练权重。第一次训练建议用 yolov5s.pt 而不是随机初始化因为预训练权重已经学会边缘和纹理特征对裂缝这类几何形状的目标有明显帮助。--epochs 150在本任务中通常够用但实际看 val mAP 是否还有上升--batch-size受显存限制Batch 从 16 降到 8 时学习率也应同步下调。yolov5 超参数不需要全部手调前期只关注几个最主要的超参数默认含义影响lr0初始学习率太大训练振荡太小收敛慢lrf最终学习率系数一般 0.1 或 0.01warmup_epochs前几轮预热避免初期梯度爆炸mosaic四张图拼接增强对裂缝长条形状影响较大fliplr水平翻转概率通用保持默认 0.5训练过程会在runs/train/crack_v1/下生成 results.csv、confusion_matrix.png、labels.jpg 和 weights 目录。weights/best.pt保存验证集 mAP 最高的一轮weights/last.pt保存最后一轮结果两者用途不同。用 TensorBoard 看曲线tensorboard --logdir runs/train/crack_v1重点看 val/box_loss 是不是在 40 轮附近仍有下降val/cls_loss 对单类别任务参考价值不大如果 val/box_loss 反复波动多为学习率偏大或 batch 过小。4.3 断点续训与训练中断恢复训练到一半断掉是最常见的问题。YOLOv5 提供了--resume参数只要保存了 last.pt 就能继续python train.py --resume runs/train/crack_v1/weights/last.ptresume会自动读取训练时的数据配置文件和当前 epoch不需要重新写一遍超参数。注意如果训练后又修改了data/crack.yaml或者把 imgsz 从 640 换成 960resume 会出现状态不一致遇到这种情况我会直接从当前 best.pt 重新开始新的训练实验。提示如果对裂缝漏检率不满意先检查 val/box_loss再回看标注中是否有大量漏标样本。漏标是裂缝检测低 mAP 的第一原因其次才是背景误检。5. 模型验证、ONNX 导出与部署参数5.1 用 val.py 量化 mAP 与 PR 曲线训练结束后官方推荐的验证命令是python val.py \ --weights runs/train/crack_v1/weights/best.pt \ --data data/crack.yaml \ --imgsz 640 \ --conf-thres 0.001 \ --iou-thres 0.6--conf-thres 0.001看起来很低但验证集评估时必须用低阈值采集足够的置信度样本才能画出完整 PR 曲线--iou-thres 0.6是判断预测框与真值框是否匹配的 IoU 阈值。验证完成后输出 mAP0.5、mAP0.5:0.95 以及 Precision、Recall。对裂缝检测来说mAP0.5 比 mAP0.5:0.95 更直观因为裂缝框长宽比很大IoU 计算比普通目标更容易受轻微偏移影响。指标推荐关注值实际含义Precision0.75 以上框中确实有裂缝Recall0.8 以上真裂缝尽量被召回mAP0.50.7 以上整体排名质量mAP0.5:0.950.4 左右即可框回归精度如果 Recall 明显低于 Precision常见做法是降低 conf-thres 并增加正样本增强。runs/val/exp/目录中的 PR_curve.png 和 labels.jpg 可以直接放进毕业设计文档前者说明模型整体性能后者说明标注分布答辩老师通常会问这两张图。5.2 导出 ONNX 模型将 NMS 放到推理端毕业设计演示阶段往往需要嵌入式工控机或 Web 后端调用模型这时继续依赖 PyTorch 的 Python 环境并不理想。用 export.py 可以导出 ONNXpython export.py \ --weights runs/train/crack_v1/weights/best.pt \ --include onnx \ --opset 12导出得到的best.onnx仍包含 YOLOv5 Head 的全部输出NMS 默认不在 ONNX 内部。推理时先做 letterbox 预处理再把输出张量还原为图像坐标import cv2, numpy as np, onnxruntime img cv2.imread(bridge.jpg) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) ratio min(640 / img.shape[1], 640 / img.shape[0]) resized cv2.resize(img, (int(img.shape[1]*ratio), int(img.shape[0]*ratio))) canvas np.full((640, 640, 3), 114, dtypenp.uint8) canvas[:resized.shape[0], :resized.shape[1]] resized这段代码把原图按比例缩放到 640再补到 640x640。canvas 经过 transpose 和归一化后输入 onnxruntime输出形状为(1, 25200, 5nc)需要先按类别置信度过滤再做 NMS。很多刚接手项目的人会直接读 PyTorch 的 decode 代码而 ONNX 端的 decode 逻辑略有差异。5.3 部署时最值得调的两个参数ONNX 或 PyTorch 模型在真实摄像头前表现不佳通常不是模型结构问题而是输入尺寸和置信度阈值。输入尺寸路面桥梁原图动辄 4000x3000直接 640 推理会丢失细小裂缝。建议部署端用切片或者把 imgsz 提高到 960但后者会让 GPU/CPU 推理时间增加 2 倍左右。置信度阈值真实场景的误检主要来自沥青纹理、水渍、护栏阴影。现场遇到连续误检时把 conf-thres 从 0.25 升到 0.4再观察召回率是否有实际损失如果只是误检说明训练数据里缺背景负样本要在数据集中加入大量无裂缝的纯背景图。6. 裂缝检测毕业设计加分点切片推理与面积统计6.1 用切片推理召回更小的裂缝直接对整张大图做一次检测小裂缝会被图像下采样稀释。常见做法是把原图按 640x640 切成若干块相邻块保留一定重叠检测后再把框偏移回原图坐标TILE_SIZE, OVERLAP 640, 64 for y in range(0, H, TILE_SIZE - OVERLAP): for x in range(0, W, TILE_SIZE - OVERLAP): crop img[y:yTILE_SIZE, x:xTILE_SIZE] preds run_640_model(crop) for pred in preds: pred[xmin] x pred[ymin] y每个切片的框要经过全图 NMS重叠区域的重复框靠--iou-thres 0.45合并。这个策略能在不更改训练代码的情况下提升 recall尤其对桥面边缘的细微裂缝效果明显。代价是推理时间按切片数量倍增实时摄像头场景需要配合多线程或 frame 间隔。6.2 把检测框换算成裂缝面积占比毕业设计里除了画框最好给一个量化指标。基于检测结果可以近似估计裂缝在图像中的占比crack_pixels 0 for box in crack_boxes: crack_pixels box.w * box.h ratio crack_pixels / (W * H)这个计算虽然不是像素级分割但用于基建巡检报告的“裂缝相对面积”排序是够用的。框的长宽也能进一步导出“主裂缝走向”把每个框的宽高比输出到 csv再按帧统计均值就能写出“该桥面最多出现横向裂缝或纵向裂缝”一类的结论。将切片得到的所有局部框拼回原图再把这些框坐标写入同一个 GeoJSON 字段后续统计代码只需要遍历该字段即可。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门