卡车倾倒建筑垃圾检测数据集:从标注到训练全流程
简介这份卡车倾倒建筑垃圾检测数据集面向计算机视觉与深度学习方向的开发者、算法工程师及环保智能监控研究者用于训练和评估目标检测模型识别图像或视频流中卡车倾倒建筑垃圾的行为可服务于城市监控、建筑工地管理与环保监测等场景。资源包共1023个文件以569张jpg、39个jpeg与106张png图像为主体覆盖不同角度、光照与倾倒阶段另含309个xml标注文件提供边界框坐标与类别标签便于直接用于监督学习训练压缩包约115.49MB结构清晰适合YOLOv7等检测模型快速接入。目前已有240人学习下载。借助该数据集读者可完成从图像预处理、标注解析到模型训练与验证的完整流程并参考mAP 0.85的检测表现评估模型在复杂现实环境中的准确率与泛化能力为非法倾倒行为的自动化识别提供可靠数据基础。1. 卡车倾倒建筑垃圾检测数据集从标注困境到可复现训练管线城市管理里有个高频场景渣土车在非指定区域偷偷倾倒建筑垃圾等执法人员赶到车早跑了。靠人盯监控不现实一个区几千路摄像头看不过来。于是「卡车倾倒建筑垃圾检测数据集」这类需求就冒出来了——用视觉模型自动识别卡车倾倒动作把事后追查变成实时告警。但真正动手的人很快会发现卡住你的不是模型结构而是数据。倾倒行为在视频里只占几秒正样本极度稀疏卡车和普通货车外观接近模型容易把路过车辆误判成倾倒不同工地、不同光照、不同拍摄角度让标注一致性很难保证。这个数据集方向要解决的核心问题就三个怎么定义「倾倒」这个动作边界、怎么在稀疏正样本下做标注、怎么让训练出来的模型在真实摄像头下不翻车。适合做智慧城管、工地扬尘监管、边缘视觉盒子的工程师也适合想入门行为识别但被数据卡住的人。2. 倾倒行为的数据集怎么定义动作边界与标注粒度2.1 为什么「倾倒」不能只标一个框很多人第一反应是把它当成目标检测任务标出卡车标出垃圾堆训练 YOLO 去检测。这个思路在 demo 阶段能跑通但上线就翻车。原因是「倾倒」是一个时序动作单帧里卡车可能只是停着垃圾堆可能还没出现。你标了卡车框模型学到的是「卡车正样本」结果所有路过的卡车都告警。常见做法是把任务拆成两层第一层做卡车检测第二层做动作分类或时序判定。数据集标注也要对应拆开——卡车用边界框倾倒动作用时间段start_time, end_time加事件标签。如果只做单帧至少要有「卡车车厢举升」或「卡车尾部垃圾滑落」这种组合特征否则单靠卡车框没有区分度。我一般会建议在标注规范里明确写死倾倒事件从车厢开始举升或尾部开始有物料滑落算起到车厢回落或物料停止滑落结束。这个边界不写清楚十个标注员能标出十种结果后面训练全是玄学。2.2 标注粒度选择帧级、段级还是事件级三种粒度对应三种成本和精度选错了要么浪费标注预算要么模型学不到东西。粒度标注内容标注成本适用场景模型输出帧级每帧标卡车框是否倾倒高逐帧数据量小、动作短单帧分类段级标出倾倒起止时间段中视频片段训练时序动作检测事件级只标视频里有无倾倒事件低弱监督、预筛选视频分类帧级标注最贵但如果你要做实时告警帧级或段级是必须的。事件级适合做粗筛比如先从几千小时视频里筛出可能含倾倒的片段再人工精标。实际项目里我通常先用事件级做一轮弱监督预筛把候选片段从小时级压到分钟级再上段级精标标注成本能降一个数量级。2.3 正负样本比例与难负样本挖掘倾倒行为在真实视频里可能只占千分之几正负样本极度不平衡。如果直接拿原始分布训练模型会倾向于全部判负准确率看着很高召回率惨不忍睹。处理方式分两步。第一步在采样阶段做重采样让正负比控制在 1:3 到 1:10 之间不要一上来就 1:1容易过拟合正样本。第二步做难负样本挖掘把模型在负样本上误报高的片段挑出来人工确认后加入训练集。这些难负样本通常是停靠但未倾倒的卡车、缓慢行驶的渣土车、外观相似的厢式货车。注意难负样本挖掘要迭代做第一轮训练完挑一批第二轮再挑一批通常两到三轮后误报率会明显下降。不要一次性挖太多容易把训练集分布带偏。3. 从原始视频到可训练数据集抽帧、标注与格式转换3.1 视频抽帧策略与去重原始视频不能直接喂给标注工具先要抽帧。抽帧策略直接影响标注成本和模型效果。import cv2 import os import imagehash from PIL import Image def extract_frames(video_path, out_dir, fps2, diff_threshold8): 按指定fps抽帧并用感知哈希去重 fps: 每秒抽几帧倾倒动作建议2-5 diff_threshold: 哈希距离阈值小于该值视为重复帧 os.makedirs(out_dir, exist_okTrue) cap cv2.VideoCapture(video_path) video_fps cap.get(cv2.CAP_PROP_FPS) interval int(video_fps / fps) saved, last_hash 0, None frame_idx 0 while True: ret, frame cap.read() if not ret: break if frame_idx % interval 0: img Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) h imagehash.phash(img) if last_hash is None or (h - last_hash) diff_threshold: cv2.imwrite(os.path.join(out_dir, f{frame_idx:06d}.jpg), frame) last_hash h saved 1 frame_idx 1 cap.release() return saved这段代码的逻辑是按目标 fps 间隔取帧再用感知哈希判断和上一张保存的帧是否足够不同。倾倒动作持续时间短fps 设太低会漏掉关键帧设太高标注量爆炸。我的经验是 2 到 5 fps 之间具体看动作快慢。diff_threshold 控制去重力度设 8 左右能去掉大部分静止画面又不至于把动作变化帧误删。如果摄像头是固定机位去重效果会很好如果是移动拍摄哈希去重会失效得换光流或特征点方法。3.2 标注工具选型与标注规范落地标注工具常见的有 LabelImg、CVAT、Label Studio。做纯检测用 LabelImg 够用但倾倒任务涉及时序CVAT 的视频标注模式更合适能直接标时间段。Label Studio 适合做多模态或事件级标注。不管用哪个工具标注规范必须提前写死至少包含卡车框的边界是否包含车厢举升部分是否包含尾部滑落物料遮挡处理卡车被遮挡超过 50% 是否还标倾倒判定车厢举升但未卸料算不算卸料但车厢未举升算不算负样本定义停靠多久算负样本路过但减速算不算这些规则不写清楚标注员之间的一致性可能只有 60% 到 70%训练时模型学到的就是噪声。我一般会先让标注员标 50 到 100 帧算一下一致性低于 90% 就回去改规范别急着铺量。3.3 转成 YOLO 与时序标注格式如果做检测时序通常需要两套标注检测用 YOLO 格式时序用 JSON 或 CSV。转换脚本要保证帧号和视频时间戳对齐。import json import os def convert_to_yolo(anno_json, out_dir, class_map): anno_json: 每帧的标注列表含frame_id, bbox, class class_map: 类别名到id的映射 os.makedirs(out_dir, exist_okTrue) with open(anno_json, r) as f: data json.load(f) for item in data: frame_id item[frame_id] img_w, img_h item[width], item[height] lines [] for obj in item[objects]: cls_id class_map[obj[class]] x, y, w, h obj[bbox] # YOLO格式class cx cy w h均归一化到0-1 cx (x w / 2) / img_w cy (y h / 2) / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w/img_w:.6f} {h/img_h:.6f}) with open(os.path.join(out_dir, f{frame_id:06d}.txt), w) as f: f.write(\n.join(lines))转换时最容易翻车的是坐标系。有些标注工具输出的是左上角宽高有些是左上角右下角有些是归一化过的有些是像素值。转换前一定先拿几帧可视化验证别等训练 loss 不降才回头查。另外帧号对齐也要注意抽帧后的帧号和原视频帧号不是一回事时序标注要映射回抽帧后的编号否则时间段全错位。4. 训练管线搭建从数据加载到模型选型4.1 数据加载与增强策略倾倒检测的数据增强不能照搬通用检测那套。水平翻转通常安全但垂直翻转会让卡车倒扣不真实。颜色抖动可以加模拟不同光照。随机裁剪要小心可能把卡车裁掉一半反而制造噪声。import albumentations as A train_transform A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(p0.3), A.HueSaturationValue(p0.2), A.MotionBlur(blur_limit5, p0.2), # 模拟运动模糊 A.Resize(640, 640), ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels]))MotionBlur 是我会特意加的一项因为真实摄像头下渣土车运动时经常有拖影不加这个增强模型在模糊帧上容易漏检。Resize 到 640 是 YOLO 系列的常见输入尺寸如果边缘设备算力有限可以降到 416 或 320但小目标召回会掉。4.2 模型选型检测时序还是端到端两条路线。第一条是检测跟踪时序分类YOLO 检测卡车ByteTrack 跟踪再把轨迹送进 LSTM 或 TSM 判断是否倾倒。第二条是端到端视频检测比如用 Video Swin Transformer 或 TimeSformer 直接输出事件。端到端精度上限高但数据需求大、推理慢边缘盒子跑不动。检测时序的方案模块化每部分可以单独优化推理也能控制在实时范围内。我一般推荐先走检测时序等数据量上来了再考虑端到端。检测模型选 YOLOv8 或 YOLOv10 都行看你的部署工具链支持哪个。时序分类用 TSM 或轻量 LSTM 就够输入是卡车轨迹的 ROI 特征序列不需要太重的模型。4.3 训练参数与损失函数调整不平衡数据下分类损失要加权。如果倾倒正样本只占 5%负样本权重可以设 0.5 到 0.8正样本权重设 2 到 5具体看验证集召回。yolo detect train datadataset.yaml modelyolov8m.pt epochs100 imgsz640 batch16 \ cls2.0 box7.5 dfl1.5 lr00.01 lrf0.01 warmup_epochs3cls 参数控制分类损失权重默认 0.5不平衡时调高到 1.5 到 2.0。box 是框回归权重一般不动。lr0 初始学习率 0.01 是常见起点如果 loss 震荡就降到 0.005。warmup_epochs 设 3 到 5让模型先稳住再学细节。训练时重点看召回率而不是准确率。倾倒检测漏报比误报代价高漏一次可能就放过一辆偷倒的车。验证集上如果召回低于 85%优先查标注质量和难负样本别急着调模型。5. 避坑与排查标注、训练、部署中的血泪经验5.1 标注一致性差导致模型学噪声现象训练 loss 降不下去验证集指标波动大同一批数据两次训练结果差很多。原因多个标注员对倾倒边界理解不一致有的标了车厢举升有的只标物料滑落模型在矛盾样本上反复震荡。解决先做标注一致性校验抽 100 帧让多人重复标算 IoU 和事件边界重合度。低于 90% 就回去改规范加示例图统一培训后再铺量。已经标完的数据用模型预测结果反向筛查把模型高置信但标注为负的样本挑出来人工复核。5.2 正负样本失衡导致召回率上不去现象模型准确率 95% 以上但召回率只有 60% 到 70%大量倾倒事件漏报。原因原始数据正样本占比太低模型学会了全部判负也能拿高准确率。解决重采样把正负比拉到 1:5 左右分类损失加权再叠加难负样本挖掘。如果还不行检查正样本标注是否太保守有些轻微倾倒被标成了负样本模型自然学不到。5.3 抽帧去重过度丢失关键动作帧现象训练集里倾倒动作不连贯模型在验证集上对快速倾倒漏检严重。原因感知哈希去重阈值设太大把动作变化帧也当重复帧删了。解决把 diff_threshold 从 8 降到 4 到 5或者对正样本时间段强制保留所有帧只对负样本做去重。更稳妥的做法是先按时间段切分正样本段内不抽帧或高 fps 抽帧负样本段再降采样。5.4 部署时输入分辨率与训练不一致现象训练时指标很好部署到边缘盒子后漏检严重。原因训练用 640部署为了省算力改成 416小目标卡车在低分辨率下特征丢失。解决训练和部署分辨率保持一致。如果必须降训练时就按部署分辨率训或者用多尺度训练让模型适应。另外检查预处理是否一致归一化参数、颜色通道顺序弄反也会导致精度暴跌。5.5 时序窗口长度设错导致动作判定失效现象检测框没问题但倾倒动作分类总是误判停靠车辆被大量误报。原因时序窗口太短模型只看到卡车停着没看到举升和卸料过程或者窗口太长把前后无关帧也包进来。解决统计正样本动作持续时间窗口长度设成动作时长的 1.5 到 2 倍。倾倒一般持续 5 到 15 秒窗口设 10 到 20 秒比较合适。同时加一个前置条件只有检测到卡车且速度低于阈值时才触发时序分类减少无效计算和误报。6. 进阶技巧用弱监督预筛把标注成本压下来标注成本是这类项目最大的瓶颈。几千小时视频全精标不现实我一般会用弱监督做两级预筛。第一级用事件级弱标签训练一个视频分类模型输入是抽帧后的低分辨率片段输出是有无倾倒事件。这个模型不需要精标只要标视频级 0/1 就行标注速度快很多。训练数据可以先用公开的车辆行为数据集做预训练再用少量精标数据微调。第二级把第一级筛出的候选片段送人工精标标段级或帧级。因为候选片段已经压缩到原始数据的 5% 到 10%标注量大幅下降。# 弱监督预筛伪代码 def weak_screen(video_list, weak_model, threshold0.7): candidates [] for vid in video_list: frames extract_frames(vid, fps1) # 低fps粗筛 score weak_model.predict(frames) if score threshold: candidates.append((vid, score)) return candidatesthreshold 设 0.7 是偏召回的宁可多筛一些也别漏。第一级模型精度不用太高召回 90% 以上就行后面还有人工兜底。这个流程跑下来整体标注成本能降 60% 到 70%代价是多花一两天搭弱监督管线。验证方法上我会留一个独立测试集按摄像头点位划分而不是随机划分。随机划分会高估指标因为同一摄像头相邻帧很像模型见过类似的。按点位划分才能反映跨场景泛化能力。测试集里正样本至少 200 个事件负样本 1000 段以上指标看事件级召回和误报率不看帧级准确率。我自己的习惯是每轮迭代先跑测试集召回没到 90% 就不看精确率因为漏报的代价比误报高太多。误报可以靠后处理规则压比如连续 3 秒以上才告警漏报没法补。希望帮到你。本文还有配套的精品资源点击获取