基于Python+YOLOv5的裂缝检测识别源码与模型详解

发布时间:2026/10/13 0:05:59
基于Python+YOLOv5的裂缝检测识别源码与模型详解
简介基于Python与YOLOv5框架的路面桥梁裂缝检测识别项目面向计算机视觉方向学习者及毕业设计、课程设计人群提供完整源码与预训练模型可直接运行并用于路面、桥梁裂缝目标检测。资源涵盖YOLOv5各版本模型配置、数据集定义、训练/检测脚本、权重下载脚本及Dockerfile等工程化内容支持图片检测与摄像头实时检测场景适合作为目标检测实战练习或项目落地的参考方案。压缩包共85个文件以Python源码、yaml配置、Shell脚本及少量示例图片为主整体大小约1.58MB轻量易部署目录按models、utils、data、scripts等模块组织结构清晰便于二次开发与学习。目前已有180人学习下载该项目评审分达98分内容经助教审定、难度适中能够满足学习、期末大作业等需求适合希望快速上手YOLOv5并完成路面病害检测任务的开发者。1. 从“肉眼巡路”到“源码级裂缝检测”这个项目到底在解决什么路面桥梁裂缝检测是结构健康监测里出现频率最高的需求之一。标题里这套基于PythonYolov5的裂缝检测识别源码模型属于典型的工程全流程项目从标注图片到训练出能框出裂缝的模型再到Python推理输出整条链路都开源。它能解决的具体问题很明确——你手里有一批桥梁或路面巡检照片想让程序自动把裂缝位置和范围框出来不用人眼在一张大图上慢慢找。适合两类人一是毕业设计想快速跑通全流程的学生二是想评估YOLO在结构病害检测上性价比的工程师。先放一个反直觉结论这类项目很少死在模型结构上多数翻车点在标注质量、anchor参数和训练超参数这些才是花时间的地方。2. 裂缝检测为什么绕不开Yolov5模型选型与检测思路2.1 裂缝在检测任务里是什么小目标、长条形、低对比度裂缝不是普通目标。路面裂缝的视觉特点是长度可以跨几十甚至上百像素宽度只有几个像素颜色接近沥青或混凝土背景还经常被阴影、水渍、车辙印干扰。普通目标检测中“目标占居中区域”的假设在裂缝身上经常失效。YOLOv5把输入图片划分成S×S网格每个网格负责预测中心点落在该网格的目标一条横向裂缝横跨十几个网格任何一个网格看到的都只是其中一小段模型必须把局部特征和上下文特征结合起来才能输出一个完整框。这就是为什么很多人第一次训练裂缝模型loss收敛了但框全是碎的。更麻烦的是对比度。裂缝在灰度图上的梯度幅值和混凝土麻面、沥青颗粒的纹理差异很小模型很容易把“裂缝边缘”和“纹理噪声”混淆。你可以做一个直观实验把一张裂缝图做Canny边缘检测会发现裂缝轮廓和不规则裂纹、石子阴影混在一起根本无法靠简单的图像处理分开。这也是为什么深度学习检测方案能替代传统opencv阈值方法的核心原因——模型学的是上下文语义而不是局部梯度。YOLOv5的另一个现实约束是anchor机制。它预设了三种尺度的anchor框训练时计算预测框和真实框的IoU匹配上的anchor才参与回归。默认anchor是从COCO这类自然图像集里聚类出来的宽高比接近行人、汽车、猫狗而裂缝的宽高比动辄1:10以上。匹配阶段如果真实框和所有anchor的IoU都低于阈值这个样本就被当成背景梯度对裂缝完全不敏感。后面会说怎么解决但这里先记住一个结论直接拿默认预训练权重跑裂缝数据mAP大概率低于0.5。2.2 Yolov5对比Faster R-CNN、SSD工程向选型的三个理由选型不能只看论文里的精度表。我做结构病害检测项目时选YOLOv5是因为三个工程理由按优先级排第一训练和推理的成本都低。Faster R-CNN理论上对中小目标更友好但RPN阶段的候选框生成、NMS调参、训练显存占用在只有一张消费级显卡的环境下很吃力。YOLOv5用单阶段结构把训练显存压得很低常见的GTX 1060 6G就能跑通小数据集这对学生机和普通办公电脑很关键。第二源码把整个训练链路串好了。从数据加载、在线增强、训练日志、checkpoint保存到TensorBoard可视化YOLOv5的仓库里都是现成的。你不需要自己写数据pipeline这对“快速跑通一个完整项目”的价值比模型精度大得多。特别是你要做毕业设计或技术预研时间比那1%的mAP更宝贵。第三社区资料密度足够。yolov5网络结构图、yolov5超参数、yolov5后处理、yolov5训练自己的数据集这些关键词在网上的讨论量非常大。工程师遇到问题能搜到现成答案学生复现项目时不容易卡死。Faster R-CNN和SSD也有开源实现但资料大多停在论文复现代码遇到工程问题很难搜到有效的排错记录。下面这张表是我在选型时常用的对比维度基于常见开源配置的定性结论维度YOLOv5Faster R-CNNSSD训练显存占用低高中推理速度快可上边缘设备慢端到端延迟高快小目标召回中需调整anchor和输入尺寸高低调参资料密度高中低工程集成难度低API完整中中如果你手里有充足显存和高精标注数据Faster R-CNN或许能拿到更高上限但在“要快速出结果、资源有限、裂缝细长且样本不均衡”的现实条件下YOLOv5是投入产出比最高的起点。2.3 网络结构图与后处理源码和模型文件里藏着什么YOLOv5的网络结构图在网上很常见主体分三块Backbone用CSPDarknet提取特征Neck用PANet做多尺度特征融合Head输出三个尺度的预测结果。裂缝这种小目标主要靠大尺寸特征图来检测——输入640×640时Head的最小特征图是80×80每个格子对应原图8个像素。这意味着宽度小于8像素的裂缝基本无法被检测很多桥梁裂缝项目把输入设成1280×1280就是为了让细裂缝在特征图上至少占一个点。后处理也值得仔细读源码。Head输出的不是最终框而是anchor偏移量、置信度和类别概率。decode之后要经过NMS去掉重叠框。很多人在推理时只调了conf_thres和iou_thres却忽略了anchor本身不适合裂缝宽高比。在YOLOv5的推理和训练逻辑里anchor既是回归基准也决定哪些样本被视为正例。如果你想确认当前模型用的是什么anchor可以跑下面这行命令让它把anchor信息和聚类结果打出来python utils/autoanchor.py --cfg models/yolov5s.yaml --data data/crack.yaml运行后会在终端显示当前anchor和重新聚类后的anchor计算出的召回率。如果两者差很多说明默认anchor确实不适合裂缝数据。后面训练时可以让YOLOv5自动重聚类也就是训练命令里不加--noautoanchor让它在训练开始前按你的标注框重新生成一组anchor。这个步骤被很多人忽略但它对裂缝这种极端长宽比目标的影响比换backbone还明显。3. 把桥梁裂缝照片变成YOLO能读懂的标签数据准备与标注3.1 裂缝数据集从哪来自己拍、公开数据集、增强补量标题里的“源码模型”通常自带一份训练好的权重但这不代表你可以跳过数据准备。要训练自己的场景——比如你们桥检车拍的是带水渍的混凝土箱梁而自带模型学的是干净沥青路面——就必须有自己的数据。常见的数据来源有三种。第一种是改造公开数据集。网上有不少路面裂纹图像集但大多是分类任务这张图有没有裂缝没有检测框。你需要自己用标注工具在里面框出裂缝。第二种是自己拍用手机或工业相机对着路面、桥墩、箱梁拍注意包含不同光照、不同角度、不同裂缝宽度。第三种是在已有图片上做增强补量。标注工具推荐LabelImg把标注结果存成Pascal VOC XML再转成YOLO格式。这里有一个我踩过的教训不要一开始就分“横向裂缝”“纵向裂缝”“网状裂缝”多个类别。数据量不够时模型会把类别边界学得乱七八糟因为裂缝形态是连续变化的横向和纵向之间没有清晰界线。先用一个类别“crack”跑通全流程等确认检测稳定了再考虑按裂缝形态细分。标注规范也要提前定好裂缝框要贴合裂缝主体区域把断断续续的裂缝段尽量圈进同一个框如果一条裂缝贯穿整张图可以用多个框分别标注后处理阶段再合并这个后面避坑部分会细说。3.2 VOC XML转YOLO txt的转换脚本与四个边界坑LabelImg默认保存为XML格式YOLOv5训练需要的是txt文件每一行对应一个框。转换脚本是这类项目的第一个技术门槛我一般用下面这个脚本import xml.etree.ElementTree as ET import os from glob import glob class_list [crack] # 类别表顺序必须和data.yaml完全一致 def convert_label(xml_path, txt_path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) with open(txt_path, w) as f: for obj in root.iter(object): cls obj.find(name).text if cls not in class_list: continue cls_id class_list.index(cls) box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) if x2 x1 or y2 y1: continue # 无效框直接跳过 # 转YOLO格式类别 中心x 中心y 宽 高全部归一化到0-1 cx (x1 x2) / 2 / img_w cy (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h f.write(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}\n) # 批量转换 os.makedirs(labels_txt, exist_okTrue) for xml_file in glob(labels_xml/*.xml): txt_file os.path.join(labels_txt, os.path.basename(xml_file).replace(.xml, .txt)) convert_label(xml_file, txt_file)脚本逻辑不复杂核心是归一化YOLO格式里的坐标全部除以图片宽高转成0到1的浮点数训练时模型再按输入尺寸缩放。这里必须强调四个边界坑。第一图片宽高一定从XML的size节点读取不能靠文件名或外部参数。我见过有人图省事写死1280×720结果训练图片是1920×1080标注框全线偏移训练出来的模型看起来收敛了推理时框全部错位。第二xmax减xmin、ymax减ymin要判断是否大于0。LabelImg偶尔会因为鼠标拖拽产生反坐标这行如果写进训练集YOLOv5的数据加载器会在loss计算时报NaN而且报错信息不会直接指向这条样本。第三XML里可能存在误标或无效的object脚本里已经用class_list过滤了但如果你的数据里混了其他类别的目标比如把钢钉也标了过滤掉后要复查txt里是否真的只有你想要的类别。第四txt文件名必须和图片文件名完全一致YOLOv5按前缀匹配图片和标签大小写差一个字母、多一个空格都会导致这张图被当成无标注样本训练时静默跳过mAP就被拉低。3.3 数据增强切片、旋转、亮度扰动裂缝数据集通常不大几十到几百张。按目标检测的经验几百张图想训练出一个稳定模型不现实。常见做法是先做“切片”把一张1280×720的大图切成多个640×640的patch裂缝在这种尺度下才更像一个“目标”。但切片后的图片数量没变所以还需要第二种增强albumentations库里的旋转、水平翻转、亮度对比度扰动。YOLOv5自带训练时的在线增强包括Mosaic、随机仿射、HSV变化这些在hyp.yaml里都有开关。但注意对裂缝这种细长目标Mosaic默认把4张图缩放到一半再拼接裂缝缩放后可能只剩几个像素宽正样本反而失效。我通常把hyp.yaml里的mosaic参数调到0.1或者直接在训练命令里关掉离线增强多做一些。增强是玄学但没有增强一定不行——这是复现项目从“能训练”到“能用”的分水岭。离线增强我一般用albumentations参数大致如下水平翻转概率0.5旋转角度在-30到30度之间亮度对比度扰动强度0.3再加上random gamma模拟桥梁上逆光和阴影的情况。增强后的图片要重新和标签做同步变换albumentations的Compose可以直接同时变换图片和bboxes不要手工先增强图片再算框那样标签会错位。4. 用Yolov5训练裂缝检测模型命令、参数与验证4.1 准备环境Python版本、依赖、目录结构YOLOv5对Python版本比较挑剔。我建议用conda建一个独立环境Python选3.8PyTorch选1.10到1.12之间CUDA版本看你显卡驱动。python安装教程网上一搜一大把这里只说容易翻车的点不要用系统默认的Python 3.11或3.12直接跑旧版YOLOv5torch和torchvision版本不匹配会让你在import阶段就报错。项目目录结构我一般这样组织yolov5/ ├── train.py ├── detect.py ├── data/ │ └── crack.yaml ├── datasets/ │ ├── crack/ │ │ ├── images/ │ │ │ ├── train/ │ │ │ └── val/ │ │ └── labels/ │ │ ├── train/ │ │ └── val/ └── runs/先git clone官方YOLOv5仓库再在datasets/crack下放自己的图片和标签。图片和标签分开是硬性规定labels目录里是第3章转换出来的txt文件。然后执行pip install -r requirements.txt。如果opencv-python和你系统里的其他库冲突优先保证torch和torchvision的匹配opencv装不上时可以单独降级不影响训练主流程。4.2 修改数据集配置与超参数yolov5训练自己的数据集必调项data/crack.yaml是训练入口内容如下train: datasets/crack/images/train val: datasets/crack/images/val nc: 1 names: [crack]nc和names必须和你转换脚本里的class_list一一对应。最容易犯的错是类别顺序不一致——脚本里class_list是[crack]yaml里names写成了[crack, net]训练不会报错但标签全错位。超参数文件hyp.scratch-low.yaml里对裂缝任务最重要的三个参数是lr0初始学习率、mosaic马赛克增强、hsv_h/hsv_s/hsv_v颜色增强。裂缝与背景的区分度本来就低hsv增强可以略微改善模型对不同光照的适应能力。我第一次跑裂缝数据时直接用默认lr00.01结果前50个epoch loss反复震荡降到0.001之后曲线才稳定下来。遇到loss不降先别怀疑模型把学习率降一个量级再试。4.3 训练命令与输出解析loss曲线和结果文件怎么看训练命令如下python train.py \ --data data/crack.yaml \ --weights yolov5s.pt \ --img 1280 \ --batch 8 \ --epochs 100 \ --hyp hyp.scratch-low.yaml \ --project runs/crack_train参数说明--img 1280意味着输入尺寸放大到1280对裂缝这种小目标非常重要代价是显存占用更高所以batch相应降到8--weights yolov5s.pt是从官方预训练权重开始迁移学习不要从yolov5x.pt开始那个模型在GTX 1060上根本跑不动--hyp指定你改过的超参数文件。训练结束后到runs/crack_train/exp目录里看results.png这张图包含train_loss、val_loss、mAP0.5、mAP0.5:0.95四条曲线。判断模型是否可用的标准不是loss多低而是val mAP0.5是否大于0.8。如果mAP一直低于0.5多半是anchor问题不是epoch不够。4.4 验证与推理detect.py和torch.hub两种方式训练完的权重在runs/crack_train/exp/weights/best.pt。推理可以直接走官方detect.pypython detect.py \ --weights runs/crack_train/exp/weights/best.pt \ --source datasets/crack/images/val \ --conf-thres 0.25 \ --iou-thres 0.45 \ --img 1280 \ --save-txt--conf-thres是置信度阈值0.25是YOLOv5默认值如果检测结果里裂缝被切碎成很多小框把这个值提高到0.3以上--iou-thres是NMS的IoU阈值0.45偏严适合裂缝这种重叠框多的场景--save-txt会额外保存每个框的坐标txt方便做后续量化分析。另一种更常见的做法是在Python程序里直接用torch.hub加载import torch model torch.hub.load(ultralytics/yolov5, custom, pathruns/crack_train/exp/weights/best.pt) results model(demo_crack.jpg, size1280) results.print() results.save(output/)torch.hub方式的好处是能把检测功能嵌进自己的业务流程里比如自动读图、检测、写报告不用每次走命令行。注意两点--img和size要保持和训练一致否则推理时的特征尺度对不上YOLOv5的后处理decode和NMS在模型内部已经完成返回的results对象里就是最终框和置信度。5. 裂缝检测源码里的5个避坑点从训练到部署的血泪经验5.1 loss降了但mAP为0先查anchor和多尺度输出现象训练曲线很漂亮val loss一直在降但mAP0.5始终是0推理时一个框都不出。原因裂缝标注框的宽度大多小于10像素YOLOv5下采样倍数最大的检测头输出是原图的1/810像素宽的框缩放到1像素左右再加上默认anchor偏方形训练时几乎没有正样本匹配。解决先用utils/autoanchor.py重新聚类anchor具体做法是训练时让它自动重算或者手动跑一遍确认。然后把输入尺寸从640提高到1280让裂缝在特征图上占更多像素。这个坑新手最容易误以为是模型结构问题其实是数据尺度问题。排查时可以在训练日志里搜“anchors”看看聚类后的anchor宽高比是不是明显偏长条如果是说明问题就在这里。5.2 一条裂缝被框成七八段调NMS阈值不如调后处理策略现象检测结果里横向裂缝被多个框切成一段一段看起来像虚线。原因裂缝中间有断开模型对每一段都给了较高置信度NMS的IoU阈值设成0.45相邻框之间IoU可能只有0.3没被合并于是一张图输出十多个框。解决把--iou-thres降到0.3同时把--conf-thres从0.25提到0.35让低置信碎片被过滤。如果还不行就在后处理里加一个“同裂缝框合并”逻辑按框中心y坐标排序重叠区域超过50%且垂直距离小于阈值就合并成一个长框。裂缝检测和普通目标检测在工程上的关键差异就在这后处理不调整模型精度再高也看不出效果。5.3 显存不够导致训练中断先降img-size再降batch现象GTX 1060 6G显存batch设16直接OOMbatch设8还是OOM。原因--img设成1280后单张图占用显存可能超过2Gbatch乘以单图显存再加上Mosaic增强的临时显存6G根本不够。解决优先把--img降到640这是性价比最高的做法还不够就把hyp.yaml里mosaic参数改成0在线增强也占显存。用梯度累积凑batch size是最后的手段YOLOv5没有内置需要自己改训练循环不建议新手碰。通常降img到640后6G显存可以勉强跑batch 8训练时间会翻倍但至少不会中途崩。5.4 白天好用晚上失效训练数据的亮度分布太窄现象训练集大多是白天顺光拍的模型在阴影、逆光、傍晚场景下的漏检率骤然上升。原因裂缝和背景的灰度差异本来就小光照一变局部对比度被抹平模型学到的特征失效。解决在hyp.yaml里把hsv_h、hsv_s、hsv_v的值调大比如hsv_h从0.015调到0.02同步做离线增强用albumentations加RandomBrightnessContrast。如果是桥梁检测这种固定机位场景还可以对输入图先做CLAHE直方图均衡化再送进模型。这个预处理能显著提升低照度下的裂缝检出率代价是每张图多几毫秒处理时间工程上完全可接受。5.5 Python环境反复报错yolov5对版本组合很敏感现象python train.py启动后先是No module named torch装完torch又提示torchvision不匹配折腾了半天还是跑不起来。原因YOLOv5的requirements.txt里pin了torch和torchvision版本但pip在Python 3.10以上环境里经常装不到精确版本两个库版本不匹配会直接引发runtime error。解决第一步conda create -n yolov5 python3.8建一个干净的Python 3.8环境这也是python安装教程里推荐的做法第二步手动pip install torch1.10.0 torchvision0.11.0再装其他依赖第三步运行python -c import torch; print(torch.version)确认能正常加载。版本匹配是这类项目里最枯燥但最值得花时间的一步环境不干净后面每一个报错都会让你怀疑模型写错了。6. 提高裂缝检出率的三个技巧验证与进阶6.1 对检测结果做连通域合并从“框裂缝”到“画裂缝”YOLOv5输出的是矩形框但裂缝是长条状。矩形框会框进大量背景定位显得不准。常见做法是拿到框内区域用Canny或自适应阈值做二值化取最大连通域做骨架提取再把骨架坐标映射回原图。这样可以把检测结果从“框住裂缝附近”提升到“贴合裂缝走向”在工程报告里写“裂缝长度”时尤其有用。代价是每张图多几十毫秒处理时间但对离线巡检分析完全够用。6.2 用TTA和多尺度推理验证模型上限改动检测逻辑前先确认模型是不是真的到了上限。detect.py里有--augment参数开启后会对图片做翻转、缩放等多尺度测试增强用多个结果投票输出。拿同一个验证集分别跑普通推理和TTA推理如果TTA的mAP明显更高说明模型还有空间优先补数据和调anchor如果两者差不多说明模型已经收敛可以把精力放到后处理优化上。这个验证方法不增加训练成本只花一点推理时间。6.3 导出ONNX做边缘部署如果要做实时巡检常见做法是导出ONNX再量化部署。YOLOv5自带export.py可以导出ONNX格式然后在RK3568这类边缘芯片上用RKNN工具链做INT8量化。裂缝检测的推理延迟要求不高但“模型能不能塞进嵌入式设备”是桥梁巡检车常问的问题。量化后精度会掉裂缝又是细长目标INT8量化尤其容易把细裂缝吞掉所以量化后必须用验证集重新评估mAP不要只看推理速度。有一回我在桥检项目里图省事跳过anchor调整直接训练mAP连着三天挂在0.3。后来发现就是默认anchor不适合裂缝的长条形。从那以后每次训练前都先跑一遍autoanchor再做数据增强顺序固定成“数据、anchor、超参数、模型结构”四步再没为模型结构的事失眠过。裂缝检测这个方向从拿到源码到真正能用中间差的就是这些细节。希望帮到你。本文还有配套的精品资源点击获取