
简介本资源是一份面向计算机视觉初学者与目标检测实践者的公路落石检测专用数据集聚焦于真实道路场景下的小目标识别任务适用于YOLOv5/v8、Faster R-CNN等主流模型的训练与验证。数据集共1019个文件包含282张JPG图像、282份Pascal VOC格式XML标注文件含坐标与类别、284份YOLO格式TXT标签文件归一化坐标另有169个labelImg备份文件zbak便于标注回溯整体压缩包仅15.16MB轻量易部署。目前已有48人学习下载适合作为课程设计、课程实验或个人项目的数据基础。用户可直接加载VOC或YOLO双格式开展数据预处理、模型训练与评估全流程实践无需额外转换所有标注均经labelImg人工校验单类别“stone”共632个高质量边界框覆盖不同光照、角度与遮挡条件下的落石样本具备较强泛化学习价值。1. 项目概述从282张图片到可用的公路落石检测模型做目标检测项目最头疼的往往不是调参而是数据。特别是当你面对一个像“公路落石”这样具体且对安全至关重要的场景时找到一个现成、标注好、质量又高的数据集难度不亚于在工地里找一颗特定的石子。最近我手头正好有这么一个项目需求要做一个针对山区公路旁坡面落石的自动检测预警原型。找了一圈公开数据集要么是通用的“石头”类别背景是河滩或山体和公路场景差异巨大要么就是数据量太少根本不够训练。最后还是决定自己动手丰衣足食整理了一个包含282张图像的小型VOC格式数据集并用YOLO系列算法进行训练和验证。别看只有282张在特定场景下经过精心处理和增强这个小数据集也能爆发出不错的能量。这个项目的核心价值在于“场景化”。通用目标检测模型比如用COCO预训练的对“落石”的识别率很低因为COCO里根本没有这个类别。落石在图像中可能呈现为颜色与路面接近、形状不规则、尺寸变化大的目标且常伴有阴影、遮挡如护栏遮挡一部分。直接套用通用模型基本无效。因此构建一个针对“公路环境落石”的专属数据集是解决这个工程问题的第一步也是最关键的一步。这个数据集虽然不大但涵盖了晴天、阴天、不同光照角度、不同拍摄距离远景、中景、近景以及落石位于路面、路肩、边坡等典型位置的情况具备了初步的多样性和代表性。接下来我就把这套从数据准备到模型训练上线的完整流程以及其中踩过的坑和总结的经验详细分享一下。2. 数据集构建282张图片背后的逻辑与精细化处理2.1 数据采集与核心考量282张图片这个数字不是随便定的。对于初期原型验证和特定场景下的模型可行性测试几百张图像是一个比较务实的起点。它既能避免因数据量过少导致的模型完全无法学习又能将数据采集、标注的成本和周期控制在可接受的范围内。我们的图片主要来源有几个一是公开的交通监控视频截图已脱敏仅包含道路和自然环境二是合作单位提供的部分历史巡检照片三是在确保安全的前提下在部分测试路段模拟拍摄的图片。在采集时我们重点关注了以下几个维度以确保数据质量场景多样性涵盖了笔直路段、弯道、隧道口、桥梁衔接处等不同公路场景。背景的多样化有助于模型学习到“落石”的本质特征而不是记忆某个特定背景。光照与天气条件包括清晨、正午、傍晚的不同光照以及晴天、多云、阴天。落石的颜色灰色、土黄色在不同光线下变化很大这是模型必须克服的挑战。目标尺度与形态既有占据图像很小区域的远景落石小目标检测的难点也有近景特写的大块落石。落石的形状从不规则的块状到片状都有收录。干扰因素特意包含了一些有干扰的图片如路面修补的沥青块、阴影、积水反光、丢弃的编织袋等这些都是在真实场景中容易引发误报的负样本。注意数据采集必须严格遵守相关安全规定和隐私政策。所有涉及车牌、人脸等敏感信息的图像必须进行模糊或剔除处理。我们的数据均来自允许研究的公开或授权资源。2.2 VOC格式详解与标注实践我们选择了PASCAL VOC格式作为标注标准主要是出于其通用性和工具支持的完善性。YOLO虽然有自己的TXT标注格式但很多数据标注工具如LabelImg默认支持VOC的XML格式输出且VOC格式包含的信息更丰富便于后续可能的数据分析或格式转换。一个典型的VOC格式XML文件结构如下它详细描述了图片信息和目标位置annotation folderimages/folder filenamerock_fall_001.jpg/filename path/path/to/rock_fall_001.jpg/path source databaseHighway Rock Fall Database/database /source size width1920/width height1080/height depth3/depth /size segmented0/segmented object namerock/name !-- 类别名称 -- poseUnspecified/pose truncated0/truncated !-- 目标是否被截断 -- difficult0/difficult !-- 是否为难例 -- bndbox !-- 边界框坐标 -- xmin560/xmin ymin320/ymin xmax890/xmax ymax650/ymax /bndbox /object /annotation在标注过程中我们制定了严格的规范边界框Bounding Box紧贴落石边缘绘制包括石块投射的小片阴影如果阴影与石块连接紧密因为阴影也是识别落石的重要上下文特征。但对于明显分离的、长长的阴影则不纳入框内。遮挡与截断处理如果落石被护栏、草木部分遮挡框选可见部分并将truncated标签设为1。这对于模型学习不完整目标的特征很重要。难例标注对于极其模糊、与背景颜色几乎融合、或尺寸极小的落石除了标注外还将difficult设为1。在评估时可以自由选择是否计入这些难例从而更客观地衡量模型在实际可用场景下的性能。类别统一整个数据集只定义一个类别rock。在初期专注于单一类别的检测效果提升比引入多类别如“大石头”、“小石子”更重要。2.3 数据增强策略小数据集的“强心剂”282张原始数据对于深度学习来说确实捉襟见肘。我们必须通过数据增强来“创造”更多的训练样本提高模型的鲁棒性。我们的增强策略分为两类离线增强和在线增强。离线增强是在训练前一次性生成一批新图像扩充数据集。我们使用Albumentations库进行了以下操作几何变换随机水平翻转模拟对向车道视角、小幅度的旋转±15°和缩放0.9-1.1倍。色彩空间变换这是针对落石检测的关键。调整亮度、对比度、饱和度模拟不同天气和光照。特别是添加随机RGB偏移可以改变石头的色调使其更能适应不同岩质的路段。模拟天气效果随机添加轻微的模糊模拟雨雾和噪声模拟传感器噪声。经过离线增强我们将数据集从282张扩充到了约1500张。这构成了我们的基础训练集。在线增强是在模型训练时每个epoch训练轮次从数据集中加载图片时实时进行的、随机的增强。这可以确保模型在每一轮看到的“相同”图片都有细微差别极大地提升了泛化能力。我们主要采用了Mosaic增强和MixUp增强。Mosaic增强将四张训练图片随机缩放、裁剪后拼接到一张图上。这能让模型在同一张图中学习到不同尺度、不同背景下的落石对于小目标检测尤其有效因为小落石在被拼接后可能变成相对较大的目标。MixUp增强将两张图片以一定比例混合其标签也按相同比例混合。这相当于一种正则化可以平滑决策边界减少模型对某些极端样本的过拟合。3. 模型选择与YOLO实战为何是YOLOv83.1 从YOLO家族中做出选择面对YOLOv3, v5, v7, v8乃至各种魔改版本选择哪个我们的考量基于以下几点项目阶段这是原型验证阶段要求快速迭代、验证可行性。因此需要一款易用、文档完善、社区活跃的框架。数据规模仅有282张增强后1500张原始数据模型不宜过于庞大否则极易过拟合。部署考量最终可能需要部署到边缘设备如带GPU的工控机或云端服务器需要平衡精度和速度。基于以上我们选择了Ultralytics YOLOv8。原因如下极致易用性其Python API和CLI命令设计得非常人性化从数据准备、训练、验证到导出几乎一行命令就能完成极大降低了开发门槛。精度与速度的平衡YOLOv8在保持YOLO系列实时性的同时精度尤其是mAP指标有显著提升。它提供了n, s, m, l, x不同尺度的模型我们可以从较小的YOLOv8n或YOLOv8s开始尝试。丰富的预训练模型虽然COCO预训练模型中没有“落石”类别但其提取通用特征边缘、纹理、形状的能力很强通过微调Fine-tuning可以快速适配我们的新任务这在数据量小时至关重要。活跃的社区与生态遇到问题容易找到解决方案且有持续更新和维护的保障。3.2 数据格式转换与配置文件准备YOLOv8训练需要的是YOLO格式的TXT标注文件每个TXT文件与图片同名内容格式为class_id x_center y_center width height坐标是归一化后的即除以图片宽高。我们需要将VOC XML格式转换过来。我们写了一个简单的转换脚本核心是解析XML中的bndbox并计算归一化中心坐标和宽高import xml.etree.ElementTree as ET import os def convert_voc_to_yolo(xml_path, img_w, img_h, class_dict): tree ET.parse(xml_path) root tree.getroot() yolo_lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_dict: continue cls_id class_dict[cls_name] bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 计算归一化坐标 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h # 确保坐标在[0,1]范围内 x_center max(0, min(1, x_center)) y_center max(0, min(1, y_center)) width max(0, min(1, width)) height max(0, min(1, height)) yolo_lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) return yolo_lines # 使用示例 class_dict {rock: 0} # 类别ID从0开始 # ... 遍历所有XML文件读取对应图片尺寸生成TXT文件 ...接下来需要创建一个YAML配置文件来告诉YOLOv8数据在哪里、有哪些类别。这个文件至关重要。# highway_rock.yaml path: /datasets/highway_rock # 数据集根目录 train: images/train # 训练集图片路径相对于path val: images/val # 验证集图片路径相对于path # test: images/test # 如果有测试集可以加上 # 类别列表 names: 0: rock我们将增强后的1500张图片按8:2的比例随机划分为训练集1200张和验证集300张。注意划分是在增强后的数据上进行的并且要确保同一原始图片及其增强版本只出现在训练集或验证集中一个地方防止数据泄露。3.3 训练过程与关键参数调优训练命令非常简单yolo taskdetect modetrain modelyolov8s.pt datahighway_rock.yaml epochs100 imgsz640 batch16但参数背后的调优才是关键模型选择 (modelyolov8s.pt)我们从yolov8s.pt小模型开始。如果欠拟合训练集精度也上不去再尝试yolov8m.pt中模型。初期切忌直接用x超大模型那会很快过拟合。训练轮数 (epochs100)对于小数据集100轮通常足够。我们需要监控训练损失和验证集精度曲线。当验证集精度连续10-15轮不再上升甚至下降时过拟合可以提前停止。图像尺寸 (imgsz640)YOLOv8默认将输入图像缩放到640x640。对于公路落石小目标较多我们尝试过增大到832这确实能提升小目标召回率但会显著增加显存消耗和训练时间。需要在硬件条件和精度间权衡。我们最终选择了640作为一个平衡点。批次大小 (batch16)在GPU显存允许的情况下我们使用RTX 3080 10GB尽可能设大。大的批次能使梯度估计更稳定收敛更快。如果出现OOM显存溢出可以减小batch或启用ampTrue自动混合精度训练。学习率与优化器我们使用默认的SGD优化器和初始学习率。一个重要的技巧是使用预训练权重modelyolov8s.pt已经包含了并在前期冻结部分骨干网络Backbone的层只训练检测头Head这样可以防止小数据破坏预训练好的通用特征提取能力。YOLOv8通过freeze参数可以方便实现例如freeze10冻结前10层。训练过程中的监控至关重要。Ultralytics提供了完善的TensorBoard或内置可视化工具。我们主要看两个图损失曲线train/box_loss,train/cls_loss,val/box_loss,val/cls_loss。理想情况是训练损失稳步下降验证损失先降后趋于平稳。如果验证损失很早就开始上升就是过拟合的信号。精度曲线metrics/mAP50-95(B)即COCO标准的mAP。这是我们评估模型性能的核心指标。我们会重点关注mAP50IoU阈值为50%时的mAP因为它更贴近实际应用中对“检测到”的宽松定义。4. 模型评估与性能分析不仅仅是看mAP4.1 理解评估指标mAP, Precision, Recall训练结束后YOLOv8会自动在验证集上运行评估并输出一系列指标。我们需要正确理解它们精确率 (Precision)模型预测出的所有“落石”中有多少是真正的落石。高精确率意味着误报少。对于预警系统误报过多会导致警报疲劳失去信任。召回率 (Recall)所有真实的落石中有多少被模型检测出来了。高召回率意味着漏报少。对于安全应用漏报的后果可能更严重。平均精度 (Average Precision, AP)在不同召回率水平下精确率的平均值。它综合衡量了精确率和召回率。mAP (mean Average Precision)对所有类别的AP取平均。我们只有一个类别rock所以mAP50就是rock类别的AP50。一个常见的误区是只追求高mAP。在实际工程中我们需要根据业务需求在精确率和召回率之间做权衡Trade-off。通过调整模型预测时的置信度阈值conf可以实现这一点提高阈值如从0.25提到0.5模型只有非常确信时才会输出预测框。这会导致精确率上升召回率下降漏掉一些不太确定的真实目标。降低阈值如从0.25降到0.1模型更“敏感”会输出更多预测框。这会导致召回率上升精确率下降混入更多误报。我们的策略是首先保证一个可接受的召回率例如85%然后通过优化模型和数据尽可能提升在此召回率下的精确率。我们可以使用YOLOv8的验证模式并输出PR曲线来观察yolo taskdetect modeval modelruns/detect/train/weights/best.pt datahighway_rock.yaml4.2 错误分析与模型迭代查看评估指标后更重要的是进行错误分析。我们使用YOLOv8提供的可视化工具查看验证集上模型的预测结果重点关注以下几类错误误报False Positives, FP模型把“非落石”检测成了落石。常见的有路面裂缝或修补痕迹。深色阴影区域。路边的土堆或灌木丛边缘。对策将这些误报的“硬负样本”裁剪出来加入到训练集中并标注为背景或者在数据增强时用这些区域做负样本增强。重新训练模型让它“认识”这些容易混淆的东西。漏报False Negatives, FN真实的落石没有被检测出来。常见于尺寸极小的落石远处。颜色与路面几乎完全一致的落石。被严重遮挡的落石。对策检查这些漏报样本看是否标注不够精确框太大或太小。如果是小目标问题可以尝试使用更小的锚框Anchor预设。YOLOv8是Anchor-Free的但可以调整特征金字塔网络FPN的结构增强小目标检测层。在数据增强中更多地使用Mosaic它能“创造”出更多小目标训练样本。稍微减小imgsz可能反而有帮助不对于小目标增大imgsz是更直接的方法但需权衡资源。定位不准Localization Error检测框与真实框的重叠度IoU不高。这通常意味着模型对目标的边界学习不够好。对策检查标注框的准确性确保每个框都紧贴目标。可以尝试使用更强大的数据增强如旋转和缩放让模型学习不同姿态的目标边界。我们进行了两轮“训练-评估-错误分析-数据补充/调整-再训练”的迭代。在第一轮训练后mAP50达到了0.78。通过加入约50张硬负样本和修正了30多张有问题的标注后第二轮训练使mAP50提升到了0.85。这个提升对于一个小数据集来说是非常显著的。5. 部署推理与优化实战让模型真正跑起来5.1 模型导出与格式选择训练好的模型best.pt是PyTorch格式适用于研究和进一步调优。但要部署到生产环境我们需要将其转换为更高效或更适合特定平台的格式。YOLOv8提供了强大的导出功能yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640 simplifyTrueONNX (formatonnx)这是一种开放的模型交换格式被绝大多数推理引擎如OpenVINO, TensorRT, ONNX Runtime支持。它是部署的首选中间格式。TensorRT (formatengine)如果你在NVIDIA GPU上部署并且追求极致的推理速度可以导出为TensorRT引擎。这需要先在本地安装TensorRT并且导出的模型将绑定特定的GPU型号和TensorRT版本。OpenVINO (formatopenvino)针对Intel CPU、集成显卡或神经计算棒的优化格式。CoreML (formatcoreml)用于苹果生态系统iOS/macOS。简化 (simplifyTrue)尝试简化ONNX模型结构可能提升推理速度。我们通常先导出为ONNX因为它通用性最强后续可以根据部署环境再转换。5.2 基于Python的简易推理服务在服务器端我们可以用ONNX Runtime或直接使用PyTorch进行推理。下面是一个使用Ultralytics YOLOv8 Python API进行实时推理的示例这比直接加载ONNX并处理前后端更简单from ultralytics import YOLO import cv2 # 加载训练好的模型 model YOLO(runs/detect/train/weights/best.pt) # 打开摄像头或视频文件 cap cv2.VideoCapture(highway_surveillance.mp4) while cap.isOpened(): ret, frame cap.read() if not ret: break # 执行推理 results model(frame, imgsz640, conf0.4) # 设置置信度阈值 # 解析结果 for result in results: boxes result.boxes if boxes is not None: for box in boxes: # 获取坐标、置信度、类别ID x1, y1, x2, y2 box.xyxy[0].cpu().numpy() conf box.conf[0].cpu().numpy() cls_id int(box.cls[0].cpu().numpy()) # 绘制框和标签 label f{model.names[cls_id]} {conf:.2f} cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) cv2.putText(frame, label, (int(x1), int(y1)-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2) # 显示结果 cv2.imshow(Highway Rock Detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()5.3 性能优化与加速技巧在真实部署中尤其是视频流处理性能至关重要。推理批处理Batch Inference如果同时处理多路视频流不要一帧一帧地推理。将多帧图片组合成一个批次Batch一次性输入模型可以极大提升GPU利用率。YOLOv8的predict方法支持传入一个图片列表。调整推理尺寸训练时用imgsz640但推理时可以根据实际情况调整。如果部署设备算力弱可以适当减小如416牺牲一点精度换取速度。可以使用model.predict(..., imgsz416)。半精度推理FP16大多数现代GPU支持FP16计算速度比FP32快很多精度损失微乎其微。在导出ONNX或使用TensorRT时可以启用FP16。使用TensorRT在NVIDIA Jetson等边缘设备上将模型转换为TensorRT引擎格式通常能获得数倍的加速比。后处理优化模型输出的后处理非极大值抑制NMS如果自己实现可以用CUDA或更高效的库进行优化。不过Ultralytics的封装已经做得不错。6. 避坑指南与经验总结6.1 数据层面的“坑”坑1标注不一致。不同人员标注的松紧度不同有的框得紧有的框得松。这会导致模型学习的目标边界模糊。解决制定详细的标注规范文档并进行交叉审核。最好由一个人完成最终审核。坑2类别不平衡与负样本不足。我们的数据全是“有落石”的正样本缺乏明确的“无落石”负样本。解决主动收集一些容易引发误报的场景图片如干净路面、有阴影的路面、有修补的路面在训练时这些图片的标注文件可以是空的即没有目标。这能有效告诉模型“这些地方不应该有检测框”。坑3数据泄露。如果将同一张原始图片的不同增强版本分别放入训练集和验证集会导致评估结果虚高。解决在数据增强前先按原始图片划分好训练集和验证集然后分别对两个子集进行增强。6.2 训练与模型层面的“坑”坑4过拟合的征兆被忽略。如果训练损失持续下降但验证损失很早就开始波动上升这就是典型的过拟合。不要只看训练集精度。解决除了使用数据增强可以增加权重衰减weight_decay使用更深的模型冻结策略freeze更多层或者直接采用早停Early Stopping。坑5盲目调参。看到效果不好就同时调整学习率、批次大小、优化器等各种参数。这会让问题复杂化。解决采用控制变量法。先固定其他参数只调整一个比如学习率观察其影响。从一个公认较好的默认配置开始YOLOv8的默认参数已经经过大量调优每次只做微调。坑6忽略锚框对于YOLOv5等Anchor-Based模型或模型结构对小目标的适配。对于落石这种小目标默认的锚框尺寸或特征金字塔可能不合适。解决对于YOLOv8Anchor-Free可以关注模型结构中的detect层确保有足够浅的、高分辨率的特征层用于检测小目标。也可以在数据增强上多下功夫。6.3 工程部署的“坑”坑7训练和推理的环境不一致。训练时用GPU推理时用CPU或者图像预处理归一化、通道顺序代码不一致导致效果暴跌。解决将预处理和后处理逻辑封装成与训练时完全一致的函数并进行单元测试。使用ONNX等格式可以更好地保证一致性。坑8实时性要求与精度的矛盾。在边缘设备上可能无法承受640x640分辨率下的实时推理。解决进行模型量化Quantization如将FP32转换为INT8可以大幅减少模型体积和提升速度但可能会带来精度损失需要仔细评估。这个基于282张图片的公路落石检测项目从数据准备到模型部署走完了一个完整的Pipeline。它证明了即使在数据有限的情况下通过精细化的数据处理、恰当的模型选择、有针对性的训练策略以及严谨的错误分析也能构建出一个在特定场景下可用的目标检测模型。对于工程实践而言这往往比追求在通用数据集上的SOTA指标更有价值。模型最终的mAP50达到了0.85在测试视频上对于明显落石的检出率很高误报也控制在了可接受范围内为后续集成到更大的公路安全监测系统中打下了坚实的基础。当然要投入实际业务还需要在更多样、更极端的场景数据上进行持续迭代和优化。本文还有配套的精品资源点击获取