Lylove Blog
返回首页

文章

蓝线分割模型标注训练流程

蓝线分割模型标注训练流程 结论 当前最适合蓝线循迹的方案是训练一个单类别分割模型: 。 标注方式不是画框,而是用画笔把真实导航蓝线涂成 mask。蓝线弯曲、断开、变成白蓝色都没有关系;模型学习的是“这条导航路线的像素区域...

蓝线分割模型标注训练流程

结论

当前最适合蓝线循迹的方案是训练一个单类别分割模型:blue_route_line

标注方式不是画框,而是用画笔把真实导航蓝线涂成 mask。蓝线弯曲、断开、变成白蓝色都没有关系;模型学习的是“这条导航路线的像素区域”,后续再把分割结果骨架化,用骨架线控制 WSAD。

推荐主流程:

  1. Label Studio 标注蓝线 mask。
  2. 导出 COCO Instance Segmentation
  3. 转成 YOLO segmentation 数据格式。
  4. 训练 YOLO11n-seg
  5. 导出 ONNX 后接入脚本。

1. 标注流程

1.1 用什么标注

主推荐:Label Studio

原因:

  • 支持画笔/Brush,适合弯曲、细长、不规则蓝线。
  • 能导出 COCO 分割格式,后面可以转 YOLO segmentation。
  • 对这种“细线 mask”比纯多边形工具省时间。

不推荐只用矩形框:

  • 框会把台阶、角色名、怪物光效、地砖高光一起框进去。
  • 模型学不到“蓝线的真实像素边界”。
  • 后续仍然会像现在一样误判环境白边。

可选备用:CVAT

  • 如果需要多人协作或项目管理,CVAT 更强。
  • 单人快速标蓝线,Label Studio 更直接。

1.2 需要什么工具

标注工具:

  • Label Studio
  • 浏览器
  • 一个用于存放截图的数据目录

训练工具:

  • Python 虚拟环境
  • ultralytics
  • opencv-python
  • numpy
  • NVIDIA 显卡环境优先;没有显卡也能小规模 CPU 训练,但会很慢

建议目录:

text
workspace/晶核/datasets/blue_line_seg/
  raw_images/
  labelstudio_export/
  yolo/
    images/
      train/
      val/
      test/
    labels/
      train/
      val/
      test/
    blue_line_seg.yaml

