ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Python+YOLOv5实现路面桥梁裂缝检测识别全流程解析

Python+YOLOv5实现路面桥梁裂缝检测识别全流程解析 简介基于Python与YOLOv5的路面桥梁裂缝检测识别项目面向计算机视觉、人工智能等专业的在校生、教师及开发人员旨在解决道路与桥梁表面裂缝的自动检测问题可作为毕业设计、课程设计或项目演示的完整参考。资源包共85个文件以Python源码、YOLOv5模型配置、Shell脚本和示例图像为主还包含文档说明、预训练模型及结果截图压缩包仅1.6MB轻量易部署。已有271人学习使用项目实用性获充分验证。代码提供摄像头实时检测和本地图片检测两种入口支持快速接入视频流或静态图像同时附带Dockerfile与自动下载权重的脚本以及整理好的训练参数和目录说明能够帮助读者从环境搭建、模型推理直到结果可视化完整走通流程。无论是初次接触YOLOv5的初学者还是需要完成裂缝识别类毕设的学生均可基于此项目快速复现、改进或二次开发。1. 基于PythonYOLOv5的路面桥梁裂缝检测识别要解决什么路面和桥梁上的裂缝是基础设施评估的核心指标传统巡检靠人眼记录缝长、宽度和走向效率低且主观性强。基于Python和YOLOv5的目标检测方案把问题从“找到裂缝”变成“在图片中画框分类”配合源代码、训练好的模型和一批带标注的数据可以在单台GPU机器上完成从训练到推理的闭环。这种方案在毕设和工程试点里都非常常见因为YOLOv5源码结构简单、超参数开放遇到“yolov5环境配置”和“yolov5训练自己的数据集”这类问题能搜到大量可参考的处理思路。这里不写夸大其词的蓝图直接记录实际搭建时会用的命令、参数和踩坑点。2. 裂缝检测识别场景下的YOLOv5选型与数据准备2.1 对比主流检测模型后我为什么选YOLOv5桥梁裂缝检测是典型的小目标识别场景裂纹细长、走向不规则周边还有阴影、车辙、水渍干扰。选择检测模型时我一般先看三点Python生态成熟度、训练显存门槛、自定义数据适配难度。Faster R-CNN检测精度高但推理慢训练时需要单独管理RPN anchor部署时对Python版本敏感SSD速度快但小目标层设计较旧neck阶段没有FPN对细长裂缝很容易漏检。YOLOv5在通用数据集上的mAP不算顶尖但因为源码把anchor、NMS、数据增强、损失函数全拆成了可修改的独立模块在裂缝这类长尾小目标上调整空间比同期其他模型更顺手。社区里大量讨论的“yolov5网络结构”和“yolov5超参数”都有现成分析改动一处配置基本可以预期效果变化的方向。模型推理速度同硬件小目标裂缝表现源码可修改性社区资料量Faster R-CNN慢中差少SSD快差中少YOLOv5快好需要调参好很多YOLOv8快好中正在变多2.2 裂缝数据集解压后怎么标注成YOLO格式数据是裂缝检测的瓶颈。下载的裂缝检测数据zip解开后常见结构是images和labels两个平级目录或者直接是标注工具导出的文件夹。如果里面是mask图就需要转成矩形框标注如果完全没有标注只能用LabelImg或AnyLabeling手工画框。采集图片时固定相机到路面的距离让裂纹宽度在图像中占3到5个像素以上避免标注框缩小到3x3这种无意义的尺度。标注导出选YOLO格式每张图会生成同名txt内容格式是0 0.6125 0.3341 0.1203 0.0658第一个0是类别id后面四个数分别是归一化后的框中心x、框中心y、框宽、框高。注意裂缝框不要死贴裂纹单像素边缘稍微留一点背景能让模型学到裂纹的上下文纹理减少把沥青颗粒当成裂缝的误检。我见过有同学用LabelImg的自动贴合功能导致大量宽度只有2px的锚框训练时几乎全部变成负样本。2.3 用Python脚本划分训练集与验证集标注完的文件夹通常只有images和labels两个目录需要按比例拆成train和val。直接手动复制容易漏文件我一般写一个小脚本import os import random import shutil from pathlib import Path dataset_dir Path(crack_dataset) random.seed(42) images list((dataset_dir / images).glob(*.jpg)) random.shuffle(images) val_ratio 0.2 val_count int(len(images) * val_ratio) train_files images[val_count:] val_files images[:val_count] for split, file_list in [(train, train_files), (val, val_files)]: (dataset_dir / split / images).mkdir(parentsTrue, exist_okTrue) (dataset_dir / split / labels).mkdir(parentsTrue, exist_okTrue) for img_path in file_list: label_path dataset_dir / labels / f{img_path.stem}.txt if not label_path.exists(): print(fmissing label: {label_path}) continue shutil.copy(img_path, dataset_dir / split / images) shutil.copy(label_path, dataset_dir / split / labels)这段脚本用random.seed(42)固定随机顺序确保每次划分结果一致。val_ratio0.2是常见设置如果总图片数不足200张我会把比例降到0.15多留训练样本。脚本用拷贝而不是移动原始标注保留一份后续重新划分或增量添加数据都方便。它还检查了每张图片是否存在对应txt这是数据标注里最隐蔽的坑漏标一张图训练时会在数据加载阶段报“No labels found”。3. 基于Python搭建YOLOv5裂缝检测推理环境3.1 Python虚拟环境与PyTorch安装搭建YOLOv5环境前先确认GPU和驱动是否匹配。终端输入nvidia-smi查看CUDA大版本然后安装相同主版本的PyTorch如果驱动不支持较新的CUDA就换一个cu117版本。常见做法是新建conda环境避免和系统Python冲突conda create -n yolov5 python3.9 -y conda activate yolov5 pip install torch1.13.1 torchvision0.14.1 --index-url https://download.pytorch.org/whl/cu117选择Python 3.9是因为YOLOv5官方文档覆盖3.8到3.113.9和PyTorch的兼容性最稳。torch和torchvision版本必须成套否则会出现意外退出或“syntax error in module”这种混淆报错。如果机器没有GPU可以装CPU版但训练500张图的数据集会比GPU慢十倍以上只建议用来跑推理demo或验证环境。安装完torch后进入项目目录安装其余依赖pip install -r requirements.txt主要依赖和用途如下表依赖库用途常见坑numpy数值运算版本过高与旧YOLOv5不兼容opencv-python图片读取与结果绘制需要4.xmatplotlib训练曲线与结果图无seaborn混淆矩阵可视化无pandas统计标签分布无tensorboard日志可视化可选安装完依赖后如果import torch报错先执行python -c import torch; print(torch.version)再检查numpy是否被覆盖成2.x。YOLOv5早期代码里很多地方用numpy.float64新版numpy移除了这个属性最常见的报错就是TypeError: numpy.float64 object cannot be interpreted as an integer解决方案是把numpy固定到1.23.5。3.2 拉取YOLOv5源代码并跑通最小推理环境准备好后克隆官方仓库固定commit避免上游改动导致文档命令失效git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt然后跑官方预训练权重做一个最小验证python detect.py --weights yolov5s.pt --source data/images/bus.jpgdetect.py是YOLOv5自带的推理入口。--weights可以指向已经存在的yolov5s.pt文件它会在第一次运行时尝试下载网络环境差时建议手动放置到项目目录。--source支持单张图片、目录、视频文件和摄像头编号0。跑完后结果写入runs/detect/exp输出的是原图叠加上边框、类别名和置信度的结果图。裂缝推理时我常调低置信度阈值python detect.py --weights yolov5s.pt --source ./crack_test.jpg --conf-thres 0.2 --iou-thres 0.45 --img-size 640--conf-thres是置信度阈值低于该分数的框会被过滤。裂缝纹理细网络输出的conf通常不算高阈值调到0.2能多召回一些局部裂纹候选框。--iou-thres是NMS的IoU阈值两个框的重叠比例超过它时分数低的会被丢弃。裂缝类别内部的重叠框本身较多我保持0.45默认值调太高会让同一道裂缝被重复画成多个框。3.3 用加载本地模型的方式检测桥梁裂缝训练完自己的模型后不需要改动源码只要把--weights指向runs/train里的best.pt即可python detect.py --weights runs/train/exp/weights/best.pt --source ./test_cracks --conf-thres 0.25 --save-txt --project ./crack_results--weights换成自己训练得到的权重文件训练时的类别数已经固化在权重里。如果类别数和模型定义的nc不一致模型加载阶段就会报错。--save-txt会在输出目录生成每个输入图片的标签预测txt包含class_id、置信度、归一化框坐标方便后续统计检测率和漏检率。--project指定结果输出根目录避免每次覆盖掉旧的runs/detect/exp。这里最常见的错误是把best.pt单独拷到另一台机器同时把训练时的crack.yaml忘在项目里推理时类别索引串位。解决办法是在inference时显式加载训练时的yaml用yaml里的nc和names初始化模型结构。通常我会把crack.yaml、best.pt、测试图片放在同一个目录归档目录名包含日期跑几个月后还能准确还原当时的模型配置。4. 训练自己的桥梁裂缝模型的超参数与数据集配置4.1 编写crack.yaml数据集配置文件YOLOv5训练前必须有一份描述数据集路径和类别数的yaml。我习惯放在项目目录下path: ../crack_dataset train: train/images val: val/images nc: 1 names: 0: crackpath字段是数据集根目录相对于yaml所在位置也可以是绝对路径。train和val是相对于path的图片目录YOLOv5会自动去同级labels目录找同名txt所以第2章的目录划分必须保留images和labels的配对关系。nc设置类别数量如果要把横向裂缝、纵向裂缝、网状裂缝分开检测就把nc改成对应数字并确保txt里的类别id与names一一对应。配置完成后先用一轮训练验证数据是否可读python train.py --data data/crack.yaml --weights yolov5s.pt --epochs 1 --batch-size 8 --img 640只要跑完一个epoch不报错说明图片路径、标注格式、类别数都配对了。如果报FileNotFoundError先检查路径是否有中文或空格如果报AssertionError: train labels not found先检查labels目录下是否有txt以及文件名是否和图片一致。4.2 训练命令与超参数调整正式训练我通常的起始命令是python train.py --data data/crack.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --img 640 --device 0 --workers 4 --adam参数逐一说明--epochs是完整轮数数据集小可以加到200--batch-size受显存限制太小会导致梯度更新不稳--device指定GPU--workers是数据加载线程数Windows下建议从2开始调太高会出现DataLoader worker崩溃。常用超参数的入口和推荐值超参数位置/入口推荐值作用说明epochstrain.py命令行100-200迭代轮数小数据集适当增大batch-sizetrain.py命令行16/32受显存限制过小训练不稳定img-sizetrain.py命令行640/1280输入尺寸裂缝小则调大lr0hyp.scratch-low.yaml0.01SGD初始学习率过大会震荡mosaichyp.scratch-low.yaml1.0四图拼接增强可关闭mixuphyp.scratch-low.yaml0.0-0.2图混合增强裂缝不建议开高weights用yolov5s.pt可以基于COCO预训练权重微调收敛明显更快。裂缝数据里大量背景是沥青和混凝土和COCO的自然图像分布差异大但迁移仍然有效。优化器方面Adam在小数据集、不规则目标上更稳SGD在数据量大时上限更高。我习惯先用50个epoch试跑观察第20轮左右的验证指标如果还在下降就继续跑到100。4.3 通过训练日志和结果指标判断模型状态训练时终端每轮输出一组指标Epoch gpu_mem box obj cls labels img_size 99 6.89G 0.023 0.011 0.000 3 640 Class Images Labels P R mAP.5 all 200 450 0.92 0.87 0.935box是边框回归损失obj是置信度损失cls是分类损失。裂缝只有一类cls低是正常的。关键要看验证集上的P、R和mAP.5P是预测框中有多大概率真的是裂缝R是所有真实裂缝中有多大比例被捡出来。mAP.5衡量预测框与真实框IoU超过0.5时的平均准确率桥梁裂缝这种容易漏检的场景R比P更值得关注。训练结束后runs/train/exp目录下会生成results.png里面画了损失和P、R、mAP随epoch变化的曲线。判断过拟合的方法很直接训练损失一直在降但验证mAP开始振荡或降低就是过拟合信号。如果训练最后阶段的R只有0.7左右优先去检查标注框是否太小、是否漏标了远处细小的裂缝。再动手画一下检测结果python detect.py --weights runs/train/exp/weights/best.pt --source data/crack_val --conf-thres 0.2打开输出图时看到裂缝框断成好几段通常是输入分辨率不够看到框把背景大面积包进去则要检查标注框是不是留了太多路边护栏。5. 裂缝检测模型调参与ONNX导出部署5.1 提升小目标裂缝召回率的三个可操作手段裂缝模型最常见的失败是远处细裂纹漏检以及把阴影当裂缝。第一个手段是调整anchor的宽高比。YOLOv5默认anchor覆盖0.5到2的长宽比但裂缝框通常是细长条宽高比可以达到5以上。可以单独跑一个k-means脚本重新聚类自己训练集上的真实框尺寸再把聚类得到的anchor写进模型配置。这个方法改动小但能明显缓解竖向裂纹被截成多段的问题。第二个手段是提高输入分辨率。把--img从640提高到1280小裂缝在特征图上能占据更多有效通道漏检率下降明显。显存不够时把batch-size减半或者改成切片推理把大图切块传入模型再合并结果。切块时相邻区域保留10%到20%重叠否则裂缝正好跨在切块边界上会被切碎。第三个手段是训练时修改hyp.scratch-low.yaml里的scale和shear。scale控制多尺度随机缩放对细长目标来说要加强训练。mixup这类混合增强会生成半透明叠影裂缝在叠影里变得模糊我一般把mixup保持0或者0.1换来更稳定的检测输出。5.2 模型导出为ONNX并用onnxruntime加载现场部署时不想带一整套PyTorch环境我会把best.pt导出成ONNXpython export.py --weights runs/train/exp/weights/best.pt --include onnx --opset 11导出成功后best.onnx可以用onnxruntime加载并推理import onnxruntime as ort import numpy as np import cv2 sess ort.InferenceSession(best.onnx) input_name sess.get_inputs()[0].name image cv2.imread(crack.jpg) image cv2.resize(image, (640, 640)) image image[:, :, ::-1].transpose(2, 0, 1).copy() image image.astype(np.float32) / 255.0 input_data np.expand_dims(image, axis0) outputs sess.run(None, {input_name: input_data})ort.InferenceSession接收导出的ONNX文件路径。input_name从模型输入节点里自动读取避免写错张量名。图像前处理做了resize、BGR转RGB、通道换序、归一化和YOLOv5的惯例一致。onnxruntime输出的是模型末尾的特征图还需要继续做NMS才能得到最终的类、分数和框。NMS逻辑可以直接从detect.py对应调用的utils/general.py里把non_max_suppression函数整段复制出来再把输入tensor换成sess.run的输出即可。加载本地模型时要记得让输入分辨率与训练时的--img一致否则输出的框坐标会整体偏移。推理结束后用原图尺寸还原归一化坐标再叠加cv2.rectangle就能得到最终检测图。我在维护这类项目时还有一个固定习惯每次训练完成后把crack.yaml、训练命令、best.pt和测试集结果图放进同一个日期目录。这样任何一个环节出现回归都不需要去猜当时用的超参数直接从归档目录里复制命令重跑即可。本文还有配套的精品资源点击获取
返回列表