十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

YOLOv5裂缝检测实战:从数据标注到模型部署全流程解析

YOLOv5裂缝检测实战:从数据标注到模型部署全流程解析 简介这份基于PythonYolov5的路面桥梁裂缝检测识别毕业设计项目面向计算机相关专业学生和需要项目实战的开发者可用于毕业设计、课程设计或期末大作业。项目经导师指导并获99分高分评价代码与模型完整、确保可运行即使是小白也能独立部署。压缩包共85个文件体积仅1.6MB包含23个Python脚本、23个YAML配置、5个Shell脚本以及模型权重等覆盖模型结构、数据配置、训练预测、工具函数等环节并附Dockerfile和示例图像便于快速复现与二次开发。已有80人学习浏览适合希望快速搭建裂缝检测原型并深入理解Yolov5落地流程的读者是一份完整可用的高分毕设参考方案。1. 裂缝检测这活儿为什么非要上 YOLOv5如果你做过路面裂缝检测相关的毕业设计一定体会过那种“跑通一个检测模型比写论文还难”的滋味。桥梁缝、路面网裂、横向裂缝光照一变、背景一杂传统图像处理直接失效。而基于 Python YOLOv5 的项目是现阶段把“检测精度”和“开发效率”平衡得最稳的方案——不需要自己设计网络不需要从头训练几天模型结构、训练脚本、推理脚本都是现成的你要做的是把数据喂进去、把参数调明白、把结果解释清楚。这个项目的核心价值就在这里它是完整可运行的 YOLOv5 裂缝检测工程不是只有一段算法片段train、val、detect 全链路都有能直接拿来当高分毕设的底子。适合三类人正在选题的计算机/土木交叉专业学生、需要快速产出检测结果的课程设计以及想看看 YOLOv5 在工业瑕疵检测上到底怎么落地的从业者。2. 先把工程架构看明白YOLOv5 目录、配置文件和权重这三件事2.1 目录结构决定了你后面怎么干活拿到压缩包先别急着跑 detect花 10 分钟把目录过一遍后面能少踩一半坑。项目的核心目录是 models、data、utils、runs外加两个相当关键的脚本 detect_photo.py 和 detect_camera.py。models 目录下有一套完整的模型定义文件yolov5s.yaml、yolov5m.yaml、yolov5l.yaml、yolov5x.yaml。这四个文件对应 YOLOv5 的四个不同深度和宽度的版本s 最小最快x 最大最准。裂缝这种目标特征其实不算复杂检测难度主要来自背景杂乱和光照不均s 和 m 基本够用强行上 x 只会让显存和训练时间翻倍。data 目录下预置了 voc.yaml、coco128.yaml、coco.yaml 还有裂缝检测场景用的自定义 YAML。你要做的是新建一个自己的 data.yaml指向你的裂缝数据集路径class 数量改成 1裂缝或者按你的分类数改。weights 目录里的 download_weights.sh 负责拉取预训练权重。这个脚本建议先看一眼它本质上是一串 wget 或 curl 命令把官方权重下载到本地。你完全可以手动下载然后把 .pt 文件放到 weights 目录效果没差别。runs 目录是训练和推理结果的输出位置默认会生成 detect 和 train 子目录。你跑的每一次检测结果都会按时间戳存下来翻历史结果很方便。这种目录组织方式是 YOLOv5 官方工程的标准结构好处是你以后想换成 YOLOv8 或者别的检测框架迁移成本极低因为数据组织、标签格式、训练入口几乎一脉相承。2.2 数据标注格式和 data.yaml 的写法YOLOv5 用的是归一化坐标的 txt 标签每行代表一个目标类别ID、中心点x、中心点y、宽度w、高度h五个值全部是相对图片宽度和高度的比例取值范围 0 到 1。0 0.523437 0.438672 0.081250 0.052431 0 0.312500 0.661240 0.056250 0.033729第一列的 0 代表类别 ID如果你的裂缝检测只有一类那所有行都是 0。如果你的数据集区分横向裂缝和纵向裂缝那类别 ID 就要按顺序排。标签文件的文件名必须和图片文件名完全一致后缀是 .txt图片是 .jpg比如 road_001.jpg 对应 road_001.txt放在 labels 目录下目录结构严格按照 images 和 labels 分离。data.yaml 是关键配置文件一般长这样train: ./data/road_crack/images/train val: ./data/road_crack/images/val nc: 1 names: [crack]train 和 val 指向的是图片目录不是标签目录。YOLOv5 会自动在同级目录下找 labels 文件夹。nc 是类别数这里只有裂缝一种所以是 1。names 是类别名列表索引顺序必须跟标注时用的 ID 一致。一个很常见的错误是 train 和 val 路径写成了相对路径但目录层级不对建议直接用绝对路径省得后面反复报错。2.3 超参数文件别乱改hyp.scratch.yaml 和 hyp.finetune.yaml 是什么项目里 data 目录下带了 hyp.scratch.yaml 和 hyp.finetune.yaml这两个文件控制训练的“脾气”。hyp.finetune.yaml 是给“在已有模型基础上继续微调”用的典型场景是你已经有一个训练好的裂缝检测权重换了一批新图片再训练。它的学习率、动量、数据增强参数相对保守改动幅度小不会把原先学到的特征一下冲掉。hyp.scratch.yaml 则是从零训练时的超参配置。如果你用预训练权重做迁移学习这是大多数人的做法train.py 默认加载的就是 hyp.scratch.yaml但这个文件对新手来说有几个风险点lr0 初始学习率默认是 0.01数据量小的时候这个值已经偏大容易出现 loss 直接爆炸成 nan 的情况建议降到 0.001 起步。mosaic 数据增强默认开启对裂缝这种细长目标马赛克增强会把裂缝切得七零八落反而让模型学不到完整的裂缝纹理。小数据集上建议把 mosaic 关掉或者降到 0.5。copy_paste 增强在某些版本里默认是关闭的但如果你打开它对裂缝这种小目标有一定帮助因为裂缝经常和路面背景融为一体复制粘贴可以增加正样本的多样性。我一般会在第一次跑通流程时完全不动超参文件等一切正常了再逐步调整。先求稳定再求效果。3. 训练自己的裂缝检测模型数据准备、train.py 参数与训练流程3.1 环境安装Python、PyTorch、CUDA 版本怎么配这个项目基于 Python 和 YOLOv5环境配置是新手翻车最多的一步。先说结论Python 3.8 到 3.10 之间都可以PyTorch 建议用稳定版1.8 到 2.x 都行CUDA 版本跟着 PyTorch 走不是越新越好。conda create -n crack python3.9 conda activate crack pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install -r requirements.txtrequirements.txt 是 YOLOv5 项目自带的依赖清单里面包含 opencv-python、numpy、matplotlib、seaborn、pandas 这些。安装完先跑一小段验证代码确认 PyTorch 能调用 GPUimport torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))这几行代码的作用很简单第一行看 PyTorch 版本第二行确认 CUDA 是否可用第三行看显卡型号。如果 torch.cuda.is_available() 返回 False说明你安装的是 CPU 版 PyTorch或者 CUDA 驱动没装好这时候直接训练效率会很低。CPU 版不是不能跑但一个小数据集也要几个小时起步建议先把 GPU 环境弄通。3.2 数据准备目录组织与标签检查把数据集准备好是训练前最重要的一步。网上能找到不少开源的路面裂缝数据集比如 CFD 数据集也可以自己用手机拍路面然后标注。标注意味着你要用 LabelImg 或者 Labelme 框出裂缝区域YOLOv5 用 txt 格式LabelImg 可以直接导出。准备好之后目录结构长这样data/ road_crack/ images/ train/ road_001.jpg road_002.jpg val/ road_100.jpg labels/ train/ road_001.txt road_002.txt val/ road_100.txt训练前先检查标签是否有问题。下面这个脚本可以快速扫描标签文件看看有没有坐标超出 0 到 1 范围的记录那些都是标注时的脏数据。import os label_dir data/road_crack/labels/train for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue with open(os.path.join(label_dir, fname), r) as f: for line in f.readlines(): parts line.strip().split() if len(parts) ! 5: print(f{fname} 格式异常: {line.strip()}) continue cls, x, y, w, h parts for v in (x, y, w, h): if not 0 float(v) 1: print(f{fname} 坐标越界: {line.strip()}) break print(检查完成)这段代码做了两件事一是判断每行是否恰好是 5 个字段类别ID加四个坐标二是检查四个坐标值是否都在 0 到 1 的范围内。只要发现异常就打印文件名和具体行你再去 LabelImg 里修正。这一步别偷懒脏标签直接影响模型收敛速度和最终精度。3.3 训练入口train.py 关键参数解读训练命令并不复杂麻烦的是每个参数到底该填多少。下面是裂缝检测场景下比较合理的训练配置python train.py \ --data data/road_crack.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 150 \ --device 0 \ --workers 4 \ --patience 30这个命令里的参数逐个拆开说data 指向你刚写的 data.yaml 文件。weights 填 yolov5s.pt表示加载官方在 COCO 上预训练好的权重作为起点。这里有一个关键点预训练权重是 80 类的你的项目只有 1 类YOLOv5 会自动把最后一层检测头替换掉所以不用手动改模型结构。img 是输入图片尺寸640 是默认值也是精度和速度最平衡的尺寸。batch 是批大小一般根据显存来定。8GB 显存跑 640 分辨率batch 设 16 基本是极限显存只有 6GB建议降到 8。epochs 是训练轮数裂缝检测这种相对简单的任务100 到 150 轮足够。太多轮反而会过拟合。device 0 表示第一张 GPU用 CPU 训练就改成 device cpu。patience 30 表示如果连续 30 轮 mAP 没有提升训练自动提前结束。这个参数是后悔药能帮你省时间。训练启动后终端会滚动显示每一轮的 loss、精度、召回率、mAP 等指标。看到 loss 稳步下降、mAP 逐渐上升说明模型在正常学习。如果 loss 出现 nan直接 CtrlC 停掉多半是学习率太大把 lr0 调到 0.0001 再试。3.4 训练产物分析weights、results 和日志训练结束后runs/train/exp 目录下会生成一批文件。最要关注的是这两个weights/best.pt 和 weights/last.pt。best.pt 是验证集上 mAP 最高那轮的权重推理时用这个last.pt 是最后一轮的权重一般不如 best。results.csv 或 results.png记录了每一轮训练的 loss 曲线、精确率、召回率、mAP0.5 等指标。这里有一个项目里常见的误区有人习惯用 last.pt 做推理觉得“最后训练的肯定最好”。实际上由于过拟合或者学习率衰减的原因last.pt 的泛化能力往往不如 best.pt。我每次都强制自己只保留 best.pt除非 last 的验证指标确实更高。4. 用训练好的模型做检测detect_photo.py 与 detect_camera.py 的参数和输出4.1 图片检测detect_photo.py 怎么玩训练完模型下一步就是拿它去检测真实图片。项目里提供了 detect_photo.py这个脚本本质上是封装了 YOLOv5 官方 detect.py 的推理流程改成了单张图片输入。python detect_photo.py \ --weights runs/train/exp/best.pt \ --source ./test_images/road_01.jpg \ --img 640 \ --conf 0.25 \ --iou 0.45 \ --save-txt参数含义说明weights 指定训练好的权重文件路径就用 best.pt。source 是输入图片路径也可以改成文件夹路径脚本会自动遍历目录下所有图片。conf 是置信度阈值默认 0.25。裂缝检测场景建议调低到 0.15 到 0.2因为裂缝和背景对比度低置信度普遍不如行人、车辆那种目标高。如果阈值设 0.5会有大量真裂缝被过滤掉。iou 是 NMS 的 IoU 阈值0.45 是默认值两个重叠的检测框 IoU 超过这个值就会合并。裂缝这类细长目标同一道缝经常被框出好几个小框适当调到 0.5 可以减少重复框。save-txt 参数会让脚本把检测结果保存成 txt 文件格式和标签一样这是方便你后续做精度评估。跑完之后结果会存到 runs/detect/exp 目录包含带检测框的图片和对应的 txt 结果。先别急着看图片打开 txt 文件对一下检测框数量和坐标是否合理——我遇到过不少次图片上看得挺准但 txt 里框的坐标偏了好几像素的情况这种问题通常来自图片 resize 时的比例处理。4.2 实时摄像头检测detect_camera.py 的工程化细节detect_camera.py 走的是摄像头实时检测路线核心是把视频帧逐帧送入模型做推理。这种场景对速度有要求参数上要做针对性调整。python detect_camera.py \ --weights runs/train/exp/best.pt \ --img 640 \ --conf 0.25 \ --device 0这里最关键的参数不是模型权重而是 img 和 conf。img 如果在摄像头场景下觉得卡可以先降到 416。分辨率的降低带来的是每秒处理帧数提升但裂缝本身是细小目标降到 416 会明显丢失细节属于权衡。conf 在实时检测时可以适当调高到 0.3 甚至 0.4因为摄像头画面里误检会被放大尤其是路面上有污渍、水痕的场景调高阈值能去掉大半假阳性框。device 0 不光是选择 GPU在摄像头场景下如果 CPU 推理跟不上可以用 --device cpu 跑一次对比一下帧率差距。通常 GPU 能做到 20 到 30 帧CPU 只有 3 到 5 帧差距很明显。还有一个经常被忽略的点摄像头画面和训练图片的色彩空间可能不一样。如果你的训练数据来自手机拍摄但摄像头是 USB 工业相机两者的白平衡和饱和度差别很大会导致检测效果骤降。常见的做法是先用 --save-txt 把摄像头检测结果保存下来比对而不是直接调参。4.3 推理阶段用到的导出工具export.py 和模型格式转换项目里还带了 models/export.py它的作用是把训练好的 PyTorch 模型导出成 TorchScript、ONNX 这些格式。对裂缝检测这个场景来说导出 ONNX 有个实际好处可以用 OpenCV 的 dnn 模块直接加载不依赖 PyTorch 环境部署到嵌入式设备或者只装了 OpenCV 的机器上都能跑。python models/export.py \ --weights runs/train/exp/best.pt \ --img 640 \ --batch 1 \ --include onnx跑完会在 weights 目录生成 best.onnx。用 OpenCV 加载的推理代码要短得多import cv2 import numpy as np net cv2.dnn.readNetFromONNX(runs/train/exp/weights/best.onnx)但如果你的最终目标是毕业设计演示PyTorch 原生推理完全够用ONNX 这步不是必需的。只有当你要把检测能力嵌进一个更大的软件系统里或者想脱离深度学习环境部署时才需要走导出这条路。延期一个决策不要一开始就把自己逼到 ONNX 推理的细节里。5. 避坑记录YOLOv5 裂缝检测最容易踩的六个坑5.1 路径带中文训练直接报错现象train.py 启动后报 FileNotFoundError 或者 UnicodeDecodeError指向某个图片路径。原因Windows 下数据集路径里带了中文目录名比如“桌面/裂缝数据集”YOLOv5 内部读取文件时用的编码方式和 Windows 中文路径不对付。解决把整个项目和数据文件夹移到纯英文路径下比如 D:\yolov5_crack所有子目录也全部用英文命名。这个习惯一定要养成不只是 YOLOv5很多深度学习框架在 Windows 下都有同样的毛病。5.2 标签坐标越界loss 居高不下现象训练时 loss 一直在 5 到 6 徘徊怎么调学习率都降不下来。原因标注时框拖出了图片边界导致 txt 里的 w 或 h 大于 1甚至出现负数模型学到了一堆非法坐标。解决用前面给的标签检查脚本跑一遍把越界标签找出来回 LabelImg 里重新调整。这一步是血泪经验我接手的项目里十个有八个 loss 不收敛是这个问题。5.3 PyTorch 装成 CPU 版训练慢到怀疑人生现象torch.cuda.is_available() 返回 False训练一个 epoch 要好几分钟。原因安装时直接 pip install torch默认装了 CPU 版本或者 CUDA 驱动版本和 PyTorch 不匹配。解决卸载重装去 PyTorch 官网用 CUDA 对应的安装命令。装完先跑一遍 3.1 节的验证代码确认 GPU 可用再开始训练。5.4 mosaic 增强在裂缝上反而帮倒忙现象训练集很小几百张开着 mosaic 增强验证集 mAP 一直上不去。原因mosaic 会把四张图拼在一起裂缝这种细长目标经常被拼接边界切断模型根本看不到完整的裂缝形态。解决在超参数文件里把 mosaic 调到 0 或者 0.5关闭或者降低它在地增强中的权重。小数据集上关闭 mosaic 带来的提升很明显属于“不按默认来反而更好”的典型场景。5.5 best.pt 和 last.pt 选错推理效果打折现象用训练生成的 last.pt 做推理检测效果明显比训练时显示的指标差。原因last.pt 是最后一轮的权重如果训练后期出现了过拟合最后一轮的效果反而不如中间某轮。解决一律用 best.pt 做推理。养成习惯训练完就去看 runs/train/exp/weights 目录复制 best.pt 单独放一个文件夹防止后面混淆。5.6 图片颜色和摄像头颜色不一致检测率骤降现象同样的权重对图片检测没问题接上摄像头之后大量漏检。原因摄像头输出的 BGR 格式和模型训练时看到的 RGB 空间有明显偏移色彩特征的分布变了。解决detect_camera.py 里把摄像头帧做一次颜色校正或者用 --save-txt 先记录一帧结果做分析确认是色彩问题还是阈值问题。我一般会在摄像头场景下加一段预处理先转换颜色空间再送进模型但这属于定制修改没有统一模板要按你的摄像头型号来定。6. 再进阶一步迁移学习、小目标优化与部署出口项目跑到这一步基本链路已经通了数据准备、训练、推理、摄像头检测都能跑。但如果你想把分数再抬高一点或者项目要拿去实际试用下面这三个方向的改进性价比最高。第一个方向是迁移学习的参数调整。很多人知道用预训练权重但不知道在微调阶段要降低学习率。用 best.pt 作为新训练的起点时建议把 lr0 设为 0.0005 甚至更低batch 可以不变但 epochs 不需要太多50 轮就能在一个新数据集上看到明显提升。原理很简单——模型已经会提取裂缝特征了新数据只是教它适应不同的路面和光照风格步子要小否则会破坏掉已经学好的特征。第二个方向是裂缝这种小目标的优化。如果你用 yolo5s 效果一般可以试试 yolov5m 或 yolov5l。虽然是同样的代码换一个模型 YAML 文件特征提取能力就有质的区别。但显存不够是个现实瓶颈8GB 显存跑 yolov5l 的 640 分辨率会爆显存一个变通方案是保持模型不变把输入分辨率降到 480小目标检测的跌幅不会太大同时显存还能撑住。调模型大小和调分辨率之间找平衡是个反复试验的过程。第三个方向是部署出口。这里给出一个常用技巧用 ONNX 格式做纯 C 或者 OpenCV 环境的部署核心代码量并不大但能脱离 PyTorch 环境运行这在现场演示环节比开着 GPU 服务稳定得多。导出 ONNX 时有一个参数要注意就是 opset 版本要和你安装的 OpenCV 版本匹配否则 dnn 读模型时会报不支持的操作符。我的个人习惯是不管项目最后演示用不用得到摄像头我都会先把 detect_photo.py 的静态图片检测跑通因为静态图片最容易排查问题一张图一张图看检测框心里有底。然后才上摄像头因为摄像头的问题是状态相关、很难复现的。从那以后我每次拿到新的检测项目都强制自己先走一遍“单图推理 → 批量图片 → 实时视频”这个顺序每一步验证通过再进入下一步。这条路走通之后你回头看这个项目会发现它的难点不在于深度学习本身而在于数据对不对、参数合不合理、环境通不通这三件事。希望这篇笔记能帮你少走点弯路把精力省下来放在真正出成果的地方。本文还有配套的精品资源点击获取
返回列表