介绍
目前,基于机器视觉的表面缺陷检测设备已广泛取代人工视觉检测,在包括3C、汽车、家电、机械制造、半导体与电子、化工、制药、航空航天、轻工等多个行业领域得到应用。传统的基于机器视觉的表面缺陷检测方法通常采用常规图像处理算法或人工设计的特征加分类器。一般而言,成像方案通常利用被检测表面或缺陷的不同特性来进行设计。合理的成像方案有助于获得光照均匀、能够清晰反映物体表面缺陷的图像。近年来,基于深度学习的许多缺陷检测方法也被广泛应用于各种工业场景。
与计算机视觉中明确的分类、检测和分割任务相比,缺陷检测的要求非常普遍。实际上,它的要求可以分为三个不同的层次:“缺陷是什么”(分类)、“缺陷在哪里”(定位)和“有多少缺陷”(分割)。
先看下结果
表面缺陷检测中的关键问题
1)小样本问题
目前,深度学习方法被广泛应用于各种计算机视觉任务,表面缺陷检测通常被视为其在工业领域的特定应用。传统理解认为,深度学习方法不能直接应用于表面缺陷检测的原因是在实际工业环境中,所提供的工业缺陷样本太少。
与ImageNet数据集中的超过140
0万个样本数据相比,表面缺陷检测面临的最关键问题是小样本问题。在许多实际工业场景中,甚至只有几张或几十张的有缺陷图像。事实上,针对工业表面缺陷检测中的小样本问题,目前有4种不同的解决方案:
数据扩增和生成
最常用的缺陷图像扩展方法是对原始缺陷样本进行多次镜像、旋转、平移、畸变、滤波和对比度调整等多种图像处理操作,以获取更多的样本。另外,更常见的一种方法是数据合成,通常将单个缺陷融合并叠加在正常(非缺陷)样本上,形成缺陷样本。
网络预训练和迁移学习
通常来说,使用小样本训练深度学习网络很容易导致过拟合,因此基于预训练网络或迁移学习的方法目前是样本数量较少时最常用的方法之一。
合理的网络结构设计
通过设计合理的网络结构,也可以大大降低对样本的需求。基于压缩采样定理对小样本数据进行压缩和扩展,使用CNN直接对压缩采样数据特征进行分类。相比于原始图像输入,压缩输入可以大大降低网络对样本的需求。此外,基于双子网络的表面缺陷检测方法也可以视为一种特殊的网络设计,可以大大降低对样本的需求。
无监督或半监督方法
在无监督模型中,只使用正常样本进行训练,因此无需缺陷样本。半监督方法可以利用未标记样本来解决小样本情况下的网络训练问题。
2)实时问题
基于深度学习的缺陷检测方法在工业应用中包括数据标注、模型训练和模型推理三个主要环节。实际工业应用中的实时性更多关注模型推理。目前,大多数缺陷检测方法侧重于分类或识别准确性,而很少关注模型推理的效率。加速模型的方法有很多,如模型权重和模型剪枝。此外,虽然现有的深度学习模型使用GPU作为通用计算单元(GPGPU),但随着技术的发展,FPGA被认为将成为一个有吸引力的替代选择。
东北大学发布的表面缺陷数据集收集了热轧钢带的六种典型表面缺陷,分别是轧痕(RS)、斑痕(Pa)、裂纹(Cr)、坑洞表面(PS)、夹杂物(In)和划痕(Sc)。该数据集包括1,800张灰度图像,每种典型表面缺陷包含300个样本。对于缺陷检测任务,该数据集提供了注释,指示每个图像中缺陷的类别和位置。对于每种缺陷,黄色框表示其位置边界,绿色标签是类别得分
检测结果
代码
在这里插入代码片# -*- coding:utf-8 -*-
#完整代码扣扣1309399183
@Tiny-Defect-Detection-for-PCB
from __future__ import absolute_import
from __future__ import print_function
from __future__ import division
import tensorflow as tf
import tensorflow.contrib.slim as slim
import os, sys
import numpy as np
import time
sys.path.append("../")
from libs.configs import cfgs
# from libs.networks import build_whole_network2
from libs.networks import build_whole_network
from data.io.read_tfrecord import next_batch
from libs.box_utils import show_box_in_tensor
from help_utils import tools
os.environ["CUDA_VISIBLE_DEVICES"] = "2"
def train():
faster_rcnn = build_whole_network.DetectionNetwork(base_network_name=cfgs.NET_NAME,
is_training=True)
with tf.name_scope('get_batch'):
img_name_batch, img_batch, gtboxes_and_label_batch, num_objects_batch = \
next_batch(dataset_name=cfgs.DATASET_NAME, # 'pascal', 'coco'
batch_size=cfgs.BATCH_SIZE,
shortside_len=cfgs.IMG_SHORT_SIDE_LEN,
is_training=True)
gtboxes_and_label = tf.reshape(gtboxes_and_label_batch, [-1, 5]