简介:本资源是一个面向计算机视觉初学者与安防智能识别方向开发者的轻量级目标检测数据集,专用于警察身份识别任务,支持YOLO系列模型(含YOLOv2至YOLOv8)快速训练与部署。数据集共357张真实场景图像,涵盖执勤、巡逻、出警等多种典型画面,每张图均配有对应txt格式的YOLO标准标注文件(含警察/非警察两类标签),并附带统一配置的data.yaml文件,便于直接接入训练流程。压缩包总计715个文件,含357张JPG图像、357个TXT标注及1个YAML配置文件,整体大小仅13.76MB,结构简洁、开箱即用。目前已有15人学习下载,配套博文详细说明了数据集构建逻辑、标签分布统计、模型训练代码及推理演示,作者还提供免费技术咨询支持,适合希望快速验证算法效果、开展小样本识别实验或拓展公共安全类AI应用的研究者与开发者。
1. 为什么需要“警察/非警察”二分类数据集:场景需求与边界设定
先说实话,做这个数据集的起因没那么玄乎。当时我手头接到一个智慧安防相关的试点项目,需求一句话就能讲清楚:在重点公共区域的监控画面里,系统要能实时判断“现场有没有民警在场”。这个需求听起来简单,真正动手做才发现,市面上的公开数据集几乎没有覆盖这个细分方向——要么是通用的COCO、VOC,重在80类日常物体;要么是行人检测、车辆检测这种大路货。真要把“民警”从画面里单独拎出来,只能自己造轮子,这就是这个带标注警察识别数据集诞生的直接原因。
这个二分类数据集的目标非常聚焦,就是识别两类目标:警察和非警察。前者是画面中穿着制式警服、具备明显警务人员特征的人;后者是画面中出现的其他所有人员,包括路人、商户、游客、其他制服人员等。357张图片,全部完成标注,并按YOLO系列的标准格式组织,理论上不只支持YOLO26,YOLOv5、YOLOv8、YOLO11这些主流版本都能直接用,只是标题里特别点名了能适配YOLO26。
必须要承认,357张图在深度学习里不算多,但它解决的问题很实际:给一个冷门的垂直识别任务提供一个能跑通全流程的“种子数据集”。对于刚接触目标检测、想走一遍“数据标注—格式整理—模型训练—效果评估”完整链路的人来说,这个规模反而合适,几十张用于快速验证、几百张用于初步训练,既不会因为数据量太大导致标注成本爆掉,又能看到模型真实的过拟合和泛化表现。
再说说应用边界。这个数据集以及最终训练出的模型,定位是辅助工具,不是评判个人身份的依据,更不是自动化处置的决策引擎。在实际落地中,它的价值体现在几类场景:一是重点区域的人员态势感知,画面中出现民警时,系统可以联动记录时间点、位置,辅助事后追溯;二是活动安保场景,协助工作人员快速定位安保力量分布;三是园区、场馆的智慧巡检,把“现场是否有警务人员”作为一条环境状态信息纳入管理视图。说白了,这是一个给业务系统提供结构化信号的小模型,不是用来做执法判断的。后续使用这个数据集的人,也应该在这个边界内做应用开发。
2. 357张图的采集、清洗与标注:数据质量才是模型的真正天花板
很多人以为目标检测项目的瓶颈在模型选型,其实做多了就会发现,数据质量才是真正的天花板。模型再强,喂进去一堆标注不一致、边界框乱画的样本,指标照样拉胯。这一节把采集、清洗、标注的完整流程拆开讲,也是我踩过不少坑之后总结出的相对稳妥的做法。
2.1 图片采集的多样性策略
357张图听起来不多,但采集时我刻意保证了几个维度的多样性,避免模型只认识“某种固定场景下的警察”:
- 时段覆盖:白天、傍晚、夜间各占一定比例。夜间的监控画面往往存在暗光、噪点、偏色问题,这部分样本直接影响模型在低光环境下的鲁棒性,后期训练时我还为此单独调整了数据增强策略。
- 场景覆盖:街道、商场入口、地铁站、办公大厅、活动现场、停车场等不同场景。不同场景的光线方向、背景复杂度、人员密度差异很大,多场景样本能逼着模型去学“人”本身,而不是学“某个固定背景下的颜色块”。
- 视角覆盖:监控俯视角、平视角、轻微仰角都有。俯视角下人的肩宽、帽檐遮挡情况和平视完全不一样,如果只用单一视角,模型部署到真实监控画面时性能会明显下降。
- 人员密度差异:单人、双人、多人场景混合。实际监控里经常出现多人并肩走、前后遮挡的情况,群体样本能帮助模型学会区分个体边界。
这一条给准备自采数据的人一个建议:不要在一个场景里连续截几百张图就算完事,那叫“同一段视频的几百帧”,信息量很低。宁可让场景更杂一些,哪怕单张图的目标少一点,也比一堆高度相似的连续帧强得多,否则训练出来的模型会表现得特别“死记硬背”。
2.2 数据清洗:肉眼可见的脏数据必须清掉
采集完原始图片后,我做了两轮清洗。第一轮是“机械清洗”,处理模糊严重的、曝光过度的、几乎全黑或全白的图;第二轮是“语义清洗”,删掉那些连人眼都很难确认是否为警务人员的图片,比如目标太小(在640分辨率下高度不足20像素)、被大面积遮挡超过50%、或者处于极端形变状态。357张是清洗后留下的数量,原始采集量比这个多出将近30%。
这里有个容易忽略的点:目标检测里的“负样本”不是拿一堆空背景图来凑数,而是画面里存在“看起来像人、但确实不是目标”的样本。这个数据集里,非警察标签覆盖了大量“容易混淆”的对象——保安、门卫、穿深色制服的物业人员,这些样本对降低误检率非常重要。如果你自己标数据集,一定要有意识地收集这种“难负样本”,否则模型训练完会发现,它检测到的警察里有三分之一是保安。
2.3 标注工具与标注规范
标注工具我选了X-AnyLabeling,理由很直接:它内置了YOLO格式的导出支持,标注界面流畅,对批量操作也比较友好。市面上常见的开源工具还有LabelImg、Label Studio、CVAT等,功能上都够用,选择哪个主要看个人习惯。如果你完全没接触过标注工具,LabelImg上手最平滑,界面朴素但该有的矩形框、标签切换、自动保存都有。
标注规范上,我提前定了三条硬规则,并让参与标注的人都严格参照:
- 判定标准:穿着制式警服(包含制式外套、衬衫、执勤服),且能明显看出警务标识的,标为警察。无法确认身份、未穿制服的便衣人员,即使业务上可能是民警,也不标为警察。
- 标注框范围:尽量框住完整人体,如果目标被遮挡,则框住可见部分即可,但可见部分的高度原则上不小于整个人的40%。
- 不标注目标:高度小于20像素、模糊无法辨识、遮挡超过一半的目标一律不标,保持背景干净。
规则的第三条特别重要,很多人做标注时喜欢“能标就标”,结果一堆模糊的小目标把学习信号打得乱七八糟。目标检测的标注不是把画面里所有对象都标出来,而是把你希望模型学到的那部分标出来。不够格的样本宁可不标,让模型在训练时把那些区域自然当作ignore区域处理。
2.4 双重标注与质量抽检
所有图片都经过两个人独立标注一遍,然后逐张比对差异。对于边界框重叠部分的IoU低于0.7、或者标签类别不一致的样本,由我复核后给出最终版本。这一轮质检下来,大概修正了6%的标注框和不到2%的标签错误,虽然工作量增加了,但模型训练时的“标签噪声”明显降低。
357张图里,最终标注出的目标实例总数大概是860个,其中警察约320个、非警察约540个,平均每张图2.4个目标。两类样本比例约为1:1.7,属于轻微不平衡,但在目标检测任务里这种程度完全可以直接训练,不需要额外做类别重采样,模型不会因此明显偏向多数类。
3. 标签体系与YOLO26训练格式的无缝对接
数据标注完成之后,真正影响后续训练效率的,是数据集的目录结构和标签文件能否被训练框架“开箱即用”。这一节讲的都是实际工程里每天会碰到的细节,弄错了虽然不大,但排查起来相当烦人。
3.1 类别定义:两行txt解决的事
YOLO系列训练时不需要什么花哨的类别注册,就是给每个类别定一个从0开始的整数索引,再维护一份classes列表。这个数据集里定义如下:
- 索引0:police(警察)
- 索引1:non-police(非警察)
对应在数据集根目录下的classes.txt文件中,就两行:
police non-police关于类别的命名,尽量别用中文、别带空格,就用小写英文字母加连字符,这是各种脚本和框架兼容性最好的写法。很多人在这上面踩过坑,比如在标签里写“警察同志”或者“police officer with hat”,导出格式一乱,后处理脚本全崩。
3.2 YOLO标签文件的真实结构
每一张图片对应一个同名的.txt标签文件。文件里每一行对应一个标注目标,格式为:
class_id x_center y_center width height其中坐标全部是归一化到0到1的浮点数,x_center和y_center是边界框中心点的相对坐标,width和height是边界框宽度和高度的相对值。举个例子,一张640x480的图片里,一个警察边界框的绝对像素坐标为左上角(120, 80)、右下角(360, 400),那么归一化计算过程为:
x_center = (120 + 360) / 2 / 640 # 0.375 y_center = (80 + 400) / 2 / 480 # 0.5 width = (360 - 120) / 640 # 0.375 height = (400 - 80) / 480 # 0.6667对应的标签文件里这一行就是:
0 0.375 0.5 0.375 0.6667这个格式约定非常简单,但实际中经常有人栽在“忘记归一化”上。如果直接写了像素坐标,训练时loss会异常巨大甚至直接NaN。建议标注工具导出之后,写一个三五行的小脚本,检查所有坐标值是否都在0到1之间,超过1的直接报错定位到具体文件,这个预处理步骤值得写入你的流水线。
3.3 数据集目录结构与YAML配置
为了让YOLO26的train命令直接找到数据,我按官方推荐的目录结构组织了数据集:
police_dataset/ ├── images/ │ ├── train/ # 280张 │ └── val/ # 77张 ├── labels/ │ ├── train/ │ └── val/ ├── classes.txt └── police_dataset.yaml图片和标签按相同文件名一一对应,只是放在不同目录下,这是YOLO系列的标准约定。分割比例上,我用了约78%和22%的训练/验证划分,没有单独留测试集——对357张这个规模来说,验证集足够观察模型表现,测试集反而会进一步压缩训练样本。
police_dataset.yaml的内容如下:
# 数据集根目录,按实际路径修改 path: /path/to/police_dataset train: images/train val: images/val # 类别数 nc: 2 # 类别名称,必须与classes.txt保持一致 names: 0: police 1: non-police这里有一个高频错误:path字段写的是相对路径,但启动训练时没有先cd到指定目录,导致图片路径全部失效。YOLO框架对路径解析的处理是比较“宽容”的,很可能延迟到训练中途才报错,影响情绪又浪费时间。我的习惯是永远写绝对路径,或者确保训练命令的终端工作目录和yaml里的path是一致的。
3.4 YOLO26对数据集的兼容性说明
YOLO26是Ultralytics在其系列模型基础上的新版本,架构层面做了一些针对实时检测的改进,我在训练中主要感受到两点直观变化:一是对低光、噪声环境的适应能力更好,暗光场景下的漏检率比前代低一些;二是推理阶段支持动态扩展计算量,训练好的模型在需要更高精度时可以临时增加推理深度。但要注意,这些特性都不影响数据集格式——YOLO26仍然完全兼容标准的YOLO标签格式和上述 yaml 配置。
所以如果你手里的数据集是按照YOLOv8/YOLO11的格式整理的,放到YOLO26下训练,改动量为零。反过来也一样,用这个警察数据集训练出的模型,如果想换回YOLOv8跑,只需要把配置文件里对应的预训练模型路径改一下,数据和标签完全不用动。这种向后兼容性,是Ultralytics系列框架做得最省心的地方。
4. 用YOLO26训练该数据集的完整流程与调参记录
数据格式确认无误之后,进入训练环节。这一节把从环境准备到训练结束的完整流程记录下来,包含我实际使用的参数配置和调参过程中的几个关键决策点。
4.1 环境准备:别在依赖版本上浪费生命
YOLO26是Ultralytics框架的一部分,最省事的安装方式就是直接装ultralytics包。我使用的环境是Python 3.10和PyTorch 2.1以上版本,显存方面,一张普通消费级显卡(8GB左右)就能跑完这个数据集的训练。安装命令很简单:
pip install ultralytics装完可以通过yolo命令验证安装是否成功。关于环境这里有一个过来人的忠告:不要为了追求“最新版”就去装非官方的源码git分支,直接用PyPI的稳定版基本不会出错。YOLO系列训练由于涉及大量数据增强的参数,稳定版的运行结果更可预期,排查问题时社区里能查到的经验也更多。
4.2 选择模型尺寸:小数据集不适合一上来就上大模型
YOLO26提供了n、s、m、l、x等不同尺寸的预训练模型,参数规模依次增大。357张图的数据量,我没有犹豫就选了yolo26n和yolo26s各跑了一轮对比,最终保留的是s版本。
原因很简单:n版本虽然训练更快、显存占用更小,但在民警识别这个任务上,警察制服与部分保安、物业制服的视觉差异不算大,n模型的特征表达能力偏弱,出现了不少混淆误检。s版本比n版本只多花一点点训练时间,但误检率能降低三到四个百分点,这个性价比非常划算。如果你的算力比较紧张,用n版本先跑通流程也是完全可以的,后面看效果再决定要不要升到s。
训练命令如下:
yolo detect train \ data=police_dataset.yaml \ model=yolo26s.pt \ epochs=200 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=30这里model=yolo26s.pt表示加载官方预训练权重进行迁移学习,而不是从头训练。这非常重要,357张图从头训练一个全随机初始化的检测头,基本不可能收敛到可用水平;而基于在COCO等大数据集上预训练过的权重继续微调,网络已经具备通用的特征提取能力,我们只需要让它适应“警察/非警察”这个特定任务。实测中,前20个epoch损失就快速下降,这就是迁移学习的效果。
4.3 关键训练参数的含义与调整逻辑
几个参数趁这个机会展开说说,都是看完文档也未必能立刻理解透彻的:
- imgsz=640:训练时把输入图片统一缩放到640x640。由于监控画面中人物往往偏小,如果后续使用场景里目标明显更小,可以考虑在推理时用imgsz=960或1280提升小目标召回率,但训练时用640的稳定性和显存占用更友好。
- batch=16:batch size影响收敛稳定性和显存占用。8GB显存跑s模型,batch=16是一个比较安全的配置。如果训练时报OOM,优先把batch降到8,而不是去调模型大小。
- lr0=0.01:初始学习率。迁移学习场景下这个值保持默认即可,不用刻意调低。真要调整,当发现验证集loss在几十个epoch后开始震荡不降时,可以试试0.005。
- patience=30:早停机制,验证集指标连续30个epoch没有提升就自动停止训练。小数据集特别依赖这个参数,因为模型在100个epoch左右可能就已经充分拟合,继续硬训只会过拟合。
另外我开启了数据增强中的Mosaic增强,默认配置即可。X-AnyLabeling或YOLO系列都在训练时对图片做随机裁剪、拼接、翻转等处理,这相当于把训练数据的有效规模放大了好几倍。小幅增强有助于泛化,但YOLO的训练增强默认值本身就比较积极,小数据集上不建议再额外加大强度,否则会出现“增强失真”问题——模型学到的特征变成了合成图特征,真实场景反而不行。
4.4 训练过程的观察点与结果判读
训练日志里需要重点盯两个指标:训练集loss和验证集mAP50。我这次训练的实际曲线大致是这样的:前20个epoch,box_loss和cls_loss快速下降,mAP50从0.3左右一路冲到0.75;到60个epoch左右,mAP50的上升速度明显放缓;到120个epoch,mAP50基本稳定在0.87到0.90之间,mAP50-95稳定在0.61左右。整个过程因为早停机制,实际跑到约150个epoch就自动停了,没有把200个epoch全部跑完。
357张图达到mAP50在0.9附近,已经是一个比较合理的结果。很多人对小数据集期望过高,以为能靠几百张图冲到mAP50接近0.99,那种结果往往意味着验证集太简单或者和训练集过分相似,真实场景一测就露馅。我的判断标准是:能在7:3划分的验证集上稳定达到0.85以上,并且人工抽查未见过的新图能稳定检出,这个模型就算初步可用了。
5. 实测效果、典型误检与针对性优化思路
模型训练出来不能只看指标,要拿到真实场景里去“用一用”才知道短板在哪。这一节记录了我在实际测试中遇到的主要问题,以及对应的解决思路,算是这次项目最有参考价值的部分。
5.1 在真实监控画面上的实测表现
我把训练好的模型部署到一段约15分钟、分辨率为1080P的实拍监控视频上做了测试,这段视频和训练集来源不同,场景是某公共区域入口。实测结果:警察目标在高清、光照良好、人物直立的情况下,召回率可以做到接近90%;但一旦出现遮挡、人物侧身、目标偏小等不利因素,漏检率会明显上升。非警察类别的检测整体稳定,但误检主要集中在“保安被识别为警察”和“深色制服人员被识别为警察”这两类,这也是可以预期的混淆点。
低光场景单独测了一轮。夜间监控画面亮度低、噪声大,肉眼都能看到明显的彩色噪点。测试中yolo26s在低光下的表现比前代模型要好,但仍然存在部分漏检。针对这个问题,我在训练时额外调整了HSV增强参数(hsv_h、hsv_s、hsv_v),把亮度扰动稍微加大了一点,让模型对亮度变化更不敏感。改动之后,夜间场景漏检率直观感受到下降了两三个百分点,且没有带来明显的白天误检副作用。
5.2 误检根源分析:不是模型傻,是特征太相近
保安被误检为警察,核心原因在于两类目标的视觉特征确实高度相似——深色制服、肩章、帽子、对讲机,这些元素警察有,保安也有。模型在有限数据量下学到的区分特征不够“硬”,就会把两者混在一起。解决这个问题不能靠单纯堆模型精度,而是要在数据上做文章。
我接手项目后续优化时,常用的三个手段是:
- 加难负样本:专门采集一批保安、门卫、物业人员的图片,标记为非警察,让模型看到更多“看起来像警察但不是警察”的案例。这个策略往往比简单增加警察样本更能有效降低误检率。
- 给警察目标增加局部细节样本:比如警服上的臂章、胸徽、警号等近景特写,帮助模型把注意力从“深色制服”提升到“具体警务标识”。
- 考虑三分类改造:如果误检持续存在,可以把任务扩成police、security、other三个类别,让模型不再被迫在“警察/非警察”二选一里做模棱两可的判断。这个改动对标注和训练的影响并不大,但业务上解释性更好。
5.3 识别阈值的调优:宁错报还是宁漏报
实际工程中,除了改模型和数据,还有个简单有效的旋钮——置信度阈值。YOLO模型默认的置信度阈值通常是0.25,但不同场景下最优阈值完全不同。如果你部署的场景是“预警辅助系统”,错报带来的负担是人去看一眼录像,那可以把阈值调到0.15甚至更低,优先保证不漏检;如果系统会基于检测结果自动触发某些操作,比如自动报警联动,那错报代价就比较大了,阈值应该上调到0.4以上,宁可漏掉一些模糊目标,也不要频繁假警报。
我做过一次对比:阈值从0.25降到0.15,警察类别的召回率从88%提升到94%,误检次数也翻了一倍;阈值从0.25升到0.4,召回率降到80%左右,但误检几乎消失。没有绝对正确的阈值,只能根据业务承受能力来平衡。建议集成时把这个参数做成可配置项,让使用者能根据现场反馈随时调整。
5.4 低光环境专项优化实践
针对夜间场景,我采用的增强策略再展开一下。YOLO的默认训练配置里对图像亮度扰动有预设范围,但对低光场景可以进一步强化。具体做法是在训练命令中追加参数:
yolo detect train \ data=police_dataset.yaml \ model=yolo26s.pt \ epochs=150 \ imgsz=640 \ hsv_h=0.015 \ hsv_s=0.7 \ hsv_v=0.6同时,我还手动筛选了训练集中夜间图片的比例,确保低光样本不低于总数的25%。如果原始训练集里夜间图很少,模型自然学不好夜间特征,这时候再怎么调参数都效果有限。实测下来,低光专项优化后,夜间场景的mAP50从0.72提升到0.79左右,效果比较明显。
6. 从357张到持续演进:数据扩展、模型迁移与部署方向
数据集的价值不应该止步于“训练完跑出个模型”,它更应该是一个可以持续积累、不断迭代的基础资产。最后这部分聊聊后续扩展方向和几个实用的工程建议。
6.1 冷启动之后如何低成本扩充数据
357张图完成冷启动后,扩充数据最经济的路径不是继续人工采集图片并手工标注,而是“用模型辅助标注”。具体套路是:用当前训练好的模型去批量预测一批新的监控视频抽帧,生成初步标注框,然后人工仅对置信度中等(比如0.4到0.8之间)的目标做复核修正,高置信度的目标基本可以直接保留,低置信度的目标直接丢弃。这样一来,人工标注工作量能减少60%以上,而数据量可以快速翻倍。我拿这个方案试过,从357张扩到800张只花了大约一个下午的复核时间,模型效果又上了一个台阶。
另一个思路是视频抽帧,不要全部帧都保留,而是每隔十几帧抽一帧,保证画面变化足够大。把所有相似帧都灌进去,会放大相近样本的权重,造成隐性过拟合。
6.2 模型迁移:换回YOLOv8、YOLO11或导出部署
这个数据集在早期版本上还跑过YOLOv8和YOLO11,两者的训练配置基本一致,唯一要改的是预训练模型路径。如果你手头已有部署环境是基于YOLOv8的,完全可以用这个数据集从新训练或直接复用权重,不需要重新标注。实测对比中,YOLO26在低光和小目标上的表现优于前代,但差距并没有“代际碾压”那么夸张,在算力受限的边缘设备上,YOLOv8n或YOLO11n反而可能是更务实的选择。
部署导出方面,推荐导出为ONNX格式再走各个平台的推理引擎:
yolo export model=best.pt format=onnx opset=12导出后的ONNX文件可以不依赖PyTorch环境运行,TensorRT、OpenVINO、ONNX Runtime等推理框架都能直接加载。在1080P监控流上,YOLO26s的ONNX模型在普通GPU上的推理速度大约是每秒30到40帧,实时性完全够用。
6.3 训练前小脚本:五秒检查标签合法性
最后分享一个我每次训练前都会跑的检查脚本,它能帮你避免绝大多数“标签文件格式错误”导致的训练事故。这个脚本会遍历验证集的标签文件,检查每个值是否在合法范围内:
import os from pathlib import Path label_dir = Path("police_dataset/labels/val") for txt_file in sorted(label_dir.glob("*.txt")): for line_num, line in enumerate(txt_file.read_text().strip().splitlines(), 1): parts = line.split() if len(parts) != 5: print(f"[格式错误] {txt_file.name} 第{line_num}行不是5个字段") continue cid, x, y, w, h = int(parts[0]), float(parts[1]), float(parts[2]), \ float(parts[3]), float(parts[4]) if not (0 <= x <= 1 and 0 <= y <= 1 and 0 <= w <= 1 and 0 <= h <= 1): print(f"[越界] {txt_file.name} 第{line_num}行坐标不在0-1范围") if txt_file.name.endswith(".txt") and cid not in (0, 1): print(f"[类别错误] {txt_file.name} 第{line_num}行类别索引非法")虽然大部分标注工具导出的文件是规范,但这个脚本能在训练前帮你拦住低级错误,省下不少排查时间。
6.4 我对这个数据集定位的真实看法
做数据集的活儿,很多时候是“做的时候枯燥、做完才有价值”。这个警察识别数据集本身不算庞大,但它把一个容易被忽略的垂直识别任务落到了可执行、可复现、可扩展的层面:357张图,两个标签,支持YOLO26及主流YOLO版本直接训练。对正在学习目标检测、或者需要快速验证安防垂直场景识别方案的人来说,它是一个很好的起步模板。
最后说一个实际使用中的小技巧:训练完成后,除了看验证集指标,一定要拿几段完全没有参与训练的真实场景视频跑一遍人工观察。指标只能告诉你模型“大概行不行”,真实场景视频才能告诉你模型“哪里不行”。数据集的积累是迭代的事,第一次跑到可用状态,就已经完成了最重要的一步。后面每一次补充新样本、调整阈值、优化增强策略,都是在这个基础上往前迈进。
本文还有配套的精品资源,点击获取