YOLO 数据集-数据清洗
·
在使用 YOLO 训练目标检测模型时,数据清洗(Data Cleaning) 是提升模型性能的关键一步。脏数据(错误标注、模糊图像、重复样本等)会导致模型学习到错误模式,造成漏检、误检、训练不稳定等问题。
以下是针对 YOLO 数据集的 系统性数据清洗方案 + 具体操作方法,适用于你“两轮电动车骑行人员未戴头盔”这类实际项目。
✅ 一、YOLO 数据集结构回顾
标准 YOLO 格式数据组织如下:
dataset/
├── images/
│ ├── img1.jpg
│ ├── img2.jpg
│ └── ...
├── labels/
│ ├── img1.txt
│ ├── img2.txt
│ └── ...
└── data.yaml
- 每张图片对应一个
.txt文件 .txt中每行格式:class_id center_x center_y width height(归一化坐标)
🧹 二、数据清洗的 7 大核心方案(含具体操作)
🔹 1. 删除无标注的空标签文件
有些图像没有目标,但 labels/ 下仍有空 .txt 文件(正常),但也可能有“本该有目标却漏标”的情况。
✅ 清洗策略:
- 保留:确实无目标的空
.txt(如背景图) - 删除或重标:应有目标但为空的文件(如骑电动车的人没被标)
🛠 操作代码(Python):
import os
label_dir = 'dataset/labels'
image_dir = 'dataset/images'
for label_file in os.listdir(label_dir):
txt_path = os.path.join(label_dir, label_file)
with open(txt_path, 'r') as f:
lines = f.readlines()
if len(lines) == 0:
print(f"空标签文件: {label_file}")
# 可选择:删除、标记人工复查、或保留
✅ 建议:对空标签文件进行人工抽查,确认是否真无目标。
🔹 2. 检查标注框是否越界或异常
YOLO 要求坐标归一化且在 [0,1] 范围内。常见错误:
x,y,w,h超出 0~1(如 1.05)- 宽高为负数或零
- 框太大(如 w=0.99,几乎整图)
🛠 检查代码:
def check_bbox_valid(file_path):
with open(file_path, 'r') as f:
for line in f:
parts = list(map(float, line.strip().split()))
cls, x, y, w, h = parts
if not (0 <= x <= 1 and 0 <= y <= 1 and 0 < w <= 1 and 0 < h <= 1):
return False
return True
# 遍历所有 label 文件
for label_file in os.listdir('labels'):
if not check_bbox_valid(os.path.join('labels', label_file)):
print(f"异常标注: {label_file}")
✅ 处理方式:用标注工具(如 LabelImg)打开修复。
🔹 3. 图像质量筛查:模糊、过曝、过暗
低质量图像无法提供有效特征,影响模型学习。
✅ 清洗方法:
| 方法 | 工具/代码 | 说明 |
|---|---|---|
| 模糊检测 | Laplacian 方差 | 值越小越模糊 |
| 亮度检测 | HSV 的 V 通道均值 | <30 过暗,>220 过曝 |
🛠 模糊检测代码:
import cv2
def is_blurry(image_path, threshold=100):
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
fm = cv2.Laplacian(gray, cv2.CV_64F).var()
return fm < threshold
# 示例
if is_blurry('img1.jpg'):
print("图像模糊")
✅ 建议:设置
threshold=80~120,根据数据集调整
🔹 4. 去重:删除重复图像
同一场景多次拍摄、翻转、轻微裁剪都会导致重复,造成过拟合风险。
✅ 方法:
方法 1:感知哈希(Perceptual Hash)
from PIL import Image
import imagehash
def get_hash(img_path):
return imagehash.average_hash(Image.open(img_path))
# 比较两张图 hash 差异 < 5 表示高度相似
hash1 = get_hash('img1.jpg')
hash2 = get_hash('img2.jpg')
if hash1 - hash2 < 5:
print("可能是重复图像")
方法 2:使用工具
- dupeGuru(图形化去重)
- OpenCV + 直方图对比
✅ 建议:对相似度 > 95% 的图像保留一张。
🔹 5. 标注一致性检查
确保:
- 同一类目标标注一致(如“头盔”是否都标了)
- 是否存在错标(把帽子标成头盔)
- 是否漏标(多人骑行只标了一个)
✅ 解决方案:
- 使用 可视化脚本 批量查看“图+框”
import cv2
def visualize_yolo(image_path, label_path, class_names):
img = cv2.imread(image_path)
h, w = img.shape[:2]
with open(label_path, 'r') as f:
for line in f:
parts = list(map(float, line.strip().split()))
cls_id, x, y, w_bbox, h_bbox = parts
x1 = int((x - w_bbox/2) * w)
y1 = int((y - h_bbox/2) * h)
x2 = int((x + w_bbox/2) * w)
y2 = int((y + h_bbox/2) * h)
cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2)
cv2.imshow('Check', img)
cv2.waitKey(0)
✅ 建议:随机抽查 10%~20% 数据,重点看困难样本(遮挡、夜间)。
🔹 6. 类别分布与平衡检查
避免某些类别样本极少(如“未戴头盔”只有 50 张,而“戴头盔”有 2000 张)
✅ 统计代码:
from collections import defaultdict
class_count = defaultdict(int)
for label_file in os.listdir('labels'):
with open(os.path.join('labels', label_file), 'r') as f:
for line in f:
cls_id = int(line.split()[0])
class_count[cls_id] += 1
print(class_count) # 输出:{0: 1200, 1: 800} → 检查是否均衡
✅ 处理建议:
- 少类样本:数据增强(翻转、亮度调整)
- 或使用 类别加权 loss(如
class_weights)
🔹 7. 自动标注错误检测(高级)
使用已训练的 YOLO 模型反向检测标注错误:
步骤:
- 用当前数据集训练一个初步模型
- 用模型推理所有训练图像
- 对比 预测框 vs 真实标注
- 模型能检出但你没标 → 漏标
- 你标了但模型完全检不出 → 可能错标或模糊
✅ 工具推荐:使用 Roboflow 或自定义脚本实现“模型辅助清洗”。
✅ 三、推荐清洗流程(实战步骤)
| 步骤 | 操作 |
|---|---|
| 1 | 删除完全空白或损坏图像(文件无法打开) |
| 2 | 检查标注格式合法性(坐标是否越界) |
| 3 | 使用哈希去重,删除重复图像 |
| 4 | 模糊/过曝图像筛查,标记或删除 |
| 5 | 可视化抽查标注质量(重点查漏标、错标) |
| 6 | 统计类别分布,必要时补充数据 |
| 7 | (可选)用预训练模型辅助发现异常标注 |
🛠 四、推荐工具汇总
| 工具 | 用途 |
|---|---|
| LabelImg / LabelStudio | 查看、修改标注 |
| Roboflow | 自动清洗、增强、格式转换 |
| OpenCV + Python 脚本 | 自定义清洗逻辑 |
| dupeGuru / VisiPics | 图像去重 |
| Weights & Biases (W&B) | 可视化标注与预测对比 |
✅ 五、针对你项目的特别建议(头盔检测)
- 重点检查“遮挡”场景:头盔被雨衣、头发遮挡是否仍标注?
- 统一标准:
- “戴头盔”:头盔覆盖头顶 ≥ 70%
- “未戴”:明显无头盔或仅戴帽子
- 增加困难样本:夜间、逆光、侧脸等
- 使用 Mosaic 增强前清洗:避免脏数据被增强放大
✅ 总结:数据清洗不是一次性的,而是迭代过程
好模型 = 好数据 × 好训练
清洗一次不够,建议:
- 训练后分析失败案例 → 反向优化数据
- 每迭代一轮模型,都复查一批“误检/漏检”对应的原始数据
如果你需要,我可以提供:
- 完整的数据清洗 Python 脚本(.py 文件)
- YOLO 格式检查工具
- 自动化清洗 pipeline
欢迎继续提问!祝你头盔检测项目成功落地 🚀
更多推荐
所有评论(0)