当前位置: 首页 > article >正文

51c~缺陷检测~合集2

我自己的原文哦~     https://blog.51cto.com/whaosoft/12386431

一、缺陷检测~使用深度学习1

这里研究工业ai, 在制造业中任何公司的主要目标都是为客户生产无缺陷产品。如果在产品开发过程中出现任何内部孔、凹坑、磨损或划痕(由于多种原因,从生产设备故障到恶劣的工作条件),其结果不仅是产品缺陷,而且导致客户满意度的损失。在本文中,您将了解可用于识别缺陷的各种深度学习方法,从而防止缺陷产品流入市场。

深度学习是如何工作的?

深度学习是一种机器学习,其特点是使用神经元或数据计算流经的节点。深度学习神经元之所以如此命名,是因为它们最初被建模为以类似于人脑中神经元的结构发送和接收信号。神经元接收一个或多个输入信号(要么来自原始数据,要么来自模型前一层的神经元),对这些输入信号进行一些计算,然后(通过突触)将输出信号发送到神经网络深处的神经元。通过这种方式,这些模型模仿了人类大脑如何学习检测、识别和分类周围环境中的项目,并做出非线性决策。最初的神经网络设计非常简单(或“肤浅”),但今天的架构已经变得极其复杂,现在被称为“深层”神经网络。

然而,深度神经网络不仅仅是一堆神经层。考虑一层作为单个神经元的外壳。这些层将始终以输入层开始(接收数据),以输出层结束(产生结果)。此外,在神经网络中,可以有零个或多个隐藏层堆叠在一起。层架构的类型包括但不限于密集(或完全连接)、卷积、反褶积和递归。然而,单独添加额外的层并不足以解决更复杂的问题,事实上可能会带来额外的挑战和潜在的错误。

必须根据需要解决的问题提出多种技术。存在不同形式的深度神经网络,每种网络都以不同的方式和不同的算法来解决问题。

图像分析-在分析图像时,更需要查看像素定义的事物层次,而不是单独查看每个像素。卷积网络使用称为卷积层的神经元的特定层,通常用于解释、编码或生成图片。由于许多卷积层的叠加,检测图片中更复杂的分层模式是可能的。卷积层越深,生成的特征图越抽象。

文本处理——文本分类、情感分析、自动翻译和语言建模概念是文本数据处理的一些最常见的深度学习用例。在某些情况下,例如分类,神经网络的表现几乎和人类一样好。然而,在某些工作中,神经网络仍然远远不能与人类进行比较,例如情绪分析等。 

自动编码器-自动编码器的目标是能够完全解构并重建输入数据。重建需要使用中间压缩表示,因此神经网络的表示必须具有足够的信息来进行此生成。自动编码器的压缩表示随后可用于各种任务,例如分类。

生成对抗网络-它们已被有效地用于黑白照片的着色、增强图像分辨率和重建部分擦除的图像等。然而,GAN陡峭的学习曲线限制了他们的潜力,这似乎非常有前景。它主要用于医学图像,以提高图像性能,并使人们更容易发现疾病。

深度学习缺陷检测技术

物体识别、智能机器人、显著性检测、停车场声音事件检测和无人机叶片问题诊断只是受益于深度学习技术的众多学科中的几个例子。有时,可以通过抽象表示或奇异特征(如边缘和梯度)更好地解释数据。深度学习模型结合了这些低级特征,以构建属性和特征的更抽象的高级表示,并提高模型的性能。利用这些核心概念,一些学者正在尝试将深度学习技术应用于产品缺陷的识别,以提高产品质量。

1.LeNet,卷积神经网络(CNN)

CNN代表“卷积神经网络”,是具有一个或多个卷积层的任何前馈神经网络,但也可能包含完全连接的层、池化层、ReLU校正层等。最初的卷积神经网络结构之一是LeNet框架,它可以识别手写字符。

在这里,我们将探讨使用LeNet模型结构原理来检测缺陷的两种方法。一种是创建复杂的多层CNN结构,使用不同的网络结构添加图像内容特征,并完成端到端训练以检测图像中的缺陷。

2.基于神经网络的产品缺陷检测工具

AutoEncoder网络的编码和解码阶段是最重要的。这是一种数据压缩技术,其中压缩和解压缩功能是从样本数据中自动学习的,而不是由人类编程的。在编码阶段将输入信号转换为用于特征提取的编码信号;特征信息在解码阶段被转换为重建信号,并且通过调整权重和偏置来最小化重建误差,以在解码阶段实现缺陷检测。

AutoEncoder网络与其他机器学习技术的区别在于,AutoEncode器网络的学习目标是特征学习,而不是分类。它还具有卓越的自学能力,能够进行极为非线性的映射。为了处理分割复杂背景和前景区域的挑战,它可以学习非线性度量函数。

3.深度残差神经网络产品故障检测技术

