labelImg 图像标注工具实战:从环境搭建到 YOLO 格式转换与质量校验
简介LabelImg-master.zip 是一款面向计算机视觉从业者与深度学习入门者的开源图像标注工具源码包主要用于为目标检测、语义分割等卷积神经网络任务快速构建高质量训练数据集。它提供直观的图形界面支持矩形框、多边形等多种标注形式标注结果可保存为 XML 或 JSON 格式并兼容 Windows、Mac OS 与 Linux 平台非编程背景人员也能快速上手。压缩包共 108 个文件约 6.29MB以 27 个 py 源码文件、39 个 png 界面素材、6 个 svg 图标及若干 sh 脚本、rst 文档、properties 配置为主另附安装方法与常见错误解决说明便于读者直接运行、二次开发或排查环境依赖问题。目前已有 425 人学习下载适合需要搭建标注流程、准备训练数据或研究标注工具实现细节的读者参考使用。1. 拆开 labelImg-master.zip一个标注工具凭什么成了算法团队的标配如果你正在做目标检测不管是 YOLO 系列还是 SSD、Faster R-CNN第一道绕不过去的坎就是标注数据。我见过太多团队在模型结构上反复调参结果 mAP 上不去回头一查发现标注框歪了三五个像素。labelImg 这个工具就是专门解决这个问题的——它是一个用 Python Qt 写的轻量级图像标注工具核心功能就一件事在图片上画矩形框、打类别标签然后导出成模型训练能直接吃的格式。这个 zip 包拿到手解压出来就是完整源码不需要编译装好依赖就能跑。它适合谁刚入门神经网络、准备自己搞数据集的学生需要快速给几百张图打框验证想法的算法工程师以及那些不想为了标注这件事去部署一套重型标注平台的小团队。它不花哨但足够稳这也是为什么这么多年过去它依然是很多人标注流程里的第一站。2. 环境搭建与首次启动从解压到画出第一个框2.1 依赖选型为什么是 PyQt5 而不是 PyQt6labelImg 的界面层用的是 PyQt但版本选择上有讲究。源码里默认走的是 PyQt5 的 API如果你直接 pip install PyQt6启动时会报一堆枚举类型不匹配的错误因为 Qt6 把很多常量挪了位置。我一般会先确认 Python 版本3.8 到 3.10 之间最稳3.11 以上偶尔会遇到 lxml 编译问题。安装依赖的命令如下# 建议在虚拟环境里操作避免污染全局包 python -m venv labelenv source labelenv/bin/activate # Windows 用 labelenv\Scripts\activate # 核心依赖PyQt5 负责界面lxml 负责解析 XML 标注文件 pip install PyQt55.15.9 lxml这里锁 PyQt5 的版本是有血泪经验的。5.15 系列是最后一个支持 Python 3.10 的稳定分支再往上走某些 Linux 发行版自带的 Qt 库会和 pip 装的冲突导致启动时提示 “could not load the Qt platform plugin xcb”。遇到这个报错先检查系统有没有装 libxcb-xinerama0没有就补上。2.2 启动方式与工作目录约定解压后进入目录你会看到 labelImg.py 这个入口文件。启动命令很简单# 在源码根目录执行 python labelImg.py # 如果想直接打开某个图片文件夹可以带参数 python labelImg.py /path/to/your/images启动后界面分三块左侧文件列表、中间画布、右侧标签列表。第一次用的时候很多人会直接点 “Open Dir” 选图片文件夹然后就开始画框。但这里有个隐藏顺序问题如果你先打开图片目录再点 “Change Save Dir” 指定标注保存位置已经画好的框会默认存到图片同级目录下。我习惯的做法是先建一个空的 annotations 文件夹启动后第一件事就是 Change Save Dir 指过去再 Open Dir 加载图片。这样标注文件和原图分离后面写数据加载脚本时路径清晰不会把原图目录搞得乱七八糟。2.3 标注格式切换Pascal VOC 与 YOLO 的取舍labelImg 支持两种主流导出格式切换按钮在左侧工具栏。Pascal VOC 生成的是 XML 文件每个框记录 xmin、ymin、xmax、ymax 四个绝对坐标YOLO 格式生成的是 txt 文件每行是 “类别索引 中心x 中心y 宽 高”全部归一化到 0 到 1 之间。选哪个取决于你的训练代码。如果你用的是 Ultralytics 的 YOLOv5/v8 仓库它默认读 YOLO 格式的 txt那就在标注前把格式切到 YOLO。但要注意YOLO 格式的类别是数字索引labelImg 里你需要先在 “predefined_classes.txt” 里写好类别名它按行号映射成 0、1、2。这个文件放在源码 data 目录下改完重启生效。如果类别写错了顺序后面训练时模型学到的类别就全乱了这种坑我踩过不止一次。3. 标注流程拆解从快捷键到批量校验的完整链路3.1 核心快捷键与画框逻辑labelImg 的效率高低八成取决于你熟不熟快捷键。画框用 W画完自动弹出类别选择下一张用 D上一张用 A。如果框画歪了CtrlZ 撤销上一步但注意它只能撤销当前图片的操作切到下一张再回来之前的撤销记录就没了。画框的时候有个细节鼠标拖拽的起点和终点决定了框的方向但 labelImg 会自动把坐标整理成左上角到右下角的标准形式。不过如果你拖拽时手抖框的宽高可能只有几个像素这种框在训练时会被当成噪声。我一般会目测一下宽高小于 10 像素的框直接删掉重画别指望模型能学到东西。3.2 类别管理与预定义标签文件前面提到的 predefined_classes.txt格式就是一行一个类别名不要有空行不要有空格。比如person car traffic_light保存后重启 labelImg右侧标签列表就会按这个顺序显示。标注时按对应的数字键 1、2、3 可以快速选类别比鼠标点快得多。如果中途需要加新类别改完文件重启就行已经标好的框不受影响因为 XML 或 txt 里存的是类别名或索引不是内存里的临时状态。这里有个容易翻车的地方如果你用 YOLO 格式标注中途改了 predefined_classes.txt 的顺序之前标好的 txt 文件里的索引就对不上了。比如原来 0 是 person你改成 0 是 car那旧文件全错。所以类别列表一旦定下来尽量别动顺序要加就往后追加。3.3 标注文件的组织与校验脚本标完一批图之后别急着扔给训练脚本。我习惯先跑一个校验脚本检查有没有空文件、坐标越界、类别名拼写错误。下面这个 Python 脚本可以快速扫一遍 Pascal VOC 格式的 XMLimport os import xml.etree.ElementTree as ET def validate_annotations(anno_dir, img_dir): issues [] for xml_file in os.listdir(anno_dir): if not xml_file.endswith(.xml): continue xml_path os.path.join(anno_dir, xml_file) tree ET.parse(xml_path) root tree.getroot() # 检查对应的图片是否存在 img_name root.find(filename).text if not os.path.exists(os.path.join(img_dir, img_name)): issues.append(f{xml_file}: 图片 {img_name} 不存在) # 检查每个框的坐标 for obj in root.findall(object): bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) if xmin xmax or ymin ymax: issues.append(f{xml_file}: 坐标顺序错误 {xmin},{ymin},{xmax},{ymax}) if xmin 0 or ymin 0: issues.append(f{xml_file}: 坐标越界) return issues # 用法示例 problems validate_annotations(./annotations, ./images) for p in problems: print(p)这个脚本的逻辑很直白遍历标注目录解析每个 XML先确认图片文件还在再检查框的坐标是否合法。参数说明一下anno_dir 是标注文件目录img_dir 是原图目录两者要对应上。跑完如果输出为空说明这批标注基本干净可以进入训练流程。如果有问题根据提示逐条修别带着脏数据去训模型否则 loss 曲线会教你做人。4. 避坑与排查标注工具用不对模型白训一半4.1 启动报错 “No module named ‘libs.resources’”现象在源码目录直接 python labelImg.py提示找不到 libs.resources 模块。 原因labelImg 的界面资源文件需要先编译成 Python 模块源码包里带的是 .qrc 文件不是 .py。 解决在源码根目录执行pyrcc5 -o libs/resources.py resources.qrc前提是 PyQt5 装好了。如果提示 pyrcc5 找不到用python -m PyQt5.pyrcc_main代替。4.2 标注文件保存位置不对训练时找不到现象画完框点保存提示保存成功但训练脚本读不到标注。 原因labelImg 默认把标注存到图片同级目录如果你没手动 Change Save Dir它不会自动建子文件夹。 解决启动后第一件事就是 Change Save Dir指定一个独立目录。另外注意YOLO 格式下labelImg 会在保存目录下生成 classes.txt这个文件记录了类别顺序训练时要用到别删。4.3 中文路径导致图片加载失败现象Open Dir 选了带中文的文件夹文件列表是空的或者图片显示不出来。 原因Qt 在部分系统上对非 ASCII 路径支持不好尤其是 Windows 下。 解决把图片和标注都放在纯英文路径下比如 D:\datasets\project_a\images。如果已经标了一半把整个目录改名再重新打开标注文件里的 filename 字段也要同步改否则校验脚本会报图片不存在。4.4 快捷键冲突导致画框中断现象按 W 没反应或者画到一半框消失了。 原因输入法没切到英文状态W 被当成中文输入了。或者焦点在右侧标签列表上快捷键不生效。 解决标注前把输入法切成英文鼠标点一下中间画布区域再按 W。如果还是不行检查是不是开了某些全局快捷键软件把 W 占用了。4.5 大图片加载卡顿甚至崩溃现象打开几千像素的大图界面卡死或者直接闪退。 原因labelImg 默认会把整张图加载到内存渲染图片太大时 Qt 的渲染压力扛不住。 解决标注前先把图片缩放到合理尺寸比如长边不超过 2000 像素。用 OpenCV 批量缩放一下再拿去标。缩放后坐标会变但如果你是在缩放后的图上标训练时也用同样尺寸那就没问题。5. 进阶技巧用脚本批量转换格式与自动预标注5.1 Pascal VOC 转 YOLO 格式的批量脚本很多团队一开始用 labelImg 标的是 VOC 格式后来换训练框架需要 YOLO 格式手动转不现实。下面这个脚本可以批量转换核心逻辑是读 XML 里的绝对坐标除以图片宽高做归一化import os import xml.etree.ElementTree as ET from PIL import Image def voc_to_yolo(anno_dir, img_dir, output_dir, class_list): # class_list 是类别名列表顺序要和训练时一致 class_map {name: idx for idx, name in enumerate(class_list)} for xml_file in os.listdir(anno_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(anno_dir, xml_file)) root tree.getroot() # 获取图片尺寸 img_name root.find(filename).text img_path os.path.join(img_dir, img_name) with Image.open(img_path) as img: w, h img.size lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_map: continue # 跳过未定义的类别 cls_id class_map[cls_name] bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 归一化并计算中心点和宽高 cx (xmin xmax) / 2.0 / w cy (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) # 写入同名 txt 文件 out_path os.path.join(output_dir, xml_file.replace(.xml, .txt)) with open(out_path, w) as f: f.write(\n.join(lines)) # 用法 voc_to_yolo(./annotations, ./images, ./labels, [person, car, dog])参数说明class_list 必须和训练时的类别顺序完全一致否则索引对不上。归一化保留 6 位小数足够YOLO 官方也是这个精度。转换完记得抽查几个 txt看看坐标是不是在 0 到 1 之间超出范围说明原 XML 里的框有越界。5.2 用预标注模型减少手工画框如果你要标几千张图纯手工画框效率太低。常见做法是先用一个已经训好的模型跑一遍推理把预测框导出成 VOC 或 YOLO 格式再用 labelImg 打开这些预标注文件人工只做修正。labelImg 支持加载已有的标注文件你只要把预标注的 XML 放到和图片同名的路径下打开图片时框会自动显示出来。具体流程用 YOLOv8 推理一批图导出成 VOC 格式的 XML然后把这些 XML 放到 annotations 目录图片放 images 目录启动 labelImg 后 Open Dir 选 imagesChange Save Dir 选 annotations它就会自动读取同名 XML 并渲染框。你只需要拖动调整不准的框删掉误检的补上漏检的。这样效率能提升三到五倍尤其是类别少、场景固定的数据集。5.3 验证标注质量的一个笨办法但有效标完一批数据别急着训。随机抽 20 张图用脚本把标注框画到原图上生成可视化结果肉眼过一遍。下面这段代码用 OpenCV 画框import cv2 import xml.etree.ElementTree as ET import os def draw_boxes(img_path, xml_path, output_path): img cv2.imread(img_path) tree ET.parse(xml_path) root tree.getroot() for obj in root.findall(object): name obj.find(name).text bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2) cv2.putText(img, name, (xmin, ymin - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cv2.imwrite(output_path, img) # 批量可视化 for xml_file in os.listdir(./annotations): if xml_file.endswith(.xml): img_file xml_file.replace(.xml, .jpg) draw_boxes(f./images/{img_file}, f./annotations/{xml_file}, f./vis/{img_file})跑完打开 vis 文件夹一张张翻。重点看三类问题框有没有把目标截断、类别有没有标错、密集区域有没有漏标。这个步骤花不了多少时间但能拦住大部分低级错误。从那以后我每次标完新数据都强制走一遍可视化抽检宁可多花半小时也不想训到一半发现标签有问题再回头返工。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

