机器视觉 缺陷检测



前言

        缺陷检测算法不同于尺寸、二维码、OCR等算法。后者应用场景比较单一,基本都是套用一些成熟的算子,所以门槛较低,比较容易做成标准化的工具。而缺陷检测极具行业特点,不同行业的缺陷算法迥然不同,常见的是对物品表面缺陷的检测,比如工件表面的斑点、凹坑、划痕、色差、缺损等缺陷进行检测。随着缺陷检测要求的提高,机器学习和深度学习也成了缺陷领域一个不可或缺的技术难点,接下来我会对标准缺陷检测算法、以及半导体行业的非标算法做一个简单分析:


1. 缺陷检测分类

1.1 标准缺陷检测

所谓标准,就是不针对行业特点,这里基本分为如下几类:

  • 标准预处理功能: 图像增强、腐蚀、膨胀、开运算、闭运算、滤波、傅立叶变换(频域空间域转换)、距离变换、差分、等
  • 面积检测:阈值后计算ROI内面积
  • Blob(阈值分割+特征提取)检测:阈值联通后计算Blob
  • 浓度差检测:计算ROI范围内的最大浓度、最小浓度、浓度差
  • 直线/曲线上的毛刺/缺陷:拟合直线/曲线,计算边缘点到直线/曲线距离

标准的做法一般都是拿标准的算法块进行组合,以达到缺陷检测的效果,缺陷检测标准流程一般是:

1设置基准图模板——>2当前图模板定位——>3生成仿射变换矩阵——>4旋转平移图像或者区域——>5预处理差分——>6预处理滤波/腐蚀/膨胀——>7Blob检测——>8面积检测


1.2 非标缺陷检测(针对行业特性)

        相对与标准做法,非标的做法就非常多,有些非标的目的是为了减少操作步骤,例如将上面的组合流程变成一个工具,这个我们称之为业务逻辑非标。还有一些非标主要是做图像预处理部分,例如修改一些标准预处理的算子和预处理流程,将瑕疵提取出来。当然,对数学理论掌握程度较高的朋友,会推导理论公式,然后直接实现数学公式达到检测效果。


2. 行业难点

  • 传统算法检测缺陷:调试难度大,容易在检测不稳定情况下反复调参,且复杂缺陷误测多,兼容性差
  • 机器学习检测缺陷:一般使用类似MLP的一些单层神经网络,对缺陷特征进行训练分类,该方法需要事先提取出缺陷部分,一般用来与传统分割法搭配使用,达到缺陷检测分类的效果。
  • 深度学习检测缺陷(打标签):一般需要客户提供大量的缺陷样本,而且缺陷种类越多、特征越不明显,需要的缺陷样本就越大。其次,打标签过程很难做到自动,需要手动辅助框出缺陷位置,工作量非常大。总结就是训练周期久,训练样本大,如果客户可以提供大量样本,那该方法是首选(半导体行业一般不会出现大量缺陷样品)
  • 深度学习检测缺陷(迁移学习法):该方法我感觉会成为后面工业领域检测瑕疵的一个大趋势,但是需要一些公司去收集各种行业的缺陷类型图片和训练的网络模型,并共享出来(突然感觉是个商机,就看谁能抓住了),然后我们可以使用迁移学习的方法学习别人训练好的模型。

