1. 方案选型与整体设计为什么坑洞检测绕不开YOLO做路面坑洞检测这个方向最早接触的时候就面临一个灵魂拷问传统图像处理能不能搞定边缘检测、阈值分割、形态学操作听起来好像也能提取坑洞轮廓但实际一测就露馅。坑洞这个东西和工业零件的缺陷检测不一样它的形态极度不规整边缘模糊颜色和路面背景接近光照一变整个特征就飘。更麻烦的是坑洞里有积水、有阴影、有落叶传统算法很难区分“这是坑”还是“这只是路面上的阴影”。所以一开始就想清楚了这个项目必须走深度学习目标检测路线。那目标检测模型一大堆Faster R-CNN、SSD、CenterNet都试过为什么最后落在YOLO系列上因为这套系统不光在实验室里跑还要装到巡检车上、手持设备上甚至可能部署到边缘计算盒子实时性就是硬指标。YOLO系列从诞生开始就是奔着“单阶段、直接回归”去的一次前向推理同时输出类别和框速度和精度平衡得最好。Faster R-CNN这类两阶段模型精度确实高但推理速度在嵌入式平台上根本跑不起来。另外还有一点很关键YOLO系列的生态成熟度在目标检测领域是独一档的。从数据集标注工具到模型导出部署从预训练权重到社区踩坑经验所有环节都能找到现成方案。对于想做落地项目的开发者来说选YOLO不是因为它是学术上最前沿的而是因为它是工程上最省心的。具体到版本选择我实际对比了YOLOv5、YOLOv8和后来的YOLOv9/YOLO11这几个版本。YOLOv5胜在稳定文档和教程最多很多边缘设备的推理引擎对v5的优化做得最久。YOLOv8在训练脚本的易用性上明显提升数据增强、训练策略都内置好了对新手极其友好。YOLOv9和YOLO11在精度上有进步但当时项目用的是边缘计算盒子对导出和加速的支持还有打磨空间。最终我选了YOLOv8作为主力训练框架理由是它兼顾了精度、训练体验和部署兼容性而且ultralytics库把整个流程封装得非常干净代码量小后续维护成本低。系统整体架构上我不搞那种复杂的微服务架构。实际落地场景就三块图像采集端、检测计算端、结果展示端。采集端可以是车载摄像头、巡检人员的手机或者道路监控摄像头的截图。计算端就是一台装了GPU的工控机或者边缘计算盒子跑YOLOv8模型。结果展示端就是一个简单的Web界面或者App用来查看检测结果、统计坑洞位置和大小。这个架构对应到实际使用场景就是巡检车跑一圈摄像头不断采集路面图像检测程序实时输出坑洞框后台记录坑洞的GPS坐标和图像截图最后生成一份巡查报告。整个流程说白了就是“采集—推理—记录—上报”四步没那么多花活但每一步都得做得扎实。2. 数据集构建坑洞检测真正的拦路虎2.1 公开数据集为什么不够用很多人做项目第一步就卡在数据集上。路面坑洞这个方向不像行人检测、车辆检测那样有现成的千万级公开数据集可以随便用。我调研过RDD2020数据集这是路面破损检测领域比较出名的公开数据集包含印度、日本、捷克等国家的路面图像标注了纵向裂缝、横向裂缝、龟裂和坑洞四类破损。但实际用下来有几个问题。第一是场景适配性。不同国家的路面材质、坑洞成因、拍摄角度差异巨大比如印度数据集里的坑洞很多是土路和破损沥青路面的混合和国内城市道路的坑洞形态差得很远。用一个城市道路的模型去检测某些公路的坑洞效果会明显打折扣。第二是标注质量参差不齐。公开数据集的标注框有些框得很大把整个破损区域都框进去了有些又只框了一小部分模型学到的边界就很不稳定。第三是坑洞这个类别的特殊性。坑洞有大有小小的可能只有十几个像素大的能占画面三分之一而且坑洞经常被车辆、行人遮挡公开数据集里这些情况覆盖得并不够。所以我最终的策略是公开数据集RDD2020打底自己采集补充数据然后花大量时间做清洗和重标注。这一步不能省也没有捷径可走。我一直觉得检测项目的天花板不是模型结构而是数据质量。2.2 自采数据的实战要点自己采集坑洞数据这件事听起来简单就是拿手机去拍嘛但实际上有很多讲究。我总结出这么几条经验拍摄角度要统一。车载视角是最理想的高度大约1.5米左右镜头略微朝下倾斜模拟实际巡检时的视角。手持手机拍摄的话要保持在腰部和胸口之间的高度垂直往下拍。不统一的拍摄角度会让模型学到一堆无关的视角特征推理时换个角度就失灵了。光照要覆盖全时段。坑洞在晴天、阴天、早晨、黄昏的表现完全不同。晴天时坑洞边缘的阴影特别明显阴天时坑洞和路面的对比度下降黄昏时拉长的阴影会干扰检测。我当时连续采集了两周故意选择不同天气和时间段出门拍摄保证数据多样性。水坑一定要包含。积水坑洞是最难处理的场景水面带反光坑洞的真实边界被掩盖。但现实世界中雨后路面大量存在这种水洼坑。如果模型没见过积水样本部署到雨季场景就废了。我会保留一部分积水样本同时在标注时把水洼边缘也尽可能框准。类的平衡要注意。城市道路上的坑洞其实没有那么多更多的是裂缝。如果只标注坑洞裂缝样本多了会干扰模型。我的做法是统一标注“破损”这个大类把坑洞、严重下沉、大裂缝都归为一类因为在实际道路养护场景中这些都需要修复区分得太细反而降低检测效率。这也是和道路养护工作人员聊过之后的体会他们的诉求是“哪儿坏了”而不是“这坏的是什么类型”。2.3 标注规则怎么定才靠谱标注规则这件事我在项目里反复修正了好几轮踩了不少坑才形成一套稳定的标准。锚定框的边界判定。坑洞的边界到底是路面开始下沉的起点还是坑底边缘这个问题如果不统一三个标注员能标出三种框。最终我的标准是以坑洞边缘路面的明显破损起点为界如果边缘模糊参考坑洞内部的颜色突变区域。简单说框要贴着坑洞实际视觉边界不要留太多冗余边距。遮挡和裁切样本的处理。如果一个坑洞被车辆轮胎压住了一半要不要标注我的做法是如果可见部分占到坑洞面积的30%以上就标注可见部分的紧致包围框如果遮挡太严重不标注直接删除该样本或者换个时刻重新采集。因为标注严重遮挡的样本会让模型学到“坑洞可以长这样”的错误信息训练结果反而不稳定。小目标坑洞的处理。有些坑洞很小在1280的分辨率下只有30×30像素左右。这种小目标要不要保留我一开始全删了因为觉得框太小没意义。后来发现这是错误的——小坑洞恰恰是道路初期损坏的表现漏检的话系统价值大打折扣。正确的做法是保留小目标样本但在训练时专门针对小目标做增强后面会细说。2.4 数据增强的取舍与教训数据增强这块YOLOv8内置了增强策略但我实际用下来发现不能全开。Mosaic增强把四张图拼接成一张对小目标检测非常有效但坑洞检测有个特殊问题Mosaic拼接后坑洞可能位于拼接边界导致区域割裂另外拼接图的色彩分布混乱对“坑洞颜色比路面深”这种关键特征的学习会有干扰。我的做法是Mosaic增强在训练前中期开启最后50个epoch关闭让模型在干净的数据上收敛。另一个吸取的教训是不要过度使用色彩类增强。HSV变换、亮度变化这些手段对坑洞检测其实很友好因为不同光照条件下坑洞视觉差异本来就大增强可以让模型更鲁棒。但像RandomErasing随机擦除这种遮挡类增强对坑洞这种纹理特征本来就弱的检测目标会起到反效果。模型容易把擦除区域当成坑洞误检率明显上升。3. 模型训练与调优从能跑到好用3.1 环境配置与训练策略训练环境这块我用的是PyTorch Ultralytics框架一张消费级GPU就能带得动YOLOv8s模型在2080Ti上就能跑得比较流畅。这里给个明确的配置参考数据集大约用了8000张图像其中6000张自采2000张来自公开数据集整理清洗。训练集、验证集、测试集按8:1:1划分注意划分时要按“路段”而不是按“单张图像”。否则同一个路段高度相似的连续帧会被同时分进训练集和验证集验证集指标会虚高部署到新路段效果就现原形了。训练超参数上我选择的输入尺寸是640×640batch size是16初始学习率0.01使用SGD优化器配合余弦退火学习率调度。这里解释一下为什么不用Adam在目标检测领域SGD配合动量通常能收敛到更好泛化性能尤其是对anchor-based的YOLO系列Adam容易过早收敛到尖锐的极小值。迁移学习方面我加载了YOLOv8s在COCO上的预训练权重。虽然COCO里没有“坑洞”这个类别但预训练模型已经学到了丰富的纹理和边缘特征这些底层特征对坑洞检测同样有效训练速度也会快很多。3.2 训练过程中的关键调优节点训练不是一口气跑完就完事了我在训练过程中关注三个关键节点。第一个是验证集mAP曲线是否持续上升。如果训练loss在降但mAP在震荡通常说明数据有问题。我遇到过的情况自采数据里某个路段连续几百张图像都是同一个坑洞的重复拍摄模型在这个坑洞里过拟合了一换场景就失准。排查方法是按图像相似度筛重连续帧中保留一帧即可。第二个是类别不平衡问题。坑洞检测只有一个类别但存在“大坑多、小坑少”的尺度不平衡。我的做法是使用多尺度训练YOLOv8里开启增强参数让模型每10个batch随机从480到960之间变换输入尺寸。这招对大目标和小目标的均衡效果非常明显。第三个是难例挖掘的概念。训练后期我会用当前模型对训练集做一次推理专门挑出置信度在0.3到0.7之间的“模糊样本”——这些样本模型不确定说明难学。我把这些样本单独抽出来和随机负样本混合额外多训练50个epoch。这个思路类似Adaboost里的样本加权对坑洞边缘模糊的样本效果特别明显。实测下来难例挖掘阶段能让mAP再提升2到3个百分点。3.3 损失函数和推理阈值怎么调YOLOv8默认使用CIoU损失来处理框回归。对于坑洞检测框的定位精度确实重要因为后续要根据框的大小估算坑洞面积。但还有一个关键点坑洞的形状极不规则紧致的矩形框往往无法贴合倾斜的长条状坑洞。这个问题的解法有两种思路——训练角度检测的旋转框或者在评估时使用可变形卷积。旋转框方案会大幅增加标注和训练复杂度我最终选择了矩形框面积估算补偿用检测框的中心点坐标加上坑洞长度粗略换算实际面积而不是直接按框面积算。推理阈值方面默认的置信度阈值0.25对坑洞检测来说偏低了会导致很多路面阴影、轮胎污渍被误检成坑洞。我经过实测定为0.45在保证召回率的同时把误检压到可接受范围。NMS的IoU阈值保持默认0.7即可坑洞之间的重叠情况没有密集目标那么严重。还有一点我反复排查过的训练时的图像分辨率对部署时的推理影响很大。部署时直接用640×640输入即可不要用更高分辨率推理。我一开始测试时用了1280×1280确实小坑洞召回率提升了一点但推理时间翻了好几倍而且边缘计算盒子跑不动。在工程场景下“够用”比“最好”更重要。4. 检测效果评估与性能分析数字会骗人曲线才靠谱4.1 评估指标怎么组合着看做目标检测评估单看一个mAP是远远不够的。坑洞检测这个场景我重点看三个指标组合mAP0.5、mAP0.5:0.95、和FPS。mAP0.5表示IoU阈值0.5时的平均精度反映了模型“找不找得到”坑洞的能力mAP0.5:0.95则对框的定位精度要求更高反映“框得准不准”的能力。检测系统应用时mAP0.5在0.75以上、mAP0.5:0.95在0.45以上就算基本能用了。但指标好不代表系统就好。我在实际测试中发现最影响用户体验的其实不是mAP而是FPS每秒处理帧数。巡检车以60km/h行驶时在640×640分辨率下大约每秒前进16.7米如果模型推理速度低于15FPS相邻帧之间路面会漏检。所以我给这个系统的底线要求是在部署设备上不低于25FPS。4.2 不同YOLO版本的实测对比为了确定最终落地的模型我在同一数据集上对比了YOLOv5s、YOLOv5m、YOLOv8s、YOLOv8m四个配置。测试结果对比如下模型配置参数量推理耗时(ms)mAP0.5mAP0.5:0.95备注YOLOv5s7.3M11.20.7430.412速度快精度一般YOLOv5m21.2M21.60.7820.438精度提升耗时翻倍YOLOv8s11.2M12.50.7680.431精度和速度均衡YOLOv8m25.9M22.80.7930.456精度最高耗时明显增加从数据可以看出来YOLOv8s在几乎不损失推理速度的情况下mAP0.5比YOLOv5s高了2.5个百分点mAP0.5:0.95高了1.9个百分点。做落地项目时这2到3个点的差距在实际场景里就是多检出几个小坑洞的区别感知非常明显。YOLOv8m精度更高但推理耗时将近翻倍在边缘设备上不一定hold得住。最终我选了YOLOv8s作为部署配置用TensorRT加速到边缘盒子上跑。实测达到30FPSmAP0.5为0.76够用了。4.3 误检和漏检的典型场景分析评估过程中最让我头疼的永远是误检和漏检案例的反复复盘。我总结了坑洞检测最常见的三类失败场景一是深色沥青补丁。路面修补过的痕迹颜色深、形状不规则与坑洞高度相似。这类误检很难通过增加训练数据彻底消除因为补丁和坑洞本身就在视觉上高度相似。我的处理方案是增加后处理逻辑检测结果会根据框内区域的平均色彩深度和纹理方差做二次判定补丁通常纹理平滑、色彩均匀坑洞则纹理更杂乱。二是光照阴影和树影。树影在路面上形成的形状不规则的黑斑误检率很高。单靠调整置信度阈值无法根治因为真实坑洞在阴天时对比度也很低。我的经验是充分利用检测框的上下文——阴影会随着一个整体阴影区域连续移动坑洞则是独立的。根据这个特点做了一个简单的帧间一致性判断如果检测框在视频流连续多帧中都稳定出现在同一位置才最终确认是坑洞。三是湿路面的反光。这个属于物理层面的干扰水的镜面反射让坑洞看起来是一片亮斑而不是暗区。模型很难学因为同一位置的坑洞在干燥时是深色在下雨时是亮色特征完全相反。我的兜底方案是缩小置信度阈值在雨天场景主动降低召回率预期把更多边缘样本交给人工复核。这类问题本质上不能完全靠模型解决必须配合业务逻辑来兜底。做AI系统有一个特别重要的思路模型解决80%的常规情况剩下20%的边界场景用规则判断。千万不要指望模型100%正确。5. 软硬件系统集成从单模型到可用系统5.1 边缘端的选型和部署方案完成模型训练和评估后要和硬件设备进行集成。我测试过几种edges设备方案Jetson Nano算力不足跑YOLOv8s只有7FPS、Jetson Orin Nano能跑28FPS价格较高、Intel RealSense D435i深度摄像头对于坑洞面积估算有帮助、普通USB工业相机工控机组合性价比最高。最终用了Jetson Orin Nano 普通工业相机的组合原因是这套方案在算力、功耗、体积之间取得了平衡。工业相机选的是红外补光型号晚上无光照环境也能拍清楚路面。部署用TensorRT对模型进行加速和int8量化量化后模型体积从22MB缩小到8MB推理速度提升约35%。需要注意int8量化对精度有一定损耗所以量化前要在验证集上确认mAP0.5下降幅度是否在可接受范围内我测下来发现大约掉了0.7个百分点完全可以接受。5.2 检测逻辑与GPS同步记录部署形态上我用车内固定支架把相机固定在挡风玻璃中上部向下倾斜15度左右这个角度能平衡近处和远处的检测范围太垂直了远处看不见太平了近处的坑洞会溢出画面。相机通过USB连接Jetson盒子盒子通过OBD接口从车辆取电。GPS模块用UART串口接入盒子。这套系统的核心逻辑是实时视频流持续推理每检测到坑洞就记一条记录记录内容包括当前帧图像、检测框坐标、GPS坐标、时间戳。GPS坐标的记录要和检测帧对齐我的做法是检测线程每处理完一帧就读取一次GPS虽然二者在时序上可能相差几百毫秒但以车辆60km/h的速度几百毫秒对应几米的范围作为一个粗略位置记录完全够用。如果需要更精确的位置可以把GPS模块设置为10Hz、5Hz输出并给检测结果做时间戳插值。软件层面我用Python写了主程序通过Flask起一个局域网Web服务巡检人员打开手机浏览器就能看到实时的检测画面和已经识别到的坑洞列表。这个展示端不复杂但对实际落地很有价值——道路养护人员不需要培训怎么用复杂软件浏览器打开就能看到结果。5.3 前端展示和后端归类的逻辑后端的数据结构我设计得很简单一张检测记录表字段包括检测时间、经度、纬度、图像路径、框坐标、置信度。后续处理筛选会用到“同位置合并”巡检一周下来同一个坑洞可能被多次检测到记录会非常冗余。我的做法是按经纬度做空间聚类半径5米内的检测记录自动合并为同一个坑洞置信度取最高值时间戳取第一次和最后一次。这套做法避免了重复上报的麻烦简化后续数据处理流程。另外一个实用细节框坐标除了记录归一化坐标还会把原始像素坐标一并存下来。因为归一化坐标依赖输入尺寸部署时如果换了推理分辨率历史坐标就全乱了。原始像素坐标加上检入时的图像尺寸信息方便后续做任何转换。6. 常见问题排查与避坑经验实打实总结做这个项目的过程中遇到的问题层出不穷我把高频问题整理成了一张速查表方便后续快速定位。问题现象可能原因排查思路与解决办法模型一换场景就不认识坑洞数据集拍摄角度和场景单一模型过拟合补充不同道路类型、不同光照的自采数据使用多尺度训练检测框一直抖动同一坑洞框位置每分钟都变置信度阈值偏低把路面噪点当成目标提高置信度阈值到0.4以上配合帧间跟踪平滑位置雨天误检率飙升路线上的水洼与坑洞特征高度混淆增加积水坑洞的训练样本或雨天切换备用“低召回”模型边缘设备推理速度慢未使用TensorRT或只用了FP32精度转TensorRT并做int8量化模型体积和延迟会明显下降模型对远处坑洞召回率低输入分辨率不够小目标特征消失推理分辨率提高到960或1280注意耗时开销或增加小目标增强策略GPS坐标和实际坑洞位置偏差过大GPS模块更新频率低和检测帧时间戳不同步开启GPS高频输出模式对检测时间戳做对齐校正训练loss持续下降但mAP不升数据重复度太高训练集和验证集分布重叠按路段划分数据集检查连续帧相似度并去重这些问题的排查核心思路永远是“数据先行”——大部分检测效果问题不是模型结构的问题而是数据没喂对。每次遇到性能瓶颈先回看数据再调模型参数。这是我反复验证出的经验。还有两个容易被忽视的工程细节。第一个是图像采集时的存储格式我建议直接存原始分辨率或至少保持采集分辨率不要训练一个压缩的截图。坑洞边缘细节在JPEG压缩下会丢失严重标注时很难看清真实边界。第二个是模型版本管理问题训练多次后会有十几个权重文件一定把每个权重对应的训练脚本、数据版本、评估指标一起记录下来。不然过两周想对比效果根本分不清哪个模型是用哪份数据练出来的。7. 实际落地的几点经验补充项目做到后面我越来越觉得坑洞检测这个方向真正的难点不在模型本身。模型训练好只是一个开始后面每一环——数据采集的规划、标注规范的统一、边缘设备的适配、异常情况的兜底——都需要花大量时间。我在最后想给后来者三条核心建议。第一条建议先定业务边界再定技术方案。如果只是做科研Demo那追求高精度指标没有问题。但如果是给道路养护单位做辅助工具那检测的目标就不是惊艳的学术指标而是“稳定、可持续、可解释”。稳定指同一路段多次检测结果一致可持续指系统能长时间运行不崩溃可解释指每个检测结果都有对应的图像证据可以追溯。这些设计维度比多调几个点的mAP重要得多。第二条建议一定要做困难场景的压力测试。别只用晴天白天的好数据测试模型。我当时专门挑了几个雨天、黄昏、逆光场景做专项测试结果发现晴天95%以上的准确率到了雨天能跌到70%以下。这个落差如果不提前发现等系统真正部署到现实环境就会措手不及。第三条建议给使用者留一个人工复核的出口。任何自动检测系统都不能完全替代人工判断尤其是在道路养护这种与公共安全相关的领域。我的系统里设置了一个简单操作巡检人员每天可以在Web页面上对检测结果一键确认或驳回驳回的样本可以自动加入下一轮训练数据。这个闭环机制让系统在持续使用中变得越来越准这也是我认为这个项目做得最有价值的一个设计。踩过这么多坑之后我的体会是做工程类AI项目扎实的数据基础比花哨的模型结构重要得多。YOLO系列只是一个工具真正决定项目成败的是会不会设计数据采集方案、会不会制定合理的标注规范、会不会从失败案例中反推问题根源。这套系统做完之后我对于“AI落地难不难”这个问题有了更具体的答案难的不在模型而在系统。模型训练只是几天的事数据整理和系统集成才是占了整个项目70%工作量的部分。
阅读完成 · 觉得有帮助?