基于Simulink的电动车制动能量回收控制策略设计与参数匹配

基于Simulink的电动车制动能量回收控制策略设计与参数匹配

做电动车整车控制有关的方向做久了就会发现,市面上各种课题和项目里,“基于MATLAB Simulink的电动车制动能量回收控制策略设计与参数匹配”是一个绕不开的高频主题。它的价值很直接:制动能量回收直接决定整车续航表现,是电控技术水…

2026/10/19 5:52:33 阅读更多 →
图表设计实战指南:用信息分层与视觉编码画出清晰的架构图与流程图

图表设计实战指南:用信息分层与视觉编码画出清晰的架构图与流程图

1. 先想清楚:图表设计到底在设计什么?上周帮团队里一位同学做架构评审演练,他画了一张"系统架构图"投到屏幕上:四十多个矩形框,红绿蓝紫四色混用,箭头从四面八方射出来,还有几条线穿过…

2026/10/19 5:51:32 阅读更多 →
LNA无线串口模块AS62:透传原理与工程实战指南

LNA无线串口模块AS62:透传原理与工程实战指南

我最早接触AS62这块模块的时候,是被“LNA”三个字母勾起来的。做射频的老哥都知道,LNA通常指低噪声放大器,是接收链路最前级的关键器件,但AS62显然不是一块单纯的放大器,而是一块完整的UART串口收发模块。带着“这到底…

