ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

labelImg汉化版使用全指南:安装、标注与VOC/YOLO格式转换

labelImg汉化版使用全指南:安装、标注与VOC/YOLO格式转换 简介面向Windows x64平台的中文汉化版labelImg 1.8.6由作者以PyInstaller打包为绿色独立exe下载解压后双击labelImg.exe即可直接使用无需额外安装Python环境适合制作深度学习目标检测数据集的新手也方便算法工程师在本地快速完成图像标注。压缩包体积38.72MB共151个文件包含85个dll、30个pyd作为底层运行依赖库23个qm为Qt语言翻译文件、支撑全中文界面显示另有labelImg.exe主程序、Python脚本及少量配置说明结构清晰且解压即用不依赖系统预先部署环境。该版本经过作者实际打包与测试验证可离线启动标注窗口菜单、工具栏均为中文提示免去命令行配置和依赖安装的繁琐步骤适合Windows x64系统用户直接纳入日常标注工作流。资源当前已有1700人浏览学习是快速获得可直接运行的汉化图像标注工具的低门槛选择。1. labelImg 汉化版直接能跑这个 exe 包里到底装了些什么做目标检测数据集的朋友对 labelImg 应该不陌生。原版项目虽然开源但想在 Windows 上跑起来要先装 Python、再装 PyQt5、再处理各种依赖运气好半小时运气不好一个下午就没了。手头这个 1.8.6 汉化中文版不一样它把环境全部打进了 Windows x64 的 exe 里解压出来双击即用界面是中文的省掉了配环境这一整段折腾。所谓直接可用不是一句宣传而是你拿到手就能出数据打开图像目录画框保存 PascalVOC 或 YOLO 文件直接喂给后面的训练脚本。它解决的是标注场景里最实际的问题快速打开、框目标、落盘格式正确。适合刚接触数据标注的新手也适合不想在工具上浪费时间的老手。2. labelImg 1.8.6 的技术底细PyQt5、打包原理与两种标注格式2.1 汉化版是怎么来的翻译文件与源码字符串labelImg 本身是 Python 写的桌面程序界面基于 PyQt5。1.8.6 是这个项目在社区里流传最广的版本号之一功能完备交互也定下来了。汉化版不是官方出的是社区维护者改的改法主要有两种直接把源码里的英文字符串替换成中文后重新打包或者走 Qt 的翻译机制把界面文案放进 .ts 文件再用 lrelease 编译成 .qm 给程序加载。直接改源码的汉化最彻底菜单、按钮、对话框基本全覆盖代价是以后升级得重新改走 .ts 翻译路线的干净但只能盖住调用了翻译接口的字符串总有些右键菜单、提示框漏在外面。这个 1.8.6 汉化版走的是前一种路线所以主界面基本全中文个别角落残留英文也正常不影响使用。理解这个来源对你判断两件事有帮助为什么 exe 体积不小以及杀毒软件为什么偶尔会叫。因为里面塞了一个完整的 Python 解释器和 PyQt5 运行库用 PyInstaller 打包体积根本压不下来。常见做法是用 PyInstaller 完成打包命令本身能说明原理# 从源码重新打包 labelImg 的常见做法理解原理用不一定真要执行 pip install pyinstaller pyqt5 pyinstaller --windowed --onefile --name labelImg labelImg.py--windowed让程序启动时不弹黑色控制台窗口--onefile把所有依赖打进单个 exe代价是启动时要把内嵌资源解压到临时目录所以第一次打开会慢一两秒--name指定产物文件名。看到这里你基本能判断杀毒软件对它的误报更多是特征匹配和程序本身没有关系。2.2 PascalVOC 与 YOLO两种输出格式两种使用场景标注的本质就一句话告诉后续训练程序这张图里某个目标在哪个位置、属于哪一类。labelImg 支持两种输出界面右侧的按钮负责在 PascalVOC 和 YOLO 之间切换。PascalVOC 格式用一个 XML 文件描述一张图文件名、图像尺寸、每个目标的类别名和边界框的四个像素坐标。XML 是人类可读的出了错可以直接打开看我一般拿它做前期摸索因为处理逻辑透明。YOLO 格式用 TXT 文件描述一张图每行一个目标内容是类别编号加 cx、cy、w、h。cx、cy 是归一化中心点w、h 是归一化目标宽高全部除以图像自身宽高取值都在 0 到 1 之间。这里最容易被忽略的一点TXT 里只存类别编号不存类别名编号含义要靠一份独立的 classes.txt 去解释序号一旦对不上训练出来的模型类别就全乱了。对比项PascalVOCYOLO存储格式单张图一个 XML单张图一个 TXT边界框xmin, ymin, xmax, ymax像素cx, cy, w, h归一化类别表示字符串类名整数索引靠 classes.txt 解释常见下游MMDetection、Detectron2 等Ultralytics YOLO 系列具体选哪个取决于你要喂给谁。训练脚本明确要 YOLO 就趁标注时直接输出 YOLO不要标完再转只是采集数据、还没定模型PascalVOC 更安全。labelImg 自带的转换功能本质就是把 XML 读出来重算坐标和后面第 4 章我给的脚本一个思路。2.3 为什么 1.8.6 到今天还有人找目标检测标注工具这些年出了不少CVAT、X-AnyLabeling、Roboflow 界面都更现代。但 1.8.6 的搜索量一直没下去原因是很多标注工程师的诉求很朴素能离线用、不折腾环境、上手零学习成本、标注文件格式和现有脚本无缝衔接。这几点 1.8.6 全占。界面虽然老但功能边界很清楚框选、标签、分类、切换下一张、保存没有多余干扰。而且汉化打包版把 Python 环境一并免掉双击就能进界面这对一台可能连编译器都没有的标注机来说是实打实的省事。还有一层是团队协作时的稳定性多人标同一批数据如果提前定了 classes.txt 和输出格式每个人拿到的文件结构完全一致训练脚本直接就能消费。这个版本源码结构简单社区里针对它的汉化包、快捷键说明、批量转换脚本非常多遇到新需求也能快速改不会卡在黑匣子里。多人协作的场景里我反而更倾向于用这种老工具因为它没有账号体系没有云端同步每个人的产出就是纯本地文件好排查也好合并。3. labelImg 安装与启动从解压到完成第一张图标注3.1 解压与目录检查先确认你拿到的包是完整的搜过 labelImg 安装教程的人应该都知道网上教程十有八九在讲配 Python 环境而这个打包版把这些步骤全略掉了直接进入使用环节。拿到 zip 先解压我习惯放到纯英文路径比如 D:\labelImg-w64而不是放在带中文用户名的「下载」目录里。虽然打包版对中文路径的容忍度比源码版高但标注数据路径里有中文后面接训练脚本时迟早要扫码。解压后先做一次目录检查# 在解压后的目录下确认关键文件都在 ls -la # 查看 exe 位宽PE32 表示 x64 file labelImg.exe # 看默认类别文件里预置了哪些类 cat data/predefined_classes.txtfile命令在 Windows 上不一定有最直观的办法是右键 exe 看属性或者任务管理器里看架构。data/predefined_classes.txt是 labelImg 启动时预读的类别清单一行一个类别名标注时界面里会直接出现这些类省去每次手输。我建议拿到包先看一眼这个文件把它替换成自己项目的类别清单。下面是一个典型解压目录的内容路径作用labelImg.exe主程序双击启动data/predefined_classes.txt预定义类别清单locale/翻译文件目录汉化包常见要注意的是如果你看到 locale 目录里有 .qm 后缀文件说明这个汉化版走的是翻译机制没有的话就是直接改源码字符串打包的。两种都不影响使用但后面遇到「汉化不完整」时判断方法不一样这个在第 5 章会展开。3.2 首次启动VC 运行库是唯一可能出问题的地方双击 labelImg.exe绝大多数情况直接进界面。但在干净的机器上可能碰到两种情况。第一种弹窗提示找不到 VCRUNTIME140.dll这是 PyInstaller 打包程序依赖微软 VC 运行库而精简版系统往往没装。解决方法是装一次微软官方 vc_redist.x64.exe装完即好不需要重启。第二种是杀毒软件直接拦截或删除了 exe。PyInstaller 打包程序的特征比较集中容易被启发式扫描标记把文件加白名单或从隔离区恢复即可。这两种情况都不代表软件本身有问题。我自己在一台装了全家桶的机器上遇到过 exe 被隔离的情况恢复后标注了一整天没有任何异常。排查闪退有个标准手段在 cmd 里先 cd 到解压目录再手动输入 labelImg.exe 回车双击时被吞掉的报错文本会直接留在终端里缺哪个 DLL 一眼就能看到。换到正常环境后这个汉化版的表现非常稳定可以长时间挂机标图不退出。3.3 新建标注项目的标准步骤图片目录、类别文件与保存位置第一张图之前按这个顺序准备建一个 images 目录把要标注的图放进去建一个 classes.txt一行一个类别名启动 labelImg用「打开目录」选 images检查界面右侧当前输出格式是 PascalVOC 还是 YOLO如果是 YOLO 模式第一次保存时会让你指定 classes.txt 路径。一个典型目录结构长这样D:\lData\ ├── images\ # 原图 │ ├── 000001.jpg │ └── 000002.jpg ├── classes.txt # 一行一个类别 └── labels\ # 标注文件保存目录给 YOLO 模式指定 classes.txt 这一步很多人会跳过结果类别编号变成默认的 0、1、2后面训练脚本一看全对不上。正确做法是先写好 classes.txt打开目录后立刻设置好。界面里的自动保存开关建议直接打开并设置默认保存目录这样切换图像时标注结果会自动落盘。第一次画框按键盘 W 或点右侧画框按钮拖出一个矩形松开后输入类别单张完成按 CtrlSD 切下一张、A 切上一张。这套动作熟练后一张图平均二十多秒就能出框。4. 标注数据全链路从一张图到训练数据文件4.1 单张图像标注的完整操作链进入标注界面后完整的单张流程是画框松手输入类别名或从预定义列表里点选检查框是否贴边微调边缘保存切下一张。如果提前写了 classes.txt双击已有框会弹出类别列表直接点选就行比每次手输快很多。微调阶段有个老版本特有的交互细节拖边界框的四条边和四个角点都能调整但鼠标必须正正好点在边缘上才生效否则容易整个框被拖走。新手最容易在这里误操作本想微调右边结果整个框平移到旁边。这不算 bug是这个版本的交互习惯用几次就适应了。选中框后按 Delete 可以删除误标的框删除动作会立刻反映在内存里保存后文件同步更新。保存动作本身没有玄学点了保存文件才落盘。如果开了自动保存切换图像时程序会把前一张的标注先写出。我见过一次比较惨的事故同事标了三百张图一直没开自动保存中途程序崩了三百张的成果全在内存里蒸发。这种场景没有任何后悔药只能重标。所以我现在拿到任何标注工具第一件事永远是找自动保存开关并且手动保存的习惯也不能丢两者互为兜底。4.2 XML 与 TXT标注产物的字段逐项对照PascalVOC 的标注产物长这样annotation folderimages/folder filename000001.jpg/filename sourcedatabaseUnknown/database/source size width800/width height600/height depth3/depth /size object namecat/name bndbox xmin120/xmin ymin100/ymin xmax300/xmax ymax280/ymax /bndbox /object /annotationsize三个字段是标注时刻图像的真实宽高和通道数训练脚本常拿它来反算归一化坐标object可以有多个每标一个目标就多一个 object 块bndbox都是像素坐标顺序是左上角和右下角。我见过有人把 ymin 和 ymax 写反肉眼很难发现但训练效果会明显变差所以校验脚本里必查 xmin 小于 xmax 且 ymin 小于 ymax。YOLO 格式的产物就简单得多每行五个数字空格分隔0 0.2625 0.3167 0.2250 0.3000第一个数字是类别编号对应 classes.txt 里的行序号从 0 开始后面四位是归一化后的 cx、cy、w、h。比如 cx0.2625含义是框中心在图像宽度的 26.25% 处不是像素坐标。这个版本保存 YOLO 文件时浮点数位数固定不用手动补精度float32 够用补多了只是让文件变大。4.3 效率设置与批量转换三个开关能省一半时间标注效率不靠手速靠设置。第一个开关是预定义类别classes.txt 写全类别后标注时从列表点选比手输快得多也杜绝了拼写不一致。第二个是自动保存加默认保存目录保存目录固定后XML 或 TXT 和图片分开放后续打包数据集时只需拷两个目录。第三个是显示模式界面里可以隐藏标注框、隐藏标签文字需要审核时再打开避免一堆框叠在一起看不清。如果前期用 PascalVOC 标了一批后面要切 YOLO不需要重新标。labelImg 自带转换按钮但数据量大时直接跑脚本批量处理更快也更好排查import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, class_names): tree ET.parse(xml_path) root tree.getroot() w int(root.find(size/width).text) h int(root.find(size/height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_names: continue # 不在类别清单里的直接跳过 cls_id class_names.index(name) box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) dw, dh 1.0 / w, 1.0 / h cx (xmin xmax) / 2.0 * dw cy (ymin ymax) / 2.0 * dh bw (xmax - xmin) * dw bh (ymax - ymin) * dh lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) return \n.join(lines)函数输入是单个 XML 路径和类别名列表返回 YOLO 格式文本。核心逻辑是先按 XML 里记录的图像宽高算出归一化系数 dw、dh再把像素框换算成中心点和宽高的 0 到 1 小数。使用前确认 XML 里的 width、height 与真实图像一致否则坐标全偏。批量跑几百个 XML 也就是几秒的事跑完随机抽几张验证一下就能交付。5. 避坑手册labelImg 使用中最常见的五个翻车现场这一个章节写的全是我自己踩过或替同事擦过屁股的坑。每一条都是真实发生过的现象按现象、原因、解决的顺序写方便你对照排查。5.1 双击 exe 没反应或闪退现象双击后鼠标转两圈窗口没出现或者一闪就消失。 原因最常见是缺 VC 运行库报错弹窗一闪而过用户只看到闪退。其次是杀毒软件把 exe 隔离了双击的其实是个空壳。 解决先在 cmd 里 cd 到解压目录手动运行 labelImg.exe把真正报错文本露出来。提示缺 DLL 就去装微软官方 vc_redist.x64.exe提示找不到文件或者干脆没报错就去杀毒软件隔离区找 exe恢复并加白名单。最后确认你解压出来的真是 x64 版本不要在 32 位系统上硬跑。5.2 打开大图后界面卡到无法画框现象打开一张十几 MB 的航拍图或长截图画框时鼠标明显延迟拖不动。 原因老版本用 Qt 组件加载整张原图超大图缩放时内存和 CPU 开销很大没有异步加载优化。 解决标注前先把图像预处理到合理尺寸。常见做法是统一把最长边缩到 2000 像素左右既保留框选精度又让界面跟手。同时检查内存占用不要同时挂着浏览器、IDE 和标注工具抢资源。还有一个容易被忽略的点如果图片目录里有损坏的图片打开时会卡住甚至崩我一般会先跑一遍脚本统计图像是否都能正常读取。5.3 YOLO 模式下类别编号错乱的玄学现象标注没问题TXT 也生成了但训练时发现类别 A 和类别 B 对调了或者出现一个从没标过的类别编号。 原因YOLO 模式靠 classes.txt 解释编号。如果你中途换过 classes.txt或者标注时用的类别清单和训练时不一致编号就漂移。举一个具体例子classes.txt 里是 dog、cat、person标了五十张图 dog 都是 0后来同事在文件开头插了一行 bird全部旧标注的 dog 从 0 变成 1模型就全乱了。 解决classes.txt 一旦定稿整个标注周期不修改、不排序、不删行。真需要改类别清单先备份旧文件改完重新检查所有已标注 TXT 的编号是否还能对上。我自己的习惯是标注前记录 classes.txt 的行号和类名对应表标注完成后对照一遍再进训练。5.4 汉化不完整菜单一半中文一半英文现象主菜单是中文的但某些右键菜单、属性对话框里还是英文。 原因这个打包版改的是源码字符串主界面覆盖全但程序里一些硬编码的英文提示没有进翻译范围。这在社区汉化版里非常常见不是文件损坏也不影响数据产出。 解决如果不介意界面直接继续用。真在意可以看解压目录里有没有 locale 文件夹和 .qm 文件有的话可以用 Qt Linguist 打开 .ts 补全翻译再重新编译没有的话说明是改源码打包的得改源码重打包工作量不小性价比很低。我一般选择忽略标注工具的核心任务是出数据不是界面美观。5.5 标了一下午退出后发现数据没进文件现象切了很多张图关掉程序回去看 labels 目录只有零星几个 XML 或 TXT。 原因自动保存没开而且你切换图片的频率比保存快。程序只在保存动作发生时写盘切换图片不会自动保存除非开了自动保存开关。 解决打开界面里的自动保存开关同时养成 CtrlS 的手动习惯。已经发生的话还有补救办法重新打开目录确认自动保存已开启然后逐张切换图片切换时会触发保存把内存里的标注重新写盘。这个坑我踩了不止一次现在无论用什么标注工具第一步永远是确认自动保存状态。6. 标注质量验证三个不花钱的检查技巧6.1 脚本校验先跑一遍别信眼睛标注完成后我习惯在目录里跑一段十几行的校验脚本检查每个 XML 能不能被解析坐标有没有越界TXT 的类别编号有没有超出 classes.txt 范围。健康数据是训练的前提脚本比人眼靠谱。import glob import os from xml.etree import ElementTree as ET xmls glob.glob(labels/*.xml) for f in xmls: root ET.parse(f).getroot() w int(root.find(size/width).text) h int(root.find(size/height).text) for obj in root.iter(object): xmin, ymin float(obj.find(bndbox/xmin).text), float(obj.find(bndbox/ymin).text) xmax, ymax float(obj.find(bndbox/xmax).text), float(obj.find(bndbox/ymax).text) if not (0 xmin xmax w and 0 ymin ymax h): print(f[越界] {os.path.basename(f)} {xmin},{ymin},{xmax},{ymax})这段脚本遍历 labels 目录下所有 XML先用 size 里的宽高做范围判断。if not 那一行是单条校验任一边不满足就会打印文件路径和坐标方便回到 labelImg 里定位修正。跑完没有输出说明这批 XML 数值上基本健康。6.2 可视化验证把框画回原图脚本只能查数值问题查不出框偏了半个身位这种质量问题。我习惯在训练前随机抽几十张图按 XML 坐标把框画回原图肉眼过一遍。用 PIL 加载原图遍历 XML 画矩形保存成带框预览图就行。抽检数量不用多三五十张足够发现系统性偏移。如果发现某些图框整体向左偏一截通常不是标错了而是图像在预处理环节被压缩过回溯预处理逻辑比一张张改快得多。6.3 训练前的最后一分钟检查把标注文件交给训练脚本前我固定做三件事核对 images 目录和 labels 目录的文件名一一对应确认 classes.txt 的类名顺序和训练配置里的类别映射一致随手打开一个 TXT 看序号有没有超出类别总数。这三步加起来不到一分钟能挡掉大部分低级事故。有一次批量标注完三千张图跑训练时发现 mAP 全乱查了两天原因就是 classes.txt 被某次操作追加了一行历史编号整体后移。从那以后我每次标注交付前都强制走一遍这套校验先跑数值脚本再抽预览图最后对一遍类别映射三个都过了才敢进训练管线。手头这个汉化打包版拿过去就能用但用之前记得先把第 3.3 节的目录和类别文件准备好再按这套习惯走一遍希望帮到你。本文还有配套的精品资源点击获取
返回列表