
简介面向目标检测与安全监控场景这份数据集专门用于训练翻越栏杆或围栏的行为识别模型。整体资源包含1680张JPEG图片及完全对应的VOC格式XML与YOLO格式TXT标注文件标注类别为climbing攀爬和person行人累计共有2454个目标标注框其中攀爬框2060个、行人框394个可支撑对危险区域闯入行为的精细化检测。压缩包内共计文件数为2000个以标注文件和图片为主体另附带一份使用说明文本整体大小约100.25MB同时提供两种主流标注格式省去格式转换环节便于直接接入YOLO、SSD等常见检测框架使用。数据标注工具为labelImg标注规则统一并含有部分增强图片以提升样本多样性适合具有一定目标检测基础的研究人员或安防算法工程师开展模型训练、验证与调优。目前已有598人学习下载介意增强图片的开发者请仔细阅读说明后按需获取。1. 翻越栏杆围栏数据集1680张VOCYOLO格式安防行为检测的微调起点从安全监控到工地围挡翻越栏杆是一个比普通行人检测更细的行为识别任务光有“人”框还不够还要判断这个人有没有跨过隔离线。手里这套翻越栏杆围栏数据集1680张VOCYOLO格式含增强正好踩在“目标检测行为判断”的交界处它把翻越动作的关键帧连同标注一起给你既可以直接拿去训 YOLO也能在常规目标检测模型上做迁移微调。适合手里没有标注团队、又想让模型在特定场景快速过审的工程师也适合准备用公开数据充实地准场景的学生。我接下来把解压、转格式、训练和踩坑链路全部铺开。2. 1680张翻越行为数据到底能做什么先读懂VOC和YOLO的双格式差异2.1 翻越场景的目标检测为什么不能只靠通用行人数据集通用行人数据集能给出非常稳的 person 框但没法告诉你“正在翻越”。翻越栏杆这类行为是一个连续动作接近栏杆、手撑、抬腿、跨过、落地。模型要抓住的是其中几个关键帧而不是每一帧都报一次。只看单帧检测结果的话所有站在栏杆旁的人都会被误判成“正在翻越”安防一天能产生几千条假告警。专用翻越数据集的标注思路通常不一样它会把动作发生时的目标框单独拿出来标成“climbing”或“翻越”类而不是简单复用行人框。这样检测模型学到的是动作姿态和空间关系后端的告警逻辑也可以直接依赖这个类别输出不再需要另外接姿态估计模型去判断“人腿在不在杆子上”。那 1680 张够不够用这取决于你怎么训练它。如果从零随机初始化1680 张连一个可靠的二分类器都难训出来但如果你从 COCO 预训练权重出发做迁移学习只调一个行为类别这个量级完全够。因为预训练模型已经把纹理、边缘、人体结构都学完了我们要改的只是输出层对动作姿态的选择性而不是重新造一个视觉骨架。迁移学习在固定场景的类目上通常只需要原数据量的 5% 到 10% 就能收敛。另一个让它“够用”的原因是场景窄。翻越是固定语义栏杆或围栏、人的侧面或背面、固定摄像头视角。它不像“行人检测”要覆盖各种环境、各种遮挡、各种光照所以样本多样性要求天然低。这也意味着换场景时一定要回补数据如果你手里这套数据里的围栏是黄色横杆拿去检测铁栅栏就要重新标注几十张做二次微调否则泛化会崩。2.2 VOC与YOLO标注的根本差异绝对坐标、归一化坐标与目录约定拿到压缩包后最常见的是两套目录VOC 目录下是JPEGImages、Annotations和ImageSets/MainYOLO 目录下是images、labels和data.yaml。两者核心差异在标注文件格式和坐标体系。对比项VOCYOLO标注文件后缀.xml.txt坐标形式像素绝对坐标 xmin/ymin/xmax/ymax归一化坐标 class cx cy w h取值范围0 到图像宽高0 到 1读取方式xml.etree 解析按空白字符 split 读取可视化友好度高人能直接看懂低必须乘回图像宽高才能画框常见标注工具LabelImg 默认导出、CVATLabelImg 也支持、X-AnyLabeling训练兼容性需要脚本转换YOLO 系列原生读取VOC 的 XML 长这样annotation filenameclimb_001.jpg/filename size width1280/width height720/height depth3/depth /size object nameclimbing/name bndbox xmin342/xmin ymin267/ymin xmax876/xmax ymax698/ymax /bndbox /object /annotationYOLO 的 txt 每一行是类别索引 中心x 中心y 宽 高四个坐标全部按图像宽高归一化0 0.4765625 0.6701389 0.4171875 0.5986111注意YOLO txt 里只写类别索引不写类别名。所以data.yaml里names的排列顺序必须和 txt 第一列索引完全一致。一旦顺序错位整个训练过程都是“张冠李戴”而且模型不会报错只会给你一个看起来正常但根本没法用的权重。为什么 YOLO 强制归一化因为训练时图像会被随机缩放到 640、512 或 896 等尺寸。如果 txt 里保存的是绝对像素坐标每次缩放都要跟着改而归一化坐标不受影响模型拿到任何分辨率都能用同一套标签训练。这也是从 VOC 转 YOLO 时最容易出错的环节很多脚本忘记除以图像宽高生成的 txt 里 cx 大于 1训练器却不拒绝最后 loss 降得很低但框全偏。2.3 “含增强”意味着什么离线增强的常见套路与重复样本风险压缩包名字里写了“含增强”但具体增强了什么要解压后看文件名后缀反推。常见套路是给增强副本加后缀_flip表示水平翻转_rot15表示旋转 15 度_bright表示亮度扰动_mixup表示混合增强_crop2x表示裁剪后放大两倍。也有的打包者不加后缀只用哈希文件名那就要靠感知哈希去重来还原原始图片关系。离线增强对这类数据确实必要。监控场景下摄像头角度固定但白天黑夜亮度差异大翻越瞬间人经常被栏杆遮挡只靠原始样本很难覆盖这些变化。增强可以铺宽分布水平翻转能模拟对面机位亮度扰动能模拟逆光裁剪放大能让小目标在训练时保持清晰。但离线增强不是越多越好。第一增强副本之间高度相关做得过多会变相增加重复样本模型看到的有效信息并没有增加第二旋转角度如果超过 30 度人体比例失真严重模型学到“斜着的人都是翻越”真实场景反而误检第三水平翻转对左右对称的视频是对的但如果围栏一侧有门或固定警示牌翻转后场景语义不成立等于给模型灌错误样本。还有一个更隐蔽的风险如果压缩包写“1680 张”而实际上原始图只有 600 张增强做了三倍扩增那么训练策略要按 600 张的规模去调而不是按 1680 张。最简单的办法是拿脚本去掉增强后缀后统计唯一 basename先把原始基数摸清。但最让我警惕的还是增强副本混进验证集。如果climb_001.jpg和climb_001_flip.jpg被同时随机切到了 train 和 val验证集里就有原图的近亲副本mAP 会虚高得离谱上线后立刻现原形。这个问题我放到第 5 章专门给你止血方案。3. 拿到压缩包后的落地校验解压、统计类别与把VOC转成YOLO打开压缩包后不要急着训练先花二十分钟做一次数据体检。这一步决定你能少熬多少个夜。我见过太多人把数据集直接丢给训练脚本跑完才发现标注错位、类别混乱、验证集重复。下面这套流程我每次都用能省下一大堆玄学调参时间。3.1 先按“最小可复现目录”整理文件不要急着改标注解压时不要瞎改文件名除非文件名本身就是乱码。保留原始文件名有助于后面和标注文件一一对应。用一条命令解压并查看目录结构unzip 翻越栏杆围栏数据集1680张VOCYOLO格式含增强.zip -d datasets/ find datasets -maxdepth 2 -type d | sort预期结构大致是datasets/ ├── VOC/ │ ├── Annotations/ │ ├── JPEGImages/ │ └── ImageSets/Main/ └── YOLO/ ├── labels/ ├── images/ └── data.yaml如果只有图片和 txt没有 data.yaml你需要自己补一个如果只有 VOC 的 XML你需要转换成 YOLO 格式。ImageSets/Main里有原始划分文件比如train.txt、val.txt这是打包者已经做好的划分能直接用就用不要自己随便随机切因为两部分标注内容可能来自不同批次随机切反而破坏原始分布。先清点类别名这是我的固定动作grep -hoP (?name).*?(?/name) VOC/Annotations/*.xml | sort | uniq -c这一步会暴露“同类不同名”的问题。很多打包者为兼容老工具会把climbing、climb、person_fence混着写。你如果不合并直接当三个类训练模型分不清它们loss 一直高。数据增补再多也救不回来。3.2 写个小脚本把VOC的XML标签转成YOLO的txt标签当压缩包里只有 VOC 格式而你打算用 yolov8 或 YOLO11 训练时必须把 XML 转成 txt。下面这个模板我用了很多次加了边界处理和类别映射# xml2yolo.py import os import glob import xml.etree.ElementTree as ET # 关键把同义类名都映射到同一个索引顺序必须和 data.yaml 的 names 一致 class_map { climbing: 0, climb: 0, person_climb: 0, } def convert_voc_annotation(xml_path, out_dir): tree ET.parse(xml_path) root tree.getroot() # XML 里没有 size 字段时跳过否则除以 0 或负宽高会污染标签 size_node root.find(size) img_w int(size_node.find(width).text) img_h int(size_node.find(height).text) lines [] for obj in root.iter(object): name obj.find(name).text.strip() if name not in class_map: continue # 未定义类直接丢弃而不是算成背景 box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 摄像头画面里目标经常半身出界标注也可能越界先裁剪到图像内 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) # 宽或高小于 1px 的都是无效框直接丢掉避免损失函数算到负坐标 if xmax - xmin 1 or ymax - ymin 1: continue # 归一化到 0~1保留 6 位小数 cx (xmin xmax) / 2.0 / img_w cy (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{class_map[name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) if lines: base os.path.basename(xml_path).replace(.xml, .txt) with open(os.path.join(out_dir, base), w) as f: f.write(\n.join(lines) \n) if __name__ __main__: os.makedirs(labels, exist_okTrue) for xml in glob.glob(VOC/Annotations/*.xml): convert_voc_annotation(xml, labels)这段代码里有两个容易被忽略的点。第一class_map的索引必须和data.yaml的names一一对应YOLO txt 只保存索引不保存名称只要顺序错训练出来就是废的。第二我对越界坐标做了裁剪看起来像是“多此一举”实则安防视频里目标经常一半在画面外不加这个处理训练时 BN 和损失函数会被一堆负坐标干扰。处理完再生成一遍统计确认每张图至少有一个有效目标。3.3 用一段脚本统计每类目标数量、宽高分布和漏标样本训练前我习惯先跑统计脚本它决定数据增强怎么做。比如“每个类别样本量低于 200”“绝大多数框高度大于宽度”“小目标占比不足 5%”这三个结论直接影响要不要开 mosaic、要不要做裁剪放大。# inspect_labels.py import glob import numpy as np stats {} empty_labels [] for txt in glob.glob(labels/*.txt): with open(txt) as f: lines f.read().strip().splitlines() if not lines: # 空 txt 说明有图无标这类样本会让模型把该区域当成背景 empty_labels.append(txt) continue for line in lines: parts line.split() # YOLO 每行固定 5 列class cx cy w h多列少列都是异常 if len(parts) ! 5: print(异常行, txt, line) continue cls, cx, cy, w, h parts[0], float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) stats.setdefault(int(cls), []).append((w, h)) for idx, v in stats.items(): arr np.array(v) print(fclass {idx}: count{len(v)}, fmean_w{arr[:, 0].mean():.3f}, mean_h{arr[:, 1].mean():.3f}) print(f空标签文件数量{len(empty_labels)})宽高分布比数量还重要。翻越场景的行人框通常高大于宽如果你发现大量框接近正方形说明标注可能把整段围栏框进去了而不是框人这时一定要回看原图。另外连续 10 张以上漏标的话我更倾向于整段剔除而不是硬补标因为漏标图像在训练时会被当成背景负样本相当于在监督信号里掺了错误答案这也是后面模型微调崩了的常见原因。3.4 把 YOLO 标签画回原图肉眼排查坐标漂移统计和转换都能自动化但最终可靠度还是要靠眼睛抽查。我会把 YOLO txt 画到原图上生成一个检查目录抽样看 20 张左右。# draw_boxes.py import os import glob import cv2 label_dir labels image_dir images out_dir check os.makedirs(out_dir, exist_okTrue) for txt in glob.glob(os.path.join(label_dir, *.txt)): img_path os.path.join(image_dir, os.path.basename(txt).replace(.txt, .jpg)) if not os.path.exists(img_path): img_path img_path.replace(.jpg, .png) # 兼容 PNG 图片 img cv2.imread(img_path) if img is None: print(无法读取图像, img_path) continue h, w img.shape[:2] with open(txt) as f: for line in f: parts line.split() if len(parts) ! 5: continue cls, cx, cy, bw, bh parts[0], float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) # 归一化坐标乘回原图尺寸才能画框 x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, fcls{cls}, (x1, max(0, y1 - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) out_path os.path.join(out_dir, os.path.basename(img_path)) cv2.imwrite(out_path, img) print(check 目录已生成建议抽查 20 张以上)这里最关键的是乘回宽高的动作。有人画框时忘了这一步出来的框全乱就误以为数据坏了实际只是展示脚本的问题。真正的检查重点是框是不是紧贴行人、是否出现多个框叠在同一个目标上、有没有框明显比人大一圈。如果出现后两种情况说明标注质量有问题需要回原标注工具修不要在训练阶段硬吃。4. 基于YOLOv8微调模型最小训练命令与三个必调参数数据规整完进入正式训练。用小数据集微调最忌两件事一是盲目堆 epoch二是拿默认超参直接跑。下面这套配置针对 1680 张翻越行为数据做过收敛可以直接抄。4.1 准备data.yaml并划分train/val先把训练、验证路径写进 data.yaml。这里我特别提醒一句不要一上来就把val指向空目录很多初学者在没切分验证集时就这么干ultralytics 会报 0 张验证图或者干脆用训练集当验证集给出一个没有意义的 mAP。我会先把训练链路跑通再改成正式分割。正式分割时按源头分组切分而不是按单张图片随机切。下面这段脚本会识别增强后缀让同一张原图的普通版和增强版只进同一个集合# split_by_source.py import os import random random.seed(42) def source_of(name: str) - str: # 常见的增强后缀按压缩包实际情况增删 for suffix in [_flip, _rot15, _bright, _mixup, _crop2x, _scale]: name name.replace(suffix, ) return name files [f for f in os.listdir(images) if f.endswith((.jpg, .jpeg, .png))] groups {} for f in files: groups.setdefault(source_of(f), []).append(f) all_keys list(groups.keys()) random.shuffle(all_keys) val_keys set(all_keys[: int(0.2 * len(all_keys))]) os.makedirs(images/train, exist_okTrue) os.makedirs(images/val, exist_okTrue) # 这里只写文件清单也可以直接移动文件但要保留原始目录 with open(train.txt, w) as tr, open(val.txt, w) as va: for f in files: target va if source_of(f) in val_keys else tr target.write(f \n)对应的 data.yaml# datasets/climb_fence.yaml path: /home/you/datasets/ # 改成你的实际绝对路径 train: images/train # 或者写 train.txt 的内容 val: images/val test: images/test # 没有测试集可以暂时留空 nc: 1 names: 0: climbingpath用绝对路径别用相对路径。跑训练的命令工作目录经常变相对路径很容易在一周后复现时找不到数据。类别索引用数字键而不是列表避免 YAML 解析时把 0 开头当成数字。4.2 启动训练的命令与训练参数怎么设用 YOLOv8m 作为预训练模型输入分辨率 640最小训练命令如下yolo train \ modelyolov8m.pt \ dataclimb_fence.yaml \ epochs150 \ batch16 \ imgsz640 \ workers8 \ device0 \ patience20 \ seed42 \ projectruns/train \ nameclimb_fence_v1 \ pretrainedTrue几个参数单独说明。pretrainedTrue是默认行为但写上可以提醒自己正在做迁移学习而不是从零训练。batch16对 8G 显存的卡来说偏高如果显存不够就降到 8同时把imgsz降到 512。翻越场景大多是中远距离监控512 输入通常足够但小目标会吃亏需要靠后面的增强弥补。patience20表示验证指标 20 个 epoch 不涨就早停1680 张的小数据往往 80 个 epoch 左右就收敛不用硬等 150。在线增强参数是小数据集的核心我只建议动这三个# 写在 yolo train 命令行里或配置文件中 hsv_h0.015 hsv_s0.7 hsv_v0.4 degrees15 translate0.1 scale0.3 fliplr0.5 mosaic1.0degrees15模拟摄像头倾斜但不能太大翻越行为是侧向的转多了人形会扭曲。scale0.3控制目标缩放扰动正负 30% 对翻越场景足够。mosaic1.0是默认开启它对小目标有效但在小数据集上会把图像割裂目标被切掉一半。我的经验是前 10 个 epoch 先关掉mosaic让模型把“人跨栏”这个语义学起来最后 10 个 epoch 再恢复或调低。另一个值得提的参数是close_mosaic10。它会在最后 10 个 epoch 自动关闭 mosaic用真实完整图像精调边框回归。小规模目标检测训练中这个参数能明显改善 mAP50-95属于必开程度。4.3 如何判断数据集是否“喂饱”了模型loss曲线、mAP50和PR曲线训练结果会写到runs/train/climb_fence_v1/目录里面有一个results.csv用tail -f results.csv实时看。正常情况是box_loss和cls_loss在 30 个 epoch 内快速下降70 个 epoch 后缓慢走平。如果val/box_loss掉到 20 个 epoch 就反弹那不是数据不够而是过拟合优先去降degrees和mosaic而不是提前停。小数据集的 mAP50 通常很好看单类任务 0.90 以上很常见。真正要盯的是 mAP50-95它偏低说明框的定位精度差一般原因是标注不齐或小目标占比太高。这时候可以先修标注再决定要不要提高imgsz。还要看 P 和 R 的平衡。如果 R 明显低于 P说明模型把很多翻越样本漏掉了典型表现是置信度阈值太高或小目标增强不足。反过来如果 P 低 R 高就是误检太多需要提高置信度阈值或增加负样本。yolo 损失函数本身不会因为你样本少而改变分布但样本分布会直接影响哪些超参有效。这也是为什么小数据集一定要天天看曲线而不是丢进去等结果。5. 常见问题与避坑记录标注错位、BN崩溃和数据增强翻车这一章是我自己的翻车记录。下面四条按“现象→原因→解决”写几乎都是小规模数据集微调时必踩的。5.1 训练正常但推理框偏上/偏小先查归一化坐标现象训练时 loss 下降正常但推理时框整体偏在目标上方宽度只有真实宽度一半。 原因VOC 转 YOLO 时把宽高写错最常见是忘了除以图像宽高另一种是 data.yaml 的类别顺序和 txt 索引对不上导致模型学到了错配的类别。 解决用第 3.3 节的方法抽查 5 张原图和对应 txt看cx, cy, w, h是否都在 0 到 1 之间。一旦出现某行w1.7基本就是宽高算反了回去重跑转换脚本。还有一种是工具导出时用的是中心点坐标你当成左上角坐标用了这种错误画框脚本会非常明显。5.2 增强副本混进验证集造成“假高分”现象训练 loss 正常验证集 mAP 冲到 0.98但换到真实监控视频上漏检严重几乎不可用。 原因离线增强后的图片和原图同时被切到了验证集模型等于“开卷考试”。它不是学会了泛化而是记住了几张特定目标的变体。 解决用第 4.1 节的split_by_source.py按源头分组切分。如果压缩包里是同一视频按帧导出则还要按视频序列切分不能只按文件名随机分。这套操作做完后验证集会立刻给你一个比之前低几个点的真实分数这才是上线前该看的数字。5.3 类别不均衡导致小目标完全不召回现象mAP50 看着还行但单独按尺寸统计小目标的召回率只有 0.2。 原因监控画面里翻越的人经常只有 20×40 像素手工标注又偏好完整的大框导致小目标在训练中被压掉。 解决第一选择是把imgsz从 640 提高到 896。图像变大后模型输出层的特征图对小目标更敏感。第二是训练参数里开scale0.4和mosaic1.0让模型见过更多中间尺度的目标。如果还不行就做裁剪离线增强把原图切成四块每块放大两倍重新生成标注翻越目标占整图比例会明显提升。5.4 yolo训练中BN崩溃或目标检测模型微调崩了多半是lr与batch不匹配现象训练到几十个 epochloss 突然出现nan或验证 mAP 直接跳成 0。 原因小数据集上 batch 太大学习率相对过高BN 层的均值和方差被推爆还有一种情况是冻结了 backbone 但热度不够反向传播把 BN 层参数直接带崩。 解决先把batch降到 8lr00.001并把warmup_epochs调到 5。如果崩在冻结阶段检查是否在freeze冻结了所有 BN 层冻结 BN 时 batch 必须等于 1 或解冻一层 BN。翻越栏杆这类细粒度行为检测尤其容易踩因为模型要学的姿态差异很小BN 统计量稍不稳定整个训练语义就崩了。5.5 类别名不统一climbing、climb、person 混在一起现象训练正常但推理时置信度普遍低打开results.csv一看分类 loss 一直不降。 原因压缩包里同一种行为被不同工具标成了多个类名统计时没有合并。 解决回到第 3.2 节的class_map把所有同义词映射到同一个索引同时把data.yaml里nc改成合并后的类别数。一定不要在原始标注文件上去“批量替换类名”那样很容易误伤别的类。在转换层做映射原始文件还能留作备份这也是给自己留一张后悔药。6. 把翻越行为检测从“能框住”做到“能报警”跟踪加虚拟绊线的进阶验证单帧检测只能给你一堆框但安防项目要的是“越过栏杆”这一事件。进阶做法是把 yolo 输出接一个跟踪器再用虚拟绊线做事件触发这也是我认为这个数据集真正的落地点。# event_trigger.py import cv2 from ultralytics import YOLO model YOLO(runs/train/climb_fence_v1/weights/best.pt) cap cv2.VideoCapture(demo.mp4) # 定义虚拟绊线图像坐标系中的两点 line ((300, 400), (900, 400)) def cross_line(p1, p2): d1 (p1[1] - line[0][1]) * (line[1][0] - p1[0]) - (p1[0] - line[0][0]) * (line[1][1] - p1[1]) d2 (p2[1] - line[0][1]) * (line[1][0] - p2[0]) - (p2[0] - line[0][0]) * (line[1][1] - p2[1]) return d1 * d2 0 prev_center {} while cap.isOpened(): ret, frame cap.read() if not ret: break results model.track(frame, persistTrue, classes[0], conf0.35, iou0.5) if results[0].boxes is not None: for box in results[0].boxes: xyxy box.xyxy[0].tolist() track_id int(box.id) if box.id is not None else 0 # 底部中心点比中心点更接近“落脚点”跨线判断更准 cx (xyxy[0] xyxy[2]) / 2 cy xyxy[3] if track_id in prev_center: if cross_line((cx, cy), prev_center[track_id]): print(fID {track_id} 跨越围栏触发告警) prev_center[track_id] (cx, cy)这里有两个细节。第一cy一定要取框底边的 y 坐标而不是框中心点。人翻越时脚先离开地面框底部更接近实际落脚点用中心点判断高低线会早报或晚报。第二单次跨越还不能算事件。我会在外面加连续帧计数和冷却时间同一个 ID 连续 3 帧落在线另一侧才确认告警触发后 10 秒内不再重复报警。这样能过滤掉行人贴栏杆造成的抖动误报。等验证好了再用yolo export modelbest.pt formatonnx imgsz640导出 ONNX接 DeepStream 或 OpenCV 推理。我自己的习惯是每次上新场景都不会直接上最终权重而是把验证集里分出的 10% 当“本周样本”用这套跟踪加绊线的脚本去跑一夜真实监控录像第二天翻报警记录。这个环节能发现数据集增强和真实场景之间的分布差也能顺带收集漏检难例。希望帮到你。本文还有配套的精品资源点击获取