深度残差网络向卷积神经网络添加残差模块。残差网络具有简单的优化过程,并且可以通过增加网络深度来提高精度。生成对抗网络、CNN等。提取特征随着网络深度的增加而改善,然而,激活函数可能无法收敛。深度残差网络的目标是在增长网络结构的同时优化网络层的数量,使得残差单元中卷积层的输出和输入元素维度相同。

4.全卷积神经网络

当两个相邻层中的所有节点都连接时,该层称为密集层或完全连接层。由于完全连接的神经网络采用完全连接的操作,因此将有更多的权重值,这意味着网络将需要更多的内存和计算。在构建完全连接的神经网络期间,卷积层创建的特征图被映射为固定长度的特征向量。整个卷积神经网络可以拍摄任何大小的输入图片,通过用去卷积层对最后一个卷积层的特征图进行采样,可以恢复到与原始图像相同的大小。   

实 施

下面,我们实施图像处理技术,这些技术产生的输出类似于深度学习网络可能产生的卷积神经网络中的特征图。

import numpy as np
import cv2
import matplotlib.pyplot as plt

接下来,将创建一个函数,使用图像处理来检测缺陷,以显示不同形式的图像,如hsv、binay、dst、扩张等。

def fab_defect_detect(img):
   image = img.copy()    
   hsv = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)    
   h = hsv[:,:,0]    
   s = hsv[:,:,1]    
   v = hsv[:,:,2]
   
   blr = cv2.blur(v,(16,16))    
   dst = cv2.fastNlMeansDenoising(blr,None,10,7,22)    
    _,binary = cv2.threshold(dst, 127,256,cv2.THRESH_BINARY+cv2.THRESH_OTSU)    kernel = np.ones((5,5),np.uint8)    
    erosion = cv2.erode(binary,kernel,iterations = 1)    
   dilation = cv2.dilate(binary,kernel,iterations = 1)    
   if(dilation==0).sum() >1:        
       print("Fabric has a defect")        
       contours,_=cv2.findContours(dilation,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
       for i in contours:
           if cv2.contourArea(i) < 261124.0:                
                cv2.drawContours(image, i, -1, (0,255,0), 3)             
             else:                  
                  print("There is No Defect in Fabric")      
       return img,hsv,v,blr,dst,binary,dilation,image

最后,使用以下命令生成输出。

input_img= cv2.imread('Fabric1.jpg')
image,hsv,v,blr,dst,binary,dilation,img = defect_detect(input_img)
fig, ax = plt.subplots(2,4,figsize=(16,12))
ax[0,0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
ax[0,0].set_title('Original Image')
ax[0,1].imshow(cv2.cvtColor(hsv, cv2.COLOR_BGR2RGB))
ax[0,1].set_title('HSV Image')
ax[0,2].imshow(cv2.cvtColor(v, cv2.COLOR_BGR2RGB))
ax[0,2].set_title('V Image')
ax[0,3].imshow(cv2.cvtColor(blr, cv2.COLOR_BGR2RGB))
ax[0,3].set_title('Blur Image')
ax[1,0].imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
ax[1,0].set_title('Filter Image')ax[1,1].imshow(binary,cmap='gray')
ax[1,1].set_title('Binary Image')ax[1,2].imshow(dilation,cmap='gray')
ax[1,2].set_title('Dilation Image')
ax[1,3].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
ax[1,3].set_title('Output Image')fig.tight_layout()

输 出 

以下是以与第一张原始图像不同的格式生成的图像。

结 论

在本文中,我们了解了什么是深度学习,它是如何工作的,以及我们可以使用什么技术来检测产品中的缺陷,同时学习了如何使用图像处理来检测图像中的缺陷。

二、缺陷检测~深度学习2

缺陷检测被广泛使用于布匹瑕疵检测、工件表面质量检测、航空航天领域等。传统的算法对规则缺陷以及场景比较简单的场合,能够很好工作,但是对特征不明显的、形状多样、场景比较混乱的场合,则不再适用。近年来,基于深度学习的识别算法越来越成熟,许多公司开始尝试把深度学习算法应用到工业场合中。

缺陷数据

如下图所示,这里以布匹数据作为案例,常见的有以下三种缺陷,磨损、白点、多线。

如何制作训练数据呢?这里是在原图像上进行截取,截取到小图像,比如上述图像是512x512,这里我裁剪成64x64的小图像。这里以第一类缺陷为例,下面是制作数据的方法。

注意:在制作缺陷数据的时候,缺陷面积至少占截取图像的2/3,否则舍弃掉,不做为缺陷图像。

一般来说,缺陷数据都要比背景数据少很多,此外通过增强后的数据,缺陷:背景=1:1,每类在1000幅左右~~~

网络结构

具体使用的网络结构如下所示,输入大小就是64x64x3,采用的是截取的小图像的大小。每个Conv卷积层后都接BN层,具体层参数如下所示。

Conv1:64x3x3
Conv2:128x3x3
ResNetBlock和DenseNetBlock各两个,具体细节请参考残差网络和DenseNet。
Add:把残差模块输出的结果和DenseNetBlock输出的结果在对应feature map上进行相加,相加方式和残差模块相同。注意,其实这里是为了更好的提取特征,方式不一定就是残差模块+DenseNetBlock,也可以是inception,或者其它。
Conv3:128x3x3
Maxpool:stride=2,size=2x2
FC1:4096
Dropout1:0.5
FC2:1024
Dropout1:0.5
Softmax:对应的就是要分的类别,在这里我是二分类。

关于最后的损失函数,建议选择Focal Loss,这是何凯明大神的杰作,源码如下所示: 

数据做好,就可以开始训练了~~~

整幅场景图像的缺陷检测

上述训练的网络,输入是64x64x3的,但是整幅场景图像却是512x512的,这个输入和模型的输入对不上号,这怎么办呢?其实,可以把训练好的模型参数提取出来,然后赋值到另外一个新的模型中,然后把新的模型的输入改成512x512就好,只是最后在conv3+maxpool层提取的feature map比较大,这个时候把feature map映射到原图,比如原模型在最后一个maxpool层后,输出的feature map尺寸是8x8x128,其中128是通道数。如果输入改成512x512,那输出的feature map就成了64x64x128,这里的每个8x8就对应原图上的64x64,这样就可以使用一个8x8的滑动窗口在64x64x128的feature map上进行滑动裁剪特征。然后把裁剪的特征进行fatten,送入到全连接层。具体如下图所示。

全连接层也需要重新建立一个模型,输入是flatten之后的输入,输出是softmax层的输出。这是一个简单的小模型。

在这里提供一个把训练好的模型参数,读取到另外一个模型中的代码

#提取特征的大模型
def read_big_model(inputs):
   # 第一个卷积和最大池化层
   X = Conv2D(16, (3, 3), name="conv2d_1")(inputs)
   X = BatchNormalization(name="batch_normalization_1")(X)
   X = Activation('relu', name="activation_1")(X)
   X = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name="max_pooling2d_1")(X)
   # google_inception模块
   conv_1 = Conv2D(32, (1, 1), padding='same', name='conv2d_2')(X)
   conv_1 = BatchNormalization(name='batch_normalization_2')(conv_1)
   conv_1 = Activation('relu', name='activation_2')(conv_1)
   conv_2 = Conv2D(32, (3, 3), padding='same', name='conv2d_3')(X)
   conv_2 = BatchNormalization(name='batch_normalization_3')(conv_2)
   conv_2 = Activation('relu', name='activation_3')(conv_2)
   conv_3 = Conv2D(32, (5, 5), padding='same', name='conv2d_4')(X)
   conv_3 = BatchNormalization(name='batch_normalization_4')(conv_3)
   conv_3 = Activation('relu', name='activation_4')(conv_3)
   pooling_1 = MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding='same', name='max_pooling2d_2')(X)
   X = merge([conv_1, conv_2, conv_3, pooling_1], mode='concat', name='merge_1')
   X = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='max_pooling2d_3')(X)  # 这里的尺寸变成16x16x112
   X = Conv2D(64, (3, 3), kernel_regularizer=regularizers.l2(0.01), padding='same', name='conv2d_5')(X)
   X = BatchNormalization(name='batch_normalization_5')(X)
   X = Activation('relu', name='activation_5')(X)
   X = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='max_pooling2d_4')(X)  # 这里尺寸变成8x8x64
   X = Conv2D(128, (3, 3), padding='same', name='conv2d_6')(X)
   X = BatchNormalization(name='batch_normalization_6')(X)
   X = Activation('relu', name='activation_6')(X)
   X = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='same', name='max_pooling2d_5')(X)  # 这里尺寸变成4x4x128

return X

def read_big_model_classify(inputs_sec):
   X_ = Flatten(name='flatten_1')(inputs_sec)
   X_ = Dense(256, activation='relu', name="dense_1")(X_)
   X_ = Dropout(0.5, name="dropout_1")(X_)
   predictions = Dense(2, activation='softmax', name="dense_2")(X_)
   return predictions
#建立的小模型

inputs=Input(shape=(512,512,3))
X=read_big_model(inputs)#读取训练好模型的网络参数
#建立第一个model
model=Model(inputs=inputs, outputs=X)
model.load_weights('model_halcon.h5', by_name=True)

识别定位结果

上述的滑窗方式可以定位到原图像,8x8的滑窗定位到原图就是64x64,同样,在原图中根据滑窗方式不同(在这里选择的是左右和上下的步长为16个像素)识别定位到的缺陷位置也不止一个,这样就涉及到定位精度了。在这里选择投票的方式,其实就是对原图像上每个被标记的像素位置进行计数,当数字大于指定的阈值,就被判断为缺陷像素。

识别结果如下图所示:

 一些Trick

对上述案例来说,其实64x64大小的定位框不够准确,可以考虑训练一个32x32大小的模型,然后应用方式和64x64的模型相同,最后基于32x32的定位位置和64x64的定位位置进行投票,但是这会涉及到一个问题,就是时间上会增加很多,要慎用。

