资讯详情

资讯详情

labelImg标注电塔数据集实战:从环境准备到YOLO格式转换的避坑指南

简介本资源为labelImg目标检测标注工具的图文操作教程文档面向计算机视觉与机器学习入门者、目标检测数据集制作人员及需要批量标注图像的学生与工程师帮助其快速掌握从安装配置到标注结果导出的完整流程。压缩包内共1个doc文件约2.96MB以图文并茂的方式讲解软件界面设置、Auto Save模式勾选、图片文件夹与保存目录指定、画框标注与快捷键切换等操作并涵盖predefined_classes.txt预定义类别修改、VOC格式XML文件生成、xml_to_csv与tfrecord转换以及YOLO格式标注文件的类别id与归一化中心点坐标、宽高参数说明。教程还结合电塔标签等实际案例演示标注过程并介绍目标检测、图像分类、对象跟踪等应用场景。目前已有731人学习适合希望提升标注效率与准确性的读者参考。1. 从一堆电塔照片到可训练数据集labelImg 到底卡在哪一步手里攒了几千张电塔巡检照片想训一个目标检测模型结果第一步就卡住了——数据标注。这不是个例我见过太多团队在模型结构上反复调参却把标注环节当成“随便点点”的体力活最后 mAP 上不去回头查半天才发现是框歪了、类别串了、坐标没归一化。labelImg 就是解决这个问题的一个轻量级的目标检测标注工具把图片里的目标框出来、打上类别标签输出 PASCAL VOC 的 XML 或 YOLO 的 TXT 格式直接喂给后续训练流程。它适合谁做电力巡检、工业质检、遥感识别这类需要自建数据集的从业者尤其是那些不想在标注工具上花冤枉钱、又需要批量处理的中小团队。这篇笔记不讲安装教程只讲我实际标注电塔数据集时踩过的坑和跑通的流程。2. 标注前的环境准备目录结构与类别定义2.1 为什么目录结构比安装更重要很多人拿到 labelImg 第一件事是找安装包但真正影响标注效率的是目录怎么摆。我一般会建一个项目根目录下面分三个子目录images放原始图片annotations放标注输出classes放类别定义文件。这样做的原因是 labelImg 的“Change Save Dir”默认会记住上次路径如果图片和标注混在一起批量转换脚本很容易把 XML 和 JPG 一起扫进去导致解析报错。# 推荐的项目目录结构 dataset/ ├── images/ # 原始图片建议按批次分子目录 │ ├── batch_01/ │ └── batch_02/ ├── annotations/ # 标注输出与 images 结构镜像 │ ├── batch_01/ │ └── batch_02/ └── classes/ └── predefined_classes.txt这个结构的好处是后续做训练集/验证集划分时直接按 batch 切分不会出现同一基塔的多角度照片同时出现在训练和验证集里避免数据泄漏。我见过有人把所有图片平铺在一个目录结果划分时随机打散同一张图的不同裁剪版本分到了两边验证集精度虚高上线就翻车。2.2 predefined_classes.txt 的编码与命名规范类别定义文件是标注一致性的源头。labelImg 启动时通过“Open Dir”旁边的“Change Save Dir”下方按钮加载这个文件之后画框时可以直接选类别不用每次手输。这里有两个硬性要求文件必须是 UTF-8 无 BOM 编码每行一个类别名不能有空格和特殊字符。# predefined_classes.txt 示例电塔巡检场景 luomuzhengchang xiaodingzhengchang luomuqueshi luomusongdong xiaodingqueshi xiaodingbiko jueyuanzi junyahuan zhongchui luosilianban xuanchuixianjia fangzhenchuitahaopai xiangxupaijing shipai注意类别名不要用中文虽然 labelImg 界面支持显示但后续转 TFRecord 或 YOLO 格式时中文类别名在编码转换环节极易出现乱码。我一般用拼音缩写团队内部维护一份映射表即可。另外类别顺序一旦确定就不要改YOLO 格式里的类别 id 是按这个文件的行号从 0 开始编号的改了顺序等于所有旧标注的类别全错位。2.3 Auto Save 与快捷键的配合逻辑在 View 菜单里勾选 Auto Save mode 之后每次按 D 切换到下一张时自动保存当前标注。这个功能配合快捷键 W画框和 D下一张能形成流水线操作W 画框 → 选类别 → D 保存并跳转。我实测标注电塔照片熟练后单张 5 个目标大约 8 秒完成。但 Auto Save 有个坑如果画框过程中误触 D会保存一个不完整的框。所以我的习惯是画完框先按 CtrlS 手动确认一次再按 D 跳转虽然多一步但避免了返工。3. 标注操作全流程从画框到格式输出3.1 批量打开与文件列表管理点击“Open Dir”选择images/batch_01右下角 FileList 会列出所有图片。如果图片数量超过 500 张labelImg 的列表加载会明显变慢这是 PyQt 的列表渲染瓶颈。我的做法是按 300 张一批切分目录标完一批再开下一批。另外FileList 支持搜索过滤输入文件名关键词可以快速定位到某张图适合补标遗漏目标时使用。标注时用 W 键激活画框模式鼠标拖拽出矩形框松开后会弹出类别选择框。如果目标被遮挡或截断框要包含可见部分即可不要脑补完整目标——这是标注规范问题不是工具问题但直接影响模型学到什么。我见过把半个绝缘子框成完整绝缘子的模型在推理时对截断目标置信度极低。3.2 PASCAL VOC XML 结构解析标注完成后在annotations/batch_01下会生成与图片同名的 XML 文件。用记事本打开可以看到完整结构annotation folderbatch_01/folder filenametower_001.jpg/filename size width1920/width height1080/height depth3/depth /size object namejueyuanzi/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin845/xmin ymin312/ymin xmax1023/xmax ymax498/ymax /bndbox /object /annotation关键字段说明size里的 width/height 是图片原始尺寸后续做数据增强时裁剪缩放都要基于这个值反算bndbox的坐标是绝对像素值左上角为原点truncated和difficult在训练时可以作为损失权重参考但大多数开源框架默认忽略这两个字段。如果标注时没勾选“Difficult”默认都是 0。3.3 切换到 YOLO 格式的注意事项在 labelImg 左侧工具栏点击“PascalVOC”按钮可以切换为“YOLO”格式。切换后重新标注或对已有标注执行一次保存会在同一目录生成.txt文件和classes.txt。YOLO 格式的每一行是类别id 中心x 中心y 宽 高全部归一化到 0-1 之间。# YOLO 格式示例对应上面的 XML 5 0.4865 0.3750 0.0927 0.1722这里的类别 id 是predefined_classes.txt里的行号减一。中心点坐标和宽高的归一化公式是x_center (xmin xmax) / 2 / widthw (xmax - xmin) / width。如果从 VOC 切到 YOLO 后发现坐标不对八成是图片尺寸读错了——labelImg 读的是 XML 里的 size 字段如果 XML 被手动改过归一化就会出错。注意切换格式后建议先拿 5 张图做一轮验证用 Python 读一下 TXT 文件把归一化坐标反算回像素值和原图对比框的位置是否一致。这一步花两分钟能省掉后面训练时 loss 不收敛的排查时间。4. 避坑与排查标注环节的五个血泪教训4.1 类别名拼写不一致导致训练报错现象训练时提示KeyError: jueyuanzi 或类别数量对不上。原因predefined_classes.txt 里某一行末尾多了空格或者标注时手动输入了类别名而不是从下拉框选。解决用脚本统一清洗所有 XML 的 name 字段去掉首尾空格并和类别文件做交集校验。import os import xml.etree.ElementTree as ET def validate_classes(anno_dir, class_file): with open(class_file, r, encodingutf-8) as f: valid_classes set(line.strip() for line in f if line.strip()) 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)) for obj in tree.findall(object): name obj.find(name).text if name not in valid_classes: print(f{xml_file}: 非法类别 {name})这个脚本遍历标注目录把不在类别文件里的 name 全部打印出来跑一遍就能定位问题文件。4.2 图片旋转后标注框错位现象手机拍摄的竖屏照片在 labelImg 里显示正常但标注后框的位置和实际目标偏移。原因JPEG 的 EXIF 方向信息被 labelImg 读取并旋转了显示但 XML 里记录的坐标是基于旋转后的显示尺寸而后续训练框架用 OpenCV 读图时默认不处理 EXIF导致坐标对不上。解决标注前统一用 PIL 或 ImageMagick 把 EXIF 方向信息固化到像素里再开始标注。from PIL import Image, ImageOps import os def fix_exif(img_dir): for fname in os.listdir(img_dir): if fname.lower().endswith((.jpg, .jpeg)): path os.path.join(img_dir, fname) img Image.open(path) img ImageOps.exif_transpose(img) img.save(path, quality95)跑完这个脚本再标注就不会出现旋转错位。4.3 大图标注卡顿与内存溢出现象标注 4K 以上分辨率图片时labelImg 界面卡死或直接崩溃。原因labelImg 默认把整张图加载到内存并渲染大图会吃掉大量显存/内存。解决标注前把图片长边缩放到 1920 以内或者用--resize参数启动。如果必须保留原图分辨率建议换用支持瓦片加载的工具但 labelImg 本身没有这个能力只能预处理。4.4 自动保存覆盖已标注文件现象重新打开一个已标注过的目录误触 D 键后原有 XML 被空标注覆盖。原因Auto Save 模式下切换到下一张时如果当前图没有标注会生成一个空的 XML 覆盖旧文件。解决标注目录做好版本备份或者关闭 Auto Save养成手动 CtrlS 的习惯。我现在的做法是每批标注完成后立刻打包一份 zip 存档标注过程中不依赖任何自动保存。4.5 YOLO 格式的 classes.txt 丢失现象切换到 YOLO 格式后只生成了 TXT 标注文件没有 classes.txt训练时类别 id 无法映射。原因classes.txt 只在第一次保存 YOLO 格式时生成如果中途删除了或者换了目录不会自动重建。解决手动从 predefined_classes.txt 复制一份重命名为 classes.txt 放到标注目录。注意 YOLO 训练时读取的类别文件路径要和这个一致。5. 从标注到训练格式转换与数据校验的进阶技巧标注完成只是第一步真正决定模型效果的是数据校验和格式转换的严谨程度。我一般会在标注结束后跑一套校验脚本检查四件事坐标是否越界、宽高是否为零、类别 id 是否连续、图片和标注是否一一对应。import os import xml.etree.ElementTree as ET def check_annotation(anno_dir, img_dir): issues [] for xml_file in os.listdir(anno_dir): if not xml_file.endswith(.xml): continue base xml_file.replace(.xml, ) img_path os.path.join(img_dir, base .jpg) if not os.path.exists(img_path): issues.append(f缺少图片: {base}) continue tree ET.parse(os.path.join(anno_dir, xml_file)) root tree.getroot() w int(root.find(size/width).text) h int(root.find(size/height).text) 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 0 or ymin 0 or xmax w or ymax h: issues.append(f{base}: 坐标越界 ({xmin},{ymin},{xmax},{ymax})) if xmax xmin or ymax ymin: issues.append(f{base}: 宽高为零) return issues这个脚本跑完把 issues 列表打印出来逐条修完再进入训练流程。我自己的习惯是标注完成后先跑校验再转 TFRecord 或 YOLO 格式最后拿 10 张图做可视化抽查把框画回原图上看一眼。这套流程走下来基本不会出现训练时才发现标注错误的情况。从那以后我每次标注新数据集都强制走一遍校验脚本宁可多花半小时也不想到训练中途才发现问题回头返工。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →