Labelme标注实例分割数据时,如何避免‘一个物体多个ID’的坑?我的COCO格式生成实战记录

张开发
2026/4/19 23:19:23 15 分钟阅读

分享文章

Labelme标注实例分割数据时,如何避免‘一个物体多个ID’的坑?我的COCO格式生成实战记录
Labelme实例分割标注实战如何精准区分同类物体的独立ID第一次用Labelme标注一堆苹果时我盯着生成的COCO格式json文件愣住了——明明标注了5个苹果为什么模型训练时只识别出3个翻看annotations字段才发现有2个苹果被系统误判为同一实例。这种一个物体多个ID或多个物体共享ID的问题正是实例分割标注中最隐蔽的坑。1. 实例分割标注的核心逻辑解析在计算机视觉领域语义分割和实例分割常被混淆但两者的数据标注逻辑有本质差异。语义分割只需区分类别比如把所有苹果标记为同一标签而实例分割要求每个物体都有独立身份每个苹果需要唯一ID。这种差异直接影响Labelme的操作方式语义分割同类别物体使用相同label和相同多边形组实例分割同类别物体使用相同label但不同group_id实际操作中Labelme通过group_id字段区分实例。当保存json文件时相同group_id的多个多边形会被合并为一个实例。这就是为什么新手标注时如果不主动设置group_id系统可能自动将相邻的相似物体合并。注意Labelme界面默认不显示group_id设置选项需要通过右键菜单操作2. Labelme标注避坑操作指南2.1 标注前的关键设置在开始标注前建议先进行这些配置启用高级选项Linux/Mac用户可添加--flags参数启动Labelme在Preferences中勾选Auto save和Keep previous annotation准备labels.txt文件时确保包含这两行__ignore__ _background_ apple2.2 多实例标注标准流程以标注5个苹果为例正确操作顺序应该是右键点击第一个苹果区域选择Create Polygon绘制完轮廓后在弹出窗口中输入label如apple关键步骤右键已标注区域 →Edit Polygons→ 设置group_id为1重复上述步骤标注第二个苹果设置group_id为2保存时生成的json文件应包含类似结构shapes: [ { label: apple, group_id: 1, points: [[x1,y1],[x2,y2],...] }, { label: apple, group_id: 2, points: [[x1,y1],[x2,y2],...] } ]2.3 常见错误排查表错误现象可能原因解决方案多个物体被合并未设置或重复group_id为每个实例分配唯一group_id转换后ID丢失使用了不支持group_id的转换脚本使用labelme2coco.py最新版边缘区域识别错误多边形闭合不精确放大图像检查锚点连接小物体被忽略iscrowd参数误设确保单个物体iscrowd03. COCO格式转换的深度验证3.1 转换命令的正确姿势使用官方示例中的转换脚本时建议添加--noviz参数避免可视化步骤干扰python labelme2coco.py input_dir output_dir --labels labels.txt --noviz3.2 关键字段解析转换后的annotations.json应包含这些核心字段{ images: [...], annotations: [ { id: 1, // 标注ID image_id: 1, // 对应图片ID category_id: 1, // 类别ID segmentation: [[x1,y1,x2,y2,...]], // 多边形坐标 area: 256.5, // 区域面积 bbox: [x,y,width,height], // 外接矩形 iscrowd: 0 // 是否群体标注 } ], categories: [ { id: 1, name: apple, supercategory: fruit } ] }特别注意每个annotation.id应该唯一相同category_id对应相同物体类别iscrowd1会触发特殊处理逻辑适用于密集小物体3.3 验证转换结果的三种方法可视化检查from pycocotools.coco import COCO import matplotlib.pyplot as plt coco COCO(annotations.json) plt.imshow(coco.loadImgs(1)[0][image]) coco.showAnns(coco.loadAnns(coco.getAnnIds(imgIds1)))ID一致性检查python -c import json;djson.load(open(annotations.json));print(len([a for a in d[annotations] if a[category_id]1]))框架兼容性测试# MMDetection测试代码片段 from mmdet.datasets import build_dataset cfg dict( typeCocoDataset, ann_fileannotations.json, ... ) dataset build_dataset(cfg) print(f成功加载{len(dataset)}个实例)4. 复杂场景的进阶处理技巧当遇到重叠物体、遮挡情况时需要特殊处理4.1 遮挡物体标注规范被遮挡部分按实际可见轮廓标注为每个可见部分分配相同group_id在attributes字段添加occludedtrue4.2 密集小物体优化方案对于成群的相似小物体如葡萄串整体标注为一个大多边形设置iscrowd1或使用--keep-ratio参数保持原始比例在categories中添加supercategory层级4.3 多标签协同标注需要同时标注类别和属性时使用Labelme的flags参数启动labelme --flags flags.txtflags.txt内容示例ripe unripe damaged标注时可在label后附加属性appleripe5. 工程化实践建议在实际项目中我们还需要考虑版本控制建议将原始Labelme json与转换后的COCO格式分开存放增量标注使用--append参数避免重复转换质量检查编写自动化脚本验证def check_annotation(ann_file): coco COCO(ann_file) for img_id in coco.getImgIds(): anns coco.loadAnns(coco.getAnnIds(imgIdsimg_id)) groups set(a[group_id] for a in anns if group_id in a) if len(groups) ! len(anns): print(fImage {img_id} has ID conflict)标注过程中发现使用CtrlZ撤销操作时Labelme有时会重置group_id。稳妥的做法是标注完每个实例后立即检查json文件中的对应字段。

更多文章