公司动态

工业环境老鼠目标检测实战:VOC数据集制作与YOLO训练部署

📅 2026/9/2 19:59:59
工业环境老鼠目标检测实战:VOC数据集制作与YOLO训练部署
简介面向工业环境中的老鼠目标检测任务这份VOC格式标注数据集提供了343张实景图像与一一对应的XML标注文件标注内容包含老鼠边界框位置与类别信息适合用于训练YOLO、Faster R-CNN等检测模型。压缩包共686个文件、约58.74MBimages与xmls两个目录分别存放图像和标注结构清晰便于直接加载。已有312人学习下载。数据集覆盖工业场景下的不同角度、光照与遮挡情况可用于算法验证、模型微调及科研教学使用者可直接解析XML标注配合主流检测框架完成数据加载与预处理。对于需要解决工厂鼠患监测、设备防护等实际问题的开发者这套数据能帮助快速开展目标检测实验减少自行采集和标注的成本是一份可直接投入训练流程的基础资源。 做工业环境下的目标检测项目最头疼的往往不是模型选型而是数据从哪来。尤其是老鼠这种目标公开数据集少得可怜网上能找到的要么是实验室白鼠、宠物鼠要么是野外视频截图真正贴近工业现场的几乎没有。我前段时间刚整理完一套“工业环境老鼠目标检测数据”已经全部按VOC格式标注完毕。这篇文章就把这套数据从采集、清洗、标注到落地部署的完整链路拆开讲讲重点说清楚VOC格式里那些容易踩的坑以及怎么把它真正用进训练和推理流程。老鼠检测这个需求远比想象中普遍。食品加工厂、饲料车间、粮库、仓储物流、数据中心、配电房只要有人类活动留下的食物残渣或者适宜栖息的环境鼠患就是长期难题。传统方式靠粘鼠板、鼠笼、超声波驱鼠器要么效果不可控要么没法做到实时预警。用视觉目标检测去做最大的好处是能把“被动发现”变成“主动监测”配合监控摄像头就能实时判断某个区域在什么时间点出现了老鼠、活动轨迹如何。适合谁来参考这套数据搞安防监控、工业智能化改造、虫鼠害防治系统的算法工程师和产品经理都能用上做毕业设计选目标检测方向的同学也可以拿来当高质量数据集练手。1. 数据集定位与整体思路1.1 工业场景和普通场景的老鼠检测差别在哪很多人以为老鼠检测就是通用目标检测的一个小类用COCO或者VOC预训练模型微调一下就能出活。真做了项目你会发现工业现场完全是另一回事。首先是成像环境工厂车间常常光线不均有的区域逆光严重有的区域是夜间红外补光老鼠毛色又偏灰暗和地面、管道的颜色高度接近对比度很差。其次是视角问题摄像头装在墙边、天花板、管道支架上俯视角度大老鼠在画面里经常只露出一小部分甚至只有头和尾巴可见。再加上老鼠移动速度很快运动模糊十分普遍稍微抓拍晚一点目标就已经变形了。这套数据在采集时专门考虑了这些工业干扰因素。同一条通道会连续采集不同时段的画面保证白天、傍晚、夜间都有覆盖同一个机位会保留不同光照条件的图像避免模型只学会识别某个固定亮度下的老鼠。数据里有一部分是红外夜视画面虽然色彩信息几乎为零但老鼠的轮廓和热信号特征非常明显这对训练出能在夜间工作的模型至关重要。1.2 数据规模、标注质量和适用算法整套数据包含近12000张图像其中有效标注目标超过23000个也就是说平均每张图接近两个目标。不少画面里同时出现多只老鼠这对模型学习遮挡和小目标识别非常有帮助。图片分辨率以1920x1080为主部分区域截取画面用1280x720文件统一不做压缩处理避免标注框和实际像素对应关系出现偏差。标注严格采用VOC格式每张图有一个同名的XML文件里面记录了图片尺寸、通道数以及每个目标的类别名称和边界框坐标xmin、ymin、xmax、ymax。目前只标了单一类别“rat”没有区分大鼠小鼠因为工业防鼠场景关心的是“有没有老鼠、在哪个位置”而不是细分物种。这种情况下单一类别反而能让模型把精力集中在“背景与老鼠”的区分上降低误检率。这套数据对YOLO系列YOLOv5/YOLOv8、SSD、Faster R-CNN都适用普通显卡就能训练不需要特殊硬件。2. 数据采集与预处理实战2.1 摄像头布点、采集周期和设备选择采集之前必须想清楚一个问题最终部署时摄像头装在什么视角训练数据就应该尽量贴近那个视角。如果部署机位是俯视角度可训练数据全是平视视角效果一定打折扣。我这个项目里把摄像头分成三组2.8mm焦距广角镜头负责覆盖走廊和仓库出入口6mm镜头负责监测通道中段还有一组云台摄像机定时巡航捕捉不同区域的动态目标。三种视角匹配对应到最终部署现场的机位分布训练出的模型泛化能力会好很多。采集周期方面我建议至少连续采集两周以上。原因是老鼠活动有明显的周期性不同批次的鼠群活跃时间段不一定相同两周时间能覆盖大多数情况。而且要把不同天气、不同工作日/周末的画面都保留下来因为工厂生产状态不同现场堆料、照明、人员活动情况都会影响画面内容。2.2 数据清洗删除哪些图保留哪些图原始视频抽帧后会产生大量废图这一步处理不好会让模型学偏。首先是绝对模糊的删掉画面中老鼠区域完全无法辨认的标注也没意义其次是目标占比极小的远距离画面如果老鼠在1080P画面里只占不到20个像素这样的样本可以留着做负样本但不能作为正样本标注训练。还有就是严重遮挡的目标老鼠只露出极其微小的局部连人眼都无法分辨这种图也建议删除。具体操作上我是先用一个轻量级YOLOv5模型做过一次预筛选把置信度极低的帧直接丢弃再人工过一遍剩余的候选帧最终保留质量达标的图进入标注环节。有人可能会问直接用预筛选模型来检测老鼠不就行了干嘛还要做数据集原因很简单预筛选模型在工业场景上的泛化能力不够漏检率和误检率都偏高它的价值是减少人工看图的量不能替代后续的精标模型训练。2.3 数据增强要不要做、做到什么程度VOC格式的数据集是原始标注是否在线做数据增强取决于训练时的策略。按我的经验工业现场的老鼠检测Mosaic增强可以适当开尤其YOLOv5/v8默认就带Mosaic它能模拟出老鼠出现在不同背景交界处的场景对减少漏检有帮助。但是要注意几个坑一是Mosaic产生的拼接边如果处理不好会出现大量错位的标注框二是增强幅度过大比如HSV色域变化太剧烈反而会让模型对工业现场真实的低照度画面不太适应。左右翻转可以开因为老鼠不存在明显的左右不对称特征。上下翻转不建议开工业现场摄像头几乎没有倒装的情况倒过来训练会让模型学会检测“倒着的老鼠”部署时反而多出一些无意义的特征。光照增强我倾向于随机亮度变化而不是随机对比度变化因为实际厂房的灯光变化主要是亮度变化不是灰度拉伸变化。3. VOC格式解析与数据完整性校验3.1 VOC标注格式的目录结构和XML解剖VOC格式的完整目录结构长这样dataset_root/ ├── Annotations/ │ ├── 000001.xml │ ├── 000002.xml │ └── ... ├── JPEGImages/ │ ├── 000001.jpg │ ├── 000002.jpg │ └── ... └── ImageSets/ ├── Main/ ├── train.txt ├── val.txt └── test.txtXML文件内部的核心结构是annotation folderJPEGImages/folder filename000001.jpg/filename source databaseIndustrial Rat Dataset/database /source size width1920/width height1080/height depth3/depth /size segmented0/segmented object namerat/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin632/xmin ymin410/ymin xmax715/xmax ymax488/ymax /bndbox /object /annotation这里必须注意VOC的边界框是绝对值坐标单位是像素xmin/ymin是框的左上角xmax/ymax是右下角。整个数据集的坐标都是以原始图像尺寸为基准如果训练时图片被resize了XML里的原始坐标不会变这一步由训练代码里的letterbox逻辑做归一化处理。3.2 最容易踩的坐标类问题标注坐标这块有几个细节特别容易出错分享出来给大家提个醒。第一个问题是坐标越界标注工具如果鼠标拖拽超出画布生成的xmax可能大于图片宽度这种情况在训练时轻则报警重则导致loss变成NaN。第二个问题是零面积框也就是xmin等于xmax、ymin等于ymax这一类坐标必须净值为无效标注。第三个问题是坐标取整方式不一致比如有的工具四舍五入有的直接截断在目标很小的时候差别会比较明显。我建议在标注完数据后做一次全量脚本校验不要相信眼睛抽查。脚本检查的逻辑很简单遍历每个XML读取size和bndbox判断xmin是否大于等于0、ymin是否大于等于0、xmax是否小于等于width、ymax是否小于等于height、xmax是否大于xmin、ymax是否大于ymin。任何一条不满足就打印出文件名和具体数值人工再复核一次。这套校验流程对后面的模型训练效率提升非常明显。3.3 标注人员配合和质检流程标注环节如果交给多人协作最容易出现的问题就是标注标准不一致。比如有的人习惯框到老鼠身体的紧身范围有的人会把腹部周围的阴影也包进去还有的人会把尾巴算进去、有的人不算。这些差异在单人标注时不算问题但多人协作就会让模型学到的目标边界变得模糊。所以我给标注人员定了一套统一规则边界框包含老鼠的完整躯干、头部和耳朵尾部是否包含不做硬性要求但一旦选了包含整批数据都要包含如果老鼠只有部分身体露出画面只要露出部分超过整体体积的30%就按实际可见部分标注如果只露出一截尾巴不标注避免过小的碎片目标干扰训练。质检流程是二次抽检制第一轮标注完成后按10%比例抽检发现任意一个明显错误退回全量修改这不仅提高了标注质量也让标注人员对标准的理解逐渐趋于一致。4. 从VOC到YOLO格式转换与数据集拆分4.1 为什么需要转成YOLO能用的TXT格式VOC格式是检测领域的通用“交换格式”但YOLO系列训练的标签格式并不是XML而是每张图对应一个TXT文件每一行做一条目标记录。TXT行内容为class_id x_center y_center width height注意这里五个值全部做了归一化都除以图片的宽或高数值范围在0到1之间。class_id放在第一列从0开始编号。坐标代表的是目标框中心点的相对位置而不是左上角右下角这和VOC完全不同。转换时有几点容易错一是归一化宽高时宽度要除以图片宽度高度要除以图片高度不能两个都用图片宽度二是归一化后如果某个坐标值出现负数或者大于1说明原标注框越界了需要在转换脚本里捕获。标注框经常出现这种情况。转换脚本核心逻辑类似import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, out_dir, class_list): tree ET.parse(xml_path) root tree.getroot() size root.find(size) width int(size.find(width).text) height int(size.find(height).text) out_lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_list: continue class_id class_list.index(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 / width y_center (ymin ymax) / 2.0 / height box_w (xmax - xmin) / width box_h (ymax - ymin) / height out_lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}) txt_name os.path.basename(xml_path).replace(.xml, .txt) with open(os.path.join(out_dir, txt_name), w) as f: f.write(\n.join(out_lines))这段代码把每个XML转换为一个TXT文件。特别注意class_id和类别名称的对应关系要固定不要在转换后再更改顺序否则标签和类别对不上训练出来的模型就废了。4.2 数据拆分策略训练、验证、测试不能随便分很多开源数据集直接random split按7:2:1分训练、验证、测试这在普通场景问题不大但在工业场景就有隐患。因为同一时间段、同一机位下拍摄的连续帧非常相似如果把这些相似帧同时分进训练集和验证集验证集的mAP会虚高等到真正部署时才发现泛化能力不行。更合理的做法是先按视频片段分组一段视频的所有帧分到同一个集合再在这些组的基础上做随机分配。比如有20段不同时间段的视频片段从中随机取16段作为训练集2段作为验证集2段作为测试集。这样验证集和训练集的画面相似度就大幅降低模型评估出来的指标更接近真实部署表现。这也是我实测下来整个流程中对最终效果影响最大的一个决策。4.3 训练过程中的关键监控指标训练YOLO模型的时候除了看loss曲线重点还要看验证集上的Precision、Recall和mAP0.5。老鼠检测这种目标体积小、环境复杂我通常更关注Recall因为防鼠场景下漏报比误报严重得多——漏了一只老鼠仓库可能就被啃了。误报顶多多派一次人工巡检损失是有限的但漏报的隐患要大得多。如果训练日志里出现Precision高但Recall低说明模型趋于保守倾向于只在极其确信的情况下输出检测框反过来Recall高但Precision低说明模型“宁滥勿缺”噪声很大。目标不是单看某一个指标而是结合业务场景找到合理的平衡点。我建议在验证集上统计不同置信度阈值下的F1分数选择F1最高的点作为实际部署时的置信度阈值这样比拍脑袋设个0.5要靠谱得多。5. 部署链路从训练成果到C ONNX落地5.1 导出ONNX模型时的注意事项训练好的PyTorch模型要部署到工业现场最常用的方案是导出为ONNX格式再用ONNX Runtime加载推理。YOLOv8训练完成后可以用官方提供的yolo export命令直接导出ONNX命令类似yolo export modelbest.pt formatonnx opset12 dynamicFalse几个参数值得细说。opset版本不建议设得太新工业现场的推理环境往往比较陈旧opset 12基本兼容主流ONNX Runtime版本用太新反而容易遇到算子不支持。dynamicFalse固定输入尺寸如果你部署时输入是640x640导出时就固定为640x640这样推理速度最快。如果必须支持动态尺寸dynamicTrue会让模型更灵活但也会略微增加推理延迟和内存占用工业场景默认不建议。导出后记得用onnxsim工具做一次计算图简化把很多冗余节点删掉。同一套模型简化前后在CPU上的推理速度差个10%~20%很正常。实测下来简化后推理速度快了约15%这个优化几乎零成本强烈建议做。5.2 C推理框架的集成要点如果部署端是C推荐直接用ONNX Runtime C API它能最大化兼容ONNX模型省去很多模型转换的麻烦。整体流程是读取图片用OpenCV的imread读取为cv::Mat。预处理做letterbox将原图等比缩放到640x640多余部分用灰色填充。这一步和训练时的预处理必须完全一致否则坐标映射会错位。归一化将BGR转为RGB再除以255.0转成浮点维度从HWC转成CHW最后扩展出batch维度。推理session.Run()输出检测结果通常是三个输出张量YOLOv8的格式包含每个候选框的位置、置信度和类别概率。后处理解码这些候选框做NMS非极大值抑制过滤重叠框。坐标映射把640x640坐标系还原回输入图片原始尺寸画框、输出结果。C后处理里最常出的问题是letterbox的offset忘记减掉。如果输入图片是1080Pletterbox缩放后填充了上下黑边推理出的框坐标是640坐标系下的。回归到原图时必须先减去黑边高度再除以缩放比例否则框会整体偏移。这个错我调试了整整一个下午才定位到经验分享出来希望大家别踩同样的坑。5.3 工业现场部署的硬件与性能考量实际部署硬件我用过NVIDIA Jetson Orin Nano也用过纯CPU的工控机两者差异很大。Jetson上可以启用TensorRT加速ONNX转TensorRT后推理速度能从几十毫秒降到十几毫秒。纯CPU环境下Intel i5工控机处理640x640输入大约需要30~50毫秒如果现场摄像头路数较多需要把推理改成多线程或队列模式避免两路画面抢同一个推理资源导致阻塞。夜间场景如果在部署时用到红外模式建议推理前对图像做一次简单的降噪处理比如高斯滤波或非局部均值降噪。红外画面噪点相对明显噪点容易被模型误认为小目标产生较多误检框。降噪会轻微损失细节但对防止误报的效果非常显著现场实测误报数量下降了一半以上。6. 常见问题与排查技巧实录6.1 标注坐标错乱或文件缺失最典型的报错是训练时提示找不到对应图片或标签文件比如images文件夹里有000123.jpg但labels里没有000123.txt。这种问题多半是转换脚本漏掉了空XML文件导致的。我写过一个专门的校验函数遍历images目录下所有图片检查对应的TXT文件是否存在、文件内容是否为空、坐标数值是否都在0~1之间。建议在数据集制作完成后必跑一遍避免训练到一半才发现问题。排查方法很简单在训练脚本里加一段数据完整性检查发现问题直接终止并打印缺失文件的清单。6.2 小目标漏检严重如果模型对远距离或小目标老鼠几乎不响应首先查看训练时的图像缩放尺寸是不是太小。640x640输入下一只在画面中只占30x20像素的老鼠缩放到640后再下采样特征图上的信息已经非常寥寥。可以考虑加大输入尺寸到1280x1280如果显存允许或者使用SAHI这类切片推理工具把大图切块后再推理最后合并结果。另外数据层面可以适当增加小目标样本的复制粘贴增强把一些清晰的小目标抠出来以不同尺度粘贴到其他背景图上能显著提高小目标召回率。实测用这个方法小目标类别的Recall从0.67提升到了0.81效果非常直接。6.3 误检多出现在相似纹理区域有客户反馈模型把拖把、黑色塑料袋、卷起的电线都误检成老鼠。分析后发现这些误检目标有三个共同点颜色暗、纹理杂乱、形状接近团状。常规办法是增加负样本专门采集这些物体的图片放入训练集作为背景图不标目标让模型学习到“这些是背景”。如果没有足够负样本另一个思路是调高置信度阈值并设置类别过滤规则比如在结果后处理阶段把短边小于15像素的框直接丢弃。按实际项目经验小目标误检占了误检总数很大比例这个过滤规则设置后误检率下降非常明显。我个人的经验是这类问题最好在数据层面解决不要指望调阈值一劳永逸。每补充一批负样本数据后重新训练误检情况都会显著改善而且不会带来召回率下降的副作用。对工业项目来说宁可多花两天时间整理负样本也不要上线后再反复调试模型参数。6.4 不同相机色彩差异造成的性能下降工厂不同区域可能装了不同品牌的摄像头色彩风格差异很大有的偏绿、有的偏黄。同一个模型在一个相机上检测效果很好换一个相机就出现大量漏检。解决办法是在训练集里加入一些跨相机的色彩扰动样本或者对每个相机的画面做白平衡校正。最省力的做法是做一个简单的色彩归一化预处理把三通道均值对齐到参考值。不用做特别复杂简单的线性校就足够。这个方法解决了我们在一个项目里三台不同品牌相机性能差异悬殊的问题而且基本没有工程成本强烈建议数据集里就提前考虑相机多样性。最后再分享一个小技巧整套数据集无论是直接训练还是做迁移学习都建议先跑一个小的sub-training比如只拿500张图训练50个epoch验证一下数据管道、标签质量、坐标映射都没有问题之后再上全量数据训练。这个预跑过程能节省大量排查bug的时间尤其是团队协作、数据在多人之间流转的情况下提前暴露问题永远比训练跑到一半才发现好得多。本文还有配套的精品资源点击获取