对背景和前景相差不大的时候,网络尽量不要太深,因为太深的网络到后面基本学到的东西都是相同的,没有很好的区分能力,这也是我在这里为什么不用object detection的原因,这些检测模型网络,深度动辄都是50+,效果反而不好,虽然有残差模块作为backbone。

但是对背景和前景相差很大的时候,可以选择较深的网络,这个时候,object detection方式就派上用场了。

三、工业缺陷检测中数据标注需要注意的几个事项

在工业场景中,网络结构决定了下限,数据决定着上限,要想模型有好的表现,数据是至关重要的。下面就这个项目来说一说,工业缺陷检测在标注数据时需要注意的几个事项:

1、离得比较近的缺陷就合并在一个框里

以上两个图里的缺陷都是可以合并的,一是为了保持缺陷的完整性,同一个缺陷被标注成好多个,会给神经网络造成误解,同时也避免出现多个小目标。

2、尽量不要有太细长的目标

神经网络的卷积基本上都是3*3的,而且先验框anchor在设计宽高比时一般也是在1左右,回归非常细长的目标,需要比较大的感受野和宽高比,不一定能做得很好。如图左边那块目标,可以合并一下,稍微标大一点,把长宽比例搞得居中一点。

3、不要打太小的目标,比如低于10x10像素的

模型一般都对小目标不敏感,除非采用比较好的trick,就拿YOLOv4来说,到第三次下采样的特征图才拿去后面做检测,也就是在原图上最小都有8个像素,才能在特征图上体现为1个像素。有人会杠了,那我的目标就是小目标啊,小哥,我说了,另外还有很多trick的,不在本文讨论范围,打标签这个环节你要么打大点,要么不要打,或者把局部区域放大成大图,再打标签,不然送到模型里头,也是没用的。这跟严谨不严谨没有任何关系。

                                     YOLOv4网络结构图

4、不要标注特别不明显的特征

这一条相信都能理解,特征连人都认不出来,哪个网络都不好识别吧。像这种标注框,恐怕谁都不好认吧。

5、框的位置尽量准确一点,把缺陷部分刚好框进去

像右下角那个框,完全可以打大点吧。

6、需要检测的缺陷在训练集中至少要出现一次相似的

另外,需要多说一句,跟标注无关的。就是虽然都是缺陷,但实际上也分很多种的,如果训练集里都没有出现过相似的,就基本上别指望测试时能够检测出来了。比如下图中,虽然只划分了一类缺陷,但是从特征的角度来说,实际上已经是好几类了,比如划痕、凸起、裂开。还是回到开头那句话:网络结构决定了下限,数据决定上限。目前的技术,不靠大量的数据喂,是训练不出很好的模型的。

四、基于深度学习的轮胎缺陷检测系统

本文主要介绍一个基于深度学习轮胎缺陷检测系统方案。

背景介绍

    由于全球制造业面临着在最短的时间内向市场推出多种最高质量产品的压力,因此所有职能向人工智能驱动的自动化的转变已成为必然。

    在质量检测方面,人工智能驱动的计算机视觉系统已经能够简化生产流程,使产品符合公司制定的质量标准。这反过来又带来了更高效率、更低运营成本的优势,同时实现 24/7 生产和更快的决策。

    全球轮胎制造商一直是质量保证等各个领域人工智能技术的早期采用者之一。人工智能的主要应用之一是使用基于深度学习的计算机视觉系统进行轮胎缺陷检测。由于轮胎制造过程中使用的原材料的性质,轮胎部件可能会受到金属或非金属杂质(例如钢丝、螺钉和塑料碎片)、气泡和重叠的污染。当轮胎有缺陷的车辆高速行驶时,这些缺陷会导致轮胎寿命缩短,甚至爆胎。

轮胎缺陷检测

    要准确检测轮胎缺陷,需要解决的主要问题是:

  • 模仿手动测试并集成到现有的制造和质量控制流程中
  • 具有机械夹具,可自动调整以适应操作员放置的不同轮胎尺寸,并旋转,以便在一次旋转中捕获轮胎的内壁和外壁。
  • 以最佳旋转速度捕获图像、处理、分析和检测故障。
  • 在每个故障位置停车并在轮胎上标记缺陷
  • 轻松安全地释放轮胎

轮胎缺陷类型

    在轮胎制造过程中常见的 80 多种可能存在的缺陷中,我们会进行隔离以创建严重程度集合。各个轮胎制造商根据其独特的化学配方和机械制造工艺,有自己特定的分类方法。通常,大约 30 多个此类类别被认为是高度严重的。下图描述了这些缺陷类别的有限样本:

    图 1:有缺陷的轮胎:从左到右:SWC — 侧壁裂纹、RLC — 轮辋线裂纹、SWB — 侧壁气泡、模板编号偏移、倒角缺陷图 1:有缺陷的轮胎:从左到右:SWC — 侧壁裂纹、RLC — 轮辋线裂纹、SWB — 侧壁气泡、模板编号偏移、倒角缺陷

