Label Studio RectangleLabels 标签详解:图像矩形边界框标注与结果格式
导读
RectangleLabels 是 Label Studio 前端编辑器中用于创建**带标签矩形边界框(Bounding Box)**的核心控制标签,广泛应用于图像目标检测(Object Detection)与语义分割类标注任务。本文围绕该标签的完整配置参数、可视化行为、底层数据模型与标注结果 JSON 序列化格式展开,并结合仓库源码(RectangleLabels.jsx、RectRegion.jsx 等)讲解参数如何影响画布交互与结果导出,帮助读者从“会配标签”进阶到“理解标注结果从何而来”。
一、标签概览:什么是 RectangleLabels
RectangleLabels 是一种控制类标签(Control Tag),用于在图像上绘制矩形边界框并为其赋予语义标签(如 "Person"、"Car")。它支持的数据类型为 image。标注结果以矩形左上角坐标为锚点存储,坐标值为相对原图的百分比(0–100),关于锚点与旋转的详细说明可参考目标检测模板示例 image_bbox/config.xml。
从源码看,该标签在 Registry 中以 rectanglelabels 名称注册,其模型由多个 Mixin 组合而成(见 RectangleLabels.jsx):
ControlBase:控制标签基础能力;LabelsModel:标签集合管理(choice、maxUsages 等);RectangleModel:矩形特有的外观与旋转参数;Validation:声明可控制的标签类型为Image(controlledTags: Types.unionTag(["Image"]));LabelMixin、SelectedModelMixin:子标签(<Label>)选择逻辑;InteractivePromptMixin:支持交互式提示。
二、基础配置示例
最简单的矩形边界框标注配置(来自 rectanglelabels.md):
<View>
<RectangleLabels name="labels" toName="image">
<Label value="Person" />
<Label value="Animal" />
</RectangleLabels>
<Image name="image" value="$image" />
</View>
要点:
name与toName必须一一对应,toName指向下方<Image>标签的name;- 每个
<Label>定义一个可选的语义标签,value会作为rectanglelabels数组中的元素出现在结果中。
仓库自带的真实示例见 image_bbox/config.xml 与 image_bbox_large/config.xml,后者展示了 fillOpacity="0.5"、strokeWidth="5" 以及 <Label background="blue"> 自定义背景色的写法。
三、完整参数说明
以下参数表完整继承自 includes/tags/rectanglelabels.md,并补充源码层面的实现说明:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| name | string |
— | 元素名称,必须唯一 |
| toName | string |
— | 要标注的图像标签名称 |
| [choice] | single | multiple |
single |
是否允许多选标签 |
| [maxUsages] | number |
— | 单个标签在单任务中最多可被使用的次数 |
| [showInline] | boolean |
true |
标签是否在同一视觉行内展示 |
| [opacity] | float |
0.6 |
矩形填充透明度 |
| [fillColor] | string |
— | 矩形填充色(十六进制) |
| [strokeColor] | string |
— | 描边颜色(十六进制) |
| [strokeWidth] | number |
1 |
描边宽度 |
| [canRotate] | boolean |
true |
显示/隐藏旋转控制柄。注意:结果中的锚点与旋转工具的锚点不同 |
| [snap] | pixel | none |
none |
是否将矩形吸附到图像像素网格 |
3.1 choice:单选与多选
choice 决定一个标注区域能绑定一个还是多个标签。在 Labels.jsx 中,该值被建模为枚举 ["single", "multiple"],默认 single。当为 multiple 时,同一矩形可以同时被赋予多个 rectanglelabels 值。
3.2 snap:像素吸附
snap 可取值 pixel 或 none(默认 none)。当开启 pixel 时,矩形绘制、拖拽与变换后,四个角都会被吸附到最近像素上。该逻辑在 RectRegion.jsx 的 setPosition 中实现:先对左上角与右下角调用 control.getSnappedPoint(),再计算吸附后的宽高,并保证吸附后尺寸不小于 1 个像素(zoomedPixelSize);绘制结束时 Rect.js 的 commitDrawingRegion 也会再次应用吸附逻辑。
3.3 外观参数(继承自 RectangleModel)
opacity、fillColor、strokeColor、strokeWidth 直接继承自无标签版 Rectangle 模型的实现(见 Rectangle.js):
- 源码中
opacity默认建模为"0.2",而文档级默认值为0.6,实际以文档与 UI 面板为准,两者用于不同展示场景; strokeColor默认值为#f48a42,fillColor默认同为#f48a42;canRotate默认true,决定是否显示旋转控制柄;- 附加参数
fillOpacity可独立控制填充透明度(见示例配置中的fillOpacity="0.5")。
四、标注结果格式与序列化
RectangleLabels 的每个标注区域(Region)类型为 rectangleregion,在 Registry 中注册(见 RectRegion.jsx)。其序列化结果由 serialize() 方法生成(RectRegion.jsx),格式与文档一致:
4.1 结果参数表
| 名称 | 类型 | 说明 |
|---|---|---|
| original_width | number |
原始图像宽度(px) |
| original_height | number |
原始图像高度(px) |
| image_rotation | number |
图像旋转角度(deg) |
| value | Object |
标注值对象 |
| value.x | number |
旋转前左上角 x 坐标(0-100) |
| value.y | number |
旋转前左上角 y 坐标(0-100) |
| value.width | number |
边界框宽度(0-100) |
| value.height | number |
边界框高度(0-100) |
| value.rotation | number |
边界框旋转角度(deg) |
| value.rectanglelabels | string[] |
该区域绑定的标签数组 |
4.2 示例 JSON
{
"original_width": 1920,
"original_height": 1280,
"image_rotation": 0,
"value": {
"x": 3.1,
"y": 8.2,
"width": 20,
"height": 16,
"rectanglelabels": ["Car"]
}
}
注意:
x、y、width、height均为 0–100 的相对坐标(相对原图宽高的百分比),而非像素值,这样可保证标注在不同分辨率下不失真;rectanglelabels由value中的rectanglelabels字段承载,single模式下通常为单元素数组;- 实际序列化时
original_width、original_height、image_rotation由父级Image对象通过createSerializedResult补充(RectRegion.jsx)。
五、源码级原理解析:矩形区域的坐标与旋转
理解 value 中的坐标需要了解编辑器内部的坐标体系:
5.1 锚点与旋转
标注结果始终以旋转前的左上角 (x, y) 为锚点存储,旋转角度由 value.rotation 单独记录。这与画布上的视觉旋转控制不同:视觉旋转以区域中心为轴,而结果中的锚点是旋转前矩形的左上角,二者在文档中已被明确提示“anchor point 不同”。
5.2 边界框计算与翻转修正
RectRegion.jsx 中的 bboxCoords 计算旋转后的边界范围:当 rotation === 0 时直接返回 {left, top, right, bottom},否则调用 rotateBboxCoords 按图像宽高比换算。对应的单元测试(RectRegion.test.jsx)验证了旋转 0 度与 90 度时的边界正确性。
5.3 绘制与翻转修正(flipBack)
RectRegion 使用 Konva 画布渲染(react-konva 的 <Rect> 组件),当拖拽导致高度为负(翻转)时,beforeSetPosition 会调用 flipBack 修正坐标与旋转,保证最终保存的高度恒为正:
- 垂直翻转:仅翻转高度,保持旋转角;
- 水平翻转:高度变正的同时旋转角加 180°。
(实现见 RectRegion.jsx,测试见 RectRegion.test.jsx。)
5.4 边界约束
draw 过程中若矩形超出画布相对范围(RELATIVE_STAGE_WIDTH/HEIGHT),会回退本次高度变更,避免绘制出界区域(RectRegion.jsx),对应测试覆盖了“bbox 越界时回退高度”的场景。
六、交互工具:两角点与三点画法
RectangleLabels 依赖 Rect 与 Rect3Point 两个画矩形工具(见 Rect.js):
- Rect(两角点):快捷键
tool:rect,从左上角拖到右下角完成绘制; - Rect3Point(三点):快捷键
tool:rect-3point,先画一条边、再拖出高度,适合绘制任意角度的矩形。
两者的 tagTypes.stateTypes 均为 rectanglelabels,controlTagTypes 为 <a href="https://link.gitcode.com/i/f8a622ec24631bb366f6b9e64a256ecf" target="_blank">"rectanglelabels", "rectangle"],即既能服务带标签的 RectangleLabels,也能服务无标签的 Rectangle。绘制完成后会校验 width > MIN_SIZE.X && height > MIN_SIZE.Y 才允许提交,避免产生过小的无效框([Rect.js)。
七、与 Rectangle 标签的区别
| 对比项 | RectangleLabels | Rectangle |
|---|---|---|
| 是否携带标签 | 是,结果含 rectanglelabels 数组 |
否,结果不含标签字段 |
| 适用场景 | 目标检测多类别标注 | 单类别或纯框选 |
| 子标签 | 必须包含 <Label> |
无需子标签 |
| 注册名 | rectanglelabels |
rectangle |
两者共享相同的矩形渲染区域类型(rectangleregion),因此外观参数、旋转与序列化格式完全一致(无标签版结果中不包含 rectanglelabels 字段)。
八、常见问题与注意事项
- 坐标为什么是 0–100 的相对值? 为了保证标注与原始图像分辨率解耦,
x/y/width/height均以原图宽高为基准归一化,还原像素坐标时需要乘以original_width / 100与original_height / 100。 - 旋转后的锚点在哪里? 结果锚点是旋转前矩形的左上角
(x, y),不是旋转后视觉上的左上角;如需计算旋转后边界请参考bboxCoords与rotateBboxCoords的实现。 snap: pixel适合什么场景? 适合需要框严格贴合像素网格的任务(如医疗影像、遥感目标),可避免半像素导致的框位漂移,开启后绘制与拖拽结束都会自动吸附。maxUsages如何生效? 当某个标签的使用次数达到上限后,该标签在画布上不可再被选中,用于约束类别分布(如限制每张图最多标注 5 个 "Person")。
九、深入阅读指引
- 标签定义与参数 JSDoc:RectangleLabels.jsx
- 矩形区域模型与序列化:RectRegion.jsx
- 绘制工具实现:Rect.js
- 无标签版矩形:Rectangle.js
- 模型单元测试(坐标、旋转、翻转、snap):RectRegion.test.jsx
- 可直接运行的配置示例:image_bbox/config.xml、image_bbox_large/config.xml
通过以上配置与源码分析,读者可以精准地使用 RectangleLabels 搭建目标检测标注界面,并准确解读与二次加工标注结果中的矩形坐标与旋转信息。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.24 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python650
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#180
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python52774
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go22545
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java36351
