新闻详情

新闻详情

首页 / 资讯中心 / 详情

LabelImg标注YOLO数据集全流程:格式、划分与避坑指南

发布时间:2026/10/1 3:32:52来源:尧图网络
LabelImg标注YOLO数据集全流程:格式、划分与避坑指南
模型可以换数据集才是正经事。跟刚接触目标检测的朋友聊过几轮之后你会发现真正耗时间的不是在网上看教程而是你亲手准备的那批图片。用labelimg标注YOLO数据集再用脚本自动划分数据集这个流程听起来人人都会但实际操作翻车率极高。我今天就把自己的完整流程写出来从labelimg安装到YOLO格式的txt文件怎么生成再到训练集、验证集、测试集自动划分顺带把过程中遇到的各种坑一起讲清楚。后面提到的方法都是我在YOLOv5、YOLOv8实际项目里验证过的方向对得上也能直接改。1. 动手之前先把YOLO数据集格式和目录结构理清楚1.1 搞懂YOLO标注文件里那5个数字很多新手一上来就打开labelimg开始画框画完却看不懂生成的txt后面手动改数据时完全懵掉。其实你得先明白一件事labelimg在YOLO模式下保存的每一个txt文件和图片同名里面的每一行对应一个目标框格式固定为5个数字类别ID 中心点x坐标 中心点y坐标 框宽度 框高度注意这5个数字里的坐标全部是归一化之后的比值范围在0到1之间。比如一张宽640像素、高480像素的图片某个目标框左上角在(160, 120)右下角在(320, 240)那么换算之后中心点x (160 320) / 2 / 640 0.375中心点y (120 240) / 2 / 480 0.375框宽 (320 - 160) / 640 0.25框高 (240 - 120) / 480 0.25对应txt里就是一行0 0.375 0.375 0.25 0.25开头的0代表这是第0个类别也就是classes列表里的第一个类。这串5个数字就是YOLO系列模型训练时真正读取的标注信息。相比PascalVOC格式那种一长串XML文件YOLO的txt简洁很多但也正因为简洁一旦坐标越界、数据对不上排查起来也更隐蔽。1.2 先立好类别清单别等标完再后悔我见过太多人标注到一半发现类名写错了或者类别顺序乱了导致txt里的ID全部错位。所以开始标注之前我建议你先在图片目录下建一个classes.txt一行一个类名顺序就是之后ID的映射顺序。比如我做一个猫狗检测项目就写cat dog person那么cat永远是0dog永远是1person永远是2。这个文件放好后labelimg在YOLO模式下会自动读取你画框时只需要从下拉列表里选类名不需要每次手动敲。类命名的规范也要提前定好统一小写、单词之间用下划线、不要带空格和中文。比如red_helmet没问题Red Helmet后续处理就得踩坑。特别是当你要把数据集交给别人或者后续做多模态、多数据集合并时类名统一能省下大把时间。图片本身也要做一遍简单清洗。我一般是把待标注图片统一放到images目录图片名改成纯数字或纯英文扩展名统一为.jpg。如果原图有PNG带透明通道或者BMP这种老格式先用Python或图片工具批量转成JPG。这样做不是为了好看而是为了让之后标签文件名严格对应省得检查脚本还要处理各种扩展名差异。2. labelimg安装与基础配置2.1 三种安装方式怎么选labelimg的安装方式不少但不同环境下表现差异很大。我分别说下我实际用下来的经验。第一种是Windows直接下载exe。从GitHub Release里找编译好的labelImg.exe解压就能用。这种方式适合临时标几十张图、不想折腾Python环境的人。缺点是版本往往比较旧有些新功能没有而且一旦图片路径是中文部分旧版会直接闪退。第二种是pip安装。命令行里执行pip install labelimg即可Linux和Windows都能用。这种方式最推荐因为能跟着GitHub仓库更新走。但要注意Python版本我建议用Python 3.8到3.10之间太高版本偶尔会遇到Qt插件加载异常。第三种是Anaconda虚拟环境安装。先建一个干净环境conda create -n labelimg python3.9 conda activate labelimg pip install labelimg然后用命令行启动labelimg。如果你平时还要跑YOLO训练再在这个环境里装torch、opencv这些也不冲突。我个人习惯这种方案因为虚拟环境隔离不会把系统Python搞乱。2.2 打开图片前的四个关键设置安装完成只是热身接下来这4个设置才是重点。第一步打开labelimg后先点击左侧的“Open Dir”选择你的图片目录。别急着画框先确认图片能正常全部加载出来。第二步点击菜单栏或工具栏里的“Change Save Dir”选择标签输出目录。这个目录和图片目录尽量分开。我建议统一的目录结构是dataset/ ├── images/ ├── labels/ └── classes.txt这样之后自动划分数据集时图片和标签能清清楚楚对应。第三步把保存格式切换到YOLO。在labelimg界面上通常显示“PascalVOC”字样点它就能切换成“YOLO”。这里有个经典坑如果你还没设置Save Dir切换YOLO之后保存按钮是灰色的因为YOLO格式必须明确知道把txt写到哪个目录。所以顺序一定是先设置保存目录再切换YOLO格式。第四步在View菜单里勾选“Auto Save mode”。勾选后你切换到下一张图片时上一张自动保存不用每张手动按CtrlS。这个功能强烈建议开不然标到后面一旦忘记保存重命名或切换时就丢标注。注意打开目录后如果发现图片被缩得很小可以先在View里调整缩放或者直接最大化窗口。标注时图片显示太小容易看不清目标边缘。3. 标注实操核心流程加效率技巧3.1 第一张框怎么打到这里可以正式开始画框了。在labelimg主界面里按一下键盘的W键进入创建框模式然后在图片上按住鼠标左键拖出一个矩形松开左键就会弹出类别选择框。如果之前设置好classes.txt这里会直接列出所有类名点一下对应的即可。画框时有一个重要细节框要贴住目标的真实边缘不要把背景大范围包进去也不要切掉目标主体。拿检测人来说框上沿贴近头顶下沿贴近脚底左右到手臂最外侧或肩膀边缘。框稍微紧一点模型学到的特征更准确框太大会把大量背景也当作正样本训练出来容易出现误检。我常用的做法是这样先快速把所有明显的大目标一个个框出来比如图片里两三个人、一辆车先把这些框打完并确认类别接着再框小目标比如远处的安全帽、小的交通标志。因为小目标容易被忽略如果边打大目标边找小目标容易漏掉很多。打完一张图后按D键跳到下一张如果勾了自动保存就不用管了。要返回上一张就按A键。有画错的框按Del删除。3.2 高频按键表和批量标注labelimg的快捷键不多但都特别实用。我把用得最多的几个列一下按键功能使用场景W创建标注框开始画新目标时A / D上一张 / 下一张逐张浏览图片Del删除选中框框画错了CtrlS保存未开自动保存时Ctrl滚轮缩放图片观察小目标空格切换框/图片拖动模式需要平移大图时批量标注方面labelimg没有一个框自动跟踪的功能但你可以把相似图片合并在一个文件夹里按顺序标。比如一批图片都是同一机位、同一角度拍的标完第一张后后续图片能很快复制位置再微调。操作是画好框后按CtrlC复制框到下一张按CtrlV粘贴再拖动调整位置和大小。另外如果某张图里没有目标千万不要硬画一个框也别标个错误类别。直接跳过就行。YOLO允许空标签图片存在它会被当作负样本参与训练。但要注意负样本数量过多会让模型偏向不检测所以我的经验是空图片和正样本图片数量控制在1:1以内。4. 标注中途必须做的质量检查4.1 检查标签文件是否对得上标注这件事最怕“标着标着就乱了”。我见过不少朋友标完500张训练时报错找不到标签或者坐标越界回头排查极其崩溃。所以我的习惯是每标完50张左右就马上跑一遍检查脚本。下面这个脚本是我一直用的逻辑很简单遍历labels目录下的每个txt检查对应图片是否存在、txt是否为空、每一行是否正好5个数字、坐标是否都在0到1之间。import os img_dir D:/dataset/images label_dir D:/dataset/labels for name in sorted(os.listdir(label_dir)): if not name.endswith(.txt): continue txt_path os.path.join(label_dir, name) img_name name[:-4] .jpg if not os.path.exists(os.path.join(img_dir, img_name)): print(f[缺图] {name} 找不到对应图片) continue with open(txt_path, r, encodingutf-8) as f: lines [line.strip() for line in f if line.strip()] if not lines: print(f[空标签] {name}) continue for line in lines: parts line.split() if len(parts) ! 5: print(f[格式错误] {name}: {line}) continue try: vals [float(v) for v in parts[1:]] except ValueError: print(f[非数字] {name}: {line}) continue if any(v 0 or v 1 for v in vals): print(f[坐标越界] {name}: {line})这段脚本输出的信息足够定位是文件缺失、格式错误还是坐标问题。我一般直接在命令行跑看到没有输出就说明这一批干净了再接着标下一批。4.2 典型标注问题与修正除了检查脚本能发现的硬错误还有一些软性问题不容易被脚本抓到需要人工复查。第一个是漏标。这个只能靠肉眼扫特别是密集场景人一多特别容易漏。我建议按类别筛选检查在labelimg里加载图片然后只显示某一个类别的框逐张确认是否都框全了。漏标比错标更隐蔽因为错标还能通过类别分布看出来漏标只有训练完观察漏检才能发现。第二个是框过大/过小。YOLO训练时对极端尺寸的框很敏感。如果框太小比如目标在整张图里的面积占比不到1%训练时可能被下采样丢掉如果框太大把多个目标都包住模型学出来的特征很混乱。我的经验是短边小于10个像素的目标要么重新截取大图要么干脆删掉这个框。第三个是类别混淆。比如“人”和“骑自行车的人”这类如果某个项目需求是只检测人那么人骑在自行车上的框也应该把人完整框出来而不是把人和车一起框进去。这种标注标准上的偏差后期很难通过算法弥补最好标的时候就跟团队或自己统一口径。5. 自动划分数据集脚本才是重点5.1 为什么要用脚本而不是手动分标注完成后下一步是把图片和标签按比例划分成训练集、验证集和测试集。我见过有人直接在文件夹里拖拽复制或者在Excel里手动写文件名第一组还好第二组开始就会出问题。手动划分最大的问题是图片和标签容易错位。你把某张图片拖进train目录但忘了把对应的txt也拖进去训练时YOLO会跳过这张无标签图片但你可能根本发现不了。另一个问题是难以保证随机性。手动挑图片总会下意识把前几十张归为train后几十张归为val如果图片本身是按时序拍的前后场景差异大划分结果就直接失真了。所以自动划分的脚本不仅是为了省事更是为了可复现、可检查。5.2 我的通用划分脚本我常用的脚本思路是读取图片目录里的所有图片随机打乱按比例切成三段再把每张图片和对应标签复制到目标目录。下面是完整代码可以直接改成自己的路径。import os import random import shutil random.seed(42) src_img_dir D:/dataset/images src_lbl_dir D:/dataset/labels dst_root D:/dataset/yolo_split train_ratio 0.7 val_ratio 0.2 # test_ratio 用剩下部分 all_images [ f for f in os.listdir(src_img_dir) if f.lower().endswith((.jpg, .jpeg, .png, .bmp)) ] all_images.sort() random.shuffle(all_images) total len(all_images) train_cnt int(total * train_ratio) val_cnt int(total * val_ratio) splits { train: all_images[:train_cnt], val: all_images[train_cnt:train_cnt val_cnt], test: all_images[train_cnt val_cnt:], } for split_name, imgs in splits.items(): img_out os.path.join(dst_root, images, split_name) lbl_out os.path.join(dst_root, labels, split_name) os.makedirs(img_out, exist_okTrue) os.makedirs(lbl_out, exist_okTrue) for img_name in imgs: shutil.copy( os.path.join(src_img_dir, img_name), os.path.join(img_out, img_name) ) label_name os.path.splitext(img_name)[0] .txt src_lbl os.path.join(src_lbl_dir, label_name) if os.path.exists(src_lbl): shutil.copy(src_lbl, os.path.join(lbl_out, label_name)) else: print(f[警告] {img_name} 没有对应标签文件) print(f{split_name}: {len(imgs)} 张)这里几个关键点你要注意。random.seed(42)必须带上。种子固定了不管跑几次脚本划分结果都一样。这样你今天分完明天想重新训练数据还是同一套实验结果才对得起比较。去掉种子每次都会得到不同的划分想复现就难了。图中没有标签的图片怎么处理脚本里只打了警告没有把它踢掉。如果那些图片确实没有目标保留着当负样本没问题如果是因为漏标导致没有txt那必须回头补标否则相当于给模型喂了错误标签。5.3 进阶按类别均衡划分上面的通用脚本适合类别分布比较均衡的数据集。但做检测项目经常遇到长尾分布比如“人”这个类有5000个框“安全帽”只有50个框。这种时候如果还是简单随机划分验证集和测试集里很可能一顶安全帽都看不见模型训练时有没有学到这个类别完全不知道。我的做法是分层划分。思路不复杂统计每张图片中包含哪些类别先单独为稀有类别预留比例。比如“安全帽”这个类总共出现在10张图里我要保证val占20%那就先从这10张图里随机抽2张放进val再抽2张放进test剩下的进train。对于普通类别仍然按整体随机划分。这样稀有类别在val和test里都有足够样本可供评估。注意一个问题一张图片可能同时包含多个类别分层时如果不同类别的图片重叠有可能把同一张图片同时划进train和val。所以我一般优先处理稀有类把它们对应的图片先锁定到某个集合其他普通类图片再到剩余池子里划分。代码写起来比通用脚本复杂一些但原理很清楚。如果你数据集里的类都很均衡直接用5.2的脚本就行不要过度设计。6. 划分完还要做的事生成数据集配置文件和验证6.1 生成YOLOv8风格的dataset.yaml脚本划分完成后目录结构应该是这样的yolo_split/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/YOLOv5和YOLOv8都能直接认这种目录结构但还需要一个yaml配置文件告诉模型数据在哪、有几个类别。我一般手动写内容如下path: D:/dataset/yolo_split train: images/train val: images/val test: images/test nc: 3 names: [cat, dog, person]这里nc必须和names列表长度一致而且names的顺序要和标注时classes.txt的顺序一致。如果顺序不一致模型训练时就会把猫当成狗这种错位非常致命。path字段可以用绝对路径也可以用相对路径。如果直接把yaml文件放在yolo_split目录下写上path: .配合train: images/train最省事换机器也不容易报路径错。6.2 训练前花10秒验证划分结果配置文件写好后不要急着开训练先跑一下验证。最简单的验证命令python train.py --data dataset.yaml --epochs 1但更快的方式是直接写个小统计脚本把各划分集合里的图片数、标签数、每类框数统计出来打印成表格。我习惯用下面这段import os from collections import Counter sets [train, val, test] for s in sets: lbl_dir fD:/dataset/yolo_split/labels/{s} img_dir fD:/dataset/yolo_split/images/{s} img_cnt len([f for f in os.listdir(img_dir) if f.endswith(.jpg)]) lbl_cnt 0 class_counter Counter() for name in os.listdir(lbl_dir): if not name.endswith(.txt): continue lbl_cnt 1 with open(os.path.join(lbl_dir, name), r) as f: for line in f: parts line.strip().split() if parts: class_counter[int(parts[0])] 1 print(f{s}: 图片{img_cnt}张, 标签文件{lbl_cnt}个) print(f 类别分布: {dict(class_counter)})你看到val的每个类别数量不为0就可以放心训练。如果发现某个类在val或test里是0回到5.3去补分层划分。7. 新手最容易踩的坑7.1 标注阶段常见问题速查现象原因解决办法保存按钮是灰色没设置Save Dir先Change Save Dir再切换YOLO打开labelimg闪退中文路径或旧版exe换pip安装路径全部用英文txt文件生成成XML没切换YOLO格式工具栏点PascalVOC切换成YOLO生成的txt类ID乱了classes.txt顺序改动标注前固定类文件后期不要增删类图片无法加载图片格式非JPG/PNG统一转成JPG并检查图片是否损坏这里最容易被忽略的是类ID顺序。我有个朋友标完2000张图后觉得自己需要加一个新类别直接在classes.txt中间插入一行结果之前所有txt的类ID全往后错了一位2000个标注文件基本作废。所以再次强调类文件一旦定稿不要动。7.2 数据集划分阶段常见问题速查现象原因解决办法train/val图片重叠划分时没处理重复复制用脚本一次性划分不手动补图val缺少某类目标类别不均衡纯随机划分用分层划分训练报no labels found标签目录结构不对或txt为空检查labels/train目录是否存在每张图都说标签不存在图片与txt文件名不一致统一扩展名按文件名检查脚本排查复现不了实验结果每次划分没固定种子代码里加random.seed固定值划分阶段还有一个很容易被忽略的问题从视频抽帧得到的数据集相邻帧的图片内容和目标位置非常接近。如果这些帧同时分到train和val等于变相把验证集漏给了模型评估结果虚高。处理办法是抽帧时每隔N帧抽一张或者按视频编号分成组保证同一段视频的帧只出现在一个划分里。最后分享一个我自己的习惯我每次标完50张图就立刻跑一遍检查脚本确认标签文件没有硬错误标完全部数据后先用通用脚本划分一次再跑统计验证脚本看看每个类在train、val、test里的分布情况。如果发现稀有类不够我直接用分层划分脚本重新来整个过程不超过10分钟。这个习惯帮我避开了很多后期训练时才能暴露的问题。数据集划分这件事不要在最后才做而是每标一批就分一次、验一次你的训练流程会稳很多。实际训练时我是这样启动YOLOv8的yolo taskdetect modetrain datadataset.yaml modelyolov8s.pt epochs50 imgsz640第一次跑之前先把epochs改成1确认能正常进入训练流程再回去跑完整训练。这样即使中间有问题也不会浪费几小时才发现。记住一点标注和划分虽然看起来繁琐但它直接决定了你的模型上限。与其后面反复调参不如在最开始就把数据集质量控住。这套流程如果你认真走一遍后面换成任何目标检测项目基本都能直接套用。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