轮胎缺陷检测

    轮胎质量检查的典型方法是使用 X 射线机并使用加权纹理差异等技术。然而,X 光机需要很大的空间并且非常昂贵。相反,我们使用 RGB 相机来捕捉轮胎的图像。为了解决轮胎缺陷检测问题,选择了实例分割(对象检测和分割的结合),以便可以识别图像中每个缺陷的每个实例,而不是像语义分割那样对每个像素进行分类。

数据生成

    为了生成数据,使用了从已识别和标记缺陷的多个轮胎捕获的图像。使用 1080p 分辨率的摄像头来拍摄有缺陷的图像和“良好”图像的视频。从不同角度进行图像捕捉以提高概括性。

数据准备

    数据准备是在处理和分析之前清理和转换原始数据的过程。这是处理之前的重要步骤,通常涉及标记数据、重新格式化数据和对数据进行更正。数据是通过从几个生成的视频中转储帧来收集的。然后使用LabelMe等标记工具标记感兴趣区域 (ROI) 内的缺陷部分。

实例分割

    实例分割是一种检测对象然后在单个像素级别进行屏蔽的技术。它结合了 1) 对象检测,其中对帧中的每个单独对象进行分类和定位,以及 2. 语义分割,其中将每个像素分为预定义的类别。实例分割允许将标签附加到图像的每个像素。

Mask-RCNNMask-RCNN

    Mask-RCNN 是一种深度神经网络,用于解决计算机视觉中的实例分割问题。Mask R-CNN 结合了两种著名的网络拓扑——Faster R-CNN 和全连接网络 (FCN)。Mask-RCNN 遵循两步过程。第一步,对于每个输入图像,生成有关对象可能存在的区域的建议。在第二步中,预测对象的类别,并根据第一步生成的建议为对象生成像素级掩模。

执行

    我们使用 Mask-RCNN 的定制变体构建推理管道。基本的 Keras 实现可以在https://github.com/matterport/Mask_RCNN.git找到,相应的参考论文可以在https://arxiv.org/pdf/1703.06870.pdf找到

推理时间

    未优化模型的推理时间如下表所示。

通过模型优化技术,每张图像的延迟可降低至 150 毫秒以下。

准确性

    我们的定制模型能够实现 96% 的检测准确率。

结论

    这项检测轮胎缺陷的研发工作表明,实现轮胎质量检测过程的显着自动化是可能的。在实际系统中,如果需要高检测吞吐量,则需要自动检测夹具。这将包括多个摄像头,用于同时查看轮胎的外表面和内表面,一个用于将轮胎旋转 360 度的电机组件,以及一个可以同步轮胎运动、图像捕获和检测的控制系统。

五、基于CNN实现可解释的缺陷检测

    尽管神经网络非常准确,但它在需要预测可解释性的领域(例如医学、银行、教育等)的应用并不广泛。

    在本教程中,我将向您展示如何克服卷积神经网络的这种可解释性限制。通过探索、检查、处理和可视化深度神经网络层生成的特征图,我们将介绍该方法并讨论如何将其应用于现实世界的任务——缺陷检测。

    本文数据集和源码下载链接:

https://github.com/OlgaChernytska/Visual-Inspection

任务

    我们有一个包含 400 张图片的数据集,其中包含良好物品(标记为“良好”类)和有缺陷物品(标记为“异常”类)的图像。数据集是不平衡的 — 良好图像的样本多于有缺陷的图像样本。图像中的物品可能属于任何类型和复杂程度 — 瓶子、电缆、药丸、瓷砖、皮革、拉链等。以下是数据集可能的样子的示例。

    我们的任务是构建一个模型,将图像分为“良好”/“异常”类别,如果图像被归类为“异常”,则返回缺陷的边界框。尽管这项任务看起来很简单,就像典型的对象检测任务一样,但有一个问题——我们没有边界框的标签。

    幸运的是,这个任务是可以解决的。

数据准备

    对于我的所有实验,我都使用了MVTEC 异常检测数据集(请注意,它是根据知识共享署名-非商业-相同方式共享 4.0 国际许可分发的,这意味着它不能用于商业目的)。

https://www.mvtec.com/company/research/datasets/mvtec-ad

    该数据集包括 15 个不同物品类型的子集,例如瓶子、电缆、药丸、皮革、瓷砖等;每个子集总共有 300-400 张图像 — 每张标记为“良好”/“异常”

    作为数据预处理步骤,将图像大小调整为 224×224 像素以加快训练速度。大多数子集中的图像大小为 1024×1024,但由于缺陷尺寸也很大,我们可以将图像大小调整为较低的分辨率而不会牺牲模型准确性。

    考虑使用数据增强。一般来说,适当的数据增强总是对你的模型有益的。数据增强具体方法和介绍可以参考下面链接:

