YOLO复杂场景人员检测数据集:5000张真实图片与三格式标签实战
简介本资源面向计算机视觉方向的学习者与算法工程师提供一套复杂场景下的人员目标检测数据集可用于YOLO系列模型的训练与验证。数据均为真实场景采集覆盖多种光照、遮挡与背景条件标注由labelimg完成框质量较高并同步提供voc、coco和yolo三种格式标签分别存放于不同文件夹便于直接接入主流检测框架。压缩包共约2000个文件以1986个xml标注文件为主另含少量html说明文档、txt列表与py脚本整体约552.93MB。资源同时附赠数据集划分脚本与YOLO环境搭建、训练教程可按需自行划分训练集、验证集与测试集并参考案例修改训练自己的数据。目前已有284人学习下载适合需要快速搭建检测实验、验证模型效果或开展课程设计的中高级读者参考使用。1. 复杂场景人员检测数据集5000 张真实图片与三格式标签的落地价值做人员检测的同行大概率都经历过这种局面开源数据集里人挤人、光线均匀、背景干净模型在测试集上 mAP 刷得漂亮一挪到工地、车站、夜市这种真实场景就疯狂漏检。问题往往不在网络结构而在数据分布和标注质量。这份 YOLO 复杂场景人员目标检测数据集核心就是冲着这个落差来的——5000 张真实场景图片场景覆盖室内外、白天黑夜、遮挡与密集人群用 labelImg 逐张标注同时给出 VOCxml、COCOjson、YOLOtxt三种格式标签分别放在独立文件夹里。它适合正在做 YOLO 系列训练、需要快速验证自己改进算法、又不想从零标数据的人。配套还塞了环境搭建、训练教程和划分脚本等于把「数据 流程」一起打包了。2. 三种标签格式的差异与选型VOC、COCO、YOLO 到底该用哪个2.1 三种格式的坐标体系与目录结构同一批图片三种标签格式描述的是同一件事但坐标表达和文件组织完全不同选错了轻则训练脚本报错重则框全偏。VOC 格式每张图对应一个 xml 文件坐标是绝对像素值结构长这样annotation folderimages/folder filename000001.jpg/filename size width1920/width height1080/height depth3/depth /size object nameperson/name bndbox xmin312/xmin ymin204/ymin xmax498/xmax ymax760/ymax /bndbox /object /annotationxmin/ymin/xmax/ymax是左上角和右下角的绝对像素坐标跟图片尺寸绑定。换分辨率就得重新算这是 VOC 在训练里越来越少见的原因之一。COCO 格式把所有标注塞进一个 json坐标同样是绝对像素但结构是images、annotations、categories三个顶层字段bbox是[x, y, width, height]注意这里是宽高不是右下角坐标很多人第一次转 COCO 就栽在这。YOLO 格式每张图一个 txt每行class x_center y_center width height全部是归一化到 0~1 的相对值0 0.2109 0.4463 0.0969 0.51480是类别索引后面四个是中心点坐标和宽高都除以了图片宽高。归一化带来的好处是换分辨率不用改标签这也是 YOLO 训练默认吃这种格式的原因。2.2 按训练框架选格式别来回转选型逻辑其实很直接用 YOLOv5/v8/v11 官方仓库训练直接上 YOLO txt用 Detectron2、MMDetection 这类走 COCO json只有老代码或某些论文复现还认 VOC xml。这份数据集三种都给全了省掉自己写转换脚本的环节。但要注意一个坑三种格式的类别索引不一定对齐。VOC 和 COCO 里类别是字符串personYOLO 里是数字0。如果你自己写脚本把 COCO 转 YOLO一定要确认categories里的 id 和 YOLO 的 class index 映射关系常见做法是建一个category_id - class_index的字典别默认它们相等。我一般会先跑一遍校验确认三种格式指向的框数量一致import os, xml.etree.ElementTree as ET def count_voc_boxes(xml_dir): total 0 for f in os.listdir(xml_dir): if not f.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, f)) total len(tree.findall(object)) return total def count_yolo_boxes(txt_dir): total 0 for f in os.listdir(txt_dir): if not f.endswith(.txt): continue with open(os.path.join(txt_dir, f)) as fp: total len([l for l in fp if l.strip()]) return total print(VOC boxes:, count_voc_boxes(Annotations)) print(YOLO boxes:, count_yolo_boxes(labels))两个数字对不上说明某一种格式在转换时丢了框或者多了空行先别急着训练。参数上xml_dir和txt_dir换成你解压后的实际路径即可脚本只做计数不做修改安全。3. 数据集划分脚本实操train/val/test 与 ImageSets 两条路线3.1 两种划分脚本的适用场景压缩包里给了两个划分脚本名字很直白一个是「训练集、验证集、测试集划分脚本图片标签划分写入新文件夹.py」另一个是「split_train_val 生成 ImageSets 下 txt 文件划分脚本.py」。它们解决的是不同习惯的流程。前者是物理划分把图片和对应标签复制到train/、val/、test/三个新文件夹每个文件夹下再分images和labels。这种结构 YOLOv5/v8 直接认改一下 data yaml 里的路径就能开训适合新手和单机训练。后者是逻辑划分不移动文件只在ImageSets/Main/下生成train.txt、val.txt、test.txt里面写图片名或路径。这是 VOC 时代的经典做法适合数据集大、不想复制占用双倍磁盘或者用 MMDetection 这类读 txt 列表的框架。选哪个取决于你的训练框架读什么。YOLO 官方仓库现在两种都支持但物理划分更省心路径不会写错。3.2 物理划分脚本的运行与参数物理划分脚本核心逻辑是读全部图片名打乱后按比例切分再复制图片和同名标签。运行前先确认图片和标签文件名主干一致比如000001.jpg对应000001.txt或000001.xml。python 训练集、验证集、测试集划分脚本图片标签划分写入新文件夹.py \ --images_dir ./images \ --labels_dir ./labels \ --output_dir ./dataset_split \ --train_ratio 0.7 \ --val_ratio 0.2 \ --test_ratio 0.1 \ --seed 42参数说明images_dir是原图目录labels_dir是 YOLO txt 目录output_dir是划分后输出根目录三个 ratio 加起来必须等于 1脚本一般会做断言seed固定随机种子保证每次划分结果可复现这点在做对比实验时很关键不然换一次划分 mAP 波动你都不知道是模型变了还是数据变了。跑完检查输出目录结构dataset_split/ ├── train/ │ ├── images/ │ └── labels/ ├── val/ │ ├── images/ │ └── labels/ └── test/ ├── images/ └── labels/如果某个子目录为空八成是文件名主干对不上或者标签扩展名不是脚本预期的.txt。先拿ls | head对比两边文件名再重跑。3.3 ImageSets 划分脚本与 data yaml 对接逻辑划分脚本生成 txt 列表后YOLO 的 data yaml 可以这样写path: /home/user/dataset train: ImageSets/Main/train.txt val: ImageSets/Main/val.txt test: ImageSets/Main/test.txt nc: 1 names: [person]注意train.txt里如果写的是相对路径path要指向数据集根目录如果写的是绝对路径path可以留空或指向任意存在目录。很多人训练时报No labels found就是 txt 里的路径和实际图片位置对不上。跑之前用一行命令验证head -3 ImageSets/Main/train.txt | while read p; do ls -l $p; done能列出文件说明路径没问题报No such file就回去改脚本里的路径拼接逻辑。4. 环境搭建与训练教程Windows 和 Linux 两条线的关键差异4.1 环境搭建教程覆盖了什么压缩包里 Windows 和 Linux 各有一份环境搭建 htmlLinux 还多一份 Ubuntu 安装教程。内容覆盖 Anaconda 安装、虚拟环境创建、PyTorch 与 CUDA 版本匹配、YOLO 仓库克隆和依赖安装。这些步骤网上到处都是但版本匹配这块最容易翻车教程里给了具体组合照着走能少踩坑。核心命令无非这几条以 Linux 为例conda create -n yolo python3.9 -y conda activate yolo pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txtcu118对应 CUDA 11.8你的显卡驱动要支持到这个版本。装完用python -c import torch; print(torch.cuda.is_available())验证返回True才算通。返回False常见原因是驱动太旧或装成了 CPU 版 torch。4.2 训练教程怎么改案例跑自己的数据训练教程的思路是拿官方案例当模板改三处data yaml 指向自己的数据集、模型配置选 yolov5s 或 yolov8n、训练参数按显存调 batch size。python train.py \ --data data/person.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0--img 640是输入分辨率复杂场景小目标多的话可以提到 960但显存占用会明显上升--batch 16在 8G 显存上跑 640 分辨率基本够用爆显存就降到 8--device 0指定第一块 GPU多卡用0,1。训练日志里重点看mAP0.5和mAP0.5:0.95两条曲线前者涨后者不涨通常是框位置不够准可以考虑加数据增强或换更大的模型。Windows 和 Linux 的差异主要在路径分隔符和 DataLoader 的 worker 数。Windows 下--workers设太大容易卡死一般设 0 或 2Linux 下可以设 8。这个细节教程里不一定强调但实际跑起来差别很大。5. 避坑与排查标注、划分、训练里最容易翻车的五件事5.1 标签文件名与图片名主干不一致现象训练启动后报No labels found或大量图片被跳过。 原因图片是000001.jpg标签却是000001_person.txt或放在多层子目录里脚本按主干匹配找不到。 解决统一改成同名主干标签放平级目录。用python -c import os; print([f for f in os.listdir(labels)][:5])和图片目录对比肉眼确认。5.2 YOLO 标签坐标越界或为负现象训练不报错但 loss 异常或者可视化时框跑到图外。 原因标注时框超出图片边界或转换脚本没做裁剪归一化后出现负值或大于 1。 解决训练前跑一遍校验把越界框裁到[0,1]def clamp_yolo_label(line): parts line.strip().split() cls, x, y, w, h parts[0], *map(float, parts[1:]) x, y max(0, min(1, x)), max(0, min(1, y)) w, h max(0, min(1, w)), max(0, min(1, h)) return f{cls} {x:.6f} {y:.6f} {w:.6f} {h:.6f}\n5.3 划分后类别分布严重倾斜现象验证集 mAP 忽高忽低换 seed 结果差很多。 原因随机划分没做分层某些场景比如夜间全被分到训练集验证集里几乎没有。 解决按场景或亮度做分层抽样或者至少固定 seed 并检查三个子集的类别框数量比例。简单做法是统计每个子集的框总数偏差超过 10% 就换 seed 重划。5.4 CUDA 版本与 PyTorch 不匹配现象torch.cuda.is_available()返回 False或训练时报CUDA error: no kernel image is available。 原因装的 torch 是 CPU 版或 CUDA 版本和显卡驱动不兼容。 解决nvidia-smi看驱动支持的 CUDA 上限去 PyTorch 官网找对应 wheel 重装。别用pip install torch裸装默认可能拉 CPU 版。5.5 训练时显存溢出但 batch 已经很小现象CUDA out of memorybatch 降到 4 还爆。 原因输入分辨率太高或者--img和模型配置里的默认尺寸冲突实际按更大尺寸跑。 解决先把--img降到 416 验证能否跑通再逐步往上加同时确认没有其他进程占着显存nvidia-smi看一眼。6. 进阶技巧用置信度门限和验证集反查数据质量训练跑通只是开始真正决定落地效果的是推理阶段的置信度门限和一轮数据质量反查。我一般会在验证集上跑一次推理把conf从 0.1 到 0.5 扫一遍看 precision 和 recall 的交叉点而不是默认用 0.25。python val.py \ --data data/person.yaml \ --weights runs/train/exp/weights/best.pt \ --img 640 \ --conf 0.001 \ --iou 0.6 \ --task val--conf 0.001是为了让 val 脚本输出完整的 PR 曲线脚本内部会自己扫门限算 AP不是让你推理时用这么低的值。跑完看runs/val/exp/下的PR_curve.png曲线拐点对应的 conf 就是比较合适的部署门限。复杂场景人员检测里遮挡多、小目标多门限设太高漏检严重设太低误检爆炸这个拐点比拍脑袋定 0.5 靠谱得多。另一个习惯是拿验证集里漏检的图反查标注。把best.pt在验证集上跑一遍导出预测框和 GT 框对比漏检的图单独拎出来看是标注漏了人还是框太松。我遇到过好几次模型「漏检」其实是原标注就没框住那个被遮挡的人这种数据问题不修模型再调也白搭。import cv2 def draw_compare(img_path, gt_boxes, pred_boxes): img cv2.imread(img_path) for x1, y1, x2, y2 in gt_boxes: cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) for x1, y1, x2, y2 in pred_boxes: cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imwrite(compare.jpg, img)绿色是 GT红色是预测叠在一起看最直观。这个脚本参数简单gt_boxes和pred_boxes传绝对像素坐标的列表就行来源可以是 VOC xml 和推理结果。从那以后我每次拿到新数据集都强制先跑一遍格式校验和划分分布检查再开始训练。数据这关没过后面调参全是玄学。希望这份数据集和脚本能帮你把精力省在模型改进上而不是耗在标数据和转格式上。本文还有配套的精品资源点击获取