截图来源:

  • 优先使用真实运行保存的:
    • workspace/晶核/logs/blue_line_debug/*_frame.png
    • workspace/晶核/logs/blue_line_debug_after_v/*_frame.png
  • 也要主动补采:
    • V 后蓝线刚出现的截图
    • 移动中蓝线弯曲的截图
    • 蓝线被角色/怪物/柱子遮挡的截图
    • 没有蓝线、只有红箭头、只有怪物光效的负样本截图

1.3 具体怎么标注

类别只建一个:

text
blue_route_line

标注对象:

  • 真实导航蓝线
  • 高亮白蓝导航线
  • 弯曲蓝线
  • 断开的可见蓝线段
  • 被地形挡住后仍然可见的每一小段

不要标:

  • 角色名蓝条
  • 角色血条
  • 怪物蓝紫光效
  • 技能光效
  • 台阶白边
  • 地砖反光
  • 小地图箭头
  • 红色方向箭头
  • 任务文字
  • UI 按钮

画笔规则:

  1. 放大图片到 200% 或更高。
  2. 选择 Brush/画笔工具。
  3. 画笔宽度一般用 4-10px
  4. 沿蓝线实际可见区域涂,不要只涂 1px 中心线。
  5. 蓝线有蓝色边缘和白色核心时,核心和贴着核心的淡蓝光晕一起涂。
  6. 蓝线很粗时,只涂导航线主体,不要把周围大面积环境蓝全涂进去。
  7. 蓝线被角色挡住时,只涂看得见的部分,不要脑补隐藏部分。
  8. 蓝线断成多段时,每一段都涂,仍然是同一个类别。
  9. 如果蓝线和角色名蓝条粘在一起,只涂路线本体,不涂文字横条。
  10. 如果不确定某块是不是蓝线,宁可不标,不要把环境噪声标进去。

弯曲蓝线怎么标:

  • 直接用画笔沿曲线刷过去。
  • 曲线转弯处要跟着蓝线形状走。
  • 不要用一根直线把弯曲蓝线拉直。
  • 如果工具只能画多边形,就沿蓝线一侧连续点点,再沿另一侧点回来,闭合成细长弯曲多边形。

浅色白线怎么标:

  • V 后出现的白蓝色线也标。
  • 标的是它的可见亮线主体。
  • 不要因为它看起来偏白就跳过;这正是当前阈值方案最容易漏的样本。

负样本怎么处理:

  • 没有蓝线的图片也要放进数据集。
  • 负样本不画任何 mask。
  • 负样本用于让模型知道:台阶白边、怪物光效、角色名蓝条不是蓝线。

每张图标完后的自查:

  • 只剩真实导航线被涂了吗?
  • 角色名蓝条有没有误涂?
  • 台阶横向白边有没有误涂?
  • 怪物蓝紫光效有没有误涂?
  • 蓝线转弯处有没有漏掉?
  • 被遮挡的地方有没有只标可见部分?

2. 训练流程

2.1 导出标注

Label Studio 标完后导出:

text
COCO Instance Segmentation

导出后放到:

text
workspace/晶核/datasets/blue_line_seg/labelstudio_export/

2.2 转 YOLO segmentation 格式

Ultralytics 支持把 COCO 分割标注转成 YOLO 分割格式,关键参数是 use_segments=True

转换脚本建议放到:

text
workspace/晶核/scripts/convert_blue_line_coco_to_yolo.py

核心逻辑:

python
from ultralytics.data.converter import convert_coco

convert_coco(
    labels_dir="workspace/晶核/datasets/blue_line_seg/labelstudio_export/",
    save_dir="workspace/晶核/datasets/blue_line_seg/yolo/",
    use_segments=True,
    cls91to80=False,
)

转换完成后检查:

  • images/train 有图片。
  • labels/train 有同名 .txt
  • 每个 .txt 里是分割多边形点,不是检测框。
  • 没有蓝线的负样本可以没有 label 文件,或 label 文件为空。

2.3 数据集配置

创建:

text
workspace/晶核/datasets/blue_line_seg/yolo/blue_line_seg.yaml

内容:

yaml
path: workspace/晶核/datasets/blue_line_seg/yolo
train: images/train
val: images/val
test: images/test

names:
  0: blue_route_line

2.4 开始训练

优先用 YOLO11n-seg,先训练轻量模型,速度快,够验证路线分割是否可行。

命令:

powershell
.\.venv\Scripts\python.exe -m pip install ultralytics

yolo segment train `
  model=yolo11n-seg.pt `
  data=workspace/晶核/datasets/blue_line_seg/yolo/blue_line_seg.yaml `
  epochs=100 `
  imgsz=640 `
  batch=8 `
  project=workspace/晶核/runs/blue_line_seg `
  name=yolo11n_seg_v1

如果显存小:

powershell
yolo segment train model=yolo11n-seg.pt data=workspace/晶核/datasets/blue_line_seg/yolo/blue_line_seg.yaml epochs=100 imgsz=512 batch=4

如果数据已经比较多:

powershell
yolo segment train model=yolo11s-seg.pt data=workspace/晶核/datasets/blue_line_seg/yolo/blue_line_seg.yaml epochs=150 imgsz=640 batch=8

2.5 训练后验证

先看训练输出:

text
workspace/晶核/runs/blue_line_seg/yolo11n_seg_v1/

重点看:

  • results.png
  • val_batch*_pred.jpg
  • confusion_matrix.png
  • weights/best.pt

验证命令:

powershell
yolo segment val `
  model=workspace/晶核/runs/blue_line_seg/yolo11n_seg_v1/weights/best.pt `
  data=workspace/晶核/datasets/blue_line_seg/yolo/blue_line_seg.yaml `
  imgsz=640

预测测试:

powershell
yolo segment predict `
  model=workspace/晶核/runs/blue_line_seg/yolo11n_seg_v1/weights/best.pt `
  source=workspace/晶核/logs/blue_line_debug `
  imgsz=640 `
  save=True

2.6 导出 ONNX

脚本接入前导出 ONNX:

powershell
yolo export `
  model=workspace/晶核/runs/blue_line_seg/yolo11n_seg_v1/weights/best.pt `
  format=onnx `
  imgsz=640 `
  opset=12

导出后建议放到:

text
workspace/晶核/models/blue_line_seg.onnx

3. 数据需求

3.1 最低可用数据量

最低验证版:

text
300 张图片

组成:

  • 220 张有蓝线
  • 80 张无蓝线负样本

这个数量只能验证方案能不能跑,不保证全地图稳定。

3.2 推荐数据量

正式可用版:

text
800-1200 张图片

组成:

  • 600-850 张有蓝线
  • 200-350 张无蓝线负样本

这个量比较适合当前任务,因为蓝线变化非常多:蓝色、白蓝色、浅斜、弯曲、断裂、遮挡、台阶高光、怪物光效都会出现。

3.3 更稳的数据量

长期稳定版:

text
2000 张以上

适合后续多地图、多副本、多光照场景。

3.4 需要多少个场景

最低:

text
5 个不同场景

推荐:

text
10-15 个不同场景

每个场景至少包含:

  • 直线蓝线
  • 左转蓝线
  • 右转蓝线
  • 浅斜蓝线
  • 弯曲蓝线
  • 白蓝色高亮线
  • 被角色遮挡的蓝线
  • 被怪物/柱子/地形遮挡的蓝线
  • 蓝线靠近台阶白边
  • 蓝线靠近地砖反光
  • 没有蓝线但有红色方向箭头
  • 没有蓝线但有怪物蓝紫光效

3.5 数据划分

推荐比例:

text
train: 70%
val: 20%
test: 10%

注意:

  • 同一个连续录屏里截出来的相邻帧,不要全部放 train。
  • 相邻帧太像,会让验证结果虚高。
  • 每个地图、每种光照、每种蓝线形态都要同时出现在 train 和 val。
  • test 集必须保留不参与调参,只用于最后验收。

3.6 第一批应该怎么采

第一批直接按下面采:

text
有蓝线 300 张:
  直线 50
  左转 50
  右转 50
  浅斜/横斜 50
  白蓝线 50
  遮挡/断裂 50

无蓝线 100 张:
  红箭头 25
  怪物光效 25
  台阶/地砖白边 25
  UI/角色名/技能光 25

第一批合计:

text
400 张

这是最推荐的起步量。先用 400 张训练第一版,看错在哪里,再补第二批难例。

4. 验收标准

模型不是看指标好不好看,主要看脚本能不能走。

第一版验收:

  • 蓝线存在时,连续 20 帧至少命中 16 帧。
  • route_only 里主要只剩导航线。
  • 角色名蓝条不能被当主线。
  • 台阶横向白边不能被当主线。
  • 怪物光效不能被当主线。
  • 浅斜蓝线不能丢。
  • 白蓝线不能丢。

移动验收:

  • 命中后默认按住 W
  • 蓝线轻微偏移不按 A/D
  • 连续偏左才按 A
  • 连续偏右才按 D
  • 短暂 1-2 帧断线不停止。
  • 连续断线才释放 WSAD 并按 V

5. 标注质量优先级

最重要的是别把假目标标进去。

优先级:

  1. 不误标台阶白边。
  2. 不误标角色名蓝条。
  3. 不误标怪物光效。
  4. 蓝线主体尽量涂完整。
  5. 弯曲处跟着真实曲线走。
  6. 断开的蓝线只标可见段。

如果标注时间有限,宁可少标几张,也要保证每张图干净。

6. 后续接入思路

模型输出 mask 后,不直接用 mask 质心移动。

正确做法:

  1. 对 mask 做开运算,去掉小噪声。
  2. 提取最大/最可信路线区域。
  3. 做骨架化,得到 1px 中心线。
  4. 从角色附近找最近骨架点。
  5. 沿骨架向前取一个前瞻点。
  6. 根据前瞻点相对角色的横向偏移控制 A/D
  7. 始终保持 W,除非连续丢线。

这样蓝线是弯的也能走,不需要把蓝线识别成直线。

参考