https://towardsdatascience.com/complete-guide-to-data-augmentation-for-computer-vision-1abe4063ad07

    但是,让我们假设,当部署到生产环境时,我们的模型将“看到”与我们现在拥有的数据集格式完全相同的数据。因此,如果图像居中、缩放和旋转(如 Capsule 和 Cable 子集),我们可能根本不使用任何数据增强,因为测试图像预计也会居中、缩放和旋转。但是,如果图像没有旋转(而只是居中和缩放),如 Screw 和 Metal Nut 子集,将旋转作为预处理步骤添加到训练管道将有助于模型更好地学习。

    将数据分为训练/测试部分。理想情况下,我们希望有训练、验证和测试部分——分别用于训练模型、调整超参数和评估模型准确性。但我们只有 300-400 张图像,所以我们将 80% 的图像放入训练集,将 20% 放入测试集。对于小型数据集,我们可以执行 5 倍交叉验证以确保评估结果是可靠的。

    处理不平衡数据集时,应以分层方式进行训练/测试拆分,因此训练和测试部分将包含相同份额的两个类别 — “良好”/“异常”。此外,如果您有关于缺陷类型的信息(例如划痕、裂纹等),最好也根据缺陷类型进行分层拆分,因此训练和测试部分将包含相同份额的带有划痕/裂纹的物品。

模型

    让我们使用在 ImageNet 上预先训练的VGG16,并更改其分类头 — 用 Global Average Pooling 和单个 Dense 层替换 Flattening 和 Dense 层。我将在“推理管道”部分解释为什么我们需要这些特定的层。

    我们将模型训练为典型的二分类模型。该模型输出一个二维向量,其中包含“良好”和“异常”类别的概率(使用一维输出,该方法也应该有效,请随意尝试)。

    在训练期间,前 10 个卷积层被冻结,我们只训练分类头和最后 3 个卷积层。这是因为我们的数据集太小,无法微调整个模型。损失是交叉熵;优化器是 Adam,学习率为 0.0001。

    我已经尝试了 MVTEC 异常检测数据集的不同子集。我使用 batch_size=10 训练了模型,最多训练了 10 个时期,并在训练集准确率达到 98% 时提前停止。为了处理不平衡的数据集,我们可以应用损失权重:对“异常”类图像使用较高的权重,对“良好”类图像使用较低的权重。

推理管道

    在推理过程中,我们不仅要将图像分类为“良好”/“异常”类别,而且如果图像被归类为“异常”,还要获取缺陷的边界框。

    为此,我们让模型处于推理模式,输出类概率和热图,然后将其处理到边界框中。热图是根据深层的特征图创建的。

    步骤1. 在 ReLU 激活后,从 Conv5-3 层获取所有特征图。对于单个输入,将有 512 个大小为 14×14 的特征图(大小为 224×224 的输入图像每次通过 4 个池化层进行两次下采样)。

    步骤2. 将 Conv5-3 层的所有 512 个特征图相加,每个特征图都乘以影响“异常”类别分数计算的密集层中的权重。仔细查看图 7 和图 8 以了解此步骤。

    为什么这样?现在您将了解为什么分类头应该有一个全局平均池化层和一个密集层。这样的架构使得我们能够跟踪哪些特征图(以及在多大程度上)影响了最终预测并使其成为“异常”类。

    每个特征图(Conv5-3 层的输出;见图 6)突出显示输入图像中的某些区域。全局平均池化层将每个特征图表示为单个数字(我们可以将其视为 1-D 嵌入)。密集层通过将每个嵌入乘以相应的权重来计算“良好”和“异常”类的分数(和概率)。此流程如图 7 所示。

    因此,密集层权重表示每个特征图对“良好”和“异常”类别的分数的影响程度(我们只对“异常”类别的分数感兴趣)。将 Conv5-3 层的特征图相加,然后乘以密集层相应的权重 — — 非常有意义。

    有趣的是,使用全局平均池化而不是全局最大池化对于让模型找到整个物体至关重要。以下是原始论文《学习深度特征进行判别定位》中所说的内容:

    步骤3. 下一步是对热图进行上采样,以匹配输入图像大小 — 224×224。双线性上采样是可以的,就像任何其他上采样方法一样。

    回到模型输出。模型返回“良好”和“异常”类别的概率,以及一个热图,该热图显示在计算“异常”分数时哪些像素很重要。无论将图像分类为“良好”还是“异常”,模型始终返回热图;当类别为“良好”时,我们只需忽略热图。

    热力图看起来相当不错,并解释了哪个区域使模型决定该图像属于“异常”类别。我们可以在这里停下来,或者(正如我承诺的那样)将热图处理成边界框。

    从热力图到边界框。您可能会想出几种方法。我将向您展示最简单的方法。在大多数情况下,它效果很好。

    1. 首先,对热图进行标准化,使得所有值都在 [0,1] 范围内。

    2. 选择一个阈值。将其应用于热图,这样所有大于阈值的值都会转换为 1,小于阈值的值则转换为 0。阈值越大,边界框就越小。我喜欢阈值在 [0.7, 0.9] 范围内时的结果。

    3. 我们假设 1 的区域 — 是一个单一的密集区域。然后通过查找高度和宽度维度中的 argmin 和 argmax 在该区域周围绘制一个边界框。

    但是,请注意,这种方法只能返回单个边界框(根据定义),因此如果图像有多个缺陷区域,它将会失败。

