4-2 图像标注实战Label Studio

学习目标

  1. 掌握 Label Studio 的安装、启动与界面使用
  2. 学会配置三种图像标注类型(分类、目标检测、语义分割)
  3. 独立完成边界框、多边形、关键点的标注
  4. 理解 VOC / YOLO / COCO 三种导出格式的区别

1. Label Studio 简介

1.1 一句话定义

Label Studio:一个开源的、多模态数据标注平台,支持图像、文本、语音、视频等几乎所有数据类型的标注与团队协作。

1.2 为什么选它

我们这门课统一用 Label Studio 的原因:

需求 Label Studio 对应能力
多种数据类型 图像 / 文本 / 语音 / 视频 / 时序,一站式
不用写代码 通过 XML 标签可视化配置标注界面
团队协作 内置成员管理、角色权限、任务分配
格式灵活 内置 YOLO、COCO、VOC、JSON、CSV 导出
本地部署 数据不出学校,开源免费
传统方案(多工具切换):
  图像 → LabelImg
  文本 → Doccano
  语音 → Audacity / ELAN
  协作 → Excel 邮件

Label Studio 一站式:
  图像 / 文本 / 语音 / 协作 → Label Studio

1.3 与其他工具的对比

工具 类型 适用场景 本课程
Label Studio 开源/多模态 课程学习 / 中小团队 / 综合项目 主选
LabelImg 开源/图像 极简目标检测 仅做对比
CVAT 开源/图像视频 大型分割、视频跟踪 了解
Doccano 开源/文本 简单文本分类 已弃用
Scale AI 商业 企业级标注 了解

2. Label Studio 安装与启动

2.1 环境要求

  • Python 3.8 及以上
  • 浏览器Chrome / Edge / Firefox
  • 建议 8G 以上内存

2.2 pip 安装(推荐)

# 在命令行中执行
pip install label-studio

# 启动 Label Studio
label-studio

启动后命令行会显示:

[INFO] Label Studio is running at http://localhost:8080
[INFO] Open it in your browser to start labeling

2.3 第一次打开

  1. 浏览器访问 http://localhost:8080
  2. 第一次进入需要 Sign Up 注册管理员账号(用你的邮箱 + 密码)
  3. 注册后自动登录到主界面
┌────────────────────────────────────────────────────────┐
│  Label Studio                                           │
│  Sign Up                                                │
├────────────────────────────────────────────────────────┤
│                                                         │
│   Email:    [___________________________]               │
│   Username: [___________________________]               │
│   Password: [___________________________]               │
│                                                         │
│             [  Create Account  ]                        │
│                                                         │
└────────────────────────────────────────────────────────┘

2.4 安装常见问题

问题 解决
端口 8080 被占用 label-studio --port 8001
启动报错找不到模块 pip install --upgrade label-studio
中文乱码 系统区域设置改为 UTF-8
浏览器无法打开 检查防火墙、放行端口

3. 主界面导览

登录后看到的主界面:

┌──────────────────────────────────────────────────────────────┐
│ [Label Studio]  Projects  Members  Settings  [用户头像]      │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   My Projects                                                │
│                                                              │
│   ┌────────────────────────────────────────────────┐        │
│   │  + Create Project                              │        │
│   └────────────────────────────────────────────────┘        │
│                                                              │
│   没有任何项目,点上面按钮开始                              │
│                                                              │
└──────────────────────────────────────────────────────────────┘

主要功能区

  • Projects:项目列表,每个项目对应一个标注任务
  • Members:成员管理(管理员可见)
  • Settings:个人设置

4. 创建第一个项目:图像分类

4.1 任务说明

任务:对 10 张动物图片进行分类类别有cat / dog / bird

4.2 创建项目

  1. 点击 + Create Project
  2. 填写:
    • Project Nameanimal_classification
    • Description:动物图片三分类
  3. 点击 Save

4.3 配置标注界面

进入项目后,先点 SettingsLabeling InterfaceCode

<View>
  <Image name="image" value="$image"/>
  <Choices name="label" toName="image" choice="single">
    <Choice value="cat"/>
    <Choice value="dog"/>
    <Choice value="bird"/>
  </Choices>
</View>

逐行解释

<View>            ← 整个标注界面的根标签
  <Image ...>     ← 显示图像($image 是任务数据里的字段名)
  <Choices ...>   ← 单选/多选控件
    <Choice/>     ← 一个选项
</View>

