简介基于YOLOV8实现的路面、桥梁与墙体裂缝识别Python项目面向深度学习学习者与计算机视觉开发者适用于结构表面缺陷检测、智能巡检等场景。项目源码已本地编译可运行评审分95分以上难度适中内容经助教审定适合作为课程设计、毕业设计或工程落地的参考基线。压缩包共78个文件仅2.55MB包含21个Python核心脚本、26个YAML模型与训练配置、18个pyc编译文件、5个PNG、4个JPEG、2个JPG图像样本及2个Markdown说明文档模型配置、训练代码、测试图片和文档笔记一一对应目录结构清晰。目前已有130人学习下载。通过学习能够掌握YOLOv8从数据准备、模型训练到预测可视化的完整流程代码中附带的输出截图和预测脚本可辅助快速理解检测效果的调参与评估方法。1. YOLOV8裂缝识别一套能跑通的路面桥梁墙体检测源码做结构巡检的人对裂缝检测都不陌生传统办法靠肉眼贴着墙看或者拿着裂缝测宽仪一点点量效率低而且主观性很强。用深度学习做裂缝识别这几年很热YOLOV8是其中综合性价比最高的方案之一——检测速度快、训练配置简单、源码生态成熟。这份资源就是一个基于Python和YOLOV8的路面、桥梁、墙体裂缝识别项目压缩包里带了完整源码、文档说明和测试图片解压后本地编译就能跑。我拆完这套资源后的感受是它不是一个只丢给你一堆代码的黑匣子而是从推理脚本到训练流程都给全了适合正在做毕业设计、课程项目或者结构检测相关课题的人直接拿去做二次开发。2. 源码构成与推理实测detect_predict.py 怎么把权重变成裂缝框2.1 压缩包里的源码脉络从目录结构看项目分工拿到压缩包先别急着运行花两分钟把目录结构过一遍。这个项目用的是Ultralytics YOLOV8标准工程结构核心脚本是根目录下的detect_predict.pyimages目录里放了测试图片包括墙面裂缝、路面裂缝的实拍图还有screenshot目录存了运行截图方便你对比预测前后的效果。整个项目的运行入口很集中不像有些开源项目散落一堆脚本找不到主文件。Python-Yolov8-crack-recogntion-for-road-bridge-wall-main/ ├── detect_predict.py # 推理脚本加载模型并预测 ├── ultralytics/ # YOLOV8核心库目录 ├── images/ # 测试图片路面、桥梁、墙体裂缝 ├── screenshot/ # 运行效果截图 ├── yolov8_out/ # 预测结果输出目录 └── requirements.txt # 依赖清单detect_predict.py是这份资源的主入口它做的事情说起来很简单加载训练好的YOLOV8权重读入一张图片经过模型前向推理输出目标框再把框画到原图上保存。实际工程里这套逻辑可以被包装成API接口也可以接进无人机巡检的实时视频流。我一般会先跑通这个脚本确认环境没问题再去看权重文件和训练配置因为推理能跑通说明整个依赖链是完整的。2.2 一条命令跑通推理detect_predict.py 的运行与输出这套源码在Python 3.8以上的环境里都能跑核心依赖是ultralytics、torch、opencv-python。安装依赖后直接在项目根目录执行下面的命令pip install -r requirements.txt python detect_predict.py如果你只是想快速验证也可以不安装requirements.txt里的全部依赖只装ultralytics和opencv-python因为推理阶段用到的核心库就这两个。运行结束后程序会在yolov8_out目录下生成带检测框的结果图。第一次跑通看到裂缝被框出来的那一刻整个项目就算立住了。这里有个参数需要留意脚本里的model_path变量指向权重文件。如果资源里附带的是best.pt那它通常是在某个裂缝数据集上训练出来的如果只有yolov8n.pt这种官方预训练权重那检测效果就只是COCO80类里的通用能力并不专门针对裂缝。我第一遍拆这个项目的时候先看的是detect_predict.py里模型加载部分的代码确认权重路径指对了再跑推理。# detect_predict.py 核心推理逻辑简化版 from ultralytics import YOLO # 加载模型权重 model YOLO(best.pt) # 换成项目里实际的权重文件路径 # 对单张图片进行推理 results model.predict( sourceimages/1.png, # 输入图片路径 conf0.25, # 置信度阈值低于此值的检测框会被过滤 saveTrue, # 保存标注后的结果图 projectyolov8_out, # 输出目录 nameexp, # 输出子目录名 exist_okTrue # 允许覆盖已有结果 ) # 打印检测到的目标信息 for result in results: boxes result.boxes if boxes is not None: for box in boxes: print(f类别: {result.names[int(box.cls)]}, f置信度: {float(box.conf):.2f}, f坐标: {box.xyxy.tolist()})代码逻辑分三段第一段初始化YOLO实例并加载权重第二段调用predict方法做前向推理source参数可以传图片路径、文件夹路径甚至视频流第三段遍历results对象读取检测框数据。conf参数控制置信度阈值默认0.25意味着模型对某个区域是裂缝的把握低于25%时就丢弃调高它会减少误检但可能漏掉细小裂缝调低则相反。2.3 预测结果长什么样置信度、类别与坐标的读取逻辑YOLOV8的预测结果封装在results对象里很多人第一次接触时不知道从哪里取坐标。result.boxes里存了检测框的全部信息xyxy是左上角和右下角坐标xywh是中心点和宽高conf是置信度cls是类别索引。裂缝识别项目通常只训练一个类别crack所以cls基本都是0。# 手动遍历检测框并过滤低置信度结果 for result in results: for box in result.boxes: conf float(box.conf[0]) if conf 0.5: # 只保留高置信度结果 continue x1, y1, x2, y2 [int(v) for v in box.xyxy[0].tolist()] cls_id int(box.cls[0]) label result.names[cls_id] print(f{label} {conf:.3f} ({x1}, {y1}) - ({x2}, {y2}))实际做巡检项目时这个遍历逻辑会改成把坐标写入CSV或者数据库方便后续统计裂缝位置和数量。我习惯把置信度阈值从0.25提到0.4以上做路面裂缝检测因为路面背景纹理复杂低置信度的框大多是把沥青颗粒误判成了裂缝。3. 训练自己的裂缝数据集标注、yaml 与参数调优3.1 裂缝数据从哪来拍摄规范与 Labelme 标注资源自带的模型能覆盖常见场景但换一个工地、换一种光照条件检测效果可能就掉了。这时候你需要用自己的数据训练模型。裂缝数据集的核心痛点是标注一致性——同样一条裂缝不同人画框的标准差别很大模型学出来的特征就飘。我一般用Labelme做标注它对裂缝这种不规则目标比较友好。每张图片里所有的裂缝都要框出来判断标准是肉眼能明显分辨的裂缝必须框宽度小于2像素的微裂缝建议框因为模型要学的就是这些早期损伤信号。图片分辨率统一缩放到1280×720左右再标注原始尺寸太大的话框的坐标在缩放后会错位。# 安装并启动 Labelme pip install labelme labelme标注完成后每个图片会对应一个同名JSON文件里面记录了多边形顶点坐标和类别名。Labelme导出的JSON是COCO格式的polygon不能直接喂给YOLOV8训练需要先转成YOLO的txt格式——每行一个目标格式是class_id x_center y_center width height四个值都是相对于图片宽高的比例。3.2 从 JSON 到 YOLO 格式标注转换脚本转换脚本是训练前必须写的一段代码。Labelme的JSON里存的是多边形顶点YOLO需要的是外接矩形框。这里有个细节裂缝往往是长条形的外接矩形会框进大量背景但YOLOV8的anchor机制能适应这种长宽比直接用外接矩形就行不需要额外做旋转框处理。# json2yolo.py 将 Labelme 标注转换为 YOLO 格式 import json import os from glob import glob def convert_labelme_to_yolo(json_path, output_dir, class_names): with open(json_path, r, encodingutf-8) as f: data json.load(f) img_w data[imageWidth] img_h data[imageHeight] # 获取图片文件名并构造输出 txt 路径 base_name os.path.splitext(os.path.basename(json_path))[0] txt_path os.path.join(output_dir, base_name .txt) lines [] for shape in data[shapes]: label shape[label] if label not in class_names: continue class_id class_names.index(label) # 计算多边形外接矩形 points shape[points] x_min min(p[0] for p in points) y_min min(p[1] for p in points) x_max max(p[0] for p in points) y_max max(p[1] for p in points) # 转换为归一化的 YOLO 格式坐标 x_center (x_min x_max) / 2 / img_w y_center (y_min y_max) / 2 / img_h width (x_max - x_min) / img_w height (y_max - y_min) / img_h lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) with open(txt_path, w) as f: f.write(\n.join(lines)) # 使用示例 class_names [crack] # 类别列表顺序决定了 class_id json_files glob(labels_json/*.json) os.makedirs(labels_txt, exist_okTrue) for jf in json_files: convert_labelme_to_yolo(jf, labels_txt, class_names) print(f转换完成共处理 {len(json_files)} 个文件)这段代码的核心逻辑是从JSON的shapes字段里取出每个目标的类别和多边形顶点遍历所有顶点求出外接矩形的左上角和右下角再转换成归一化坐标。class_names的顺序很重要训练时yaml文件里names列表的顺序必须和这里完全一致。如果漏掉某个label没写进class_names对应的框就被静默丢弃了训练时你会困惑为什么有些图片没有标注文件。转换完检查一下txt文件内容是否正常。我习惯随机打开几个txt看看坐标值是否都在0到1之间、有没有空文件——空文件说明原图的标注全部被过滤了这个问题要提前发现不然训练时模型在这些图上看不到任何目标。3.3 训练配置与启动crack.yaml 和训练参数详解YOLOV8用yaml文件描述数据集配置包括训练集和验证集路径、类别数量、类别名称。文件夹结构建议按YOLO的标准格式组织dataset/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 └── labels/ ├── train/ # 训练标注 txt └── val/ # 验证标注 txtcrack.yaml内容如下# crack.yaml 数据集配置文件 path: ./dataset # 数据集根目录 train: images/train # 训练图片相对路径 val: images/val # 验证图片相对路径 nc: 1 # 类别数量裂缝只算一类 names: [crack] # 类别名称列表训练命令可以直接指定yaml文件路径yolo train datacrack.yaml modelyolov8n.pt epochs100 imgsz640 batch8这里每个参数都值得细说。modelyolov8n.pt表示用YOLOV8nano的预训练权重做初始化nano是最小的变体显存占用低适合在消费级显卡上训练。如果显卡是RTX 3060以上的级别可以换yolov8s.pt精度会高一截。epochs是训练轮数裂缝检测这种单一类别任务100轮足够再多就容易过拟合。imgsz是训练时输入图片的尺寸640是速度和精度的常规平衡点如果裂缝很细可以试试800甚至960但显存占用会明显增大。batch是批大小默认8显存不够就降到4或者2。训练过程中关注两个指标box_loss和cls_loss。box_loss是检测框的回归损失cls_loss是分类损失。正常情况下两者都持续下降如果cls_loss降不下去先查数据集里有没有空标注文件或者类别标错的图。4. 推理脚本二次开发置信度、NMS 与批量检测4.1 置信度与 NMS两个参数决定漏检和误检的平衡YOLOV8后处理阶段有两个参数直接影响输出质量置信度阈值conf和NMS的IoU阈值iou。conf决定一个检测框保留还是丢弃iou决定两个重叠的框是否合并。对于裂缝检测这两个参数需要联动调单独调一个效果有限。from ultralytics import YOLO model YOLO(best.pt) # 高精度模式严格过滤低置信度NMS 也设严 results model.predict( sourceimages/, conf0.5, iou0.45, saveTrue, projectyolov8_out, namehigh_precision, exist_okTrue ) # 高召回模式多保留可疑框NMS 放宽 results model.predict( sourceimages/, conf0.2, iou0.6, saveTrue, projectyolov8_out, namehigh_recall, exist_okTrue )判断用哪个阈值取决于场景。桥梁定检时裂缝漏检的后果比误检严重我会把conf放到0.3以下让模型把疑似区域都标出来人工再复查如果是自动化流水线做初筛误检会浪费人力conf提到0.6更合适。NMS方面裂缝这种细长目标之间很少有大面积重叠iou设0.45到0.5就够用不需要调太高。4.2 批量检测文件夹把单图推理改成目录遍历实际巡检不是一张张图手动跑而是面对一个目录下成千上万的图片。detect_predict.py的predict方法已经支持传入文件夹路径直接指定source为目录就能自动遍历全部图片。但如果你想在批量模式下加一些自定义逻辑——比如跳过已经检测过的图片、把结果汇总成报表——就需要自己写循环了。# batch_predict.py 批量检测并汇总结果 from ultralytics import YOLO import os import csv model YOLO(best.pt) img_dir inspection_images output_csv detection_results.csv results_data [] img_extensions (.jpg, .jpeg, .png, .bmp) for img_name in os.listdir(img_dir): if not img_name.lower().endswith(img_extensions): continue img_path os.path.join(img_dir, img_name) results model.predict( sourceimg_path, conf0.3, saveTrue, projectyolov8_out, namebatch_run, exist_okTrue ) # 统计该图片中的裂缝数量 for result in results: num_cracks len(result.boxes) if result.boxes is not None else 0 results_data.append([img_name, num_cracks]) print(f{img_name}: 检测到 {num_cracks} 条裂缝) # 写入 CSV 报表 with open(output_csv, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([图片名, 裂缝数量]) writer.writerows(results_data)这个脚本把逐张图片的检测结果汇总成CSV方便后续导入Excel做统计。os.listdir遍历目录时依赖文件扩展名过滤遇到大小写混合的.jpg和.JPG时用lower()做了统一。批量跑的时候建议把save参数设为False先只收集结果等筛选出重点图片再单独保存标注图否则几千张图跑完磁盘空间会很紧张。4.3 视频流与实时检测cap 读帧的改造思路结构巡检里视频检测也很常见——无人机沿着桥梁飞一圈录一段视频回来逐帧分析。YOLOV8的predict方法传视频路径就能直接检测但帧率可能跟不上更好的方案是用OpenCV逐帧读取再喂给模型。# video_predict.py 视频逐帧裂缝检测 import cv2 from ultralytics import YOLO model YOLO(best.pt) video_path bridge_inspection.mp4 cap cv2.VideoCapture(video_path) fps cap.get(cv2.CAP_PROP_FPS) width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 初始化视频写入器 out cv2.VideoWriter( bridge_inspection_result.mp4, cv2.VideoWriter_fourcc(*mp4v), fps, (width, height) ) frame_count 0 while cap.isOpened(): ret, frame cap.read() if not ret: break # 每隔 3 帧检测一次控制耗时 if frame_count % 3 0: results model.predict(sourceframe, conf0.3, verboseFalse) annotated_frame results[0].plot() else: annotated_frame frame out.write(annotated_frame) frame_count 1 cap.release() out.release() print(f处理完成共 {frame_count} 帧)逐帧检测的耗时瓶颈在模型推理上。这里每隔3帧检测一次中间两帧直接复用原画面巡检视频中裂缝在连续帧中的位置变化不大这种做法能省掉三分之二的推理时间。如果你对实时性要求更高可以把模型换成yolov8n.pt并用TensorRT加速。5. 避坑与常见问题环境、显存与预测结果排查5.1 ultralytics 版本升级导致 API 不兼容现象代码报错AttributeError: module ultralytics has no attribute YOLO或者train参数解析失败。原因ultralytics库更新很快不同版本之间API有差异。旧版本用model.predict()传参新版本改成了model.predict()支持更多参数但部分旧写法不兼容装成最新版反而把老接口废掉了。解决按照requirements.txt里锁定的版本安装不要用pip install ultralytics直接装最新版。我一般先建虚拟环境再装依赖这样不同项目之间版本不会互相污染。python -m venv venv venv\Scripts\activate # Windows # 或 source venv/bin/activate # Linux/Mac pip install -r requirements.txt如果已经装了新版想降级先卸载再装指定版本pip uninstall ultralytics pip install ultralytics8.0.20。5.2 训练时显存溢出程序直接崩溃现象训练刚开始几十秒就报OutOfMemoryError或者CUDA error: device-side assert triggered。原因batch size设太大、imgsz设太大或者显卡显存不够。裂缝数据集里的原图经常是几千万像素的航拍图直接训练必爆显存。解决先看显卡型号RTX 3060 12G的情况下batch8、imgsz640是安全的。如果还不够batch降到2imgsz降到480。改参数后模型精度会受一点影响但至少能跑完训练。还有个办法是开启梯度累积Ultralytics的train方法里没有直接暴露这个参数可以通过设置batch2配合accumulate参数缓解。5.3 标注框太小导致训练不收敛现象训练几十轮后loss还在高位波动验证集mAP0.5不到0.1。原因裂缝本身是细长目标标注框的面积可能只占整张图的千分之一甚至更少。YOLO系列对微小目标的检测天生吃力框太小会让正负样本极度不平衡。解决训练时把imgsz调大让目标在输入图像中占据更多像素。原始图是1920×1080的话imgsz设960或1280模型能看到更多细节。数据侧可以裁切——把大图切成多个512×512的小图再训练裂缝在切分后相对尺寸会大很多。这是裂缝检测项目里最有效的手段。5.4 推理结果全空白一张裂缝都没框出来现象程序正常运行也生成了输出图但图上没有任何检测框。原因首先是权重不对加载的模型没有见过裂缝数据其次是置信度阈值太高微弱裂缝的置信度普遍低于0.5再就是推理图片的色调和训练集差异大。解决用项目自带的测试图片跑一遍确认模型本身没问题然后调低conf到0.1看看有没有框最后检查输入图片是不是有严重的曝光问题过曝或过暗的图片可以先用OpenCV做直方图均衡化再送进模型。5.5 CPU 推理慢到没法用现象一张720p的图片在CPU上跑yolov8s要1秒多视频检测基本是幻灯片效果。原因没有调用GPU推理或者用的是s/l这种大模型。解决先确认torch.cuda.is_available()是否为True如果环境没有CUDA版torch重装pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118。然后把推理模型换成yolov8n.pt速度能快三四倍。检测时把imgsz从默认640降到480推理耗时进一步缩短。6. 进阶验证从指标曲线到 ONNX 平台迁移6.1 用混淆矩阵和 PR 曲线验证模型真实水平只看mAP数字很容易被误导。模型训练完后我会跑一次model.val()生成混淆矩阵和PR曲线这两张图比总分更能说明问题。对于裂缝检测特别注意一下precision和recall的走势——PR曲线下的面积大但曲线头部掉得快说明模型对高置信度的裂缝识别好对模糊裂缝识别差这时候应该关注数据侧的标注质量而不是盲目调参。from ultralytics import YOLO # 加载训练好的模型在验证集上评估 model YOLO(runs/train/exp/weights/best.pt) metrics model.val(datacrack.yaml, splitval) # 打印关键指标 print(fmAP0.5: {metrics.box.map50:.4f}) print(fmAP0.5:0.95: {metrics.box.map:.4f}) print(f精确率: {metrics.box.mp:.4f}) print(f召回率: {metrics.box.mr:.4f})6.2 导出 ONNX 提升部署效率训练好的模型如果要部署到无人机机载电脑或者边缘设备ONNX格式是比PyTorch更通用也更快的中转格式。导出过程一行代码但导出的参数要选对。# 导出 ONNX 模型 model YOLO(best.pt) model.export(formatonnx, imgsz640, opset12)导出的best.onnx可以用ONNX Runtime跑在CPU上比PyTorch原模型快30%左右在RK3588这类NPU设备上可以直接用板端推理框架加载。导出后务必用onnxruntime验证一下和PyTorch推理结果是否一致常见问题是opset版本太高导致某些算子不兼容。从那以后我每次训练完模型都强制走一遍导出ONNX onnxruntime验证 样本图片对比的流程这套组合拳帮我避免过好多次部署现场的翻车事故。裂缝识别这个项目从跑通到落地最关键的还是把数据工作做扎实——这一行走到位了模型效果不会差。希望帮到你。本文还有配套的精品资源点击获取