3、常见标注格式详解(上):COCO JSON格式(目标检测)、LabelMe JSON格式
好,咱们今天来啃两块硬骨头——COCO JSON 和 LabelMe JSON。
这两个格式,做目标检测的朋友肯定不陌生。我个人习惯把 COCO 格式称为「工业标准」,而 LabelMe 更像是「个人作坊」的产物。为什么这么说?往下看你就明白了。
3.1 COCO JSON 格式:目标检测的「通用语言」
先聊聊 COCO。这个格式最早来自微软的 COCO 数据集,后来慢慢成了目标检测、实例分割领域的通用格式。说白了,你训练 YOLO、Mask R-CNN、Detectron2 这些模型,最后导出标注时,十有八九会碰到它。
3.1.1 整体结构长什么样?
COCO JSON 是一个大的字典,里面包含几个关键字段。我直接给你看一个简化版的结构:
{
"images": [
{
"id": 1,
"file_name": "img_001.jpg",
"width": 1920,
"height": 1080
}
],
"annotations": [
{
"id": 1,
"image_id": 1,
"category_id": 2,
"bbox": [100, 150, 200, 300],
"area": 60000,
"iscrowd": 0
}
],
"categories": [
{
"id": 1,
"name": "person"
},
{
"id": 2,
"name": "car"
}
]
}
嗯,这里要注意:bbox 的格式是 [x, y, width, height],不是 [x1, y1, x2, y2]。我刚开始做标注时,就因为这个搞混过,结果模型训练出来检测框全偏了……
3.1.2 三个核心字段详解
| 字段 | 作用 | 关键点 |
|---|---|---|
| images | 记录每张图片的元信息 | id 必须唯一,file_name 建议用相对路径 |
| annotations | 存储每个标注框的数据 | bbox 是 [x,y,w,h],area 可以手动算 |
| categories | 定义类别列表 | id 从 1 开始,不要用 0 |
3.1.3 避坑指南:bbox 和 area
我曾经在导出 COCO 格式时,把 bbox 写成了 [x1, y1, x2, y2]。结果呢?模型训练出来的检测框全跑到图片外面去了。排查了半天才发现是格式问题。
还有 area 字段。很多人觉得它不重要,随便填个 0。但如果你用 COCO 的评估工具(比如 cocoapi),area 会影响小目标、中目标、大目标的统计。我建议你老老实实算一下:area = width * height。
3.2 LabelMe JSON 格式:多边形标注的「老朋友」
LabelMe 是 MIT 开发的一个标注工具,它的 JSON 格式和 COCO 完全不同。我个人觉得,LabelMe 更适合做语义分割或实例分割的标注,因为它天然支持多边形。
3.2.1 结构长什么样?
LabelMe JSON 是每张图片一个 JSON 文件。不像 COCO 把所有图片的标注塞到一个大文件里。来看个例子:
{
"version": "5.0.1",
"flags": {},
"shapes": [
{
"label": "car",
"points": [
[120, 150],
[200, 150],
[200, 300],
[120, 300]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
}
],
"imagePath": "img_001.jpg",
"imageData": null,
"imageHeight": 1080,
"imageWidth": 1920
}
你想想看,这里最核心的是 shapes 数组。每个 shape 就是一个标注对象,points 是多边形的顶点坐标。如果是矩形,shape_type 可以写成 rectangle,但一般建议统一用 polygon。
3.2.2 和 COCO 的关键区别
| 对比项 | COCO JSON | LabelMe JSON |
|---|---|---|
| 文件组织 | 所有图片一个文件 | 每张图片一个文件 |
| 标注形状 | 矩形框 (bbox) | 多边形 (polygon) |
| 坐标格式 | [x, y, w, h] | [[x1,y1], [x2,y2], ...] |
| 适用场景 | 目标检测、实例分割 | 语义分割、实例分割 |
imageData 字段有时会包含 base64 编码的图片数据。如果你导出时不需要,记得设为 null,不然 JSON 文件会变得巨大。我见过一个标注文件因为带了图片数据,直接飙到 50MB……
3.3 两种格式的转换思路
实际项目中,你经常需要在 COCO 和 LabelMe 之间来回转换。比如你用 LabelMe 标注了数据,但训练模型时要用 COCO 格式。怎么办?
我一般这样处理:
- LabelMe → COCO: 遍历所有 LabelMe JSON,把
shapes里的多边形转成 bbox(取最小外接矩形),然后合并到一个大 JSON 里。 - COCO → LabelMe: 把 COCO 的
annotations拆开,每个bbox转成四个点的多边形,生成独立的 JSON 文件。
核心逻辑: 转换的本质就是「坐标格式的映射」和「文件结构的重组」。别被复杂的字段吓到,抓住这两个核心,你就能写出通用的转换脚本。
3.4 本章小结
COCO JSON 和 LabelMe JSON,一个适合大规模数据集,一个适合灵活标注。我个人建议:
- 如果你做目标检测,优先用 COCO 格式。
- 如果你做分割任务,或者标注工具是 LabelMe,那就用 LabelMe 格式。
- 不管用哪种,一定要写一个验证脚本,检查坐标、类别 id 是否正确。
嗯,今天就先聊到这儿。这两种格式搞明白了,后面再讲其他格式(比如 YOLO、Pascal VOC)就轻松多了。