评估

    让我们在 MVTEC 异常检测数据集的 5 个子集(榛子、皮革、电缆、牙刷和药丸)上评估该方法。

    对于每个子集,我都训练了一个单独的模型;20% 的图像被随机分层地选为测试集。没有使用数据增强。我在损失函数中应用了类别权重——1 表示“良好”类别,“异常”类别为 3,因为在大多数子集中,良好图像的数量是异常图像的 3 倍。该模型最多训练 10 个时期,如果训练集准确率达到 98%,则提前停止。这是我的笔记本,里面有训练脚本。

    以下是评估结果。子集的训练集大小为 80-400 张图像。平衡准确率在 81.7% 到 95.5% 之间。一些子集(例如 Hazelnut 和 Leather)对于模型来说更容易学习,而 Pill 是一个相对困难的子集。

    现在让我们看看预测是什么样子。在大多数情况下,如果类别是“异常”,模型会产生正确的类别预测和精确的边界框。但是,当类别被正确预测为“异常”时,也存在一些错误:它们要么是错误的类别预测,要么是错误的边界框位置。

结论

    在这篇文章中,我们向你展示神经网络不是某些人认为的黑盒算法,而是当你知道在哪里看的时候是可以解释的:)这里描述的方法是解释模型预测的众多方法之一。

    当然,这个模型并不是那么准确,主要是因为这是我的快速小项目。但如果你正在做类似的任务,可以把我的结果作为起点,投入更多时间并获得所需的准确度。

    本文数据集和源码下载链接:

https://github.com/OlgaChernytska/Visual-Inspection

六、基于GAN的零缺陷样本产品表面缺陷检测

缺陷检测是工业生产过程中的关键环节,其检测结果的好坏直接影响着产品的质量。而在现实场景中,但产品瑕疵率非常低,甚至是没有,缺陷样本的不充足使得需要深度学习缺陷检测模型准确率不高。如何在缺陷样本少的情况下实现高精度的检测呢?目前有两种方法,一种是小样本学习,另一种是用GAN。本文将介绍一种GAN用于无缺陷样本产品表面缺陷检测。

深度学习在计算机视觉主流领域已经应用的很成熟,但是在工业领域,比如产品表面缺陷检测,总感觉没有发挥深度学习的强大能力,近几年表面缺陷的 相关研究主要是集中在各种借鉴主流神经网络框架,从CNN到YOLO,SSD,甚至到语义分割的FCN相关论文,通过一些技术,对框架进行轻量化,对缺陷进行分类或检测。不过,逃不出一个问题:一定要有缺陷样本可供训练,而且数量不能太少!当然,也有一些课题组使用稀疏编码、字典学习、稀疏自编码等对表面缺陷进行检测,这类方法很有局限性,主要针对那些有周期性背景纹理的图像,比如丝织品,印刷品等。国内外很多课题组、工业软件公司都想开发出一些切合实际应用的算法软件,在缺陷检测领域,比较好的公司有:VIDI、Halcon等,听说海康威视也在搞工业产品方便的算法研究。

论文标题:A Surface Defect Detection Method Based on Positive Samples

论文链接:https://doi.org/10.1007/978-3-319-97310-4_54

作者提出只依据已有的正常表面图像样本,通过一定的技术手段对缺陷样本进行检测,很好的将最近研究火热的GAN应用于框架中,这一年,课题组的老师也一直讨论这种方法的可行性,缺陷的检测要不要有缺陷样本,从稀疏自编码,小样本学习再到计算机视觉研究热点之一的零样本学习,得出结论:大多数工业产品表面缺陷检测是需要缺陷样本或者人为制作的缺陷样本,论文虽然是没有直接使用生产线上的缺陷样本,但是通过算法人为的产生了缺陷样本,并很好的融合和GAN在图像修复领域的强大能力,整个框架的设计很巧妙。

文章思路:论文的整体思路就是GAN在图像修复和重建方便具有很强大的能力,通过人为的去在正常样本上“随意”添加一些缺陷,训练阶段让GAN去学习一个可以修复这些缺陷区域的网络,检测阶段时,输入一个真实缺陷样本,训练好的GAN会对其进行修复,再基于LBP可完成缺陷检测。整个算法框架不需要真实的缺陷样本和手工标签,但是在框架中,人为的去产生(比如PS)一些缺陷区域。

通俗说:

作者利用GAN在图像修复(重建)上的能力,在工业现场收集一些正常(无缺陷)样本,人工PS一些缺陷,比如线条、斑点等。

训练时,将PS的人工制作的缺陷图像和原图像做输入样本训练GAN,得到一个具有图像修复重建能力的网络。

测试时,直接使用训练好的GAN对采集到的图像进行重建修复,如果样本中中有缺陷区域,缺陷区域按照网络设计,肯定需要修复,将修复后的图像和原缺陷图像使用LBP找出显著差异区域即为缺陷区域。