macOS LVSecurityAgent 彻底卸载指南:M1 Pro 专用四层清除法 2026/10/1 4:40:15

macOS LVSecurityAgent 彻底卸载指南:M1 Pro 专用四层清除法

1. 项目概述:这不是普通卸载,而是一场 macOS 系统清洁战“LVSecurityAgent”这名字听起来像正经安全软件,但实际用过的人基本都骂过街——它不走 App Store、不提供明确卸载入口、不响应系统偏好设置里的常规移除流程,反而在后台疯…

阅读更多 →
Win11永久关闭实时保护的底层原理与三重锁定方案 2026/10/1 4:40:15

Win11永久关闭实时保护的底层原理与三重锁定方案

1. 这不是“关掉杀毒软件”那么简单:Win11实时保护关闭背后的真实逻辑与风险边界你搜“win11永久关闭实时保护”,页面刷出来全是“三步搞定”“一键禁用”的教程,点进去却发现——要么命令行敲完没反应,要么组策略编辑器根本打不开…

阅读更多 →
Java递归从背代码到真理解:四盘汉诺塔拆解与调用栈思维 2026/10/1 4:40:15

Java递归从背代码到真理解:四盘汉诺塔拆解与调用栈思维

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

阅读更多 →
Q-Learning迷宫求解实战:从零实现可调试Q表与避坑指南 2026/10/1 4:40:15