关键参数

  • toName="image":告诉 Label Studio这个控件是对上面 Image 控件的结果
  • choice="single":单选(可选 single-radiomultiple

保存后点 Label All Tasks 就能看到标注界面。

4.4 导入数据

在项目页 → SettingsData Import

方式 A上传本地文件

1. 准备文件夹
   images/
     ├── cat_001.jpg
     ├── cat_002.jpg
     ├── dog_001.jpg
     └── bird_001.jpg

2. 拖拽到上传区域
   或点击 Upload Files 选中文件夹

方式 B上传 CSV / JSONL推荐标签稳定

tasks.csv

image
images/cat_001.jpg
images/cat_002.jpg
images/dog_001.jpg
images/bird_001.jpg

方式 C粘贴 URL

image
https://example.com/cat_001.jpg
https://example.com/dog_001.jpg

上传完后点 Save → 任务列表里就会看到每一张图对应一行任务。

4.5 开始标注

  1. 点击 Label All Tasks
  2. 进入标注界面:
    • 上面是图片
    • 下面是三个单选按钮
  3. 选中正确类别
  4. 点击右下角 Submit 进入下一张
  5. 全部完成后回到项目页,可以看到完成进度
┌──────────────────────────────────────────────────┐
│  Project: animal_classification                   │
├──────────────────────────────────────────────────┤
│  Tasks:     10 total / 7 done / 3 skipped         │
│  Progress:  ████████████░░░░░░  70%               │
└──────────────────────────────────────────────────┘

4.6 导出数据

项目页 → Export

  • 格式选 JSON
  • 下载得到 project-1-at-2024-05-20.json

导出内容示例:

[
  {
    "id": 1,
    "data": {"image": "images/cat_001.jpg"},
    "annotations": [{
      "result": [{
        "from_name": "label",
        "to_name": "image",
        "type": "choices",
        "value": {"choices": ["cat"]}
      }]
    }]
  }
]

5. 创建第二个项目:目标检测(边界框)

5.1 任务说明

任务:对 10 张街景图进行目标检测,标出每张图中的 personcarbicycle

5.2 项目配置 XML

<View>
  <Image name="image" value="$image"/>
  <RectangleLabels name="label" toName="image" strokeWidth="3">
    <Label value="person" background="#FF0000"/>
    <Label value="car"    background="#00FF00"/>
    <Label value="bicycle" background="#0000FF"/>
  </RectangleLabels>
</View>

新增标签

  • <RectangleLabels>:矩形框 + 标签Label Studio 专门用于目标检测)
  • <Label value="..." background="...">:每个标签的颜色
  • strokeWidth="3":边框线宽

5.3 标注操作

进入标注界面后:

┌──────────────────────────────────────────────────┐
│  [image]                                          │
│  ┌────────┐                                       │
│  │  人    │ ← 拖动鼠标画框                        │
│  └────────┘                                       │
│         ┌─────────┐                                │
│         │   车    │                                │
│         └─────────┘                                │
├──────────────────────────────────────────────────┤
│  标签栏:                                          │
│  [ person ]  [ car ]  [ bicycle ]                 │
└──────────────────────────────────────────────────┘

操作步骤

  1. 选中上方标签(点击 person/car/bicycle 之一)
  2. 在图片上 按住鼠标左键拖动,画矩形框
  3. 松开后,框会自动带上刚才选中的标签
  4. 继续选下一个标签,再画下一个框
  5. 同一张图可以有多个框
  6. 标完后点 Submit

5.4 快捷键速查

快捷键 功能
Ctrl + Enter 提交当前任务
H 切换显示已画框
Ctrl + Z 撤销上一个框
Delete 删除选中的框
数字 1-9 快速选择第 N 个标签
+ / - 缩放图像
滚轮 上下滚动

5.5 边界框标注规范

基本规则

正确(紧贴目标)           错误(框太大)            错误(截断)

┌──────────┐               ┌────────────────┐        ┌──────────
│ ▓▓▓▓▓▓▓ │               │ ▓▓▓▓▓▓▓▓▓▓▓▓▓ │        │ ▓▓▓▓▓▓▓ │
│ ▓ 人 ▓▓ │               │ ▓  人  ▓▓▓▓▓▓ │        │ ▓ 人 ▓▓ │
│ ▓▓▓▓▓▓▓ │               │ ▓▓▓▓▓▓▓▓▓▓▓▓▓ │        │ ▓▓▓▓▓▓▓ │
└──────────┘               └────────────────┘        └──────────┘

多目标处理

  • 一张图有几个就标几个,每个独立画框
  • 互相重叠的目标也要分别标
  • 远处很小的目标可以标 "difficult" 标记

遮挡处理

情况1目标被部分遮挡
   → 标可见部分(标框框住能看到的人)

情况2目标被严重遮挡< 20% 可见)
   → 建议不标(标记为非标注目标)

情况3多人重叠
   → 每个独立标,画框按可见边界

5.6 YOLO 格式导出

项目页 → Export → 选 YOLO

下载得到压缩包,解压后结构:

