LabelMe 图像分类标注实战:基于 --flags 的图像级类别标注指南
2026/9/21 19:01:01 网站建设 项目流程
  • 数据标注
  • 计算机视觉
  • 桌面应用

【免费下载链接】labelme

Image annotation with Python. Supports polygon, rectangle, circle, line, point, and AI-assisted annotation.

项目地址:https://gitcode.com/gh_mirrors/la/labelme
点击查看免费下载

导读

图像分类标注不需要画框、画多边形,只需要为整张图片打上一个类别标签(例如“cat”“dog”)。本文以 labelme 仓库中的 classification 示例 为骨架,完整讲解如何用 labelme 的--flags机制完成图像级分类标注:从flags.txt的编写、命令行启动,到 JSON 标注文件的解析、GUI 交互行为,再到与实例分割等形状标注流程的差异与进阶用法(正则驱动的--label-flags动态规则)。读完本文,你将掌握一套可复制、可运行的图像分类标注工作流,并能理解其底层实现原理。

一、示例概览:用 Flags 表达图像级类别

在 examples/classification 目录下,官方提供了最简化的分类标注示例:

  • flags.txt:声明可用的类别标签(flag)列表;
  • data_annotated/0001.jpg0001.json:一张猫图片及其标注结果(flagcat: true);
  • data_annotated/0002.jpg0002.json:一张狗图片及其标注结果(flagdog: true)。

与实例分割示例(examples/instance_segmentation)不同,分类示例的 JSON 中shapes为空数组——不标注任何几何形状,类别信息全部存放在flags字段中。这正是“图像分类”与“目标检测 / 实例分割”在标注层面的本质区别:前者给整张图打标签,后者给图中的每个目标画形状。

二、启动命令与 flags.txt 的编写

官方 README 给出的启动命令只有一行:

labelme data_annotated --flags flags.txt

其中data_annotated是待标注图片目录,--flags flags.txt指定类别定义文件。示例中的 flags.txt 内容如下:

__ignore__ cat dog

每行一个 flag 名。第一行__ignore__是保留项:勾选后表示“跳过/忽略”该图,不参与分类,常用于过滤质量不合格的样本。后面每一行就是一个候选类别,例如catdog。类别名称支持任意自定义字符串(如buspersondefect_ok),实际使用中可按业务命名。

--flags 参数解析规则(源码级验证)

--flags参数在 labelme/main.py 中定义,帮助信息写明其接受两种形式:

  • 逗号分隔列表:如--flags "cat,dog"
  • 文件路径:每行一个 flag,如--flags flags.txt

具体解析由_parse_list_arg完成(labelme/main.py):

def _parse_list_arg(value: str, /) -> list[str]: if os.path.isfile(value): with open(value, encoding="utf-8") as f: return [line.strip() for line in f if line.strip()] return [line.strip() for line in value.split(",") if line.strip()]

可以看到,当参数值是一个存在的文件时按行读取、自动去除首尾空白与空行;否则按逗号切分。因此两种写法的效果等价:

# 写法一:文件 labelme data_annotated --flags flags.txt # 写法二:内联逗号列表 labelme data_annotated --flags "cat,dog"

三、标注结果解析:JSON 中的 flags 字段

完成标注并保存后,每张图对应一个 JSON 文件。示例中 0001.json 的完整内容为:

{ "version": "4.0.0", "flags": { "__ignore__": false, "cat": true, "dog": false }, "shapes": [], "imagePath": "0001.jpg", "imageData": null, "imageHeight": 480, "imageWidth": 640 }

0002.json 则对应dog: true, cat: false。逐字段说明:

