4. 数据集准备与标注
做工业缺陷检测,模型选得再好,算法调得再花哨,最后卡住的往往是一个最基础的问题——数据。我见过太多项目,算法工程师花三个月调模型,最后发现数据集本身就有问题,标注错了一半,或者样本量根本不够。说白了,数据是深度学习的“粮草”,粮草不行,仗就没法打。
这一章,我就结合自己踩过的坑,聊聊工业缺陷数据集的特点、标注工具怎么选、以及那些能让你数据量翻倍的数据增强策略。
4.1 工业缺陷数据集的特点
工业场景的数据集,跟网上那些公开数据集(比如 COCO、ImageNet)完全不是一回事。你想想看,工厂产线上拍出来的图片,环境是固定的,光照是固定的,连缺陷的位置都往往集中在几个区域。我刚开始做这个方向时,拿公开数据集训练的模型,一到现场就崩,后来才明白——工业数据有自己的“脾气”。
| 特点 | 说明 | 对项目的影响 |
|---|---|---|
| 样本极度不均衡 | 良品占 99% 以上,缺陷样本可能只有几十张 | 模型容易“偷懒”,全部预测为良品 |
| 缺陷种类多、形态差异大 | 划痕、脏污、气泡、缺角……每种缺陷长不一样 | 需要为每种缺陷单独收集样本 |
| 背景高度重复 | 同一产线拍出来的图,背景几乎一模一样 | 模型容易过拟合到背景,而不是缺陷本身 |
| 标注成本极高 | 需要专业人员标注,一张图可能标半小时 | 必须精打细算,不能浪费任何一张标注 |
| 数据隐私与合规 | 工厂数据不能外传,标注只能在内部进行 | 标注工具必须支持本地部署 |
核心结论:工业缺陷检测的数据集,不是“越多越好”,而是“越精越好”。一张高质量、覆盖关键形态的缺陷图,比一百张重复的图更有价值。
4.2 标注工具:LabelImg 与 CVAT
标注工具的选择,直接影响项目进度。我个人习惯是:小项目用 LabelImg,大项目或者团队协作用 CVAT。为什么?下面细说。
4.2.1 LabelImg:轻量级首选
LabelImg 是纯 Python 写的,基于 Qt 界面,安装简单,开箱即用。我最早做 PCB 缺陷检测时,就是拿它标的。
- 优点:轻量、免费、支持 Pascal VOC 和 YOLO 格式
- 缺点:单机版,不支持多人协作;没有自动标注功能
- 适用场景:个人项目、小样本(几百张以内)
安装也很简单:
# 安装 LabelImg
pip install labelImg
# 启动
labelImg
启动后,界面很直观。左边是图片列表,中间是标注区域,右边是标签列表。快捷键记熟几个就行:W 画框,A/D 切换图片,Ctrl+S 保存。
我的习惯:标注前先建一个 classes.txt 文件,把缺陷类别写进去,比如 scratch、dent、stain。这样标注时直接选,不用每次手动输入,效率能提升 30%。
4.2.2 CVAT:团队协作利器
CVAT(Computer Vision Annotation Tool)是 Intel 开源的在线标注平台。我去年做一个汽车零部件项目,团队 5 个人同时标注,用 CVAT 管理起来非常方便。
- 优点:支持多人协作、自动标注(基于预训练模型)、支持视频标注
- 缺点:部署稍复杂(需要 Docker)、资源占用高
- 适用场景:团队项目、大规模标注(几千张以上)
部署命令:
# 使用 Docker 部署 CVAT
docker compose up -d
部署完成后,浏览器打开 http://localhost:8080,注册账号就能用了。CVAT 支持的任务类型很多,包括目标检测(矩形框)、语义分割(多边形)、关键点等。
注意:CVAT 默认使用 PostgreSQL 存储数据,如果标注量很大(比如超过 10 万张),建议提前调大数据库连接池,否则并发标注时会卡死。我曾经因为这个原因,让团队停工了半天。
4.2.3 两种工具对比
| 维度 | LabelImg | CVAT |
|---|---|---|
| 部署方式 | pip 安装,单机运行 | Docker 部署,Web 访问 |
| 多人协作 | 不支持 | 支持,有任务分配和审核 |
| 自动标注 | 不支持 | 支持(集成 OpenVINO 模型) |
| 输出格式 | VOC XML、YOLO TXT | COCO JSON、VOC XML、YOLO、Mask 等 |
| 适合规模 | < 1000 张 | > 1000 张,或团队协作 |
4.3 数据增强策略:让有限的数据发挥最大价值
工业缺陷样本往往很少,几十张甚至几张。这时候,数据增强就是“无中生有”的关键手段。但要注意——不是所有增强都适合工业场景。
4.3.1 基础增强:几何与颜色变换
这些是最常用的,也是我每次必用的:
- 随机翻转:水平翻转、垂直翻转。注意:有些缺陷有方向性(比如划痕),垂直翻转可能改变缺陷语义,要慎用。
- 随机旋转:±15° 以内。旋转太大,缺陷形态会失真。
- 亮度/对比度调整:模拟产线上光照变化。我一般把亮度范围设在 0.8~1.2 之间。
- 高斯噪声:模拟传感器噪声。噪声强度不要太大,否则模型会学到“去噪”而不是“检测缺陷”。
4.3.2 Mosaic 增强:把四张图拼成一张
Mosaic 是 YOLOv4 里提出来的,后来成了目标检测的标配。它的做法很简单:随机取四张图,缩放后拼成一张大图。
这样做的好处有三个:
- 增加小目标检测能力:四张图拼在一起,每张图里的目标相对变小了,模型被迫去学习小目标的特征。
- 丰富背景多样性:一张图里同时出现四种背景,模型不容易过拟合到单一背景。
- 变相增加 batch size:相当于一次训练看到了四张图的信息。
代码实现(简化版):
import cv2
import numpy as np
def mosaic_augment(images, labels, img_size=640):
# images: 4张图片的列表
# labels: 对应的标注列表
# 返回拼接后的图片和标注
# 随机选择中心点
cx, cy = np.random.randint(img_size//4, 3*img_size//4, 2)
# 创建画布
canvas = np.zeros((img_size, img_size, 3), dtype=np.uint8)
# 将4张图分别放到4个象限
positions = [(0, 0), (img_size//2, 0), (0, img_size//2), (img_size//2, img_size//2)]
for i, (img, pos) in enumerate(zip(images, positions)):
h, w = img.shape[:2]
# 缩放图片
scale = min(img_size//2 / w, img_size//2 / h)
new_w, new_h = int(w * scale), int(h * scale)
img_resized = cv2.resize(img, (new_w, new_h))
# 放置到画布
x_offset, y_offset = pos
canvas[y_offset:y_offset+new_h, x_offset:x_offset+new_w] = img_resized
# 调整标注坐标(略)
return canvas, new_labels
避坑指南:Mosaic 增强后,标注框的坐标需要重新计算。如果原图里的目标被切到了边界,要判断是否保留该目标。我一般设定一个阈值——如果目标在拼接后面积小于原来的 30%,就丢弃这个标注。
4.3.3 MixUp 增强:两张图混合
MixUp 最早是图像分类里用的,后来被引入目标检测。它的原理很简单:把两张图按一定比例混合,标签也按同样比例混合。
公式:
new_image = lambda * image1 + (1 - lambda) * image2
new_label = lambda * label1 + (1 - lambda) * label2
其中 lambda 从 Beta 分布中采样,通常取 α=0.2。
MixUp 的好处是让模型学会“软标签”——不是非黑即白地判断有没有缺陷,而是学会概率化的判断。这在缺陷样本极少的情况下特别有用。
我的经验:MixUp 在缺陷检测中不要用得太猛。我试过把 MixUp 概率设为 0.5,结果模型训练出来,对真实缺陷的置信度普遍偏低。后来我把概率降到 0.2,效果就好多了。说白了,MixUp 是“调味料”,不是“主菜”。
4.4 本章知识结构图
下面这张图,把本章的核心知识点串起来了:
4.5 本章小结
数据集准备是工业缺陷检测项目中最“苦”的活,但也是回报最高的活。我见过太多项目,模型结构改来改去,精度就是上不去,最后发现是标注数据里有一半的框画偏了。所以,别急着调模型,先把数据搞扎实。
- 工业数据集的特点是样本少、不均衡、背景重复——针对这些特点设计策略
- 小项目用 LabelImg,大项目用 CVAT——工具选对,事半功倍
- Mosaic 和 MixUp 是数据增强的“核武器”,但要用对剂量
数据准备好了,下一步就是模型选型和训练了。不过那是后面章节的事,先把这章的内容消化掉。