project-1-at-2024-05-20-yolo/
├── images/
│   ├── street_001.jpg
│   └── street_002.jpg
├── labels/
│   ├── street_001.txt
│   └── street_002.txt
├── classes.txt
└── notes.json

classes.txt(类别映射):

0: person
1: car
2: bicycle

street_001.txt(一张图的标注):

# 格式: <class_id> <x_center> <y_center> <width> <height>
# 所有值都是相对图片尺寸的归一化值 (0-1)
0 0.35 0.45 0.18 0.55
1 0.75 0.50 0.30 0.20

逐字段解释

0      → 类别 ID0=person
0.35   → 框中心点 x / 图片宽度
0.45   → 框中心点 y / 图片高度
0.18   → 框宽度 / 图片宽度
0.55   → 框高度 / 图片高度

5.7 Pascal VOC 格式导出

项目页 → Export → 选 PascalVOC

street_001.xml

<?xml version="1.0" encoding="UTF-8"?>
<annotation>
    <filename>street_001.jpg</filename>
    <size>
        <width>1920</width>
        <height>1080</height>
        <depth>3</depth>
    </size>
    <object>
        <name>person</name>
        <bndbox>
            <xmin>134</xmin>
            <ymin>216</ymin>
            <xmax>478</xmax>
            <ymax>810</ymax>
        </bndbox>
    </object>
    <object>
        <name>car</name>
        <bndbox>
            <xmin>1100</xmin>
            <ymin>450</ymin>
            <xmax>1680</xmax>
        </bndbox>
    </object>
</annotation>

注意 VOC 用的是绝对像素坐标xmin、ymin、xmax、ymax而 YOLO 是归一化坐标0-1

5.8 COCO 格式导出

项目页 → Export → 选 COCO

result.json

{
  "images": [
    {"id": 1, "file_name": "street_001.jpg", "width": 1920, "height": 1080},
    {"id": 2, "file_name": "street_002.jpg", "width": 1920, "height": 1080}
  ],
  "categories": [
    {"id": 0, "name": "person"},
    {"id": 1, "name": "car"},
    {"id": 2, "name": "bicycle"}
  ],
  "annotations": [
    {
      "id": 1, "image_id": 1, "category_id": 0,
      "bbox": [134, 216, 344, 594],
      "area": 204336,
      "iscrowd": 0
    }
  ]
}

注意 COCO 的 bbox 格式是 [x_min, y_min, width, height]前两个是左上角,后两个是宽高),和 VOC 略有区别。

5.9 三种格式对比

特性 VOC YOLO COCO
文件类型 每个图一个 XML 每个图一个 TXT 所有图一个 JSON
坐标系 绝对像素 (xmin,ymin,xmax,ymax) 归一化 0-1中心点+宽高) 绝对像素 (x,y,w,h)
多目标 一个 object 一对 bndbox 一行一个目标 一个 annotation 一个目标
适用框架 Faster R-CNN, SSD YOLO 系列 Mask R-CNN, Detectron2
优缺点 直观但文件多 紧凑、YOLO 专用 强大、适合大项目
人类可读

怎么选

  • 学 YOLO 模型 → 导 YOLO
  • 用 MMDetection / Detectron2 → 导 COCO
  • 通用、自己写训练脚本 → 导 VOC 或 JSON

6. 创建第三个项目:语义分割(多边形)

6.1 任务说明

任务:对 5 张街景图做像素级语义分割类别road、building、sky、vegetation

6.2 项目配置 XML

<View>
  <Image name="image" value="$image"/>
  <PolygonLabels name="label" toName="image" strokeWidth="2">
    <Label value="road"        background="#808080"/>
    <Label value="building"    background="#A52A2A"/>
    <Label value="sky"         background="#87CEEB"/>
    <Label value="vegetation"  background="#228B22"/>
  </PolygonLabels>
</View>

<PolygonLabels>:多边形 + 标签,专门用于语义分割。

6.3 标注操作

  1. 选中标签(点击 road / building / sky / vegetation
  2. 在图像上连续点击多个点画出多边形
  3. 双击或按回车结束当前多边形
  4. 一个类别画完,再选下一个类别继续
  5. 一张图可能有很多个多边形
标注过程示意:

点 1 ──→ 点 2
         │
         ↓
点 4 ←── 点 3
(双击结束)

┌──────────────────┐
│                  │
│   1────────2     │
│   │        │     │
│   │  区域  │     │
│   │        │     │
│   4────────3     │
│                  │
└──────────────────┘

6.4 分割标注注意事项

情况 处理
两个区域紧贴 各画一个多边形,不要合成一个
区域很小 至少 3 个点画出三角形
形状不规则 多点描边,越细越准
类别不确定 选最接近的,宁可错记也不要漏

6.5 导出多边形

项目页 → Export → 选 JSON

{
  "id": 1,
  "data": {"image": "street_001.jpg"},
  "annotations": [{
    "result": [{
      "from_name": "label",
      "to_name": "image",
      "type": "polygonlabels",
      "value": {
        "points": [[0.1, 0.8], [0.9, 0.8], [0.9, 1.0], [0.1, 1.0]],
        "polygonlabels": ["road"]
      }
    }]
  }]
}

points 数组里每个点都是 [x, y] 的归一化坐标0-1是按顺时针或逆时针排列的多边形顶点。

💡 想转成 mask像素级 PNG 图)?需要用 label-studio-converter 工具,详见 4-4 节。


