• Halcon 光度立体 缺陷检测


    一、概述

    halcon——缺陷检测常用方法总结(光度立体) - 唯有自己强大 - 博客园 (cnblogs.com)

            上周去了康耐视的新品发布会,我真的感觉压力山大,因为VM可以实现现在项目中的80% 的功能,感觉自己的不久就要失业了。同时康耐视开始布局工业的每个方面,生成一个完整的生态链,国内很喜欢搞某某一条龙服务。相机方面出了很多尤其是3D的,还有2.5D的相机,精度方面不好说,他们说Z方向的重复性精度可以达到0.15u,我们没有使用过,我对此保持怀疑,因为我用过的精度最高的是基恩士的的0.2u的,我尊重日本企业的严谨性和专业性,今天我看了一下那个halcon 的光度立体法,是2.5D 的。

    光度立体法主要是表面检测的,在检测缺口、凹痕,适用于检测金属物料。在采集图片的时候最好是使用灰度图,至少是3张 最好是4张图像

    光度立体的局限性:

    • 一方面假定相机是无畸变成像,也就是说必须使用远心镜头或者长焦镜头。
    • 另一方面假定每一个光源发射的光束都是平行且均匀的,也就是说必须使用具有均匀强度的远心照明光源,或者使用远距离的点光源代替。

    此外,物体必须具有朗伯反射特性,即它必须以漫反射的方式反射入射光。有镜面反射的物体或者区域(镜子或者光滑的表面)不能使用此方法,会得到一个错误的结果

    光照方向说明

    安装说明:

        1、远心镜头必须与被测试的物体表面垂直按照,在采集多张图片的时候一定要保证相机和物体不动,对于采集至少三张的灰度图像,其每次取像的照明方向必须改变(相对于相机)。

        2、在采集的多张图像中的每付图像照明方向必定是制定Slants和Tilts两个参数角度

    Slants:

    表示光束方向与相机中轴线的夹角,一般是30-60度之间

    Tilts:

    Tilt角度通常都是均匀分布在被测物体周围,比如3个方向打光,Tilt角度应该是[0,120,240]OR[0,120,-120],4个方向打光是[0,90,180,-90]。需要注意的是,打光方向不能相同,否则重构的图像结果达不到预期效果

    二、算子解释

    •  photometric_stereo (根据光度立体技术重建曲面)
    1. *参数列表:
    2. *Images(in)//输入灰度图像(4张)
    3. *HeightField(out)//返回重建高度信息图
    4. *Gradient(out)//返回表面的梯度信息图
    5. *Albedo(out)//返回表面的反射率信息图
    6. *Slant//光源光线与摄像机光轴的夹角
    7. *Tilt//光源光线投影与被测物主轴的夹角
    8. *ResultType//请求结果类型(高度场/梯度场/反射率)
    9. *ReconstructionMethod//重建方法类型
    10. *GenParamName//一般参数名称
    11. *GenParamValue// 一般参数设置
    12. * 重建高度信息图 表面的梯度信息图 表面的反射率信息图 光源光线与摄像机光轴的夹角 光源光线投影与被测物主轴的夹角 请求结果类型(高度场/梯度场/反射率) 重建方法类型(迫松重建)
    13. photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ResultType, 'poisson', [], [])
    • derivate_vector_field(处理photometric_stereo 函数输出的重建后的梯度、反射率、以及高度场信息图)
    1. *derivate_vector_field 处理photometric_stereo 函数输出的重建后的梯度、反射率、以及高度场信息图
    2. *将向量场的分量与高斯函数的导数进行卷积,并计算由此得到的各种特征。
    3. *在光度立体项目中,专门用于处理photometric_stereo 函数输出的重建后的梯度、反射率、以及高度场图像。
    4. *参数列表:
    5. *VectorField(in)// 梯度场图像
    6. *Result(out) // 返回平均曲率场图像
    7. *Sigma(in) // 高斯系数
    8. *如果在Sigma中传递一个值,那么在列和行方向上的平滑量是相同的。
    9. *如果在Sigma中传递两个值,第一个值指定列方向的平滑量,第二个值指定行方向的平滑量。
    10. *Component(in) //组件计算
    11. *curl,向量场的旋度。旋度的一个应用是分析光流场。旋度是如果向量场是流体,小船会旋转多少。
    12. *divergence,向量场的散度。“divergence”的一个应用是分析光流场。打个比方,如果向量场是流体,散度就是源和汇的位置。
    13. *mean_curvature,当输入向量场 VectorField为梯度场时,下垫面的平均曲率H。用于处理photometric_stereo返回的向量场。
    14. *gauss_curvature,当输入向量场 VectorField 为梯度场时,下垫面的高斯曲率K。用于处理photometric_stereo返回的向量场。
    15. derivate_vector_field (Gradient, Curl, 1, 'curl')

     

    三、缺陷检测

    反射率信息图

    思路

    1、不同角度采集4张灰度图,设置不同的角度参数 Slants   Tilts
    2、photometric_stereo  ,返回不同的图 重建高度信息图 表面的梯度信息图 表面的反射率信息图
    3、得到反射率信息图 然后利用blob 分析进行缺陷检测

    1. *思路:
    2. * 1、不同角度采集4张灰度图,设置不同的角度参数 Slants Tilts
    3. * 2、photometric_stereo ,返回不同的图 重建高度信息图 表面的梯度信息图 表面的反射率信息图
    4. * 3、得到反射率信息图 然后利用blob 分析进行缺陷检测
    5. dev_close_window ()
    6. dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
    7. set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
    8. * Part 1利用反射率图像检测皮革表面缺陷
    9. read_image (Images, 'photometric_stereo/leather_1_0' + [1:4])
    10. write_image (Images, 'tiff', 0, 'D:/1.tiff')
    11. ** 展示不同方向光源成像图像
    12. for I := 1 to 4 by 1
    13. Message := 'Sample 1: Acquire image ' + I + ' of 4'
    14. select_obj (Images, ObjectSelected, I)
    15. dev_display (ObjectSelected)
    16. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    17. * wait_seconds (0.5)
    18. endfor
    19. stop ()
    20. * 应用光度立体法生成的反射率图进行缺陷检测
    21. Tilts := [6.1,95.0,-176.1,-86.8]
    22. Slants := [41.4,42.6,41.7,40.9]
    23. * 梯度场 反射率
    24. ResultType := ['gradient','albedo']
    25. *参数列表:
    26. *Images(in//输入灰度图像(4张)
    27. *HeightField(out//返回重建高度信息图
    28. *Gradient(out//返回表面的梯度信息图
    29. *Albedo(out//返回表面的反射率信息图
    30. *Slant//光源光线与摄像机光轴的夹角
    31. *Tilt//光源光线投影与被测物主轴的夹角
    32. *ResultType//请求结果类型(高度场/梯度场/反射率)
    33. *ReconstructionMethod//重建方法类型
    34. *GenParamName//一般参数名称
    35. *GenParamValue// 一般参数设置
    36. * 重建高度信息图 表面的梯度信息图 表面的反射率信息图 光源光线与摄像机光轴的夹角 光源光线投影与被测物主轴的夹角 请求结果类型(高度场/梯度场/反射率) 重建方法类型(迫松重建)
    37. photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ResultType, 'poisson', [], [])
    38. * 显示反射率图
    39. dev_display (Albedo)
    40. *检测缺陷 反射率的基础上进行缺陷检测
    41. var_threshold (Albedo, Region, 15, 15, 0.4, 0.4, 'light')
    42. connection (Region, ConnectedRegions)
    43. select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10, 99999)
    44. union1 (SelectedRegions, RegionUnion)
    45. closing_circle (RegionUnion, RegionClosing, 3.5)
    46. connection (RegionClosing, Defects)
    47. area_center (Defects, Area, Row, Column)
    48. gen_circle (Circle, Row, Column, gen_tuple_const(|Row|,sqrt(Area) + 30))
    49. *显示缺陷
    50. dev_display (Albedo)
    51. dev_set_color ('red')
    52. dev_set_draw ('margin')
    53. dev_set_line_width (4)
    54. dev_display (Circle)

    梯度信息图

    思路

    1、不同角度采集4张灰度图,设置不同的角度参数 Slants   Tilts
    2、photometric_stereo  ,返回不同的图 重建高度信息图 表面的梯度信息图 表面的反射率信息图
    3、得到梯度信息图然后利用blob 分析进行缺陷检测

    1. *思路:
    2. * 1、不同角度采集4张灰度图,设置不同的角度参数 Slants Tilts
    3. * 2、photometric_stereo ,返回不同的图 重建高度信息图 表面的梯度信息图 表面的反射率信息图
    4. * 3、得到梯度信息图然后利用blob 分析进行缺陷检测
    5. * Part 2 利用梯度图像检测皮革表面缺陷
    6. read_image (Images, 'photometric_stereo/leather_2_0' + [1:4])
    7. for I := 1 to 4 by 1
    8. Message := 'Sample 2: Acquire image ' + I + ' of 4'
    9. select_obj (Images, ObjectSelected, I)
    10. dev_display (ObjectSelected)
    11. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    12. *wait_seconds (0.5)
    13. stop()
    14. endfor
    15. * 应用光度立体法生成的反射率图
    16. photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ResultType, 'poisson', [], [])
    17. *对反射率图二值化(发现无法二值化)
    18. threshold (Albedo, Region1, 128, 255)
    19. * 显示反射率图
    20. dev_display (Albedo)
    21. *derivate_vector_field 处理photometric_stereo 函数输出的重建后的梯度、反射率、以及高度场信息图
    22. *将向量场的分量与高斯函数的导数进行卷积,并计算由此得到的各种特征。
    23. *在光度立体项目中,专门用于处理photometric_stereo 函数输出的重建后的梯度、反射率、以及高度场图像。
    24. *参数列表:
    25. *VectorField(in)// 梯度场图像
    26. *Result(out) // 返回平均曲率场图像
    27. *Sigma(in) // 高斯系数
    28. *如果在Sigma中传递一个值,那么在列和行方向上的平滑量是相同的。
    29. *如果在Sigma中传递两个值,第一个值指定列方向的平滑量,第二个值指定行方向的平滑量。
    30. *Component(in) //组件计算
    31. *curl,向量场的旋度。旋度的一个应用是分析光流场。旋度是如果向量场是流体,小船会旋转多少。
    32. *divergence,向量场的散度。“divergence”的一个应用是分析光流场。打个比方,如果向量场是流体,散度就是源和汇的位置。
    33. *mean_curvature,当输入向量场 VectorField为梯度场时,下垫面的平均曲率H。用于处理photometric_stereo返回的向量场。
    34. *gauss_curvature,当输入向量场 VectorField 为梯度场时,下垫面的高斯曲率K。用于处理photometric_stereo返回的向量场。
    35. derivate_vector_field (Gradient, Curl, 1, 'curl')
    36. *derivate_gauss.hdev
    37. *derivate_gauss (Image, ImageGauss, 3, 'none')
    38. * 将一个图像与高斯函数的导数进行卷积。 效果与FFT进行高斯滤波差不多。
    39. *主要的区别是边界处理:FFT的定义假设信号是周期性的,因此边界处理是循环的延续。与此相反,derivate_gauss在图像边界使用灰度值的镜像。
    40. *通过FFT进行过滤的速度已经快于在Sigma=3(排除创建过滤器的时间)中使用derivate_gauss。这种优势随着Simag的增大而变得更加明显。
    41. *'none' 仅使用平滑
    42. *'x' 沿X的一阶导数
    43. derivate_gauss (Curl, CurlGradient, 1, 'gradient')// 将一个图像与高斯函数的导数进行卷积。 效果与FFT进行高斯滤波差不多。
    44. * 显示梯度图
    45. dev_display (CurlGradient)
    46. Message := 'Changes in the gradient curl'
    47. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    48. disp_continue_message (WindowHandle, 'black', 'true')
    49. stop ()
    50. * 用梯度图寻找缺陷
    51. threshold (CurlGradient, Region, 0, 0.01)
    52. *
    53. rank_region (Region, RegionCount, 10, 10, 30)//归类区域
    54. connection (RegionCount, ConnectedRegions)
    55. select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 2000, 99999)
    56. union1 (SelectedRegions, RegionUnion)
    57. rank_region (RegionUnion, RegionCount1, 25, 25, 170)
    58. connection (RegionCount1, NoTextured)
    59. * 显示
    60. dev_display (Albedo)
    61. dev_set_draw ('margin')
    62. dev_set_color ('red')
    63. dev_set_line_width (3)
    64. dev_display (NoTextured)
    65. disp_message (WindowHandle, 'Non-textured areas on leather', 'window', 12, 12, 'black', 'true')
    66. stop ()

    四、洗发水表面检测 

    思路:

    梯度信息图来检测

     inspect_shampoo_label_photometric_stereo.hdev

    1. *思路 :
    2. * inspect_shampoo_label_photometric_stereo.hdev
    3. dev_close_window ()
    4. dev_update_off ()
    5. dev_open_window (0, 0, 640, 512, 'black', WindowHandle)
    6. set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
    7. Message := 'Inspect the label of a shampoo bottle'
    8. Message[1] := 'using photometric stereo. In this case four'
    9. Message[2] := 'different light orientations were used.'
    10. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    11. disp_continue_message (WindowHandle, 'black', 'true')
    12. stop ()
    13. *
    14. * Show input images with different illumination
    15. read_image (Images, 'photometric_stereo/shampoo_label_0' + [1:4])
    16. for I := 1 to 4 by 1
    17. Message := 'Acquire image ' + I + ' of 4'
    18. select_obj (Images, ObjectSelected, I)
    19. dev_display (ObjectSelected)
    20. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    21. wait_seconds (0.5)
    22. endfor
    23. *
    24. * Apply photometric stereo to determine the albedo
    25. * and the surface gradient.
    26. Tilts := [6.1,95.0,-176.1,-86.8]
    27. Slants := [41.4,42.6,41.7,40.9]
    28. ResultType := ['gradient','albedo']
    29. photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ResultType, 'poisson', [], [])
    30. *
    31. * Display the albedo image
    32. dev_display (Albedo)
    33. disp_message (WindowHandle, 'Albedo image', 'window', 12, 12, 'black', 'true')
    34. disp_continue_message (WindowHandle, 'black', 'true')
    35. stop ()
    36. *
    37. * Calculate the gaussian curvature of the surface
    38. * using the gradient field as input for the operator
    39. * derivate_vector_field.
    40. * Defects are usually easy to detect in the curvature image.
    41. derivate_vector_field (Gradient, MeanCurvature, 1.0, 'mean_curvature')
    42. *
    43. * Detect defects
    44. *
    45. * Segment the tablet areas in the curvature image
    46. threshold (MeanCurvature, Region, -10, -0.07)
    47. opening_circle (Region, RegionOpening, 1)
    48. connection (RegionOpening, ConnectedRegions)
    49. select_shape (ConnectedRegions, Defects, 'area', 'and', 50, 99999)
    50. shape_trans (Defects, Circle, 'outer_circle')
    51. * Display the defects in curvature image
    52. dev_set_draw ('margin')
    53. dev_set_color ('red')
    54. dev_set_line_width (2)
    55. dev_display (MeanCurvature)
    56. dev_display (Circle)
    57. Message := 'The defect can easily be detected'
    58. Message[1] := 'in the surface curvature image'
    59. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    60. stop ()
    61. * Display the defects in the albedo image
    62. dev_set_draw ('margin')
    63. dev_set_color ('red')
    64. dev_display (Albedo)
    65. dev_display (Circle)
    66. disp_message (WindowHandle, 'Defect in albedo image', 'window', 12, 12, 'black', 'true')

    我用反射率的图做了,是达不到这个效果的

    五、药片缺陷检测

    1. * Initialization
    2. dev_close_window ()
    3. dev_update_off ()
    4. dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
    5. set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
    6. Message := 'Inspect the backside of a blister'
    7. Message[1] := 'using photometric stereo. In this case four'
    8. Message[2] := 'different light orientations were used.'
    9. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    10. disp_continue_message (WindowHandle, 'black', 'true')
    11. stop ()
    12. *
    13. * Show input images with different illumination
    14. read_image (Images, 'photometric_stereo/blister_back_0' + [1:4])
    15. for I := 1 to 4 by 1
    16. Message := 'Acquire image ' + I + ' of 4'
    17. select_obj (Images, ObjectSelected, I)
    18. dev_display (ObjectSelected)
    19. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    20. wait_seconds (0.5)
    21. endfor
    22. stop ()
    23. *
    24. * Apply photometric stereo to determine the albedo
    25. * and the surface gradient.
    26. Tilts := [6.1,95.0,-176.1,-86.8]
    27. Slants := [41.4,42.6,41.7,40.9]
    28. ResultType := ['gradient','albedo']
    29. photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ResultType, 'poisson', [], [])
    30. *
    31. * Display the albedo image
    32. dev_display (Albedo)
    33. disp_message (WindowHandle, 'Albedo image', 'window', 12, 12, 'black', 'true')
    34. disp_continue_message (WindowHandle, 'black', 'true')
    35. stop ()
    36. *
    37. * Calculate the gaussian curvature of the surface
    38. * using the gradient field as input for the operator
    39. * derivate_vector_field.
    40. * Defects are usually easy to detect in the curvature image.
    41. derivate_vector_field (Gradient, GaussCurvature, 1, 'gauss_curvature')
    42. *
    43. * Detect defects
    44. *
    45. * Segment the tablet areas in the curvature image
    46. regiongrowing (GaussCurvature, Regions, 1, 1, 0.001, 250)
    47. select_shape (Regions, TabletRegions, ['width','height'], 'and', [150,150], [200,200])
    48. shape_trans (TabletRegions, TabletRegions, 'convex')
    49. union1 (TabletRegions, TabletRegions)
    50. erosion_circle (TabletRegions, TabletRegions, 3.5)
    51. * Search for defects inside the tablet areas
    52. reduce_domain (GaussCurvature, TabletRegions, ImageReduced)
    53. abs_image (ImageReduced, ImageAbs)
    54. threshold (ImageAbs, Region, 0.03, 255)
    55. closing_circle (Region, RegionClosing, 10.5)
    56. connection (RegionClosing, ConnectedRegions)
    57. select_shape (ConnectedRegions, Defects, 'area', 'and', 10, 99999)
    58. area_center (Defects, Area, Row, Column)
    59. gen_circle (Circle, Row, Column, gen_tuple_const(|Row|,20.5))
    60. * Display the defects in curvature image
    61. dev_set_draw ('margin')
    62. dev_set_color ('red')
    63. dev_set_line_width (2)
    64. dev_display (GaussCurvature)
    65. dev_display (Circle)
    66. Message := 'The defect can easily be detected'
    67. Message[1] := 'in the surface curvature image'
    68. disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    69. stop ()
    70. * Display the defects in the albedo image
    71. dev_set_draw ('margin')
    72. dev_set_color ('red')
    73. dev_display (Albedo)
    74. dev_display (Circle)
    75. disp_message (WindowHandle, 'Defect in albedo image', 'window', 12, 12, 'black', 'true')

  • 相关阅读:
    element el-table 设置fixed导致行错乱问题
    jenkins-pipeline语法总结(最全)
    Excel VLOOKUP实用教程之 10 在使用 VLOOKUP 函数时处理错误?(教程含数据excel)
    ESP32基础应用之LVGL基础
    前端常用设计模式
    设计模式(七)桥接
    基于Android驾校驾考助手 java驾照考试系统
    python -opencv形态学操作
    (免费领源码)php#Thinkphp#MYSQL校园二手交易app 99211-计算机毕业设计项目选题推荐
    第2-2-4章 常见组件与中台化-常用组件服务介绍-分布式ID-附Snowflake雪花算法的代码实现
  • 原文地址:https://blog.csdn.net/weixin_39354845/article/details/139227632