Label Studio 图像关键点标注(Keypoint Labeling)实战:从配置模板到坐标导出
【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio
关键点标注(Keypoint Labeling)是计算机视觉数据标注中最精细的任务类型之一:标注者不需要绘制矩形或轮廓,而是直接在图像上点选具有明确语义的点位(如人脸五官、人体关节、飞机引擎与机翼等),为后续的人脸关键点检测、人体姿态估计等模型训练提供数据。本指南以 Label Studio 官方模板 image_keypoints.md 为核心,完整讲解基于KeyPointLabels标签的标注配置方法、全部参数语义、输出结果 JSON 格式,并结合仓库源码说明点选工具在前端编辑器的实际实现,帮助你从零搭建一个可直接运行、可导出标准化结果的关键点标注项目。
模板核心配置:三行标签完成关键点标注
模板提供的标注配置非常精简,完整内容如下:
<View> <KeyPointLabels name="kp-1" toName="img-1"> <Label value="Face" background="red" /> <Label value="Nose" background="green" /> </KeyPointLabels> <Image name="img-1" value="$img" /> </View>整个配置只有三个组成部分:
<View>:所有标注配置必须包裹在 View 标签内;<KeyPointLabels>:控制标签(Control Tag),负责在图像上添加可标注的关键点,并绑定到图像对象;<Image>:对象标签(Object Tag),声明待标注的图像数据来源。
仓库中label_studio/annotation_templates/computer-vision/keypoints/config.yml提供了同款官方模板,其附带的应用场景说明给出了关键点标注的典型行业用途:人体姿态估计、人脸关键点检测、运动表现分析、医学诊断、增强现实、动作捕捉、健身追踪、手势识别、自动驾驶安全、驾驶员监控、生物特征认证与动画制作等,并列举了 OpenPose、MediaPipe、PoseNet、DensePose、Face++、Dlib 等常见下游模型。
逐标签拆解配置语义
1. KeyPointLabels 控制标签
<KeyPointLabels name="kp-1" toName="img-1">name:元素名称,标注结果中from_name字段会引用该值;toName:绑定到待标注图像的名称(即下方Image标签的name)。
它决定了关键点工具出现在工具栏中,并在点选时要求先选中一个标签类别。
2. Label 标签定义关键点类别
<Label value="Face" background="red" /> <Label value="Nose" background="green" />Label是单个关键点类别:value指定类别名称,background指定该类别的关键点在画布上的显示颜色(十六进制色值)。background默认值为#36B37E,selectedColor(激活状态下标签文字颜色)默认#ffffff。
3. Image 对象标签声明数据源
<Image name="img-1" value="$img" />value="$img"引用任务数据中的img字段,该字段存放图像的 URL 或本地路径。
提示:若任务中每个标注只需要一个关键点类别,可以省略
Label子标签,改用更精简的KeyPoint标签(不带标签类别,直接点选),详见后文“不带类别的简化方案”。
关键点标注标签的参数全解析
完整的关键点标注配置除了模板示例外,还支持大量可调参数。下表来自 keypointlabels 参数说明,列出了KeyPointLabels标签的全部参数:
| Param | Type | Default | Description |
|---|---|---|---|
| name | string | 元素名称 | |
| toName | string | 待标注图像的名称 | |
| [choice] | single|multiple | single | 配置每个关键点只能选择单个标签,还是可以选择多个标签 |
| [maxUsages] | number | 每个任务中一个标签最多可被使用的次数 | |
| [showInline] | boolean | true | 标签是否在同一行内显示 |
| [opacity] | float | 0.9 | 关键点的透明度 |
| [strokeWidth] | number | 1 | 关键点描边宽度 |
| [snap] | pixel|none | none | 是否将关键点吸附到图像像素 |
choice参数在需要"一个关键点同时命中多个语义"时很有用,例如同一骨骼节点既属于肢体又属于躯干;maxUsages则适合限制类别出现次数,如规定每张图最多标注 5 个"Face";snap="pixel"适合需要亚像素级精度的医学影像等场景,可将关键点精确吸附到像素格点。
Label标签同样拥有独立参数(见 label 参数说明),除value与background外,常用的还有:
| Param | Type | Default | Description |
|---|---|---|---|
| [selected] | boolean | false | 是否预选中该标签 |
| [maxUsages] | number | 该标签在每个任务中的最大使用次数 | |
| [hint] | string | 鼠标悬停时的提示文本 | |
| [hotkey] | string | 该标签的快捷键,不指定时自动生成 | |
| [alias] | string | 标签别名 | |
| [size] | string | "medium" | 标签文字大小 |
| [category] | int | 导出时(label-studio-converter)用于 YOLO/COCO 格式的标签排序编号 |
以人脸关键点为例,一个更完整的配置可以是:
<View> <KeyPointLabels name="kp-face" toName="img-1" choice="single" strokeWidth="2" opacity="0.8" snap="pixel"> <Label value="Left Eye" background="#FF0000" hotkey="1" maxUsages="1" /> <Label value="Right Eye" background="#00FF00" hotkey="2" maxUsages="1" /> <Label value="Nose Tip" background="#0000FF" hotkey="3" maxUsages="1" /> <Label value="Mouth Corner" background="#FFFF00" hotkey="4" maxUsages="2" /> </KeyPointLabels> <Image name="img-1" value="$image" zoom="true" zoomControl="true" /> </View>这里同时展示了Image标签的常用增强参数(完整参数见 image 参数说明):zoom="true"允许鼠标滚轮缩放、zoomControl="true"在工具栏显示缩放控件——对于需要精细点选的关键点任务,缩放能力几乎是必备的。
不带类别的简化方案:KeyPoint 标签
如果整个任务只有一种关键点语义(比如所有点位都是"人体关节点"),可以不使用KeyPointLabels,改用KeyPoint标签,省去每次点选前切换标签类别的操作:
<View> <KeyPoint name="kp-1" toName="img-1" /> <Image name="img-1" value="$img" /> </View>KeyPoint标签的参数(见 keypoint 参数说明)与KeyPointLabels高度相似,但多了颜色相关参数:
| Param | Type | Default | Description |
|---|---|---|---|
| name | string | 元素名称 | |
| toName | string | 待标注图像名称 | |
| [opacity] | float | 0.9 | 关键点透明度 |
| [fillColor] | string | "#8bad00" | 关键点填充颜色(十六进制) |
| [strokeWidth] | number | 1 | 描边宽度 |
| [strokeColor] | string | "#8bad00" | 描边颜色(十六进制) |
| [smart] | boolean | 显示智能工具用于交互式预标注 | |
| [smartOnly] | boolean | 仅显示智能工具用于交互式预标注 | |
| [snap] | pixel|none | none | 是否吸附到图像像素 |
其中的smart/smartOnly参数与 Label Studio 的 ML 交互式预标注能力挂钩:开启后可在关键点附近调用后端模型辅助定位,属于进阶用法。
标注结果与导出格式:百分比坐标
关键点标注完成后,每个关键点对应一个标注结果(Result)对象。根据 keypointlabels 结果参数说明,字段结构如下:
| Name | Type | Description |
|---|---|---|
| original_width | number | 原始图像宽度(像素) |
| original_height | number | 原始图像高度(像素) |
| image_rotation | number | 图像旋转角度(度) |
| value | Object | 关键点数值对象 |
| value.x | number | x 坐标,按图像尺寸百分比(0-100) |
| value.y | number | y 坐标,按图像尺寸百分比(0-100) |
| value.width | number | 点的大小,按图像尺寸百分比(0-100) |
一个典型的关键点标注结果 JSON:
{ "original_width": 1920, "original_height": 1280, "image_rotation": 0, "value": { "x": 3.1, "y": 8.2, "width": 2, "keypointlabels": ["Car"] } }仓库中web/libs/editor/src/examples/image_keypoints/annotations/0.json提供了一个真实的多关键点标注示例,与文档给出的百分比坐标系完全一致(坐标值归一化到 0-100,keypointlabels为类别名数组):
{ "result": [ { "id": "hqudA4A3U4", "from_name": "tag", "to_name": "img", "source": "$image", "type": "keypointlabels", "value": { "x": 49.6, "y": 52.340425531914896, "width": 0.6666666666666666, "keypointlabels": ["Hello"] } }, { "id": "Rz9oHDXIwG", "from_name": "tag", "to_name": "img", "source": "$image", "type": "keypointlabels", "value": { "x": 47.733333333333334, "y": 52.765957446808514, "width": 0.6666666666666666, "keypointlabels": ["World"] } } ] }需要注意的工程要点:
from_name对应配置中KeyPointLabels的name,to_name对应Image的name;- 坐标为相对百分比而非像素绝对值:
x、y取值范围 0-100,width代表点在图上显示的尺寸占比。这保证了不同分辨率的图像标注结果可直接对齐复用; - 要还原像素坐标,用
x / 100 * original_width、y / 100 * original_height计算即可(original_width、original_height记录在结果顶层字段中); type字段固定为keypointlabels,这是下游解析与导出(如 label-studio-converter 将关键点转换为 COCO/YOLO 等格式)时识别该结果类型的依据。
源码视角:关键点工具的前端实现
关键点标注并非简单的"画一个点",其交互逻辑在前端编辑器中有明确的实现路径,值得标注流程设计者了解。
工具定义:web/libs/editor/src/tools/KeyPoint.js中定义了KeyPointTool,其tagTypes明确声明该工具支持的控制标签类型为["keypointlabels", "keypoint"],即上面两种配置方案的底层入口都是同一个工具:
get tagTypes() { return { stateTypes: "keypointlabels", controlTagTypes: ["keypointlabels", "keypoint"], }; }点选交互:clickEv动作实现了单击落点逻辑(见 KeyPoint.js)——当使用keypointlabels类型且尚未选中任何标签时(!c.isSelected),点击不会生成关键点;只有选中某个标签类别后才允许落点,并通过createRegion创建关键点区域。这印证了文档中"先选标签、再点图像"的操作语义。
区域模型:创建出的关键点在web/libs/editor/src/regions/KeyPointRegion.jsx中管理,负责关键点的渲染、选中与坐标计算。
吸附行为:snap参数的实现与Image对象的像素坐标换算相关(配置解析可追溯至web/libs/editor/src/tags/control/KeyPointLabels.jsx),当snap="pixel"时,落点坐标会被吸附到最近的整数像素位置。
这些源码证据说明:模板配置中的每个参数都对应编辑器内真实的交互与坐标计算逻辑,理解参数语义有助于精确控制标注行为。
配套资源与进一步阅读
围绕关键点标注主题,仓库中还有以下可直接对照使用的资源:
- KeyPointLabels 标签参考文档:标签完整说明与示例;
- KeyPoint 标签参考文档:无类别关键点方案;
- Label 标签参考文档:类别标签参数详解;
- Image 标签参考文档:图像对象标签参数详解;
- 关键点标注模板配置:官方模板(含行业应用与关联模型说明);
- 关键点标注示例数据:真实标注结果样例。
快速上手三步
- 创建项目:在 Label Studio 中新建一个图像标注项目,进入 Labeling Setup 页面;
- 粘贴配置:将上文"模板核心配置"中的 HTML 配置粘贴到标签配置编辑器,保存;
- 导入数据并标注:上传包含
img字段(图像 URL 或路径)的任务数据,进入标注界面,先选中标签类别(如 Face/Nose),再在图像上单击即可放置关键点,可通过Image的缩放参数辅助精确定位;完成后在导出界面选择所需格式(如 COCO、JSON)获取标准化标注结果。
【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考