7. 课堂演示Python SDK

7.1 简介

Label Studio 提供 label-studio-sdk,可以用 Python 编程式管理项目、查询任务、写入预标注。

7.2 安装

pip install label-studio-sdk

7.3 常用代码

from label_studio_sdk import Client

# 连接本地服务
ls = Client(url='http://localhost:8080', api_key='YOUR_API_KEY')

# 获取 API Key
# Label Studio → Settings → Account → Access Token

# 列出所有项目
projects = ls.list_projects()
for p in projects:
    print(p.id, p.title)

# 获取某个项目的任务
project = ls.get_project(id=1)
tasks = project.get_tasks()
print(f"项目里有 {len(tasks)} 个任务")

# 导入新任务
project.import_tasks([
    {"image": "images/new_001.jpg"},
    {"image": "images/new_002.jpg"}
])

# 导出标注
project.export_tasks(export_type='JSON')

这一节以了解为主,详细用法 4-4 节会展开。


8. 实战练习

8.1 任务一:图像分类(必做)

任务:在 Label Studio 创建项目 fruit_classification

步骤

  1. 准备 10 张水果图片apple、banana、orange
  2. 启动 Label Studio创建项目
  3. 配置 <Choices> 三分类界面
  4. 上传 10 张图
  5. 完成 10 张标注
  6. 导出 JSON 并截图

8.2 任务二:目标检测(必做)

任务:创建项目 vehicle_detection

步骤

  1. 准备 10 张街景图
  2. 配置 <RectangleLabels> 目标检测界面
  3. 类别person / car / bicycle / traffic_light
  4. 标完所有目标
  5. 导出 YOLO 格式
  6. 检查导出的 .txt 文件坐标是否正确

8.3 任务三(选做):语义分割

任务:创建项目 scene_segmentation

步骤

  1. 准备 3-5 张风景图
  2. 配置 <PolygonLabels> 分割界面
  3. 类别sky / vegetation / road / building
  4. 画多边形
  5. 导出 JSON

8.4 标注自检清单

图像分类:
□ 类别选择是否正确
□ 是否有漏标的任务
□ 导出 JSON 是否完整

目标检测:
□ 边界框是否紧贴目标
□ 是否每个目标都标了
□ 框内类别是否正确
□ 导出 YOLO 格式后坐标值是否在 0-1 之间
□ classes.txt 是否齐全

语义分割:
□ 多边形顶点是否足够(至少 3 个)
□ 类别判断是否准确
□ 不同区域之间是否有遗漏

9. 本节知识小结

┌────────────────────────────────────────────────────────────┐
│                4-2 图像标注实战Label Studio             │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  📌 Label Studio 是多模态标注平台,一站式解决图像/文本/语音 │
│                                                            │
│  📌 安装:                                                  │
│     pip install label-studio                               │
│     label-studio                                           │
│     浏览器访问 http://localhost:8080                       │
│                                                            │
│  📌 三种图像标注类型:                                       │
│     分类      → <Choices>                                   │
│     目标检测  → <RectangleLabels>                          │
│     语义分割  → <PolygonLabels>                            │
│                                                            │
│  📌 三种导出格式:                                           │
│     VOC    → XML像素绝对坐标                              │
│     YOLO   → TXT归一化 0-1 坐标                          │
│     COCO   → JSON[x,y,w,h] 像素坐标                      │
│                                                            │
│  📌 标注规范:框要紧贴目标、不多不少                       │
│                                                            │
└────────────────────────────────────────────────────────────┘

课后任务

  1. 安装 Label Studio截图证明能正常打开
  2. 完成"任务一"图像分类 10 张图
  3. 完成"任务二"目标检测 10 张图,导出 YOLO 格式
  4. (选做)完成"任务三"语义分割

下节预告

下一节我们将学习 4-3 文本标注与语音标注Label Studio

  • 文本分类、NER 命名实体识别
  • 意图识别与槽位标注
  • 语音转写 ASR
  • 说话人分离与音频分类
Description
No description provided
Readme 12 MiB