资讯动态

labelImg图像标注工具实战:从安装配置到XML/YOLO格式输出

发布时间:2026/10/17 11:42:58 来源:尧图企业网站定制
简介LabelImg 是一款广泛使用的可视化图像标注工具该压缩包提供其完整源码面向需为 Faster R-CNN、YOLO、SSD 等目标检测网络制作数据集的开发者。借助工具可快速框选图像中的目标并生成遵循 PASCAL VOC 格式的 XML 标注文件也可作为学习图像标注工具实现原理的参考。压缩包共 127 个文件、约 6.39MB其中以 Python 脚本44个、PNG 图片38个、Shell 脚本、SVG 图标、文本配置等类型为主同时包含 setup.cfg、labelImg-1.8.1-py3.6.egg、MANIFEST.in 等打包与安装相关文件能够支持本地部署与二次开发。源码中还包括测试位图、示例图片等辅助资源便于直接验证标注效果。已有 357 人浏览学习适合无法访问 GitHub 或希望离线获取该工具的研究者与算法工程师使用。1. labelImg图像标注工具里那个绕不开的老牌默认选项做目标检测的人第一批要啃的不是模型结构而是数据标注。不管你是要跑 YOLO、SSD 还是 Faster R-CNN训练之前都逃不掉给图片画框、填类别这个又碎又耗时的环节。labelImg 作为开源界流传最早、也最广的图像标注工具界面不花哨功能也不多就是把一张图、一个矩形框、一个类别名这三件事稳定地落成 XML 标注文件适合一个人或者小团队在本地快速攒出第一版标注集。它能解决的核心问题只有一个让标注过程肉眼可见让标签有处可查。对新手它门槛低对熟手它足够透明不玩黑匣子。2. 环境准备依赖装对、参数认准标注才不返工2.1 解压后的目录结构与依赖安装下载回来的压缩包解压后是一份完整源码目录不是那种需要再联网拉一堆东西的残缺工程。入口文件是labelImg.py标注逻辑封装在libs/目录下界面资源在resources/另外data/目录里通常会带一份预定义标签的样例文件。这种结构的好处是你能直接看到工具在跑什么出了问题也方便自己改。第一次启动前先装两个运行依赖PyQt5 负责画界面、处理鼠标事件lxml 负责 XML 标注文件的读写。这两样不装全工具要么起不来要么能画框但存不出有效文件。# 进入解压出来的源码目录 cd labelImg-master # 安装图形界面和 XML 解析依赖 pip install pyqt5 lxml # 带参数启动直接载入图片目录和预设类别文件 python labelImg.py ./images ./data/classes.txt这段命令的逻辑是先用cd进到源码根目录再一次性装齐两个依赖。pip install pyqt5 lxml是并列安装不是两个命令分两次跑。最后启动时./images会被当成图片目录在左侧文件树里展开./data/classes.txt则是预定义类别列表每一行一个类名。如果这两个参数都不传工具也能启动只是每次都要手动去点“打开目录”和“选择标签文件”效率低不少。参数说明上IMAGE_PATH只接受目录不接受单张图片PRE-DEFINED CLASS FILE是纯文本文件编码建议用 UTF-8Windows 下尤其容易因为默认 ANSI 编码导致中文类名乱码。我一般会在启动前先python --version确认当前 Python 环境避免 pip 装到了别的解释器里然后才去跑labelImg.py。这一步花不了十秒钟但能挡住后面一大半“启动即报错”的问题。2.2 三种常用启动姿势与界面关键位置实际使用中我基本只用三种启动姿势。第一种是裸启动适合临时看看某张图第二种是只带图片目录适合分批标注时不用每次重新选择第三种是图片目录和预设类别一起给适合固定标注一个数据集、类别已经确定的场景。约定好启动姿势比在界面里反复点设置要稳得多。# 姿势一裸启动临时用 python labelImg.py # 姿势二直接载入图片目录省一次“打开目录”操作 python labelImg.py ./images # 姿势三图片目录 预设类别适合固定数据集 python labelImg.py ./images ./data/classes.txt三个姿势的差别只在于参数填充程度核心逻辑都走同一套代码。姿势三最贴近生产环境因为在标注大量图片时类别一旦靠手敲就容易出现大小写不一致、中英文混用这类问题。预定义类别文件加载后关掉再打开依然生效前提是你每次启动都带上同一个文件。界面打开后有四个位置需要先认清楚。左侧是文件列表当前目录下所有图片会按文件名排好中间大区域是图片画布画框和看结果都在这右侧下方是标签列表每一张图上的所有对象会列在这里右下角是格式切换PascalVOC 和 YOLO 两种模式在这切。第一次打开时右下角默认是 PascalVOC对应输出.xml文件。如果切到 YOLO 模式再保存时生成的是.txt每行内容变成了类别编号和归一化后的中心点坐标、宽高而不是直观的框坐标。我在实际标注前一般会先固定一套classes.txt把允许出现的类别一行一个写进去启动后从下拉框里选绝对不手打新词。这套文件尽量一开始就定全因为类别合并、改名这种事在标注后期做代价比重新标一批图还高。提示如果图片目录里混有非图片文件左侧列表会出现无法预览的条目不影响其他图片标注但建议启动前先清理目录省得误标。3. 把 label 落成 XML从画框到导出的一整套操作流3.1 标注前必做的三项设置画框本身不难但很多人都吃过“画了几百个框结果没存下来”的亏。标注前花一分钟把三件事设好后面全程不用操心保存和路径问题。第一设置输出目录。默认情况下XML 会跟着图片走也就是图片在哪标注文件就写到哪。如果你把图片目录和标注目录混在一起后面训练脚本要分拣数据时会相当痛苦。工具栏里有一项 Change Save Dir点它选一个专门放 XML 的目录比如./Annotations。第二勾选 Auto Save mode。这个选项在 View 菜单里勾上之后每次切换下一张图片时当前图自动保存不需要手动按CtrlS。我踩过一个真实的坑连续标了半小时以为都存了结果回看时只有最初几张有 XML因为中途一直没按保存切换图片时又没有开自动保存。从那以后我再没关过这个选项。第三准备一份预定义类别文件。可以直接用data/目录里的样例也可以自己新建。类别的设计有个原则互斥。比如同时标“人”和“头”就容易出现同一个位置叠两个框训练时两个类都学不干净。宁可大类少不要模糊类多。person car dog cat这份文件的作用是给下拉框提供候选值。启动时把它作为第二个参数传进去标注时点类别输入框能看到所有预设类别直接点选即可。注意labelImg 的预设类别只是候选不是强制白名单你仍然可以手输一个文件里不存在的类名。这也是后面第 4 章要展开的坑点。文件命名无所谓但内容和实际标注必须一一对应且每次启动都带着同一个文件不要半路换。3.2 画框流程、快捷键与 XML 结构设置完成后标注动作本身很简单。按W进入画框模式鼠标左键按下拖动拉出一个矩形框松手后弹出类别输入框选好类别后框就挂在图上了。接着按D切到下一张再按W继续画。切图之前如果没开自动保存记得手动按一下CtrlS。常用操作集中在几个快捷键上。W新建框D下一张A上一张CtrlS保存Del删除当前选中框E编辑框C复制选中框。画完的框可以拖动微调选中框后四个角有控制点可以拉伸画歪了直接改不用删了重画。坐标数据最终落到 XML 文件里结构大概长这样annotation folderimages/folder filename001.jpg/filename pathC:/datasets/images/001.jpg/path source databaseUnknown/database /source size width1920/width height1080/height depth3/depth /size segmented0/segmented object nameperson/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin120/xmin ymin80/ymin xmax460/xmax ymax900/ymax /bndbox /object /annotation这个 XML 的根节点是annotation里面先记录图片本身的元信息文件名、路径、尺寸。size下的width和height很重要后续做数据增强或转 YOLO 时都要用到原图尺寸来归一化坐标。每个object节点对应一个标注框name是类别名bndbox里面四个字段分别表示框的左上角 x、左上角 y、右下角 x、右下角 y。这个坐标系的原点在图片左上角y 轴向下增加和很多图像处理库的默认方向一致。这里有一个容易被忽略的细节truncated和difficult两个字段默认都是 0分别表示目标是否被截断、是否属于难例。如果某些目标在图片边缘被截断了一半建议把 truncated 标成 1避免模型在训练时被不完整目标干扰。但 labelImg 在 PascalVOC 模式下没有直接提供这两个字段的编辑入口需要后期脚本批量改所以大多数情况下保持默认也不影响主流程。注意XML 中的filename只是文件名不包含路径。后续做训练集划分时别把filename直接当成图片路径去读否则会报文件不存在。3.3 标注导出后先跑一轮自检第一批几十张图标完先别急着发给下游直接在标注目录里跑一个计数脚本看看各类别的框数是否合理。这一步能提前发现类别串名、XML 解析失败等问题比训练时才暴露要划算得多。import xml.etree.ElementTree as ET from pathlib import Path xml_dir Path(./Annotations) stats {} total_boxes 0 for xml_file in xml_dir.glob(*.xml): tree ET.parse(xml_file) root tree.getroot() for obj in root.iter(object): name obj.findtext(name) if not name: print(f发现空标签: {xml_file.name}) continue box obj.find(bndbox) xmin int(box.findtext(xmin)) ymin int(box.findtext(ymin)) xmax int(box.findtext(xmax)) ymax int(box.findtext(ymax)) if xmin xmax or ymin ymax: print(f坐标异常: {xml_file.name} - {name}) stats[name] stats.get(name, 0) 1 total_boxes 1 print(类别统计:, stats) print(总框数:, total_boxes)这段脚本的逻辑是遍历Annotations目录下所有 XML用root.iter(object)找出每一个标注对象读取类别名和四个坐标值做基本检查。findtext(name)返回空说明这个 object 节点有结构问题需要人工复查。坐标判断里xmin xmax或ymin ymax属于异常框通常不会出现但一旦出现就说明画框时手滑了。脚本里的xml_dir指向的就是你在 Change Save Dir 里设置的输出目录。如果 XML 没存到这个目录下脚本会一个文件都扫不到这时候首先要检查的不是脚本而是标注时是否真的指定了输出目录。我一般会把这段脚本放在标注工具同一个项目目录下每标完一批就跑一次顺手把类别分布截图发给协作者效率很高。4. 图像标注避坑五个高频故障与排查记录4.1 标注了半天XML 却没出现在输出目录现象连续标注了一百多张图切到输出目录一看里面只有零星几个 XML大量标注白做了。原因最常见的是没设置 Change Save Dir而且也没开 Auto Save mode。不设置输出目录时XML 会写到图片所在目录你在别的目录自然找不到没开自动保存时切换图片不会主动保存只有手动CtrlS才会落盘。两个问题叠在一起就出现“标了很多张存下来的没几个”。解决标注前先指定输出目录并勾选 Auto Save mode。如果已经标完一批但发现丢了先用文件搜索看图片目录里有没有残留的 XML能找回一部分。避免这个问题最好的习惯是每标完一张看一眼状态栏有没有保存提示或者直接按CtrlS手动保底。4.2 类别名越标越多预设文件“不管用”现象明明传了classes.txt下拉框里也有预设类别但标注时还是能输入一个不在列表里的新类别几十张图标下来类别越攒越多。原因预定义类别文件在 labelImg 里只负责提供下拉候选并不做输入拦截。输入框默认允许任意文本W 键画框后如果手快了直接回车就会把当前输入内容当作新类别写入 XML。这个行为和很多新手预期不一致以为是白名单机制。解决一个是靠自觉只在预设类别里点选。另一个是从源头拦截写一个后续校验脚本扫描所有 XML 的name字段凡是没出现在预设列表里的类名全部打印出来。我在第 3 章的统计脚本基础上加了白名单比对后这类脏标签基本一天内能被清干净。标注团队协作时也可以规定启动参数必须带同一个 classes 文件并每周跑一次类别统计。4.3 高分辨率大图打开就卡画框拖不动现象打开一张 4000×3000 以上的大图图片加载慢滚动或画框时明显掉帧拖拽时框跟不上鼠标。原因labelImg 直接把整张大图读进内存Qt 渲染时也没有像专业看图软件那样的金字塔分层策略内存占用和界面卡顿随图片像素数线性增长。图片尺寸到一定量级后界面基本是半瘫痪状态。解决先批量把图片压缩到训练分辨率再标注。我一般用 1920 或 1280 作为标注用图的短边上限保存为 JPEG 质量 90 以上视觉信息损失很小但标注流畅度大幅提升。如果只是个别超大图需要标注可以直接用系统自带看图工具切分后再分别标注最后再合并结果。记住原图和标注用的压缩图要分开存训练时也用同一份压缩图避免坐标偏移。4.4 切到 YOLO 模式后txt 里类别数字和预期对不上现象界面右下角切到 YOLO 格式后保存下来的 txt 文件里每行第一个数字是 0 或 1但打开图看内容发现类别对应关系全乱了。原因切到 YOLO 模式后labelImg 不再写类别名而是写类别编号。这个编号的排序依据是当前加载的预定义类别文件顺序还是首次出现的顺序取决于启动时的参数。如果没传类别文件工具会按你标注时第一次输入类别的先后顺序编号每个数据集的顺序都不一样最后你以为 0 是 person实际可能是 car。解决固定使用同一个classes.txt作为启动参数并且保证 train 和 val 阶段加载同一个文件。YOLO 模式保存后写个小脚本读几个 txt 前两行和预设文件里的顺序对一遍确认无误再进训练流程。这里最忌讳的就是用默认模式标了一批、又切格式标另一批格式混着来最后一锅粥。4.5 双击启动一闪而过或窗口白屏现象在文件管理器里双击labelImg.py窗口闪一下就消失或者命令行启动后窗口白屏菜单能用但画布不刷新。原因双击.py文件依赖系统默认关联的 Python 解释器如果这个解释器里没装 pyqt5 和 lxml就会报错退出。白屏则多半是 PyQt5 和当前 Python 版本兼容性有问题常见于较新的 Python 版本界面组件初始化异常但又没抛致命错误。解决不要依赖双击在命令行里用绝对路径的 Python 解释器执行。先python --version确认版本然后python labelImg.py启动报错信息会直接打在终端里比黑匣子瞎猜强得多。如果白屏试着用 pyqt5 的最新小版本覆盖安装或者换一个稍旧的 Python 版本重新建虚拟环境。我习惯用虚拟环境跑这类开源工具依赖隔离不会污染系统级 Python。5. 交付前自检把 XML 坐标画回原图再放行5.1 一个可视化脚本等于给标注集上一道保险标注生成的 XML 是给人看的但训练时真正读取的是数字坐标。坐标值差一个像素人眼未必看得出来但模型会老老实实地按偏的框去学习。所以我在交付任何一批标注数据之前都会强制跑一遍可视化验证把 XML 里的坐标用 OpenCV 画回到原图上随机抽查几张确认框和内容确实对得上。import cv2 import xml.etree.ElementTree as ET from pathlib import Path image_dir Path(./JPEGImages) xml_dir Path(./Annotations) out_dir Path(./check) out_dir.mkdir(exist_okTrue) for xml_file in xml_dir.glob(*.xml): tree ET.parse(xml_file) root tree.getroot() filename root.findtext(filename) img_path image_dir / filename img cv2.imread(str(img_path)) if img is None: print(f图片缺失: {img_path}) continue for obj in root.iter(object): name obj.findtext(name) box obj.find(bndbox) x1 int(box.findtext(xmin)) y1 int(box.findtext(ymin)) x2 int(box.findtext(xmax)) y2 int(box.findtext(ymax)) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, name, (x1, max(0, y1 - 6)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 1) out_path out_dir / filename cv2.imwrite(str(out_path), img) print(f已生成: {out_path})这个脚本的逻辑和前面统计脚本类似区别在于它把 XML 里的每个框直接画到原图上标注了类别文字然后输出到一个独立目录。cv2.rectangle接收左上角和右下角坐标正好对应 XML 里的xmin, ymin, xmax, ymaxcv2.putText的标签位置放在框上方如果y1太小就取 0避免文字画到画布外面。filename是从 XML 里取出来的所以如果图片实际文件名和 XML 记录的不一致脚本会直接打印图片缺失这类问题用眼睛瞪目录是看不出来的。脚本跑完后我会随机抽 10 张左右逐个看一遍框位置是否贴合目标、类别是否匹配、有没有漏标目标。不要只挑看起来顺眼的图专挑有遮挡、多目标、边缘目标的图看问题往往藏在难例里。这个可视化输出目录我一般保留到训练结束模型训练出问题时还能回来核对。从那以后我每次交付标注集之前都把这段脚本跑一遍确认没框错再往下游送。哪怕只抽查十张也比直接把几百个 XML 丢给训练脚本要踏实。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