数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)

图片数量(jpg文件个数):1000

标注数量(xml文件个数):1000

标注数量(txt文件个数):1000

标注类别数:4

所在github仓库:firc-dataset

标注类别名称(注意yolo格式类别顺序不和这个对应,而以labels文件夹classes.txt为准):["diban","qiangbi","renyuan","wuti"]

每个类别标注的框数和占有图片数:

diban(地板) 框数=1152,占有图片数=988

qiangbi(墙壁) 框数=1946,占有图片数=883

renyuan(人员) 框数=2627,占有图片数=836

wuti(物体) 框数=1401,占有图片数=863

总框数:7126

图片分辨率:640x640

使用标注工具:labelImg

标注规则:对类别进行画矩形框

重要说明:数据集没有划分训练验证测试集需自行划分

特别声明:本数据集不对训练的模型或权重文件精度作任何保证

图片预览:

标注例子:

单张图片:

这个数据集非常适合做室内机器人巡检的多类目标检测,但有一个关键点需要注意:地板和墙壁是"大面积区域类",和人员、物体这种"实例类"混合标注时,训练策略需要区别对待。下面给出针对该数据集的应用场景、数据检查、训练和推理流程。


一、数据集应用场景

室内机器人巡检系统(安防/清洁/巡检机器人)

机器人在室内自主移动,需要同时感知四类信息:

  • diban(地板):判断可通行区域、清洁区域边界
  • qiangbi(墙壁):建图/避障参考、贴边行驶
  • renyuan(人员):人员检测、避让、异常人员告警
  • wuti(物体):地面/通道障碍物检测(箱子、设备、杂物等)

为什么适合 YOLO26:

  • 机器人本体算力受限(常见 Jetson Orin Nano / RK3588 / CPU 工控机),YOLO26n 的 CPU 推理速度和端到端无 NMS 特性非常适合。
  • 4 类、1000 张属于中小规模数据集,用 nano/small 预训练模型微调即可。
  • 地板/墙壁是大面积目标,STAL 标签分配对小目标友好,同时大面积目标也能稳定收敛。

二、先做数据检查(重要)

1. 核对类别顺序

用户已提示 YOLO 类别顺序以 ​​labels/classes.txt​​​ 为准,VOC 的类别顺序可能不同。训练前必须确认:

# 确认 classes.txt 内容与顺序
with open("dataset/labels/classes.txt") as f:
    classes = [l.strip() for l in f if l.strip()]
print(classes)
# 假设输出: ['wuti', 'diban', 'renyuan', 'qiangbi']
# 则 YOLO 训练 yaml 的 names 必须按这个顺序写

VOC 转 YOLO 时,脚本必须读取 ​​classes.txt​​ 建立 ​​name -> id​​ 映射,不能按字母序或 VOC 顺序硬编码。

2. 统计类别分布与"面积类"问题

类别

框数

占有图片数

框/图

特点

diban

1152

988

~1.17

大面积,几乎每张都有

qiangbi

1946

883

~2.20

大面积,多段墙

renyuan

2627

836

~3.14

实例类,多人场景多

wuti

1401

863

~1.62

实例类,障碍物

注意:

  • 地板/墙壁框数接近图片数甚至更多,说明是大框覆盖背景区域。这类目标容易让模型学到"整图都是地板/墙"的捷径,会挤压小物体(wuti)的检测能力。
  • 人员框数最多(2627),可能存在密集小目标,需关注 ​​imgsz​​ 和 ​​conf​​ 设置。
3. 检查标注质量
import os
from collections import Counter

def check_yolo_labels(label_dir, num_classes):
    stats = Counter()
    bad = []
    for fn in os.listdir(label_dir):
        if not fn.endswith(".txt") or fn == "classes.txt":
            continue
        with open(os.path.join(label_dir, fn)) as f:
            for line in f:
                p = line.split()
                if len(p) != 5:
                    bad.append((fn, line.strip())); continue
                cid = int(p[0])
                w, h = float(p[3]), float(p[4])
                stats[cid] += 1
                if cid >= num_classes:
                    bad.append((fn, f"invalid class {cid}"))
                if not (0 < w <= 1 and 0 < h <= 1):
                    bad.append((fn, f"bad wh {w},{h}"))
    return stats, bad

stats, bad = check_yolo_labels("dataset/labels/train", 4)
print(stats, "bad:", len(bad))

重点检查:地板/墙壁框是否越界、是否几乎等于整图(w/h 接近 1.0),以及是否有类别 id 超出范围。


三、训练流程

1. 数据集 YAML(严格按 classes.txt 顺序)
# indoor_robot.yaml
path: ./dataset
train: images/train
val: images/val

# 顺序必须与 labels/classes.txt 完全一致!
names:
  0: wuti
  1: diban
  2: renyuan
  3: qiangbi
2. 选择模型与训练

1000 张、4 类,建议用 YOLO26n 或 YOLO26s:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")   # 边缘部署选 n;精度不够换 s

