4、工业数据集构建:从产线到标注,再到训练集

数据,说白了就是模型的“饭”。没有好数据,再牛的YOLO也白搭。我在工业现场摸爬滚打这些年,见过太多项目死在数据上——要么采集得不对,要么标得稀烂。今天咱们就把这顿饭怎么做透,讲明白。

核心观点:工业视觉的数据集构建,不是简单的“拍照片+画框”。它是一套从产线光照、相机选型、标注规范到格式转换的完整工程流程。任何一个环节偷懒,模型上线后都会加倍还给你。

4.1 数据采集策略:别让模型“看”不懂产线

很多新手上来就问:“我要拍多少张?” 我的回答永远是:“先别管数量,先管质量。” 工业场景下,数据采集的核心是 覆盖真实工况。

我经历过一个项目,客户在实验室拍了1000张完美样本,模型跑起来准确率99%。一上产线,直接掉到60%。为什么?产线上的光照是暖色的,还有震动,产品表面有油污。模型没见过这些,当然懵。

4.1.1 采集策略清单

维度 策略要点 我的踩坑经验
光照 覆盖不同时段、不同角度、不同亮度 我曾经只拍了正光,结果模型在侧光下完全失效
角度 模拟产线传送带的轻微偏移和旋转 建议用振动台模拟产线抖动,哪怕只有±2°
背景 包含传送带、夹具、其他产品的干扰 纯色背景训练出来的模型,换条传送带就废了
缺陷 确保正负样本比例合理,缺陷类型全覆盖 别只拍“标准缺陷”,真实产线上的划痕千奇百怪
分辨率 与部署时的相机分辨率一致 用高分辨率拍,训练时降采样,效果比低分辨率拍好很多

我的习惯:每次采集前,先写一份《数据采集SOP》,把光照色温、相机高度、拍摄距离、文件命名规则全部定死。产线工人按SOP操作,数据质量才有保障。

4.2 标注工具:LabelImg vs LabelStudio

标注工具选哪个?我个人的建议是:小项目用LabelImg,大项目或团队协作用LabelStudio。别纠结,两个我都会教你怎么用。

4.2.1 LabelImg:轻量级单兵利器

LabelImg是我最早用的工具。它轻、快、不需要装数据库。适合一个人标几百张图的小项目。

  • 安装: pip install labelImg 一行命令搞定
  • 输出格式: 默认Pascal VOC(XML),也支持YOLO格式(TXT)
  • 快捷键: W(画框)、D(下一张)、A(上一张)——标得快全靠它
  • 缺点: 不支持多人协作,没有自动保存(我吃过亏,标了一下午没保存……)
# 启动LabelImg
labelImg

# 如果想直接输出YOLO格式,启动时指定
labelImg data/ pre-defined_classes.txt

4.2.2 LabelStudio:企业级协作平台

后来项目大了,团队五六个人同时标注,LabelImg就不够用了。LabelStudio支持Web界面、多人协作、自动保存、版本管理。说白了,它就是标注界的“GitHub”。

  • 安装: pip install label-studio,然后 label-studio start
  • 核心功能: 支持图像、文本、音频多模态标注
  • 导出格式: COCO JSON、Pascal VOC、YOLO、CSV等
  • 我的用法: 先让两个标注员独立标同一批数据,然后我用LabelStudio的“标注一致性检查”功能找出差异,再让专家仲裁。这样能显著提升标注质量。

注意:LabelStudio默认导出的是JSON格式,需要转换成YOLO需要的TXT格式。别慌,后面我会给转换脚本。

4.3 数据集划分:别让验证集“作弊”

数据标完了,接下来就是划分。很多教程说“训练集70%、验证集20%、测试集10%”,但工业场景下,我建议你换个思路。

为什么会这样?因为工业数据往往存在 时序相关性。比如你从产线上连续拍了1000张图,前500张是上午拍的,后500张是下午拍的。如果随机划分,模型可能“记住”了光照变化,而不是真正学会了检测目标。

4.3.1 我的划分策略

划分方式 适用场景 比例建议
随机划分 数据独立同分布,无时序依赖 70% / 20% / 10%
时序划分 产线连续采集,光照/背景缓慢变化 前60%训练,中间20%验证,后20%测试
按批次划分 不同批次产品有差异(如不同模具) 留一个完整批次做测试

避坑指南:我曾经犯过一个错——用随机划分训练了一个缺陷检测模型,验证集准确率95%,但上线后一塌糊涂。后来发现,训练集和验证集里混入了同一张图的不同裁剪版本。模型其实在“背答案”。所以,划分前一定要做 去重。

4.4 格式转换:从标注到YOLO能吃的格式

YOLO需要的标注格式很简单:每个图像对应一个TXT文件,每行代表一个目标,格式为 class_id x_center y_center width height,所有坐标都是归一化到[0,1]的。

但标注工具输出的格式五花八门。我整理了一个对照表:

标注格式 文件类型 坐标表示 转换难度
Pascal VOC XML xmin, ymin, xmax, ymax(像素) 低
COCO JSON JSON x, y, width, height(像素) 中
YOLO TXT TXT x_center, y_center, width, height(归一化) 无需转换

下面是我常用的转换脚本片段,把Pascal VOC转成YOLO格式:

import xml.etree.ElementTree as ET
import os

def convert_voc_to_yolo(xml_file, output_dir, classes):
    tree = ET.parse(xml_file)
    root = tree.getroot()
    
    # 获取图像尺寸
    width = int(root.find('size/width').text)
    height = int(root.find('size/height').text)
    
    # 获取文件名(不含扩展名)
    filename = os.path.splitext(root.find('filename').text)[0]
    
    with open(os.path.join(output_dir, filename + '.txt'), 'w') as f:
        for obj in root.findall('object'):
            class_name = obj.find('name').text
            class_id = classes.index(class_name)
            
            # 读取像素坐标
            xmin = int(obj.find('bndbox/xmin').text)
            ymin = int(obj.find('bndbox/ymin').text)
            xmax = int(obj.find('bndbox/xmax').text)
            ymax = int(obj.find('bndbox/ymax').text)
            
            # 转换为YOLO格式(归一化)
            x_center = (xmin + xmax) / 2.0 / width
            y_center = (ymin + ymax) / 2.0 / height
            w = (xmax - xmin) / width
            h = (ymax - ymin) / height
            
            f.write(f"{class_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\n")

# 使用示例
classes = ['bottle', 'cap', 'label']  # 你的类别列表
convert_voc_to_yolo('annotation.xml', 'labels/', classes)

重要提醒:转换后一定要做 可视化验证。我写了一个小脚本,把YOLO标注画回原图上,肉眼检查框的位置对不对。这一步能发现很多坐标转换错误,比如宽高算反了、归一化除错了。

4.5 知识体系总览

下面这张图,是我对本章知识体系的总结。你可以把它当作一个检查清单,做项目时对照着来。

工业数据集构建知识体系 数据集构建 数据采集策略 标注工具选择 数据集划分 格式转换 光照/角度 背景/缺陷 LabelImg LabelStudio 随机/时序 按批次 VOC→YOLO COCO→YOLO 核心原则 先覆盖工况,再追求数量;先验证标注,再开始训练

4.6 最后说几句

数据集构建这件事,听起来不酷,但它是整个项目里最值得花时间的地方。我见过太多团队花两周调模型,却只花两天准备数据——结果就是反复返工。

我的建议是:把数据集的构建流程标准化、工具化。写脚本、做检查、留文档。这样下次做类似项目时,你就能直接复用这套流程,效率翻倍。