01 主要内容

论文的主体框架思想是基于GAN网络的结构。GAN 主要包括了两个部分,即生成器 G与判别器 D。生成器主要用来学习真实图像分布从而让自身生成的图像更加真实,以“骗过”判别器。判别器则需要对接收的图片进行真假判别。在整个过程中,生成器努力地让生成的图像更加真实,而判别器则努力地去识别出图像的真假,这个过程相当于一个博弈过程,随着时间的推移,生成器和判别器在不断地进行对抗,最终两个网络达到了一个动态均衡:生成器生成的图像接近于真实图像分布,而判别器识别不出真假图像,对于给定图像的预测为真的概率基本接近 0.5(这段话从李宏毅老师那引用的,致敬李老师)。

  • 训练阶段

在训练阶段,模型采用一些图像处理技术,人为的在正常样本图像上产生一些缺陷(示意图中的红色框模块),使用由自编码器构成的G模块进行缺陷修复学习,学习的目标是与正常样本之间的L1范数最小,通过一定数量的样本训练可以获得有缺陷修复能力的G模块。GAN用于图像修复的一些资料可以参考[3][4],当然也可以参考论文里的参考文献。

图片

训练阶段

  • 测试阶段

在测试阶段,将上步骤训练好的G模块作为测试阶段的图片修复模块,对于输出的图像样本,假如存在缺陷区域,通过修复模块G将得到修复后的图像,与原缺陷样本图像一起作为LBP算法的输入,通过LBP算法对其缺陷区域进行精确定位。

图片

测试阶段

02 其他细节

2.1缺陷生成

在实际训练中,论文作者手工生成一些缺陷样本,如图3所示,训练网络自动修复缺陷。另外作者也通过一些技术进行了样本的扩充,比如加入高斯噪声、随机resize大小等。

图片

缺陷生成

2.2缺陷图像重建

缺陷图像重建部分主要的作用是:缺陷图像重建后尽量和正常样本一样,作者在这部分在文献[5][6]基础上进行框架修改的,比如使用L1 distance作为衡量重建差异的目标函数。

图片

然后实验中作者又发现只使用L1不行,图像边缘等细节可能会衡量不准确,又加入GAN loss来提升网络的重建效果。

图片

最后,得到了下面目标函数。

图片

2.3缺陷检测

因为使用GAN修复后的图片和原始缺陷样本图片之间在像素级的细节上有一些差异,作者使用了前几年在人脸领域应用比较好的LBP算法进行缺陷区域的检测,这里不介绍算法的细节,示意图如下。

图片

03 实验

文章对DAGM 2007数据集和织物密集图像进行了验证实验。实验表明,提出的GAN+LBP算法和有足够训练样本的监督训练算法具有较高的检测准确率。实验使用两种类型的数据集,4.1是印花纹表面,4.2是织物表面。

3.1Texture surface

图片

测试样本

图片

结果

图片

a.原始图像,b.修复图像,c.论文方法,d. FCN方法,e.真实标签

3.2 Fabric Picture

实验中缺陷样本的类型有五种。实验样本按背景分有三类,每类包含5个缺陷样本,25个正常样本。

图片

测试样本

图片

结果

图片

a.原始图像,b.修复图像,c.论文方法,d. FCN方法,e.真实标签

七、

八、

http://www.kler.cn/a/512603.html

相关文章:

  • CSS实现实现票据效果 mask与切图方式
  • 2024春秋杯密码题第一、二天WP
  • Javascript 将页面缓存存储到 IndexedDB
  • BUUCTF_Web([GYCTF2020]Ezsqli)
  • R数据分析:有调节的中介与有中介的调节的整体介绍
  • Armv8/Armv9架构从入门到精通-介绍
  • CAN 网络介绍
  • mysql 如何清理磁盘碎片
  • 怎么使用langchain和ollama自己简单开发搭建一个本地有记忆的大模型?
  • LLM 的星辰大海:大语言模型的前世今生
  • Python毕业设计选题:基于django+vue的二手电子设备交易平台设计与开发
  • ServiceEntry 是一种用于将外部服务引入到Istio内部的服务注册表中的配置资源。
  • kafka学习笔记6 ACL权限 —— 筑梦之路
  • PC端自动化测试实战教程-1-pywinauto 环境搭建(详细教程)
  • 面试题-redis的大key与热key
  • 系统架构演进:从单体到微服务的智能转型
  • Spring boot启动原理及相关组件
  • 【机器学习实战中阶】使用Python和OpenCV进行手语识别
  • 欧拉(Euler 22.03)安装ProxySQL
  • Flutter项目和鸿蒙平台的通信
  • Skyeye 云 VUE 版本 v3.15.5 发布
  • 计算机基础问答-面试总结
  • 路径参数和查询参数分别是什么
  • 什么是股指期货的到期风险?
  • 从前端视角看设计模式之结构型模式篇
  • Springboot和Android项目接入Firebase Cloud Message(FCM)