Label Studio 导出指南:注解与数据的格式、API 与实操详解
【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio
Label Studio 支持在标注项目的任意阶段导出注解(annotations)与数据,导出结果可直接用于训练机器学习模型或数据科学项目。本指南以官方文档为基础,结合仓库源码(label_studio/data_export/、label_studio/tasks/functions.py等)深入讲解 UI 导出、命令行导出、Easy Export API、快照(Snapshot)异步导出、受支持的全部导出格式、原始 JSON 结构以及图像注解单位换算,帮助读者在社区版与企业版中选择最合适的导出路径并规避超时陷阱。
一、导出机制概览:注解存储在哪里
Label Studio 将注解以原始 JSON 格式存储在后端数据库中,包括 SQLite、PostgreSQL,或你指定的云存储与数据库目标存储。云存储桶中每个已标注任务对应一个名为task_id.json的文件。关于目标存储同步的更多说明,参见云存储配置。
从源码看,同步导出的核心调用链位于 data_export/api.py 的ExportAPI.get():先按条件筛选任务并序列化为 JSON 列表,再由 data_export/models.py 的DataExport.generate_export_file()交给label_studio_sdk.converter.Converter完成格式转换。若转换结果只有一个文件则直接返回,否则会打包成 ZIP 归档返回。快照异步导出的核心在 data_export/mixins.py 的export_to_file()与后台任务export_background()。
有一点需要特别注意:部分导出格式只导出注解而不导出任务数据本身,具体见下文"受支持的导出格式"一节。图像注解以 JSON 导出时,边框尺寸与位置使用相对整张图片尺寸的百分比而非像素,换算方法见"图像注解单位换算"。
二、注解结果在 JSON 中的保存方式
每个标注生成的注解(annotation)都包含**区域(Regions)与结果(Results)**两部分:
- Regions指被选中的数据区域,可能是文本片段、图像区域、音频片段或其他实体;
- Results指赋予该区域的标签。
每个区域在每条注解内拥有唯一 ID,由A-Za-z0-9_-字符组成的字符串;每条 result 的 ID 与其对应的区域 ID 相同。当预测(prediction)被用来生成注解时,结果 ID 会保持一致,从而可以追踪模型生成的区域,并与人工创建、审核过的注解直接对比。
Label Studio JSON 格式的注解任务
标注完成后,每个任务的原始 JSON 结构如下(完整字段说明见API 文档与任务格式):
{ "id": 1, "created_at":"2021-03-09T21:52:49.513742Z", "updated_at":"2021-03-09T22:16:08.746926Z", "project":83, "data": { "image": "https://example.com/opensource/label-studio/1.jpg" }, "annotations": [ { "id": "1001", "result": [ { "from_name": "tag", "id": "Dx_aB91ISN", "source": "$image", "to_name": "img", "type": "rectanglelabels", "value": { "height": 10.458911419423693, "rectanglelabels": [ "Moonwalker" ], "rotation": 0, "width": 12.4, "x": 50.8, "y": 5.869797225186766 } } ], "was_cancelled": false, "ground_truth": false, "created_at":"2021-03-09T22:16:08.728353Z", "updated_at":"2021-03-09T22:16:08.728378Z", "lead_time":4.288, "result_count":0, "task":1, "completed_by":10 } ], "predictions": [ { "created_ago": "3 hours", "model_version": "model 1", "result": [ { "from_name": "tag", "id": "t5sp3TyXPo", "source": "$image", "to_name": "img", "type": "rectanglelabels", "value": { "height": 11.612284069097889, "rectanglelabels": [ "Moonwalker" ], "rotation": 0, "width": 39.6, "x": 13.2, "y": 34.702495201535505 } } ] }, { "created_ago": "4 hours", "model_version": "model 2", "result": [ /* ... 结构同上 ... */ ] } ] }关键 JSON 字段说明
| JSON 属性名 | 说明 |
|---|---|
| id | 数据集中的标注任务标识符。 |
| data | 从输入任务格式复制的原始数据,参见任务格式。 |
| project | 该任务所属 Label Studio 项目的标识符。 |
| annotations | 包含该任务标注结果的数组。 |
| annotations.id | 已完成任务的标识符。 |
| annotations.lead_time | 标注该任务所花费的秒数。 |
| annotations.result | 包含标注结果的数组。 |
| annotations.updated_at | 注解创建或修改的时间戳。 |
| annotations.completed_at | 注解创建或提交的时间戳。 |
| annotations.completed_by | 创建注解的用户 ID,与 UI 人员页面上的用户列表顺序一致。 |
| annotations.was_cancelled | 布尔值,表示该注解是否被跳过或取消。 |
| result.id | 该任务下特定标注结果的标识符,可用于将不同控制标签(如<Labels>与<Rectangle>)的区域关联起来。 |
| result.parentID | (可选)父区域 result.id 的引用,用于在 Regions 面板中组织区域的层级树。 |
| result.from_name | 标注该区域所用标签的名称,参见控制标签。 |
| result.to_name | 提供待标注区域的对象标签名称,参见对象标签。 |
| result.type | 用于标注该任务的标签类型。 |
| result.value | 标签相关的值,包含标注结果的细节,其结构取决于标签类型,参见各标签文档。 |
| drafts | 草稿注解数组,结构与 annotations 类似。仅当通过UI 快照导出或快照 API导出时包含。 |
| predictions | 机器学习预测数组,结构与 annotations 相同,但额外带一个参数。 |
| predictions.score | 基于概率输出、置信度或其他指标得到的结果总体得分。 |
| task.updated_at | 任务或其注解/审核被创建、更新或删除的时间戳。 |
导入时指定标注者(completed_by)
在导入注解时,可以通过注解对象中的completed_by字段控制标注者分配:
// 方式 1:不指定标注者(使用导入者) { "result": [...], "completed_by": null } // 方式 2:通过邮箱指定 { "result": [...], "completed_by": { "email": "annotator@example.com" } } // 方式 3:通过 ID 指定 { "result": [...], "completed_by": 42 }系统会将该邮箱或 ID 匹配到组织内已有用户;若配置允许,则回退到导入者。该规则同时适用于通过 UI、API 或 SDK 导入的场景。
企业版补充字段:
annotations.reviews(注解审核详情数组)、reviews.id(审核 ID)、reviews.created_by(审核人的用户 ID、邮箱、姓名等字典信息)、reviews.accepted(布尔值,表示审核人是否接受该注解)。
三、社区版:通过 UI 与命令行导出
通过 UI 导出
在社区版(Community Edition)中,按以下步骤导出数据与注解:
- 在项目中点击Export;
- 选择可用的导出格式;
- 点击Export导出数据。
注意三点:
- 无论标签页上设置了什么过滤器,导出结果始终包含已标注任务;
- 已取消(cancelled)的已标注任务也会包含在导出结果中;
- 若要对导出应用标签页过滤条件,可改用 SDK 创建导出快照。
社区版的导出超时问题
社区版 UI 的导出是同步生成的,作为请求的一部分执行。社区版为保持部署简单,默认不运行后台导出 worker;Label Studio Enterprise 支持后台 worker 的异步快照导出,更适合大规模项目。对于大型项目,社区版导出耗时可能超过反向代理或 ingress 配置的超时时间(通常约90 秒),导致 502/504 错误或导出超时。
遇到该限制时,可选择以下替代方案:
- 使用 SDK 导出快照:见 SDK 导出快照 API;
- 使用控制台命令:在运行 Label Studio 的机器上直接使用下面的控制台命令导出项目;
- 在大规模场景下使用 UI 导出:Label Studio Enterprise 在 UI 中提供后台快照导出(见下文"导出快照")。
从源码可以印证这一点:同步导出 APIExportAPI.get()直接在同一请求内完成查询、序列化、转换与文件响应(data_export/api.py),而快照导出则通过ExportListAPI创建Export记录、由后台任务export_background()异步生成文件(data_export/mixins.py)。
使用控制台命令导出
label-studio export <project-id> <export-format> --export-path=<output-path>启用调试日志:
DEBUG=1 LOG_LEVEL=DEBUG label-studio export <project-id> <export-format> --export-path=<output-path>该子命令由 core/argparser.py 注册,支持project_id、export_format(如 JSON、JSON_MIN、CSV 等)与--export-path参数;--export-serializer-context可用于传入序列化上下文,默认值为{"annotations__completed_by": {"only_id": null}, "interpolate_key_frames": true}。实际执行逻辑位于 tasks/functions.py 的export_project():先校验格式是否受支持,再按每批 1000 个任务批量序列化,最终调用DataExport.generate_export_file()生成文件并写入--export-path(若为目录则追加生成的文件名)。
四、Easy Export API:同步导出
对于小型标注项目,可直接调用导出端点同步导出注解。
导出包含未标注任务在内的全部任务
Label Studio 开源版默认只导出已标注任务。若想轻松导出包括未标注任务在内的全部任务,可在调用 Easy Export API 时带上查询参数download_all_tasks=true。例如:
curl -X GET https://localhost:8080/api/projects/{id}/export?exportType=JSON&download_all_tasks=true对应的同步导出接口为 data_export/urls.py 中的project-export(ExportAPI)。从源码看,ExportAPI.get()中only_finished = not download_all_tasks;当only_finished为真时会执行query.filter(annotations__isnull=False).distinct(),这正是"默认只导出已标注任务"的底层实现(data_export/api.py)。
如果项目很大,通常应改用快照导出以避免超时。快照默认包含所有任务(包括未标注任务)。
五、使用快照 API 导出
对于拥有数十万任务的的大型标注项目,按以下三步操作:
- 向创建新导出文件/快照发起 POST 请求,响应中会包含创建文件的
id; - 使用该
id作为export_pk,检查导出文件的状态; - 仍以该
id作为export_pk,向下载导出文件发起 GET 请求完成下载。
对应的 REST 路由在 data_export/urls.py 中定义:POST /api/projects/{id}/exports/创建快照(ExportListAPI),GET /api/projects/{id}/exports/{export_pk}查看状态(ExportDetailAPI),GET /api/projects/{id}/exports/{export_pk}/download下载文件(ExportDownloadAPI)。
快照模型Export维护了created / in_progress / failed / completed四种状态,并通过FileField存储生成的文件、记录md5与counters元数据(data_export/models.py)。快照文件名默认由get_default_title()生成,格式为PROJECT-NAME-at-YEAR-MM-DD-HH-MM(UTC 时间)。
六、导出快照(Snapshot)异步导出(企业版)
在 Label Studio Enterprise 中,可以创建数据与注解的快照,按需精确导出标注项目中想要的内容。这种延迟导出方式更适合从 UI 导出大型标注项目。
- 在项目的 Label Studio UI 中点击Export;
- 点击Create New Snapshot;
- Apply filters from tab ...:从下拉列表中选择Default;
- (可选)Snapshot Name:输入快照名称便于日后查找。默认快照命名为
PROJECT-NAME-at-YEAR-MM-DD-HH-MM,时间为 UTC; - Include in the Snapshot…:选择要包含的数据类型:All tasks(全部任务)、Only annotated(仅已标注)或Only reviewed(仅已审核);
- Drafts:选择导出完整草稿注解(Complete drafts)还是仅导出草稿注解的 ID(Only IDs,仅标记存在草稿);
- Predictions:选择导出完整预测(Complete predictions)还是仅导出预测 ID(Only IDs,仅标记任务存在预测);
- Annotations:启用要导出的注解类型,可指定Annotations(普通注解)、Ground Truth与Skipped(跳过的注解)。默认只导出普通注解;
- (可选)启用Remove user details移除用户详细信息;
- 点击Create a Snapshot开始导出;
- 在快照列表中可以看到可下载的快照,以及其中包含的内容、创建时间与创建者信息;
- 点击Download并选择导出格式,快照文件即下载到本地。
从源码看,快照导出支持丰富的过滤选项:_get_filtered_tasks()支持按 tab 视图(view)、跳过(skipped)、完成(finished)与已标注(annotated)过滤任务(data_export/mixins.py);_get_filtered_annotations_queryset()支持按普通注解、Ground Truth、跳过的注解取并集过滤(data_export/mixins.py);序列化选项则控制草稿、预测、completed_by是否展开,以及是否插值视频关键帧、是否下载资源(data_export/mixins.py)。
七、受支持的导出格式
Label Studio 支持多种通用与标准格式导出已完成的标注任务。如果缺少你需要的格式,还可以为项目贡献一种。更多信息参见 Label Studio SDK 仓库中的 Converter 工具。
格式支持的实际判定发生在 data_export/models.py 的DataExport.get_export_formats():它基于项目解析后的标签配置创建Converter,将converter.supported_formats中不支持的格式标记为disabled(在 UI 中置灰),企业版启用自定义界面时还会额外加入DOCLANG格式。
ASR_MANIFEST
将自动语音识别的音频转写标签导出为 NVIDIA NeMo 模型期望的 JSON manifest 格式。适用于使用Audio标签配合TextArea标签的音频转写项目。
{"audio_filepath": "/path/to/audio.wav", "text": "the transcription", "offset": 301.75, "duration": 0.82, "utt": "utterance_id", "ctm_utt": "en_4156", "side": "A"}Brush labels to NumPy and PNG
将画笔遮罩标签导出为 NumPy 二维数组与 PNG 图片。每个标签输出为一张图片。适用于使用BrushLabels标签的画笔标注图像项目。
COCO
COCO 数据集常用的机器学习格式,用于目标检测与图像分割任务。适用于使用BrushLabels、RectangleLabels、KeyPointLabels(见下方说明)或PolygonLabels标签的边界框与多边形图像标注项目。
KeyPointLabels 导出支持:如果使用KeyPointLabels,需要在标注配置中添加以下内容:
- 至少一个
<RectangleLabels>选项,作为关键点的父边界框; - 在
<KeyPointLabels>内的每个<Label>上添加model_index,该值定义输出数组中关键点坐标的顺序(供 YOLO 使用)。
例如:
<View> <Image name="image" value="$image"/> <KeyPointLabels name="kp" toName="image"> <Label value="nose" model_index="0"/> <Label value="eye" model_index="1"/> <Label value="tail" model_index="2"/> </KeyPointLabels> <RectangleLabels name="bbox" toName="image"> <Label value="animal"/> </RectangleLabels> </View>标注完成后,必须在Regions面板中将每个关键点区域拖放到其对应的矩形区域下方,从而通过parentID建立父子层级关系,这是导出所必需的(见上图与下方导出示例)。
导出示例
Keypoints in JSON:
[ { "id": "17n06ubOJs", "type": "keypointlabels", "value": { "x": 6.675567423230974, "y": 20.597014925373134, "width": 0.26702269692923897, "keypointlabels": ["nose"] }, "origin": "manual", "to_name": "image", "parentID": "QHG4TBXuNC", "from_name": "kp", "image_rotation": 0, "original_width": 200, "original_height": 179 }, { "id": "QHG4TBXuNC", "type": "rectanglelabels", "value": { "x": 3.871829105473965, "y": 4.029850746268656, "width": 94.39252336448598, "height": 92.08955223880598, "rotation": 0, "rectanglelabels": ["animal"] }, "origin": "manual", "to_name": "image", "from_name": "bbox", "image_rotation": 0, "original_width": 200, "original_height": 179 } ]Keypoints in COCO:
[ { "id": 0, "image_id": 0, "category_id": 0, "segmentation": [], "bbox": [7.74365821094793, 7.213432835820895, 188.78504672897196, 164.84029850746268], "ignore": 0, "iscrowd": 0, "area": 31119.38345654903 }, { "id": 1, "image_id": 0, "category_id": 0, "keypoints": [13, 37, 2, 33, 33, 2, 167, 24, 2], "num_keypoints": 3, "bbox": [13, 24, 154, 13], "iscrowd": 0 } ]Keypoints in YOLO:
0 0.5106809078771696 0.5007462686567165 0.9439252336448598 0.9208955223880598 0.06675567423230974 0.20597014925373133 2 0.1628838451268358 0.18507462686567164 2 0.8371161548731643 0.13134328358208955 2CoNLL2003
CoNLL-2003 命名实体识别挑战赛常用格式。适用于使用Text与Labels标签的文本标注项目。
CSV
结果以逗号分隔值存储,列名由标注配置中"from_name"与"to_name"字段的值决定。支持所有项目类型。
JSON
以原始 JSON 格式存储在一个 JSON 文件中的条目列表。适合同时导出数据集的数据与注解。支持所有项目类型。
JSON_MIN
仅导出原始 JSON 格式中"from_name"、"to_name"值的条目列表。适合导出数据集的数据与注解,且不包含 Label Studio 特有字段。支持所有项目类型。
例如:
{ "image": "https://htx-pub.s3.us-east-1.amazonaws.com/examples/images/nick-owuor-astro-nic-visuals-wDifg5xc9Z4-unsplash.jpg", "tag": [{ "height": 10.458911419423693, "rectanglelabels": ["Moonwalker"], "rotation": 0, "width": 12.4, "x": 50.8, "y": 5.869797225186766 }] }Pascal VOC XML
用于目标检测与图像分割任务的流行 XML 格式。适用于使用RectangleLabels标签的边界框图像标注项目。
spaCy
Label Studio 不支持直接导出为 spaCy 二进制格式,但可以将导出的注解转换为与 spaCy 兼容的格式。进行此转换前必须安装 spacy Python 包。
转换步骤:
先将注解导出为 CONLL2003 格式;
打开下载的文件,在第一行添加
O:-DOCSTART- -X- O O在命令行运行
spacy convert,将 CoNLL 格式注解转换为 spaCy 二进制格式(将/path/to/<filename>替换为注解文件的路径与文件名):spaCy 2.x:
spacy convert /path/to/<filename>.conll -c nerspaCy 3.x:
spacy convert /path/to/<filename>.conll -c conll .
更多信息参见 spaCy 文档中关于 Converting existing corpora and annotations 运行spacy convert的说明。
TSV
结果存储在制表符分隔的表格文件中,列名由标注配置中的"from_name"与"to_name"值决定。支持所有项目类型。
YOLO
以 YOLOv3 与 YOLOv4 格式导出目标检测注解。适用于使用RectangleLabels与KeyPointLabels标签的目标检测项目。
如果使用 KeyPointLabels,请参见 COCO 小节下的说明。
八、图像注解单位换算
图像注解中x, y, width, height的单位是占整体图像尺寸的百分比。使用以下换算公式:
pixel_x = x / 100.0 * original_width pixel_y = y / 100.0 * original_height pixel_width = width / 100.0 * original_width pixel_height = height / 100.0 * original_height完整示例(含双向换算):
task = { "annotations": [{ "result": [ { "...": "...", "original_width": 600, "original_height": 403, "image_rotation": 0, "value": { "x": 5.33, "y": 23.57, "width": 29.16, "height": 31.26, "rotation": 0, "rectanglelabels": ["Airplane"] } } ] }] } # 从 LS 百分比单位转换为像素 def convert_from_ls(result): if 'original_width' not in result or 'original_height' not in result: return None value = result['value'] w, h = result['original_width'], result['original_height'] if all([key in value for key in ['x', 'y', 'width', 'height']]): return w * value['x'] / 100.0, \ h * value['y'] / 100.0, \ w * value['width'] / 100.0, \ h * value['height'] / 100.0 # 从像素转换为 LS 百分比单位 def convert_to_ls(x, y, width, height, original_width, original_height): return x / original_width * 100.0, y / original_height * 100.0, \ width / original_width * 100.0, height / original_height * 100 # 从 LS 转换 output = convert_from_ls(task['annotations'][0]['result'][0]) if output is None: raise Exception('Wrong convert') pixel_x, pixel_y, pixel_width, pixel_height = output print(pixel_x, pixel_y, pixel_width, pixel_height) # 转换回 LS x, y, width, height = convert_to_ls(pixel_x, pixel_y, pixel_width, pixel_height, 600, 403) print(x, y, width, height)注意:只有当 result 中包含original_width与original_height时才能完成换算,因此请确保这些字段存在于导出的 JSON 中。
九、手动将 JSON 注解转换为其他格式
可以通过命令行或 Python,在已完成 JSON 注解的目录或文件上运行 Label Studio converter 工具,将 Label Studio JSON 格式的注解转换为其他格式。
如果使用早于 1.0.0 的 Label Studio 版本,这是将 Label Studio JSON 注解转换为其他标注格式的唯一方式。
在仓库中,Converter 正是同步/快照导出链路里实际执行格式转换的组件:DataExport.generate_export_file()通过Converter(config=project.get_parsed_config(), ...)加载项目标签配置,在临时目录中调用converter.convert(input_json, tmp_dir, output_format, is_dir=False)完成转换(data_export/models.py)。
十、在 Label Studio 之外访问任务数据(供 ML 后端使用)
机器学习后端需要使用任务中的数据生成预测,因此需要在 ML 后端侧下载这些资源。Label Studio 提供了下载工具,位于label-studio-toolsPython 包中。如果使用官方 Label Studio Machine Learning 后端,label-studio-tools会随其他依赖自动安装。
从 Label Studio 实例访问任务数据
Label Studio 中存储任务资源(图像、音频、文本等)的方式有以下几种:
- 云存储(Cloud storages)
- 外部网页链接(External web links)
- 上传的文件(Uploaded files)
- 本地文件目录(Local files directory)
Label Studio 以上传文件时按项目级别组织目录结构,每个项目拥有独立的文件文件夹。
可以使用label_studio_tools.core.utils.io.get_local_path获取任务数据——它会将任务数据中的路径或 URL 转换为本地路径。对于本地路径会返回完整本地路径;使用download_resources参数时会下载资源。访问外部资源时需要提供Hostname与access_token。
在 Label Studio 实例之外访问任务数据
同样可以使用label_studio_tools.core.utils.io.get_local_path方法,从外部机器获取外部链接与云存储中的数据。
重要:不要忘记提供凭证(credentials)。
如果在外部机器上挂载了相同的磁盘,也可以直接使用get_local_path获取数据。另一种访问方式是利用任务中的链接与 ACCESS_TOKEN(参见认证文档):拼接 Label Studio 主机名与任务数据中的链接,然后在请求中加入访问令牌:
curl -X GET http://localhost:8080/api/projects/ -H 'Authorization: Token {YOUR_TOKEN}'十一、常见问题(FAQ)
问题 1:请求返回了以下 API 响应
- 没有提供任何数据(No data was provided);
- 返回了 404 或 403 错误码。
解答:首先检查发送 API 请求时与 Label Studio 实例之间的网络连通性。可以使用示例数据执行测试 curl 请求来验证。
问题 2:访问文件时收到FileNotFound错误
解答:
- 确认已挂载与 Label Studio 实例相同的磁盘,并先在 Label Studio 实例中确认文件存在;
- 检查 Label Studio 实例中的
LOCAL_FILES_DOCUMENT_ROOT环境变量,并在访问数据的脚本中添加该变量。
问题 3:如何修改 COCO 与 YOLO 导出中类别的顺序
标签默认按字母顺序排序。如需修改,请在<Label>中添加category属性来改变行为。例如:
<Label value="abc" category="1" /> <Label value="def" category="2" />十二、延伸阅读
- 云存储配置:目标存储同步与云存储桶中的
task_id.json文件 - API 参考:认证方式与导出相关端点的完整说明
- 访问令牌:ML 后端与外部脚本访问任务数据所需的认证
- 任务格式:输入任务的 JSON 格式
- 标注界面与标签文档:各控制标签与对象标签的
from_name/to_name语义 - SDK 导出快照 API:以编程方式创建、查询与下载快照
【免费下载链接】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),仅供参考