恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
labelme标注工具全流程实战:安装配置、五种标注模式与JSON格式转换
首页
资讯中心
/
labelme标注工具全流程实战:安装配置、五种标注模式与JSON格式转换
labelme标注工具全流程实战:安装配置、五种标注模式与JSON格式转换
发布时间:2026/10/14 17:14:13
1. 为什么标注工具选型阶段就该把labelme放进候选清单做视觉方向的数据标注绕不开一个核心矛盾标注效率和数据质量往往互相拉扯。商业标注平台功能全但数据要上传到别人的服务器很多做医疗影像、工业质检、遥感解译的团队根本不敢这么干纯自研标注工具又太费人力一个能画多边形、能存JSON、能回显标注结果的界面从零写出来少说两周。labelme恰好卡在中间——开源、本地运行、跨平台、支持多边形/矩形/圆形/线段/点五种标注形态而且标注结果直接落成JSON后续转COCO、VOC、YOLO格式都有现成脚本。我最早接触labelme是在一个语义分割项目里当时需要标注一批道路裂缝图像裂缝形状极不规则矩形框根本框不住必须用多边形逐点描边。试过几个在线工具要么免费版限制导出次数要么多边形编辑手感极差拖一个顶点整个形状都跟着变形。后来换成labelme虽然界面朴素得像上个时代的软件但多边形编辑的交互逻辑非常扎实——单击加点、拖拽移动、右键删除、快捷键切换用顺手之后标注速度反而比花哨的在线工具快。这篇内容面向三类人刚入门计算机视觉、需要自己标数据的学生和初级工程师做垂直领域项目、对数据隐私有要求、想在内网部署标注环境的开发者以及已经用过labelme但总觉得“能用但不好用”、想系统梳理一遍配置和技巧的老用户。我会从安装环节的坑开始讲把每种标注模式的操作逻辑拆开再重点说JSON格式的字段含义和批量转换的实操方案最后分享几个我踩过坑之后总结出来的效率技巧。全程基于实际项目经验不堆砌官方文档里能查到的内容只讲真正影响你标注效率和结果质量的东西。2. 安装环节的三种路径与各自暗坑2.1 pip安装最省事但最容易踩版本坑绝大多数人第一次装labelme都是直接pip install labelme这条命令本身没问题但坑在于Python版本和依赖库的兼容性。labelme依赖PyQt5做界面而PyQt5对Python版本相当挑剔。我实测下来Python 3.8到3.10是最稳的区间3.11以上偶尔会出现PyQt5.sip相关的导入错误3.7以下则可能遇到numpy版本冲突。如果你用的是Anaconda建议单独建一个虚拟环境别在base环境里直接装。原因很简单labelme会锁定一批依赖版本比如numpy、Pillow、scikit-image这些库你在其他项目里可能已经装了不同版本直接装在base环境里很容易把别的项目搞崩。建环境的命令很直接conda create -n labelme_env python3.9 conda activate labelme_env pip install labelme装完之后在终端敲labelme如果界面能弹出来就说明成功了。如果报ModuleNotFoundError: No module named PyQt5大概率是pip装的时候PyQt5没装上手动补一句pip install PyQt55.15.9通常能解决。这里特别提醒一点不要用pip install labelme --upgrade去追最新版labelme的更新频率不高但偶尔新版本会引入一些界面上的小改动如果你跟着教程操作却发现按钮位置对不上八成是版本差异。我一般会锁定一个已知稳定的版本比如pip install labelme5.4.1这样团队里所有人环境一致避免“我这能跑你那不能跑”的扯皮。2.2 源码安装需要改代码时的必经之路有些场景下你必须走源码安装比如你想改标注界面的默认颜色、想加一个自定义的快捷键、想把标注结果直接存成别的格式。这时候pip装的那个包是编译好的你改不了源码只能从仓库克隆下来手动装。源码安装的步骤不复杂但有一个细节很多人忽略——依赖安装的顺序。正确的做法是先装PyQt5再装labelme的其他依赖最后以开发模式安装labelme本身git clone https://github.com/wkentaro/labelme.git cd labelme pip install PyQt55.15.9 pip install -e .pip install -e .这个-e参数是关键它表示“可编辑安装”你改了源码之后不用重新安装直接重启labelme就能生效。如果你不加-e那改完代码还得重新pip install .一遍调试效率极低。源码安装最容易出的问题是setuptools版本太老导致pip install -e .报setup.py相关的语法错误。解决办法是先升级setuptools和wheelpip install --upgrade setuptools wheel还有一个坑是Windows系统上路径里有中文或空格pip install -e .有时候会解析失败。把labelme克隆到一个纯英文、无空格的路径下比如D:\projects\labelme能避开这个问题。2.3 独立可执行文件不装Python也能用如果你只是偶尔标一批数据不想在电脑上折腾Python环境labelme官方提供了打包好的可执行文件。Windows下是一个exemacOS下是一个app下载下来双击就能用。这种方式最大的好处是零配置坏处是版本固定而且没法用命令行批量转换脚本——你只能用界面标注转换格式得另外找工具。我一般不建议长期做标注的人用这种方式因为标注到后期一定会遇到“批量把JSON转成掩码图”的需求这时候还是得有Python环境。但如果你是产品经理或者算法工程师只是想快速标几十张图验证一下想法独立可执行文件是最省时间的路径。注意无论用哪种方式安装第一次启动labelme时它都会自动创建一个配置文件路径在用户目录下的.labelme文件夹里。这个文件里记录了上次打开的目录、窗口大小、默认标注类型等信息。如果你发现labelme的界面行为异常比如每次打开都跳到某个不存在的路径可以把这个配置文件删掉重启labelme会重新生成一份默认配置。3. 五种标注模式的操作逻辑与适用场景3.1 多边形标注不规则目标的唯一正解多边形是labelme里最核心也最常用的标注模式快捷键是CtrlN有些版本是直接点左侧工具栏的Polygon按钮。操作逻辑是在目标边缘依次单击左键打点点与点之间自动连线围成一圈之后按回车闭合然后输入类别名称。这里有几个决定标注效率的细节。第一打点的时候不用追求一次到位先把大致轮廓勾出来闭合之后再微调顶点位置。labelme允许你拖动任意一个顶点也允许在边上双击新增顶点。我见过新手标注时一个点一个点地抠标一张图花五分钟其实先粗勾再精修同样的精度能省一半时间。第二闭合多边形时按回车和双击左键效果一样但回车更稳因为双击有时候会被识别成“新增顶点”而不是“闭合”。第三如果标到一半发现点打错了按CtrlZ可以撤销上一个点不用全部重来。第四标注完成后如果发现类别名打错了不用删掉重标双击标注区域就能重新编辑标签。多边形标注最典型的应用场景是语义分割和实例分割。语义分割里同一类别的所有像素归为一类多边形只需要把该类别的区域圈出来实例分割则要求每个个体单独一个多边形比如一张图里有三辆车就得标三个多边形每个都叫“car”。这个区别在标注前一定要和算法同学确认清楚标错了返工成本极高。3.2 矩形与圆形快速框选与规则目标矩形标注的快捷键是CtrlR操作就是拖拽出一个框松手后输入标签。这是最省事的标注方式适合目标检测任务也适合作为多边形标注的“预标注”——先用矩形快速框出所有目标再对需要精细分割的目标逐个转成多边形。圆形标注快捷键是CtrlE拖拽出一个椭圆适合标注圆形目标比如细胞、气泡、圆形零件。但要注意labelme的圆形标注实际存储的是一个椭圆参数中心点、长短轴、旋转角如果你的下游任务需要精确的圆形掩码转换脚本里得自己处理这个参数。矩形和圆形在实际项目里经常配合使用。我做过一个工业零件缺陷检测的项目缺陷分两类一类是划痕形状细长不规则必须用多边形另一类是凹坑近似圆形用圆形标注快得多。标注规范里明确写了“划痕用多边形凹坑用圆形”标注员按规则执行效率比全部用多边形高了将近40%。3.3 线段与点关键点检测和车道线标注线段标注CtrlL适合标注车道线、裂缝走向、血管中心线这类“有方向但无宽度”的目标。操作是单击起点、单击终点两点确定一条线段。点标注CtrlP则是单击一下打一个点适合关键点检测比如人脸的五官关键点、人体的关节位置。这两种模式在labelme里用得相对少但特定场景下不可替代。我做过一个车道线检测的数据集用线段标注比用多边形快很多因为车道线本身宽度就几个像素用多边形去描边纯属浪费精力。关键点标注则要注意顺序——同一个类别的关键点在所有图片里的标注顺序必须一致否则训练时关键点索引对不上模型学出来的东西完全是乱的。3.4 标注模式的切换与混合使用labelme允许在同一张图里混合使用多种标注模式。比如一张街景图可以用矩形框出所有车辆用多边形标出人行道区域用线段标出车道线用点标出交通标志的中心位置。所有标注结果都存在同一个JSON文件里每个标注对象有自己的shape_type字段来区分。混合标注时有一个容易忽略的点不同标注模式的快捷键会互相干扰。比如你正在画多边形突然想切到矩形直接按CtrlR有时候不会立即生效得先按Esc退出当前标注状态。这个交互逻辑在官方文档里没写清楚我是被卡了好几次才摸出来的。4. JSON文件里到底存了什么字段逐项拆解4.1 顶层结构与版本字段labelme保存的JSON文件结构非常清晰顶层就几个关键字段{ version: 5.4.1, flags: {}, shapes: [], imagePath: example.jpg, imageData: null, imageHeight: 1080, imageWidth: 1920 }version字段记录的是标注时使用的labelme版本号。这个字段看起来不起眼但在团队协作里很重要——如果标注员用的版本和转换脚本假设的版本不一致某些字段的命名可能有细微差异。我一般要求团队统一版本并且在标注规范文档里写明版本号。flags字段用于存储图像级别的额外信息默认是空对象。你可以通过界面上的“Flags”按钮添加键值对比如{reviewed: true, quality: high}。这个功能在多人协作标注时很有用可以用来标记哪些图已经复核过、哪些图有争议需要讨论。imageData字段默认是null表示JSON文件里不存图像本身的二进制数据只存图像路径。这样做的好处是JSON文件很小几百张图的标注文件加起来可能就几MB。但坏处是JSON文件和图像文件必须保持相对路径关系如果你把JSON文件单独拷到别的地方imagePath就失效了。labelme在打开JSON时会尝试根据imagePath去找原图找不到就会报错。4.2 shapes数组每个标注对象的完整描述shapes是JSON文件里最核心的字段它是一个数组每个元素代表一个标注对象{ label: cat, points: [[100, 200], [150, 180], [200, 220]], group_id: null, shape_type: polygon, flags: {} }label是类别名称必须和你的标注规范里定义的类别完全一致大小写敏感。我见过有人一会儿写“Person”一会儿写“person”导致转换脚本里类别映射对不上白白浪费半天排查时间。points是标注点的坐标数组每个点是[x, y]格式单位是像素。对于矩形标注points只有两个点左上角和右下角对于圆形points也是两个点第一个是圆心第二个是圆周上的一点对于线段两个点分别是起点和终点对于点标注只有一个点。shape_type标识标注类型取值有polygon、rectangle、circle、line、point五种。转换脚本里必须根据这个字段做分支处理不能假设所有标注都是多边形。group_id用于把多个标注对象编成一组。比如标注一个人的时候身体用多边形、头部用矩形可以把它们设成同一个group_id表示它们属于同一个实例。这个字段在实例分割里很有用但labelme界面上设置group_id的操作比较隐蔽需要右键标注对象才能找到。4.3 坐标系的坑原点在左上角labelme使用的坐标系是图像坐标系原点在左上角x轴向右y轴向下。这和数学里常用的笛卡尔坐标系原点在左下角y轴向上是反的。如果你在转换脚本里直接把坐标喂给某些可视化库可能会发现标注框上下颠倒。这个坑我在第一次做标注可视化时踩过。当时用matplotlib画标注框出来的结果和原图完全对不上排查了半天才发现是y轴方向的问题。解决办法很简单要么在可视化时把y轴反转plt.gca().invert_yaxis()要么在转换坐标时做一次y_new image_height - y_old的变换。但要注意如果你的下游任务比如COCO格式也使用左上角原点那就不需要变换直接透传即可。5. 从JSON到训练格式批量转换的实操方案5.1 转COCO格式实例分割的标准路径COCO格式是实例分割最通用的格式labelme官方提供了一个转换脚本labelme2coco.py但那个脚本功能比较基础实际项目里往往需要自己改。核心逻辑是遍历所有JSON文件把每个标注对象转成COCO的annotation结构。转换过程中有几个关键点。第一类别ID的映射必须固定。COCO格式要求每个类别有一个唯一的整数ID从1开始0通常留给背景。我一般会在转换脚本里维护一个category_map字典把所有类别名映射到固定ID并且把这个映射关系存成单独的文件训练和推理时都用同一份。第二iscrowd字段的处理。COCO格式里iscrowd1表示这个标注是“人群”级别的粗略标注训练时损失函数会区别对待。labelme的JSON里没有直接对应字段但可以通过group_id来推断——如果多个标注对象共享同一个group_id可以认为它们属于同一个crowd区域。第三面积和边界框的计算。COCO的annotation里需要area和bbox字段。area是多边形的面积可以用鞋带公式计算bbox是外接矩形取所有点的最小/最大x、y即可。这两个字段虽然不影响训练但COCO评估指标会用到不填的话评估时会报错。5.2 转VOC格式目标检测的经典选择VOC格式比COCO简单得多每张图对应一个XML文件里面记录每个目标的类别和外接矩形。从labelme转VOC的核心工作是把多边形或圆形转成外接矩形——取所有点的最小/最大x、y作为矩形的左上角和右下角。这里有一个取舍如果你的标注是多边形转成VOC格式会丢失形状信息只保留外接矩形。所以VOC格式只适合目标检测任务不适合分割任务。如果你的项目同时需要检测和分割建议直接转COCO格式COCO同时支持bbox和segmentation字段。VOC格式的另一个坑是文件名。VOC要求图像文件和XML文件同名只是扩展名不同。labelme保存的JSON文件名默认和图像文件名一致转换时把.json换成.xml即可。但如果你的图像文件名里有特殊字符比如空格、中文某些训练框架读取时会出问题最好在标注前就把文件名规范化。5.3 转YOLO格式轻量训练的首选YOLO格式是纯文本格式每张图对应一个.txt文件每行一个目标格式是类别ID 中心x 中心y 宽度 高度所有坐标都归一化到0到1之间。从labelme转YOLO需要做两步先把多边形转成外接矩形再归一化坐标。归一化的时候要注意中心点和宽高的计算必须基于外接矩形不能直接用多边形的质心。我见过有人用多边形质心当中心点结果标注框偏移得厉害。正确的做法是x_center (x_min x_max) / 2 / image_widthy_center (y_min y_max) / 2 / image_heightwidth (x_max - x_min) / image_widthheight (y_max - y_min) / image_height。YOLO格式还有一个容易忽略的点类别ID从0开始而不是从1开始。这和COCO不一样转换时如果搞混了训练出来的模型会把所有类别都预测错位。格式适用任务坐标表示类别ID起始是否保留多边形COCO检测分割绝对像素1是VOC检测绝对像素无ID用类别名否YOLO检测归一化0-10否6. 标注效率翻倍的几个实操技巧6.1 快捷键体系把鼠标操作降到最低labelme的默认快捷键已经覆盖了大部分操作但很多人只用了其中一小部分。我整理了一套高频快捷键组合熟练之后标注速度能提升至少30%CtrlN新建多边形标注CtrlR新建矩形标注CtrlE新建圆形标注CtrlL新建线段标注CtrlP新建点标注CtrlZ撤销上一个点CtrlShiftZ重做CtrlS保存当前JSOND下一张图A上一张图Ctrl滚轮缩放图像空格拖拽平移图像其中D和A这两个键是效率关键。标注完一张图之后右手不用离开键盘直接按D切到下一张比用鼠标去点“Next Image”按钮快得多。我统计过一个标注员一天标500张图如果每张图省2秒切图时间一天就能省将近17分钟。6.2 预标注与半自动标注的配合纯手工标注始终是瓶颈。我的做法是先用一个粗糙的模型做预标注把预测结果转成labelme的JSON格式然后标注员在预标注的基础上修改。修改比从零标注快得多尤其是多边形标注预标注已经给出了大致轮廓标注员只需要拖动几个顶点微调。预标注的模型不需要很准哪怕mAP只有0.3也能显著提速。因为标注员看到预标注框之后判断“这个框对不对”比“从零开始画框”快得多。我做过对比实验同一批1000张图纯手工标注平均每张45秒带预标注平均每张28秒效率提升接近40%。把模型预测结果转成labelme JSON的脚本不难写核心就是构造shapes数组把预测的类别、坐标、置信度填进去。置信度可以放在flags字段里标注员在界面上能看到方便判断哪些框需要重点检查。6.3 多人协作时的标注规范制定多人协作标注最大的问题是标准不统一。同一个人在不同时间标同一张图结果可能都不一样不同人标同一批图差异更大。我的经验是在开始标注之前必须花半天时间做三件事第一写一份标注规范文档明确每个类别的定义、边界情况的处理方式、标注的精细程度。比如“车辆”类别要不要标被遮挡的部分遮挡超过50%的车辆标不标这些细节不写清楚标注员只能凭感觉结果就是数据质量参差不齐。第二选20张代表性图片做“黄金标准集”由项目负责人亲自标注然后让所有标注员标同一批图对比差异。差异大的地方就是规范里没写清楚的地方补充到规范文档里。第三定期做质量抽检。我一般按10%的比例随机抽检发现错误率超过5%就暂停标注重新对齐标准。抽检不是不信任标注员而是标注本身就是一件容易疲劳、容易走神的工作及时发现问题比事后返工成本低得多。6.4 大图标注的卡顿问题与缓解方案labelme在处理超大图像比如4K、8K的遥感影像或病理切片时界面会明显卡顿拖拽顶点时延迟感很强。这不是labelme的bug而是PyQt5在渲染大图时的性能瓶颈。缓解方案有几个。最直接的是把大图切分成小块再标注比如把8000x8000的图切成16张2000x2000的图标注完再合并。切图的时候要保留重叠区域避免目标被切断。另一个方案是降低显示分辨率——labelme在缩放显示时其实已经做了降采样但如果你把缩放比例调到很大它还是会渲染原图。标注时保持缩放比例在50%以下卡顿会明显减轻。还有一个偏方把图像转成JPEG格式再标注而不是PNG。JPEG的解码和渲染速度比PNG快不少尤其是大图。标注完成后JSON里记录的imagePath指向JPEG文件训练时再用原图替换即可不影响标注坐标。7. 几个真实踩过的坑与排查过程7.1 JSON文件打开报错imageData字段的陷阱有一次团队里一个标注员反馈说某张图的JSON文件打不开labelme报“Error opening file”。我拿到文件一看JSON本身格式没问题但imageData字段不是null而是一长串Base64编码的图像数据。原来这个标注员在保存时不小心勾选了“Save with image data”选项导致图像数据被嵌进了JSON里。文件本身能打开但因为数据量太大labelme加载时内存爆了。解决办法很简单用文本编辑器打开JSON把imageData字段的值改成null保存即可。但更重要的是在团队里明确规范——除非有特殊需求否则永远不要勾选“Save with image data”。这个选项在保存对话框里是一个不起眼的复选框很容易误勾。7.2 标注点坐标偏移图像被旋转过的隐性问题另一个坑是图像EXIF旋转信息导致的坐标偏移。手机拍的图片经常带有EXIF旋转标记图像查看器会自动旋转显示但labelme读取的是原始像素数据不做EXIF处理。结果就是你在labelme里看到的图是正的标注的坐标也是基于这个“正”的图但JSON里记录的imagePath指向的原图在别的工具里打开时是旋转过的坐标就对不上了。排查这个问题的办法是用PIL.Image.open()打开图像检查image._getexif()里有没有Orientation标签。如果有在标注前先用脚本把所有图片的EXIF旋转信息应用掉也就是物理旋转图像像素再开始标注。这个预处理步骤花不了几分钟但能避免后期大量返工。7.3 批量转换时类别名大小写不一致前面提过类别名大小写的问题这里展开说一个真实案例。一个项目里标注规范写的是“person”但有个标注员习惯性写成了“Person”。转换COCO格式时脚本里category_map只有“person”这个键遇到“Person”就报KeyError。排查的时候先检查了JSON文件发现确实有大小写混用但已经标了300多张图不可能全部重标。解决办法是写一个批量修正脚本遍历所有JSON文件把label字段统一转成小写或者按规范映射。这个脚本很简单但如果没有提前发现等到训练时才发现类别对不上返工成本就大了。我的建议是在标注规范里明确写“所有类别名一律小写”并且在转换脚本里加一个断言遇到不在category_map里的类别名直接报错退出而不是静默跳过。7.4 多人协作时JSON文件覆盖labelme默认的保存行为是覆盖同名JSON文件。如果两个人同时标注同一张图后保存的人会覆盖先保存的人的结果而且没有任何提示。这个问题在多人协作时非常隐蔽往往等到训练时发现某些图的标注“丢了”才意识到。规避方案有两个。一是用版本控制工具管理JSON文件比如Git每次保存后提交这样即使覆盖了也能找回历史版本。二是给每个标注员分配独立的图像子集从源头上避免多人标同一张图。如果确实需要多人标同一张图比如做标注一致性检查那就约定好文件命名规则比如image_001_annotatorA.json和image_001_annotatorB.json最后再合并。8. 标注完成之后数据校验与版本管理标注做完不等于数据就能直接用了。我习惯在转换格式之前先做一轮校验检查几个关键指标每张图的标注对象数量是否合理比如一张空图不应该有标注、类别分布是否均衡某个类别特别少可能是漏标了、标注框的面积是否异常比如一个框占了整张图的90%很可能是误操作。校验脚本可以用Python写遍历所有JSON文件统计每个类别的标注数量、每张图的标注数量、标注框的平均面积然后输出一份报告。如果发现某个类别的数量明显低于预期就回去检查是不是标注规范里对这个类别的定义不够清晰导致标注员漏标。版本管理方面我强烈建议用Git管理JSON文件。JSON是纯文本格式Git的diff功能可以精确显示每次修改了哪些标注点、增删了哪些标注对象。这对于追溯标注错误、回滚有问题的标注非常有用。图像文件本身不建议放进Git体积太大可以用Git LFS或者单独的文件服务器管理JSON文件里只保留相对路径。最后说一个实际项目里的经验标注数据的质量比数量重要得多。我见过太多团队为了赶进度标注质量放得很松结果模型训练出来效果不好回头排查发现是标注数据里噪声太大。与其标10000张低质量的图不如标3000张高质量的图后者训练出来的模型往往更好。labelme只是一个工具工具本身不保证质量质量靠的是清晰的规范、严格的抽检和及时的反馈。