2026/10/19 5:51:32 阅读更多 →

最新新闻

YOLOv7量化部署实战:PTQ/QAT训练到TensorRT C++推理全链路

YOLOv7量化部署实战:PTQ/QAT训练到TensorRT C++推理全链路

简介:从YOLOv7模型的PTQ后训练量化与QAT量化感知训练,到基于TensorRT的C推理部署,这份下载包面向需要在GPU端高效落地检测模型的算法工程师与嵌入式开发人员。压缩包共134个文件,约35.14MB,包含35个Python脚本&#xf…

2026/10/19 7:13:11 阅读更多 →
前端绘图组件实战:从架构拆解到交互实现的完整指南

前端绘图组件实战:从架构拆解到交互实现的完整指南

diagram-design 这个项目,说起来其实是被实际业务逼出来的。当时我们团队在做一款业务中台类的产品,开发和交付过程中需要大量绘制架构图、流程图、部署拓扑图,但工具散落在各处:有人用通用绘图软件,有人直接在文档里用…

2026/10/19 7:13:11 阅读更多 →
自研轻量级Canvas图表引擎:JSON驱动、可配置的前端可视化方案

自研轻量级Canvas图表引擎:JSON驱动、可配置的前端可视化方案

1. 项目概述做前端这么多年,我发现自己有个收藏夹,里面存了不少图表库、可视化框架的链接,真到要用的时候,反而一个都拿不准。不是功能不够,而是太重了,改个颜色要翻半天文档,想加个交互得理解一…