3. 常规缺陷检测算法(Halcon

总的来说,缺陷检测的算法包括:

  • Blob分析+特征提取(常用,较简单)
  • 定位(Blob定位、模板匹配定位)+ 差分(常用)
  • 光度立体
  • 特征训练
  • 测量拟合(常用)
  • 频域+空间域结合(常用)
  • 深度学习

3.1 差分法

        标准缺陷检测我觉得用差分法还是蛮多的。顾名思义,差分就是通过对两幅图像或和两个区域作差,来找出其中有差异的区域。处理流程基本就是定位Blob分析+差分模板匹配+差分的方式,主要用来检测物品损坏,凸起,破洞,缺失,以及质量检测等。两种方式的具体流程如下:

3.1.1 blob分析+差分

检测流程如下:

  1. 读取图像
  2. 对图像进行Blob分析,提取图像上的Roi检测区域
  3. 在对Roi区域直接进行差分处理或者与没有缺陷的图像进行差分处理
    ps:这里差分包含区域差分图像差分两种方式。
  4. 最后求差集,根据差集部分的面积判断该物品是否有缺陷

流程解析:以标准图像中的灰度值为模板,计算处检测图像的灰度值,并与标准图像作差,灰度值差异越大,则证明检测图像中存在与标准图比有明显灰度变化的区域,即这部分区域就是我们所要筛选出的缺陷区域。

示例分析:提取灰度值明显的缺陷区域

*1.使用`intensity()`算子计算出模板图(即标准图,图1)的检测区域图像的灰度平均值`OriginalMean`
intensity(OriginalRegion, ImageReduced1, OriginalMean, Deviation1) 

   
   
  • 1
  • 2

*2.</span><span class="token variable">intensity</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">算子计算出待测图(图2)的检测区域图像的灰度平均值</span><span class="token variable">DetectMean</span><span class="token punctuation">,计算出两幅图像灰度均值的差值
intensity (DetectRegion, ImageReduced2, DetectMean, Deviation2)
tuple_abs (OriginalMean-DetectMean, Abs)

3.
如果两个区域的灰度值差值大于10(if(Abs>10)),则生成一副图像(图3),其灰度值为模板图中计算得到的的平均灰度值;
如果两个区域的灰度值差值小于10(if(Abs<10)),则生成一副图像(图3),其灰度值为待测图中计算得到的的平均灰度值。
ps:这里计算结果是差值小于10,也就是检测图的灰度值差异和模板图差异不大,直接生成一个后者的灰度均值图像
if(Abs>10)
gen_image_proto (ImageReduced2, ImageCleared, OriginalMean)
else
gen_image_proto (ImageReduced2, ImageCleared, DetectMean)
endif
reduce_domain (ImageCleared, RegionDifference, ImageReduced1)

*4.将待测图与新生成的灰度值图像做差值(图4),可以找到待测图和模板图灰度值有差异的区域
abs_diff_image (ImageReduced2, ImageReduced1, ImageAbsDiff, 1)
invert_image (ImageAbsDiff, ImageInvert)
threshold (ImageInvert, Region1, 0, 30)
opening_circle (Region1, RegionOpening, 1.5)
connection (RegionOpening, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ‘area’, ‘and’, 10, 99999)

    NumImages := 16
    for Index := 1 to NumImages by 1
    read_image (Image, ‘plastics/plastics_’ + Index$‘02’)
    rgb1_to_gray (Image, Image)
    3.计算一个图像的实值快速傅里叶变换(空间域转至频域)
    rft_generic (Image, ImageFFT, ‘to_freq’, ‘none’, ‘complex’, Width)
    4.用在频域内的滤波器使一个图像卷积。
    convol_fft (ImageFFT, Filter, ImageConvol)
    5.卷积后的频域图像转至空间域
    rft_generic (ImageConvol, ImageFiltered, ‘from_freq’, ‘n’, ‘real’, Width)
    6.滤波之后的图像交给形态学来分析
    空间域上的blob图像分割
    原图矩形内的灰度值范围(max-min)作为输出图像像素值,扩大了亮的部分
    gray_range_rect (ImageFiltered, ImageResult, 10, 10)
    获得图像最大灰度值和最小灰度值
    min_max_gray (ImageResult, ImageResult, 0, Min, Max, Range)
    二值化提取( 5.55是经验值,在调试中得到)
    threshold (ImageResult, RegionDynThresh, max([5.55,Max * 0.8]), 255)
    select_shape (RegionDynThresh, SelectedRegions, ‘area’, ‘and’, 1, 99999)

      * 1.创建一个高斯滤波器,用于将傅里叶转换后的图像进行滤波
      gen_gauss_filter (GaussFilter, 3.0, 3.0, 0.0, ‘none’, ‘rft’, Width, Height)

      对灰度图像进行颜色反转
      invert_image (ImageGray, ImageInvert)
      2.对反转后的图像进行傅里叶变换
      rft_generic (ImageInvert, ImageFFT, ‘to_freq’, ‘none’, ‘complex’, Width)
      3.对傅里叶图像做卷积,使用之前创建的高斯滤波器作为卷积核
      convol_fft (ImageFFT, GaussFilter, ImageConvol)
      4.将卷积后的傅里叶图像还原为空间域图像。可见图像的突变部分得到了增强
      rft_generic (ImageConvol, ImageFiltered, ‘from_freq’, ‘n’, ‘real’, Width)

      * 5.设置提取线条的参数,将图像中的有灰度差异的线条提取出来
      calculate_lines_gauss_parameters (17, [25,3], Sigma, Low, High)
      lines_gauss (ImageFiltered, Lines, Sigma, Low, High, ‘dark’, ‘true’, ‘gaussian’, ‘true’)

      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

      在这里插入图片描述
      🐎 木板划痕检测

      *http://www.ihalcon.com/read-13031-1.html
      dev_update_off ()
      dev_close_window ()
      read_image (Image, '缺陷检测木板划痕提取.jpg')
      * 1.彩色转灰度图
      count_channels (Image, Channels)
      if (Channels == 3 or Channels == 4)
          rgb1_to_gray (Image, Image)
      endif
      get_image_size (Image, Width, Height)
      dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle)
      dev_display (Image)
      * 2.傅里叶变换去背景
      fft_generic (Image, ImageFFT, 'to_freq', -1, 'sqrt', 'dc_center', 'complex')
      gen_rectangle2 (Rectangle1, 308.5, 176.56, rad(-0), 179.4, 7.725)
      gen_rectangle2 (Rectangle2, 306.955, 175, rad(-90), 180.765, 4.68)
      union2 (Rectangle1, Rectangle2, UnionRectangle)
      paint_region (UnionRectangle, ImageFFT, ImageResult, 0, 'fill')
      fft_generic (ImageResult, ImageFFT1, 'from_freq', 1, 'sqrt', 'dc_center', 'byte')
      * 3.提取划痕
      threshold (ImageFFT1, Regions, 5, 240)
      connection (Regions, ConnectedRegions)
      select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20, 99999)
      union1 (SelectedRegions, RegionUnion)
      dilation_rectangle1 (RegionUnion, RegionDilation, 5, 5)
      connection (RegionDilation, ConnectedRegions1)
      select_shape (ConnectedRegions1, SelectedRegions1, ['width','height'], 'and', [30,15], [150,100])
      dilation_rectangle1 (SelectedRegions1, RegionDilation1, 11, 11)
      union1 (RegionDilation1, RegionUnion1)
      skeleton (RegionUnion1, Skeleton)
      * 4.显示
      dev_set_color ('red')
      dev_display (Image)
      dev_display (Skeleton)
      
         
         

      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34

      在这里插入图片描述


      3.3 光度立体

             在工业领域,表面检测是一个非常广泛的应用领域。在halcon中,使用增强的光度立体视觉方法,三维表面检测被加强。利用阴影可方便快速的检测物体表面的缺口或凹痕。 使用光度立体视觉方法可在复杂图像中轻松找到表面缺陷 。

      • 适用场景: 适用于检测金属物料上面的凹凸特征。
        检测原理:
        1.通过photometric_stereo算子获得表面梯度图像,该算子可以得到表面梯度图像和反照率图像。需要输入多张从不同角度照明所得到的图像。
        2.通过derivate_vector_field算子获得高斯(平均)曲率图像,该算子中需要输入上面得到的表面梯度图像
        光源: 光度立体法不需要特殊的光源,只需要从不同的角度打光而已。

      算子photometric_stereo详解:

      * 使用光度立体法重建表面
      photometric_stereo (Images : HeightField, Gradient, Albedo : Slants, Tilts, ResultType, ReconstructionMethod, GenParamName, GenParamValue : )
      * Images:输入图像(4张)
      * HeightField:返回重建高度场
      * Gradient:返回表面的梯度场
      * Albedo: 表面的反射率
      * Slants:光源光线与摄像机光轴的夹角(下面有示意图)
      * Tilts: 光源光线投影与被测物主轴的夹角
      * ResultType: 请求结果类型(高度场/梯度场/反射率)
      * ReconstructionMethod: 重建方法类型
      * GenParamName: 一般参数名称
      * GenParamValue: 一般参数设置
      
       
       
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      算子derivate_vector_field详解:

      * 梯度场转平均曲率场
      derivate_vector_field(VectorField : Result : Sigma, Component : )
      * VectorField: 梯度场图像
      * Result: 返回平均曲率场图像
      * Sigma: 高斯系数
      * Component: 组件计算
      
       
       
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      3.3.1 初试光度立体法

      🐨 药片外包装破损的检测

      Halcon案例:方法-光度立体法- inspect_blister_photometric_stereo.hdev

      read_image (Images, './blister_back_0' + [1:4])
      for I := 1 to 4 by 1
          select_obj (Images, ObjectSelected, I)
          *wait_seconds (0.1)
      endfor
      
       
       
      • 1
      • 2
      • 3
      • 4
      • 5

      Tilts := [6.1,95.0,-176.1,-86.8]
      Slants := [41.4,42.6,41.7,40.9]
      光度立体
      photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ‘all’, ‘poisson’, [], [])
      梯度场转平均曲率场
      derivate_vector_field (Gradient, Result, 1, ‘mean_curvature’)
      scale_image_max (Result, ImageScaleMax)
      种子生长
      regiongrowing (Result, Regions, 1, 1, 0.01, 250)
      select_shape (Regions, SelectedRegions, ‘area’, ‘and’, 16332.6, 28629.5)
      shape_trans (SelectedRegions, RegionTrans, ‘convex’)
      union1 (RegionTrans, RegionUnion)
      erosion_circle (RegionUnion, RegionErosion, 3.5)
      reduce_domain (Result, RegionErosion, ImageReduced)

      求图像的绝对值
      abs_image (ImageReduced, ImageAbs)
      threshold (ImageAbs, Regions1, 0.3, 0.5)
      显示

      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

      在这里插入图片描述
      此外,Halcon中关于光度立体法的例程还有:

      1.洗发水瓶身缺陷检测(inspect_shampoo_label_photometric_stereo.hdev)

      2.皮革表面缺陷检测(inspect_leather_photometric_stereo.hdev)

      例程解析参考:halcon——缺陷检测常用方法总结(光度立体)


      戳戳小手帮忙点个免费的赞和关注吧,嘿嘿。

      参考资料:
      1.微信公众号:机器视觉那些事儿
      2.https://www.cnblogs.com/xyf327/p/14872873.html
      3.http://www.ihalcon.com/read-16432.html
      4.https://blog.csdn.net/weixin_38566632/article/details/116377384
      6.https://libaineu2004.blog.csdn.net/article/details/105366681
      6.傅里叶分析之掐死教程(完整版)更新于2014.06.06 - 知乎 (zhihu.com)
      7.图像的傅里叶变换
      8.光度立体

      • 1
        点赞
      • 18
        收藏
        觉得还不错? 一键收藏
      • 1
        评论

      “相关推荐”对你有帮助么?

      • 非常没帮助
      • 没帮助
      • 一般
      • 有帮助
      • 非常有帮助
      提交
      评论 1
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值