results = model.train(
    data="indoor_robot.yaml",
    epochs=100,
    imgsz=640,
    batch=16,
    device=0,                # 有 GPU 用 0;纯 CPU 训练建议减小 epochs/imgsz
    patience=20,
    optimizer="auto",        # YOLO26 会用 MuSGD
    # 数据增强:室内场景建议适度
    hsv_h=0.015, hsv_s=0.5, hsv_v=0.4,
    degrees=5.0,             # 机器人视角轻微旋转
    translate=0.1, scale=0.3,
    fliplr=0.5,              # 左右翻转对室内场景合理
    mosaic=1.0,
    close_mosaic=10,         # 最后 10 epoch 关 mosaic 稳定收敛
    name="indoor_robot_yolo26n"
)
3. 针对本数据集的训练调整建议
  • 大面积类拉低小目标性能:如果 ​​wuti​​ 检测效果差,可尝试:
  • 提高 ​​imgsz​​ 到 800 或 960(增加小目标分辨率)
  • 对 ​​wuti​​ 类做过采样(复制含 wuti 的图片)或单独裁剪增强
  • 评估时分类型看 mAP,不要只看整体 mAP(地板/墙的 mAP 会虚高)
  • 人员密集:2627 框 / 836 图 ≈ 3.1 人/图,属中等密度,默认设置一般够用;若出现漏检,调低推理 ​​conf​​ 到 0.25。
  • 验证集划分:确保 train/val 按场景/房间划分(同一房间的连续帧不要跨集),否则 mAP 会虚高。
4. 训练后分类评估
metrics = model.val(data="indoor_robot.yaml", imgsz=640)
for i, name in enumerate(metrics.names.values()):
    print(f"{name}: mAP50={metrics.box.ap50[i]:.3f}, mAP50-95={metrics.box.ap[i]:.3f}")

重点看 ​​wuti​​​ 和 ​​renyuan​​ 的 mAP,地板/墙的 mAP 高是正常的,但不能代表系统可用性。


四、推理流程

1. 单帧/图片推理
from ultralytics import YOLO
from PIL import Image

model = YOLO("runs/detect/indoor_robot_yolo26n/weights/best.pt")
image = Image.open("test_room.jpg")

results = model.predict(
    source=image,
    conf=0.3,          # 人员/物体建议 0.25~0.35
    imgsz=640,
    verbose=False
)

# 各类别结果
names = results[0].names
for box in results[0].boxes:
    cid = int(box.cls)
    print(names[cid], float(box.conf), box.xyxy.tolist())

Image.fromarray(results[0].plot()[..., ::-1]).show()
2. 机器人实时巡检推理(视频流 + 业务逻辑)
import cv2

cap = cv2.VideoCapture("rtsp://robot_camera/stream")  # 或 0
model = YOLO("best.pt")

while True:
    ret, frame = cap.read()
    if not ret:
        break

    results = model.predict(frame, conf=0.3, imgsz=640, verbose=False)
    r = results[0]
    names = r.names

    # 业务逻辑示例:只关心人员和障碍物告警
    alarms = []
    for box in r.boxes:
        name = names[int(box.cls)]
        conf = float(box.conf)
        x1, y1, x2, y2 = box.xyxy[0].tolist()
        area_ratio = ((x2 - x1) * (y2 - y1)) / (frame.shape[0] * frame.shape[1])

        if name == "renyuan" and conf > 0.4:
            alarms.append(f"检测到人员 conf={conf:.2f}")
        if name == "wuti" and area_ratio > 0.02:   # 障碍物占画面一定比例才告警
            alarms.append(f"检测到障碍物 conf={conf:.2f}")

    annotated = r.plot()
    if alarms:
        cv2.putText(annotated, " | ".join(alarms[:2]), (10, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

    cv2.imshow("Robot Inspection", annotated)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()
3. 边缘部署导出
# 机器人端(Jetson/瑞芯微/CPU 工控机)
model.export(format="onnx", imgsz=640, simplify=True, dynamic=False)
# Jetson 可再转 TensorRT;瑞芯微转 RKNN

五、关键注意事项汇总

  1. 类别顺序以 ​​labels/classes.txt​​​ 为准,训练 yaml 的 ​​names​​ 必须与之逐行对应,VOC 的类别顺序不可直接沿用。
  2. 地板/墙壁是大面积背景类,整体 mAP 会虚高,评估和调参应按类别分别看,重点优化 ​​wuti​​ 和 ​​renyuan​​。
  3. train/val 按房间/场景划分,避免连续帧泄漏导致指标失真。
  4. 1000 张规模偏小,用预训练微调 + 适度增强;若 ​​wuti​​ 小目标多,提高 ​​imgsz​​ 或做过采样。
  5. YOLO26 端到端无 NMS,部署到机器人端延迟稳定,但导出前务必用 ​​model.val​​​ 确认微调后精度。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