1. 钢材表面缺陷检测项目概述
在工业质检领域,钢材表面缺陷检测一直是个技术难点。最近我基于YOLOv5模型和东北大学(NEU)表面缺陷数据集,完成了一个钢材表面缺陷检测项目。这个数据集包含了热轧带钢6种典型表面缺陷的1800张灰度图像,每种缺陷各300个样本,原始分辨率为200×200像素。这些缺陷包括:
- 轧内垢(RS)
- 斑块(Pa)
- 裂纹(Cr)
- 点蚀面(PS)
- 夹杂物(In)
- 划痕(Sc)
这个项目特别适合想要了解工业质检中计算机视觉应用的朋友,或者正在寻找实际项目练手的深度学习爱好者。通过这个项目,你不仅能学习YOLOv5的实际应用,还能掌握处理工业图像数据集的技巧。
2. 数据集分析与处理
2.1 数据集特点解析
NEU表面缺陷数据集有几个显著特点需要我们特别注意:
-
类内差异大:同一种缺陷可能有完全不同的表现形式。比如划痕缺陷,既有水平方向的,也有垂直和倾斜方向的,形态差异很大。
-
类间相似度高:不同类别的缺陷可能看起来很相似。例如轧内垢、裂纹和点蚀面,在视觉特征上有很多相似之处。
-
光照和材质影响:由于采集环境不同,同类缺陷的灰度值可能有明显变化,这增加了模型学习的难度。
2.2 数据预处理技巧
针对这个数据集的特点,我采用了以下预处理方法:
python复制import cv2
import numpy as np
def preprocess_image(img_path):
# 读取灰度图像
img = cv2.imread(img_path, 0)
# 直方图均衡化增强对比度
img_eq = cv2.equalizeHist(img)
# 高斯模糊降噪
img_blur = cv2.GaussianBlur(img_eq, (3, 3), 0)
# 归一化处理
img_norm = img_blur / 255.0
return img_norm
这段代码实现了几个关键预处理步骤:
- 以灰度模式读取图像(因为原始数据就是灰度的)
- 使用直方图均衡化增强图像对比度
- 应用高斯模糊减少噪声
- 将像素值归一化到0-1范围
注意:预处理步骤需要根据具体缺陷类型调整。比如对于细微的裂纹,过强的模糊可能会丢失重要特征。
2.3 数据增强策略
为了提升模型泛化能力,我采用了多种数据增强方法:
python复制from albumentations import (
Compose, Rotate, RandomBrightnessContrast,
GaussianBlur, HorizontalFlip, VerticalFlip
)
augmentation = Compose([
Rotate(limit=30, p=0.5),
RandomBrightnessContrast(p=0.3),
GaussianBlur(blur_limit=(3, 7), p=0.2),
HorizontalFlip(p=0.5),
VerticalFlip(p=0.5)
])
这个增强组合包含了:
- 随机旋转(±30度)
- 亮度和对比度调整
- 不同程度的高斯模糊
- 水平和垂直翻转
特别重要的是旋转和翻转操作,这能有效模拟不同方向的划痕缺陷,解决类内差异大的问题。
3. YOLOv5模型训练与优化
3.1 模型选择与配置
我选择YOLOv5s作为基础模型,因为它在速度和精度之间取得了很好的平衡。对于200×200的小尺寸图像,这个轻量级模型已经足够。
模型配置的关键参数:
yaml复制# yolov5s.yaml
nc: 6 # 6种缺陷类别
depth_multiple: 0.33 # 模型深度系数
width_multiple: 0.50 # 模型宽度系数
训练参数设置:
python复制# 训练命令示例
python train.py --img 200 --batch 64 --epochs 100 --data neu.yaml --cfg yolov5s.yaml --weights yolov5s.pt
3.2 训练技巧与调优
在训练过程中,我发现几个关键点:
-
学习率设置:对于小数据集,初始学习率设为0.01比较合适,然后采用余弦退火策略。
-
早停机制:设置patience=10,当验证集mAP连续10个epoch没有提升时停止训练。
-
类别权重调整:对于样本数量不均衡的类别,可以在loss函数中设置类别权重。
一个实用的训练监控技巧是使用TensorBoard实时观察各项指标:
bash复制tensorboard --logdir runs/train
3.3 模型评估指标
我主要关注以下几个指标:
- mAP@0.5:IoU阈值为0.5时的平均精度
- Precision-Recall曲线
- 各类别的混淆矩阵
对于工业质检场景,我们通常更关注Recall(召回率),因为漏检的代价往往比误检更高。
4. 实际应用与部署
4.1 模型导出与优化
训练完成后,我将模型导出为ONNX格式以便部署:
python复制python export.py --weights runs/train/exp/weights/best.pt --include onnx --img 200
对于边缘设备部署,还可以进一步量化模型:
python复制import onnxruntime as ort
from onnxruntime.quantization import quantize_dynamic
quantize_dynamic("best.onnx", "best_quant.onnx")
4.2 推理性能优化
在实际应用中,我实现了多线程流水线处理:
python复制import threading
import queue
class InferencePipeline:
def __init__(self, model_path):
self.model = ort.InferenceSession(model_path)
self.input_queue = queue.Queue(maxsize=10)
self.output_queue = queue.Queue(maxsize=10)
def preprocess_thread(self):
while True:
img = self.input_queue.get()
# 预处理代码
preprocessed = preprocess_image(img)
self.output_queue.put(preprocessed)
def infer_thread(self):
while True:
img = self.output_queue.get()
# 推理代码
outputs = self.model.run(None, {'images': img})
# 后处理...
这种设计可以充分利用CPU和GPU资源,提高吞吐量。
5. 常见问题与解决方案
5.1 类间混淆问题
问题现象:模型经常把轧内垢(RS)误认为裂纹(Cr)。
解决方案:
- 在数据增强中加入更多灰度变换,增强模型对灰度变化的鲁棒性
- 使用注意力机制增强模型对细微特征的捕捉能力
- 调整损失函数中的类别权重
5.2 小缺陷漏检问题
问题现象:小的点蚀面(PS)经常被漏检。
解决方案:
- 修改anchor box尺寸,使其更匹配小缺陷的尺寸
- 在训练时增加小缺陷样本的权重
- 使用更高分辨率的输入(虽然会增加计算量)
5.3 光照变化敏感问题
问题现象:在不同光照条件下,模型性能波动较大。
解决方案:
- 在预处理中加入更强大的光照归一化方法
- 使用更多样化的光照条件数据进行增强
- 考虑使用HDR成像技术获取更稳定的输入
6. 项目扩展与改进方向
在实际部署后,我总结了几个值得尝试的改进方向:
-
多模型集成:结合分类模型和检测模型的结果,提升整体准确率。
-
主动学习:在实际应用中收集难样本,持续优化模型。
-
3D缺陷检测:对于某些缺陷(如深裂纹),可以考虑使用3D成像技术。
-
异常检测:对于未知类型的缺陷,可以结合异常检测算法。
这个项目最让我惊喜的是,即使使用相对简单的YOLOv5模型,经过合理的数据处理和调优,也能在钢材表面缺陷检测任务上取得不错的效果。关键在于深入理解数据特点,并针对性地设计解决方案。