2026/10/19 7:13:11 阅读更多 →
The Gentlemen勒索软件攻击链拆解与应急响应实战指南

The Gentlemen勒索软件攻击链拆解与应急响应实战指南

过去两年,勒索软件的形态已经发生了根本性的变化。它不再是“把你的文件锁住”这么简单的恶作剧,而是一套完整运转的商业工程。看到The Gentlemen以及它背后超过1570个受害者的公开统计时,我的第一反应不是“又来了一个狠角色”,而…

2026/10/19 7:13:11 阅读更多 →
手作副业从0到工作室:选品、工艺、定价与避坑全指南

手作副业从0到工作室:选品、工艺、定价与避坑全指南

说实话,我第一次看到"artcraft"这个名字,只觉得它是把"艺术"和"工艺"两个单词拼在一起,像是一时兴起起的副业名。等自己真正上手做了一段时间才明白,这两个词的组合恰恰戳中了手作项目最核心的难题…

2026/10/19 7:13:11 阅读更多 →
C语言实现链表、栈与队列:从指针操作到内存管理实战

C语言实现链表、栈与队列:从指针操作到内存管理实战

链表的指针操作、栈的先进后出、队列的先进先出,这三个基础数据结构在 C 语言里的实现,几乎是每一位想搞懂底层原理的开发者都绕不开的关卡。我当年第一次写链表时,头指针、尾指针、临时指针搅在一起,一调试就是大半个晚上&#x…

2026/10/19 7:12:10 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →