1. 铝片缺陷检测系统概述
在工业质检领域,铝片表面缺陷检测一直是个技术难点。传统人工检测方式效率低下且容易漏检,而基于深度学习的视觉检测方案正在逐步改变这一现状。最近我基于YOLOv8实现了一套完整的铝片缺陷检测系统,能够自动识别zhen_kong(针孔)、ca_shang(擦伤)、zang_wu(污渍)和zhe_zhou(褶皱)四类常见缺陷。
这套系统的主要优势在于:
- 采用最新的YOLOv8模型,在保持高精度的同时实现实时检测
- 完整的数据处理流程,支持XML和TXT两种标注格式
- 配备直观的PyQt5图形界面,便于产线人员操作使用
- 经过优化的模型大小和推理速度,适合部署在工业现场
提示:虽然YOLOv8官方推荐使用TXT格式标注,但保留XML标注可以方便后续与其他系统集成,建议两种格式都保留。
2. 数据集准备与处理
2.1 数据集构成分析
我们使用的铝片缺陷数据集包含1400张工业现场采集的高清图像,涵盖四种典型缺陷:
- zhen_kong(针孔):直径0.5-2mm的圆形孔洞
- ca_shang(擦伤):表面线性划痕
- zang_wu(污渍):不规则形状的污染物
- zhe_zhou(褶皱):材料变形形成的波纹
数据集特点:
- 每张图像分辨率1920×1080
- 标注包含目标位置和类别信息
- 同时提供PASCAL VOC格式的XML和YOLO格式的TXT标注
- 缺陷样本分布均衡,每类约350个样本
2.2 数据划分策略
采用8:2的比例划分训练集和验证集:
- 训练集:1120张图像
- 验证集:280张图像
划分时特别注意:
- 确保每个缺陷类别在训练集和验证集中都有代表
- 保持不同产线、不同批次的样本分布均匀
- 避免相似背景或光照条件的图像集中在同一集合
python复制# 改进版数据集划分代码
def split_dataset(data_dir, train_ratio=0.8):
# 按类别组织文件
class_files = defaultdict(list)
for f in os.listdir(data_dir):
if f.endswith('.jpg'):
# 从标注文件获取类别信息
label_file = f.replace('.jpg', '.txt')
with open(os.path.join(data_dir, label_file)) as lf:
for line in lf:
class_id = int(line.strip().split()[0])
class_files[class_id].append(f)
# 按类别分层抽样
train_files, val_files = [], []
for cls, files in class_files.items():
random.shuffle(files)
split_idx = int(len(files)*train_ratio)
train_files.extend(files[:split_idx])
val_files.extend(files[split_idx:])
# 复制文件到目标目录
copy_files(train_files, 'train')
copy_files(val_files, 'val')
2.3 数据增强方案
为提高模型鲁棒性,训练时采用了以下增强策略:
- 色彩扰动:调整亮度(±30%)、对比度(±20%)、饱和度(±20%)
- 几何变换:随机水平翻转(50%概率)、小角度旋转(±15度)
- 模糊处理:高斯模糊(σ=0.5-1.5)
- 网格遮挡:随机遮挡部分区域
注意:避免使用过大角度的旋转,这会导致铝片缺陷的形态特征失真。对于小目标缺陷(如针孔),过度模糊也会降低检测精度。
3. YOLOv8模型训练
3.1 模型选型考量
我们测试了YOLOv8的不同尺寸模型:
| 模型类型 | 参数量(M) | mAP@0.5 | 推理速度(ms) |
|---|---|---|---|
| YOLOv8n | 3.2 | 0.82 | 6.5 |
| YOLOv8s | 11.2 | 0.86 | 8.2 |
| YOLOv8m | 25.9 | 0.87 | 12.1 |
最终选择YOLOv8s作为基础模型,在精度和速度间取得良好平衡。对于部署在高端GPU设备的情况,可以考虑使用YOLOv8m获得更高精度。
3.2 训练配置细节
创建data.yaml配置文件:
yaml复制# 数据集配置
path: ../datasets/aluminum
train: images/train
val: images/val
# 类别信息
names:
0: zhen_kong
1: ca_shang
2: zang_wu
3: zhe_zhou
启动训练命令:
bash复制yolo task=detect mode=train model=yolov8s.pt data=data.yaml epochs=150 imgsz=640 batch=16 optimizer=Adam
关键训练参数说明:
- 输入尺寸640×640:平衡小目标检测需求和计算效率
- 150个epoch:配合早停策略防止过拟合
- Adam优化器:比默认SGD收敛更快
- 学习率0.001:配合余弦退火调度
3.3 训练过程监控
使用TensorBoard监控训练指标:
python复制from torch.utils.tensorboard import SummaryWriter
# 在训练回调中添加
class TensorBoardLogger:
def __init__(self, log_dir):
self.writer = SummaryWriter(log_dir)
def on_train_epoch_end(self, trainer):
metrics = trainer.metrics
self.writer.add_scalar('train/loss', metrics['train/loss'], trainer.epoch)
self.writer.add_scalar('val/mAP', metrics['val/mAP'], trainer.epoch)
常见训练问题处理:
- 过拟合:增加数据增强、添加Dropout层、提前停止
- 欠拟合:增大模型容量、延长训练时间、调整学习率
- 类别不平衡:使用Focal Loss、调整样本权重
4. PyQt5界面开发
4.1 界面功能设计
主界面包含以下功能区域:
- 图像显示区:展示原始图像和检测结果
- 控制面板:文件操作、检测执行、参数调整
- 结果展示区:缺陷统计表格和分类计数
- 日志窗口:记录操作和检测结果
python复制class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("铝片缺陷检测系统 v1.0")
self.resize(1200, 800)
# 核心组件
self.image_view = QGraphicsView()
self.result_table = QTableWidget()
self.log_text = QTextEdit()
# 工具栏
toolbar = self.addToolBar("操作")
open_action = toolbar.addAction("打开图像")
open_action.triggered.connect(self.open_image)
# 布局
central_widget = QWidget()
layout = QHBoxLayout(central_widget)
left_panel = QVBoxLayout()
left_panel.addWidget(self.image_view)
left_panel.addWidget(self.log_text)
right_panel = QVBoxLayout()
right_panel.addWidget(self.result_table)
layout.addLayout(left_panel, 3)
layout.addLayout(right_panel, 1)
self.setCentralWidget(central_widget)
4.2 检测结果可视化
改进检测结果显示效果:
python复制def visualize_results(self, image, results):
# 绘制检测框
for box in results.boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0])
cls_id = int(box.cls)
conf = float(box.conf)
# 根据类别设置不同颜色
colors = [(255,0,0), (0,255,0), (0,0,255), (255,255,0)]
color = colors[cls_id]
# 绘制矩形框
cv2.rectangle(image, (x1,y1), (x2,y2), color, 2)
# 添加类别和置信度标签
label = f"{self.class_names[cls_id]}: {conf:.2f}"
cv2.putText(image, label, (x1, y1-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
# 转换为QPixmap显示
height, width, channel = image.shape
bytes_per_line = 3 * width
q_img = QImage(image.data, width, height,
bytes_per_line, QImage.Format_RGB888).rgbSwapped()
pixmap = QPixmap.fromImage(q_img)
self.image_view.setPixmap(pixmap)
4.3 性能优化技巧
- 图像加载优化:
python复制# 使用多线程加载大图像
class ImageLoader(QThread):
finished = pyqtSignal(QPixmap)
def __init__(self, path):
super().__init__()
self.path = path
def run(self):
# 使用OpenCV加速图像加载
img = cv2.imread(self.path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
height, width, channel = img.shape
bytes_per_line = 3 * width
q_img = QImage(img.data, width, height,
bytes_per_line, QImage.Format_RGB888)
self.finished.emit(QPixmap.fromImage(q_img))
- 模型推理加速:
python复制# 预热模型
self.model.warmup(imgsz=(1, 3, 640, 640))
# 启用半精度推理
self.model.half()
5. 系统部署与优化
5.1 模型导出与压缩
将训练好的模型导出为ONNX格式:
bash复制yolo export model=best.pt format=onnx imgsz=640 opset=12
应用模型量化压缩:
python复制import onnxruntime as ort
from onnxruntime.quantization import quantize_dynamic
# 动态量化模型
quantize_dynamic(
"best.onnx",
"best_quant.onnx",
weight_type=onnxruntime.quantization.QuantType.QInt8
)
量化后模型对比:
| 指标 | 原始模型 | 量化模型 |
|---|---|---|
| 大小 | 42MB | 11MB |
| mAP | 0.86 | 0.85 |
| 速度 | 8.2ms | 5.1ms |
5.2 多线程处理架构
采用生产者-消费者模式提高系统响应性:
python复制class DetectionWorker(QThread):
finished = pyqtSignal(list)
def __init__(self, model, image):
super().__init__()
self.model = model
self.image = image
def run(self):
try:
results = self.model(self.image)
self.finished.emit(results)
except Exception as e:
print(f"Detection error: {str(e)}")
# 在主窗口中使用
def start_detection(self):
if self.current_image is None:
return
self.statusBar().showMessage("检测中...")
self.worker = DetectionWorker(self.model, self.current_image)
self.worker.finished.connect(self.on_detection_finished)
self.worker.start()
5.3 实际应用建议
- 光照条件控制:
- 建议在产线安装环形光源,确保铝片表面均匀照明
- 避免强反光,可考虑使用偏振滤镜
- 相机选型建议:
- 分辨率:至少500万像素
- 帧率:与产线速度匹配(通常30fps足够)
- 接口:GigE或USB3.0
- 部署注意事项:
- 工业电脑建议配置:i7处理器/16GB内存/独立GPU
- 保持运行环境温度在0-40℃
- 定期清洁相机镜头
这套系统在实际产线测试中达到了98.5%的检出率,误检率低于1.5%,单次检测耗时约15ms,完全满足工业实时检测需求。通过调整模型参数和检测阈值,可以针对不同产线的具体需求进行优化。
