简介:行人实例分割数据集面向智能安防、自动驾驶感知、服务机器人及计算机视觉研究等场景,提供精细化的行人轮廓标注样本,适合从事目标检测与实例分割的开发者、算法工程师及高校研究人员使用。资源包共约2000个文件,以1226个txt标注文件、772张jpg图片为主,另含1个yaml配置与1份docx说明文档,压缩包整体约96.18MB,原生YOLO实例分割格式可直接对接YOLOv5、YOLOv8等主流框架。数据集划分为训练集1131张、验证集48张、测试集47张,每个行人实例包含50余个轮廓点,能精确捕捉复杂姿态与遮挡情况,并覆盖监控、航拍等多视角及不同光照、天气条件。目前已有277人学习下载,可用于实例分割基准测试、行人重识别前期处理及多任务迁移,兼顾算法验证与工程落地需求。
1. 行人实例分割数据集.zip:拿到压缩包之后,先别急着解压
你从某个渠道拿到一个叫「行人实例分割数据集.zip」的压缩包,双击之前先想清楚一件事:行人实例分割和行人检测、行人 ReID 是三件不同的事。检测只给你框,ReID 只给你一个跨镜头的身份向量,而实例分割要求对每一个行人像素级地画出轮廓——遮挡、重叠、贴边、只露半个身子,都得单独成 mask。这个区别决定了后面所有标注格式、训练配置和评估指标的走向。
这个数据集能解决的核心问题是:让模型学会「哪些像素属于第几个行人」。适合谁?做智慧园区客流统计、自动驾驶行人避让、零售门店动线分析、安防视频结构化的人。如果你只是想数人头,检测就够;一旦要做像素级抠图、遮挡关系推理、或者给下游 ReID 提供干净的行人裁剪,实例分割才是对的路。压缩包本身只是原料,真正决定成败的是解压后你怎么读它、怎么转格式、怎么喂给模型。
2. 解压后先做体检:目录结构、标注格式与三类常见组织方式
2.1 先看目录,判断它属于哪种标注体系
行人实例分割数据集常见的组织方式有三种,解压后第一件事就是tree或find看结构,别急着写训练脚本。
# 只看两层目录,避免输出爆炸 find ./pedestrian_seg -maxdepth 2 -type d | head -50 # 统计图片和标注文件数量 find ./pedestrian_seg -name "*.jpg" -o -name "*.png" | wc -l find ./pedestrian_seg -name "*.json" -o -name "*.xml" -o -name "*.txt" | wc -l如果看到images/配annotations/*.json,大概率是 COCO 系;如果看到JPEGImages/配SegmentationClass/和SegmentationObject/,那是 VOC 分割系;如果每张图旁边跟一个同名.txt,每行是归一化的多边形点,那是 YOLO-seg 系。三种格式的转换成本完全不同,先认清楚再动手。
提示:不要用
ls直接看几万文件的目录,会卡住终端。用find ... | wc -l先数数量。
2.2 用一段脚本把标注统计出来
光看目录不够,得知道每个类别多少实例、每张图平均几个行人、mask 面积分布。下面这段脚本对 COCO 格式做体检,其他格式改读取逻辑即可。
import json from collections import Counter with open("annotations/instances.json", "r") as f: data = json.load(f) # 类别分布 cats = {c["id"]: c["name"] for c in data["categories"]} cat_counter = Counter() for ann in data["annotations"]: cat_counter[cats[ann["category_id"]]] += 1 print("类别实例数:", cat_counter) # 每图实例数分布 img_ann = Counter(ann["image_id"] for ann in data["annotations"]) counts = list(img_ann.values()) print(f"图片数: {len(data['images'])}, 有标注图片数: {len(img_ann)}") print(f"每图实例数 min/avg/max: {min(counts)}/{sum(counts)/len(counts):.1f}/{max(counts)}") # mask 面积分布,判断小目标占比 areas = [ann["area"] for ann in data["annotations"] if ann.get("area")] areas.sort() n = len(areas) print(f"mask 面积 P10/P50/P90: {areas[n//10]:.0f}/{areas[n//2]:.0f}/{areas[n*9//10]:.0f}")逻辑说明:cat_counter告诉你有没有混入非行人类别;img_ann反映拥挤程度,平均值超过 15 的基本是密集场景,训练时要注意 NMS 和 mask 重叠;面积分位数决定你是否需要开小目标增强。参数上,如果 P10 面积小于 32×32,建议在训练配置里把imgsz提到 1024 以上,否则小行人 mask 会糊成一团。
2.3 抽 20 张图肉眼过一遍,比任何统计都值
统计只能告诉你数量,质量得靠眼睛。随机抽 20 张带标注的图,把 mask 叠加到原图上可视化,重点看四件事:遮挡行人的 mask 是否断裂、贴边行人是否被裁掉、多人重叠处 mask 是否串了、有没有整张图漏标。这一步花 10 分钟,能省掉后面几天的「模型玄学不收敛」排查。
import cv2, json, numpy as np, random with open("annotations/instances.json") as f: data = json.load(f) img_map = {im["id"]: im for im in data["images"]} ann_map = {} for ann in data["annotations"]: ann_map.setdefault(ann["image_id"], []).append(ann) for img_id in random.sample(list(ann_map.keys()), 20): info = img_map[img_id] img = cv2.imread(f"images/{info['file_name']}") overlay = img.copy() for ann in ann_map[img_id]: for seg in ann["segmentation"]: pts = np.array(seg).reshape(-1, 2).astype(np.int32) cv2.fillPoly(overlay, [pts], (0, 255, 0)) cv2.addWeighted(overlay, 0.4, img, 0.6, 0, img) cv2.imwrite(f"vis_{img_id}.jpg", img)这段代码把每个实例的多边形填成半透明绿色。看的时候注意:如果两个行人重叠区域出现颜色叠加变深,说明 mask 有交叠,训练时 IoU 计算会受影响;如果某个行人完全没有绿色,就是漏标,得决定是补标还是丢弃该图。
3. 转成 YOLO-seg 格式:多边形归一化与四个边界坑
3.1 为什么优先转 YOLO-seg 而不是死磕 COCO
现在做实例分割落地,YOLOv8-seg 和 YOLOv11-seg 是性价比最高的选择,推理速度快、部署链路成熟,yolov8训练自己的数据集这套流程社区资料也最全。COCO 格式虽然通用,但训练时读取慢、内存占用高。转成 YOLO-seg 的 txt 格式后,每张图一个 txt,每行是类别 x1 y1 x2 y2 ...,坐标归一化到 0-1,读取效率高一个量级。
3.2 转换脚本:COCO 多边形转 YOLO-seg
import json, os from pathlib import Path def coco_to_yolo_seg(json_path, img_dir, out_dir): with open(json_path) as f: data = json.load(f) img_map = {im["id"]: im for im in data["images"]} # 只保留行人类别,按你的数据集改 cat_map = {c["id"]: i for i, c in enumerate(data["categories"]) if c["name"] == "pedestrian"} Path(out_dir).mkdir(parents=True, exist_ok=True) for ann in data["annotations"]: if ann["category_id"] not in cat_map: continue info = img_map[ann["image_id"]] w, h = info["width"], info["height"] cls = cat_map[ann["category_id"]] lines = [] for seg in ann["segmentation"]: if len(seg) < 6: # 少于3个点无法构成多边形 continue coords = [] for i in range(0, len(seg), 2): x = min(max(seg[i] / w, 0.0), 1.0) # 裁剪到[0,1] y = min(max(seg[i+1] / h, 0.0), 1.0) coords.append(f"{x:.6f} {y:.6f}") lines.append(f"{cls} " + " ".join(coords)) if lines: name = Path(info["file_name"]).stem + ".txt" with open(os.path.join(out_dir, name), "w") as f: f.write("\n".join(lines)) coco_to_yolo_seg("annotations/instances.json", "images", "labels")逻辑说明:cat_map把行人映射为类别 0,多类别数据集按需扩展。坐标除以宽高做归一化,min(max(...))是防止标注越界导致训练报错。len(seg) < 6过滤掉退化的两点线段。参数上,.6f保留六位小数足够,再多是浪费存储。
3.3 四个边界坑,每个都让我翻过车
第一个坑:多边形自交。有些标注工具画出的多边形自己交叉,YOLO 训练时计算 mask 会得到奇怪结果。解决方法是转换后用shapely检查Polygon(pts).is_valid,无效的直接丢弃或修复。
第二个坑:坐标越界。标注时图片被缩放或裁剪过,坐标可能超出原图尺寸。上面脚本里的裁剪是兜底,但更好的做法是转换前先统计越界比例,超过 5% 说明标注流程有问题,得回头查。
第三个坑:空标注图。有些图里没有行人,COCO 里就没有对应 annotation,转换后没有 txt 文件。YOLO 训练时如果按图片路径找标签找不到会报错,需要为这些图生成空 txt 文件,或者在数据集配置里允许缺失。
第四个坑:类别名不一致。有的数据集用person,有的用pedestrian,有的用walker。转换前先打印data["categories"]确认,别硬编码。
4. 训练配置怎么设:从 imgsz 到 mask 比率的实操参数
4.1 数据集 yaml 与目录约定
YOLO-seg 要求固定的目录结构,转换完按下面组织:
# pedestrian_seg.yaml path: /data/pedestrian_seg train: images/train val: images/val names: 0: pedestrian图片和标签分开放,images/train/xxx.jpg对应labels/train/xxx.txt。如果标签和图片同目录,YOLO 也能读,但分开更清晰。划分比例上,行人场景我一般用 8:1:1,如果总图少于 2000 张,用 7:1.5:1.5,验证集留够才能看出过拟合。
4.2 关键训练参数与取值理由
yolo segment train \ model=yolov8s-seg.pt \ data=pedestrian_seg.yaml \ epochs=100 \ imgsz=1024 \ batch=8 \ rect=True \ mask_ratio=4 \ overlap_mask=True \ lr0=0.01 \ patience=20imgsz=1024是因为行人 mask 普遍偏小,640 下小目标 mask 会丢细节。rect=True做矩形训练,减少 padding,对长宽比差异大的监控画面友好。mask_ratio=4表示 mask 相对输入下采样 4 倍,这是精度和显存的平衡点,显存够可以设 2,但收益递减。overlap_mask=True允许训练时 mask 重叠,推理时再分离,密集场景必须开。patience=20是早停,行人数据集容易过拟合,别硬跑满。
注意:
batch=8配imgsz=1024在 12G 显存上基本是上限,再大就 OOM。显存小就降 imgsz 到 768,别降 batch 到 4 以下,BN 层会不稳定。
4.3 训练时盯哪几个指标
box_loss和seg_loss要一起看。如果 box 降但 seg 不降,说明框对了但轮廓学不好,通常是 mask 标注质量差或 mask_ratio 太大。metrics/mAP50-95(M)是分割的主指标,行人场景能到 0.4 以上就算可用。验证时重点看val/seg_loss有没有反弹,反弹就是过拟合,提前停。
5. 避坑与排查:行人实例分割训练里最常见的五类翻车
5.1 现象:训练 loss 正常但 mask 全是糊的
原因:mask_ratio设太大,或者标注本身是粗糙的矩形近似而非真实轮廓。解决:先可视化几张预测 mask,如果形状是方的,回去检查标注;如果形状对但边缘糊,把mask_ratio从 4 降到 2,同时确认imgsz不低于 768。
5.2 现象:密集场景漏检严重,重叠行人只出一个 mask
原因:NMS 阈值太高,或者overlap_mask没开。解决:推理时把iou从默认 0.7 降到 0.5,训练时确认overlap_mask=True。另外检查标注里重叠行人是否真的各自有独立 mask,有些数据集重叠处只标了一个,模型学不出来。
5.3 现象:验证集指标远低于训练集
原因:训练集和验证集场景分布不一致,比如训练全是白天、验证混了夜间。解决:划分时按场景分层抽样,别随机分。如果数据集本身场景单一,验证指标虚高也别高兴,换个场景测就崩。
5.4 现象:小目标行人 mask 面积几乎为零
原因:imgsz太小,或者数据增强里的缩放把小人缩没了。解决:提高imgsz,关掉或减弱scale增强,考虑用copy_paste增强专门补小目标。面积小于 32×32 的行人,在 640 输入下基本学不到有效 mask。
5.5 现象:转格式后训练报「label out of bounds」
原因:归一化坐标出现负数或大于 1,通常是标注越界或除错了宽高。解决:转换脚本里加裁剪兜底,同时打印越界样本的文件名,回头查原标注。别直接忽略,越界样本往往对应标注工具或流程的系统性问题。
6. 进阶:用 mask 质量筛选反哺标注,把数据集越用越干净
数据集不是拿到就固定不变的。训练一轮之后,用模型在训练集上推理,把预测 mask 和标注 mask 的 IoU 算出来,低于 0.3 的样本单独拎出来看。这些样本要么是标注错了,要么是极难样本。我一般会分两堆处理:标注错的直接修,极难样本留着做 hard example mining。
import cv2, numpy as np from pathlib import Path def mask_iou(pred_path, gt_path): pred = cv2.imread(pred_path, 0) > 127 gt = cv2.imread(gt_path, 0) > 127 inter = np.logical_and(pred, gt).sum() union = np.logical_or(pred, gt).sum() return inter / union if union else 0.0 bad = [] for gt in Path("labels_vis").glob("*.png"): pred = Path("pred_vis") / gt.name if pred.exists(): iou = mask_iou(str(pred), str(gt)) if iou < 0.3: bad.append((gt.stem, iou)) print(f"低 IoU 样本数: {len(bad)}") for name, iou in sorted(bad, key=lambda x: x[1])[:20]: print(f"{name}: {iou:.3f}")这段代码把预测 mask 和标注 mask 都转成二值图算 IoU。低于 0.3 的样本,人工过一遍,能修则修,修不了就标记为困难样本。迭代两三轮之后,数据集的标注一致性会明显提升,模型指标也跟着涨。参数上,0.3 这个阈值不是死的,标注质量高的数据集可以提到 0.5,质量差的先降到 0.2 看趋势。
还有一个习惯:每次改完标注,重新转格式、重新划分、重新训练,别在旧标签上打补丁。我吃过亏,改了一半标签忘了重新生成 txt,训练出来的模型在验证集上表现诡异,排查了一整天才发现是标签和图片对不上。数据集这东西,干净比大重要,一致比多重要。希望帮到你。
本文还有配套的精品资源,点击获取