字段含义分类示例中的取值
version标注文件格式版本4.0.0
flags图像级布尔标志字典勾选的类别为true,其余为false
shapes形状标注列表(点、矩形、多边形等)[],分类标注不画形状
imagePath关联的图片文件名0001.jpg
imageData内嵌图片 base64 数据(默认nullnull
imageHeight/imageWidth图片像素尺寸480/640

flags字段的语义是**“本图属于哪些类别”**:分类任务通常只勾选一个(互斥),但机制本身支持多选(如cat: true, dog: true表示图中同时存在猫和狗)。下游训练代码只需解析flags字典中值为true的键,即可得到该图的类别标签。若未安装 labelme CLI 环境,也可直接用 Python 读取:

import json with open("data_annotated/0001.json", encoding="utf-8") as f: data = json.load(f) labels = [k for k, v in data["flags"].items() if v] print(labels) # ['cat']

四、GUI 中的 Flags 交互行为

启动后,labelme 会在标注界面中为flags.txt里的每个 flag 渲染一个复选框(checkbox),位置位于标签输入对话框(Label Dialog)区域。其底层实现在 labelme/_widgets/_label_dialog.py:

  • 对话框初始化时通过compile_label_flags编译 flags 规格(labelme/_widgets/_label_dialog.py);
  • 用户在文本框中输入类别名时,_update_flags会按当前文本动态刷新复选框(labelme/_widgets/_label_dialog.py);
  • 每个复选框对应一个布尔状态,确认后写入 shape / 图像级flags字典。

注意一个细节:分类标注中即使不输入任何 label 文本,仅勾选cat复选框同样能提交一条有效标注(labelme/_widgets/_label_dialog.py 的 OK 按钮启用逻辑只要求“label 被锁定或文本框非空”,而分类场景下类别信息由 flags 承载)。这也是示例中 JSON 的shapes为空、类别全在flags里的原因。

五、与形状标注(实例分割)流程的区别

将分类示例与 examples/instance_segmentation/README.md 对比,可以清晰看到两种标注范式的差异:

维度分类标注实例分割标注
标注单位整张图片图中每个目标对象
标注方式勾选 flags 复选框绘制多边形 / 矩形等形状
类别载体JSON 的flags字段每个 shape 的label字段
shapes内容空数组[]一个或多个形状定义
典型下游任务图像分类(CNN 分类器)目标检测、分割(如 labelme2voc / labelme2coco 转换)

分类任务中一个 shape 都没有,因此不需要在画布上做任何几何操作,只需为每张图片勾选类别并保存,标注速度非常快。

六、进阶:正则驱动的动态 Flags(--label-flags)

--flags提供的是全局固定的候选类别列表;而 labelme 还提供--label-flags参数,让 flag 集合随标签名动态变化。该参数同样定义在 labelme/main.py,接受内联 YAML 映射或 YAML/JSON 文件,键为正则表达式、值为该正则匹配的标签应显示的 flag 列表,例如:

labelme data_annotated \ --label-flags '{person-\d+: [male, tall], dog-\d+: [black, brown, white], .*: [occluded]}'

其核心实现位于 labelme/_label_flags.py:

  • compile_label_flags将键编译为正则对象,并对非法模式做容错——非字符串键、无法编译的正则(如cat()会被记录警告后跳过,保证应用不因用户配置错误而崩溃(labelme/_label_flags.py);
  • get_default_flags根据当前标签名匹配到的正则,返回对应的默认 flag 字典(labelme/_label_flags.py);
  • apply_default_flags在加载标注时为每个 shape 应用默认 flags(labelme/_label_flags.py)。

该行为有专门单元测试覆盖,见 tests/unit/_label_flags_test.py:例如{"^cat$": ["occluded", "truncated"]}会为标签cat生成{"occluded": False, "truncated": False}的默认复选框;而非法模式(如cat(、非字符串键2024、bytes 键)会被静默丢弃(tests/unit/_label_flags_test.py)。

对纯分类场景,--flags已足够;--label-flags更适合目标检测 / 实例分割中“同一类目标拥有不同属性”(如行人性别、车辆颜色、遮挡与否)的细粒度标注。

七、配置文件中的 flags 项

除了命令行参数,flagslabel_flags也出现在用户配置文件(默认~/.labelmerc,可通过--config覆盖)中,见 labelme/_config/default_config.yaml:

flags: # 全局 flag 列表,等价于 --flags label_flags: # 标签正则 -> flag 列表,等价于 --label-flags

命令行参数会作为配置覆盖项与配置文件合并(labelme/main.py),因此两种配置途径可以混用:把团队共用的类别写进配置文件,把临时类别通过--flags内联传入。关于配置架构的完整设计可参考 docs/adr/0001-settings-architecture.md。

八、完整实战流程

下面是一条端到端的分类标注流水线:

  1. 准备图片目录:将待分类图片放入一个目录,例如data_annotated/

  2. 编写 flags.txt:首行保留__ignore__,后续每行一个类别:

    __ignore__ cat dog
  3. 启动标注

    labelme data_annotated --flags flags.txt
  4. 逐图勾选类别:为每张图片勾选正确的类别复选框,__ignore__用于剔除无效样本,然后保存(默认自动保存,可在配置中通过auto_save控制,见 labelme/_config/default_config.yaml);

  5. 导出标注:遍历目录下所有*.json,读取flags中为true的键作为类别标签,组装成训练数据集(如{image_path: label}的 CSV 或 TFRecord),供下游分类模型使用。

九、小结

图像分类标注在 labelme 中是一个“轻量”但完整的流程:通过--flags(或配置文件中的flags项)声明类别候选,GUI 中勾选复选框写入 JSON 的flags字段,shapes保持为空,下游按布尔值为true的键读取类别。其底层由 labelme/_label_flags.py 的编译、匹配、应用三段式实现支撑,并配有单元测试与官方示例(examples/classification),无论是快速标注实验数据,还是搭建正式的分类数据集生产管线,都可以直接参考本文流程落地。

  • 数据标注
  • 计算机视觉
  • 桌面应用

【免费下载链接】labelme

Image annotation with Python. Supports polygon, rectangle, circle, line, point, and AI-assisted annotation.

项目地址:https://gitcode.com/gh_mirrors/la/labelme
点击查看免费下载

相关推荐

上一篇:在umijs/dumi中编写组件Demo的最佳实践
下一篇:深入解析redb嵌入式键值存储引擎的设计原理

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询