Q-Learning迷宫求解实战:从零实现可调试Q表与避坑指南

简介:本资源是一份面向人工智能与强化学习初学者的实践型教学材料,聚焦Q-Learning算法原理与工程实现,适用于高校课程设计、AI实验课及自主学习者完成迷宫路径规划任务。压缩包共9个文件,含3个核心Python源码(maze.py构…

阅读更多 →
IDM 6.41.2 多线程下载与浏览器接管实战:安装、关闭自动更新 2026/10/1 4:40:14

IDM 6.41.2 多线程下载与浏览器接管实战:安装、关闭自动更新

大文件下载到 99% 突然断流,浏览器重头再来一遍——这种事碰上两次,你就会开始认真找一个正经的下载管理器。Internet Download Manager 6.41.2 就是这类工具里的老牌选手,它的核心能力说穿了三件事:把一个大文件切成若干段并发拉…

阅读更多 →
稀疏奖励下的强化学习:事后经验重放(HER)原理与工程实践 2026/10/1 4:40:08

稀疏奖励下的强化学习:事后经验重放(HER)原理与工程实践

我从"hindsight"这个词切入,聊一个在强化学习里非常经典的思路。做RL的工程师和研究者应该都听过Hindsight Experience Replay(事后经验重放,简称HER),这个思路最早由OpenAI在2017年提出,核心就一…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