缺陷检测技术详解(含 Halcon 示例)
一、缺陷检测概述
缺陷检测是通过图像分析技术识别产品表面或内部的异常区域(如划痕、凹陷、污渍、裂纹等),广泛应用于工业制造(电子、汽车、食品包装等)、医疗影像等领域。核心目标是:快速、准确地区分合格产品与存在缺陷的产品,并定位缺陷位置、判断缺陷类型。
缺陷检测的一般流程:
图像采集(工业相机、显微镜等);
预处理(去噪、增强、校正);
感兴趣区域(ROI)提取;
缺陷检测与分割;
缺陷特征分析(大小、形状、灰度等);
判定与分类(合格 / 不合格,缺陷类型)。
二、缺陷检测的关键技术与方法
1. 基于灰度差异的检测
适用于缺陷与背景灰度值差异明显的场景(如白色表面的黑点、金属表面的划痕)。
原理:通过灰度阈值、灰度差分析或滤波提取灰度异常区域。
2. 基于形态学的检测
适用于缺陷表现为形状异常的场景(如孔洞、凸起、边缘缺损)。
原理:利用形态学操作(腐蚀、膨胀、开运算、闭运算)突出缺陷的形状特征。
3. 基于模板匹配的检测
适用于有标准模板的场景(如零件缺失、装配错误)。
原理:将待检测图像与标准模板对比,通过差异区域定位缺陷。
4. 基于边缘与轮廓的检测
适用于缺陷导致边缘不连续或轮廓异常的场景(如裂纹、边缘毛刺)。
原理:提取图像边缘,通过边缘完整性或轮廓特征(如曲率、长度)识别缺陷。
5. 基于频域的检测
适用于周期性纹理背景中的缺陷(如布料、电路板的纹理缺陷)。
原理:通过傅里叶变换过滤背景纹理,突出缺陷的高频分量。
三、Halcon 缺陷检测核心算子
| 算子类别 | 关键算子 | 功能描述 |
|---|---|---|
| 预处理 | mean_image、gauss_filter | 平滑去噪 |
emphasize、scale_image | 增强对比度、灰度缩放 | |
| 阈值分割 | threshold、dyn_threshold | 固定阈值、动态阈值分割(适应光照变化) |
| 形态学操作 | erosion、dilation | 腐蚀(去除小区域)、膨胀(连接断裂区域) |
opening、closing | 开运算(去噪点)、闭运算(填孔洞) | |
| 差异分析 | sub_image | 计算两幅图像的灰度差(模板对比) |
| 边缘检测 | edges_sub_pix、canny_edge | 提取亚像素级边缘、Canny 边缘检测 |
| 区域特征分析 | select_shape、area_center | 根据面积、形状等筛选缺陷区域 |
| 频域处理 | fft_image、rft2 | 傅里叶变换、快速傅里叶变换 |
四、Halcon 缺陷检测实例
实例 1:金属表面划痕检测(基于灰度差异与形态学)
场景:检测金属表面的深色划痕(划痕灰度低于正常区域)。
dev_update_off () * 1. 读取图像 read_image (MetalImage, 'metal_surface.png') dev_close_window () get_image_size (MetalImage, Width, Height) dev_open_window (0, 0, Width, Height, 'black', WindowHandle) dev_display (MetalImage) disp_continue_message (WindowHandle, 'black', 'true') stop () * 2. 预处理:去噪与增强 mean_image (MetalImage, MeanImage, 5, 5) // 均值滤波去噪 emphasize (MeanImage, EmphasizeImage, 10, 10, 1) // 增强边缘对比度 * 3. 阈值分割:提取低灰度区域(划痕) threshold (EmphasizeImage, DarkRegions, 0, 80) // 假设划痕灰度≤80 * 4. 形态学处理:去除噪声点,保留连续划痕 opening_circle (DarkRegions, OpenRegions, 3) // 开运算(半径3)去小噪点 closing_circle (OpenRegions, DefectRegions, 2) // 闭运算连接断裂划痕 * 5. 筛选缺陷:排除过小区域(误检) select_shape (DefectRegions, Scratches, 'area', 'and', 50, 10000) // 面积≥50像素 * 6. 显示结果 dev_display (MetalImage) dev_set_color ('red') dev_display (Scratches) disp_message (WindowHandle, '检测到 ' + |Scratches| + ' 处划痕', 'window', 10, 10, 'red', 'true') stop ()实例 2:瓶盖缺陷检测(基于模板匹配)
场景:通过标准瓶盖模板与待检测瓶盖的差异定位缺陷(如缺口、污渍)。
dev_update_off () * 1. 读取标准模板与待检测图像 read_image (TemplateImage, 'cap_template.png') // 无缺陷的标准瓶盖 read_image (TestImage, 'cap_test.png') // 待检测瓶盖 dev_close_window () get_image_size (TemplateImage, Width, Height) dev_open_window (0, 0, Width*2, Height, 'black', WindowHandle) * 2. 预处理:转为灰度图并归一化 rgb1_to_gray (TemplateImage, TemplateGray) rgb1_to_gray (TestImage, TestGray) scale_image (TemplateGray, TemplateScaled, 1, 0) scale_image (TestGray, TestScaled, 1, 0) * 3. 模板匹配:定位瓶盖位置(确保两幅图像对齐) create_ncc_model (TemplateGray, 'auto', 0, 0, 'auto', 'use_polarity', ModelID) find_ncc_model (TestGray, ModelID, 0, 0, 0.7, 1, 0.5, 'true', 0, Row, Col, Angle, Score) clear_ncc_model (ModelID) * 4. 图像对齐:将待检测图像与模板对齐(消除位置偏差) vector_angle_to_rigid (0, 0, 0, Row, Col, Angle, HomMat2D) affine_trans_image (TestScaled, AlignedTest, HomMat2D, 'constant', 'false') * 5. 差异分析:计算模板与待检测图像的灰度差 sub_image (TemplateScaled, AlignedTest, DiffImage, 1, 128) // 灰度差图像 threshold (DiffImage, DiffRegions, 30, 255) // 提取差异明显的区域(阈值30) * 6. 筛选缺陷:排除微小差异(噪声) opening_rectangle1 (DiffRegions, DefectRegions, 3, 3) select_shape (DefectRegions, Defects, 'area', 'and', 100, 10000) * 7. 显示结果 dev_display (TemplateScaled) dev_set_window (WindowHandle) dev_display (AlignedTest) dev_set_color ('red') dev_display (Defects) disp_message (WindowHandle, '模板', 'window', 10, 10, 'green', 'true') disp_message (WindowHandle, '待检测(缺陷:' + |Defects| + ')', 'window', 10, Width+10, 'red', 'true') stop ()实例 3:电路板焊点缺陷检测(基于边缘分析)
场景:通过焊点边缘的完整性判断是否存在虚焊(边缘不连续)或漏焊。
dev_update_off () * 1. 读取图像 read_image (PCBImage, 'pcb_solder.png') dev_close_window () get_image_size (PCBImage, Width, Height) dev_open_window (0, 0, Width, Height, 'black', WindowHandle) * 2. 预处理:增强对比度,提取焊点区域 threshold (PCBImage, SolderRegions, 150, 255) // 焊点为高灰度区域 connection (SolderRegions, SingleSolders) // 分割单个焊点 * 3. 边缘提取:获取焊点边缘 edges_sub_pix (PCBImage, Edges, 'canny', 1, 20, 40) // Canny边缘检测(亚像素级) segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 2) // 分割轮廓为线和圆 * 4. 分析边缘:筛选边缘不完整的焊点(缺陷) gen_empty_obj (DefectSolders) for i := 0 to |SingleSolders| - 1 by 1 select_obj (SingleSolders, Solder, i+1) * 提取焊点内的边缘 reduce_domain (PCBImage, Solder, SolderROI) edges_sub_pix (SolderROI, SolderEdges, 'canny', 1, 20, 40) * 计算边缘长度(正常焊点边缘应连续且长度达标) length_xld (SolderEdges, Length) sum_tuple (Length, TotalLength) * 若边缘总长度低于阈值,判定为缺陷 if (TotalLength < 200) // 阈值根据正常焊点设定 concat_obj (DefectSolders, Solder, DefectSolders) endif endfor * 5. 显示结果 dev_display (PCBImage) dev_set_color ('green') dev_display (SingleSolders) dev_set_color ('red') dev_display (DefectSolders) disp_message (WindowHandle, '缺陷焊点:' + |DefectSolders|, 'window', 10, 10, 'red', 'true') stop ()五、缺陷检测的优化技巧
图像采集优化:确保光照均匀(避免反光、阴影),选择合适分辨率(缺陷尺寸≥2 像素);
预处理关键:
噪声处理:根据噪声类型选择滤波(高斯滤波去高斯噪声,中值滤波去椒盐噪声);
对比度增强:对低对比度图像用
histogram_equalization或local_std_dev增强;
阈值自适应:对光照不均的场景,用
dyn_threshold(动态阈值)替代固定阈值;缺陷筛选:通过
select_shape筛选面积、圆形度、长宽比等特征,排除误检(如灰尘);模板更新:对于批量生产中的细微差异,定期更新模板以适应产品一致性变化。
六、总结
缺陷检测的核心是突出缺陷与正常区域的差异,根据缺陷类型选择合适的检测方法(灰度差异、形态学、模板匹配等)。Halcon 提供了丰富的算子支持从预处理到缺陷分析的全流程,通过实例中的模板可快速搭建检测系统,并结合优化技巧提升检测精度与鲁棒性。