时间:2025-03-21 17:26
人气:
作者:admin
原文作者:aircraft
原文链接:https://www.cnblogs.com/DOMLX/p/18785484
有兴趣可以多看其他的halcon教程
本篇主要讲一些常见的缺陷检测方法,目前只会讲一些,后面有空的话会不断的补充完整。因为缺陷的种类实在太多太多了,各种各样的缺陷可能都要用各种不同的检测方法去检测,所以想要精通缺陷检测特别难,基本大家都是熟悉自己经常遇到的缺陷领域。
第一种:就是最常见的Blob分析加上特征提取(本篇也会多给一些这个示例。因为确实是最基础也是最常用的,用的好你可能百分之八九十的缺陷都可以检测,主要还是看对这块的理解)
第二种:图像匹配定位后再加Blob分析,可以结合本篇的Blob分析和我下一篇的:halcon 入门教程(六) 图像匹配(基于形状的模板匹配)与缺陷检测区域定位
第三种:建立模板区域的差异模型,原理就是后面所有的产品都与一个标准品做差异模型,可以差异的程度对其判断NG,OK。可以看我这篇博客理解:halcon 入门教程 (七) halcon中是怎么实现半导体/Led中的GoldenDie的检测方法的 基于局部可变形模板匹配 variation_model模型或者用差异模型去提取缺陷的位置,然后再用深度学习分类去分类,再或者提取了缺陷的位置裁剪了给深度学习的目标检测去检测,都行,都是可行的思路
第四种:光度立体法(基本属于2.5d的视觉范围了,适用于一些物体表面有凹凸情况下的检测,通过多个角度方向的打光图片,来获取伪3d的信息进行缺陷检测)
第五种:图像匹配定位后再加测量(比如一些钢管,或者元器件表面的某个东西的长度,宽度,厚度,半径之类的达不达标),可以结合halcon 入门教程(六) 图像匹配(基于形状的模板匹配)与缺陷检测区域定位 和 halcon 入门教程(三) 测量量测相关(点到线距离,线到线距离,轮廓线距离,一维测量,圆形测量,矩形测量等)这两篇来看,组合起来基本就是这种检测方法了。
第六种:机器学习和深度学习的缺陷检测(基本都是通过标记好的和坏的训练集,给神经网络程序训练学习,学习成功后,后面只要传入该产品图,或者某个区域图,便可以直接给出判断好坏,甚至处理一下可以把具体缺陷都标注显示出来)
有兴趣可以看看我这篇博客:halcon 深度学习教程(一)分类检测 (工业里如何使用halcon深度学习去检测分类产品)和
第七种:空域和频域分析(适用于一些像皮革,木材,纹理石板之类的对比度低的产品上去进行检测)
第八种:三维重建后再加特征提取(属于3d视觉的领域了,会多一些诸如高度或者说深度信息)
然后这边说一下目前主流的工业的缺陷检测基本主流就是三种:
第一种:就是绘制需要检测的区域,用Blob分析加上特征提取分别去卡控每个区域的瑕疵来判断NG-OK。
第二种:对需要检测的物体或者区域建立差异模型,进行差异分析判断NG-OK.
第三种:使用深度学习的分类或者目标检测,对晶圆进行分类,对瑕疵进行目标检测。然后结果进行NG-OK的判定。
实际使用中最好你的算法里三种都有,然后结合一种或者两种或者三种分别的结果一起去卡控判断,这样基本就可以符合不管是半导体,面板,LED等行业的缺陷检测了。
下面一些算子的原型我就不介绍了,有看过前面教程的应该都认识这些常用的算子了。而且每个示例代码我都打了非常详细的注释,基本看着注释应该是可以理解的吧。
一.Blob分析加上特征提取
示例1:榛子威化饼的质量检测

OK图:

NG图:

示例代码:
* *************************************************************
* 本程序演示针对榛子威化饼的质量检测
* 检测方法:基于形态学处理提取目标区域,通过孔洞面积和矩形度进行缺陷判断
* 工业应用:食品包装完整性检测(破损、变形检测)
* 检测标准:孔洞面积>300 或 矩形度<0.92 判定为不合格
* *************************************************************
* 初始化图像和显示窗口
read_image (Image, 'food/hazelnut_wafer_01')
* 关闭可能存在的旧窗口
dev_close_window ()
* 创建自适应图像尺寸的显示窗口
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
* 禁止窗口自动更新(提升执行效率)
dev_update_window ('off')
* 设置可视化参数
* 线宽3像素用于突出显示轮廓
dev_set_line_width (3)
* 轮廓显示模式(节省显示资源)
dev_set_draw ('margin')
* 设置等宽字体便于字符对齐
set_display_font (WindowHandle, 20, 'mono', 'true', 'false')
* 处理24张连续拍摄的威化饼图像
for Index := 1 to 2 by 1
* 读取序列图像(文件名格式:1~2.bmp)
read_image (Image, Index+'.bmp')
* 图像预处理
* 使用直方图平滑法进行二值化(适合低对比度场景)
binary_threshold (Image, Foreground, 'smooth_histo', 'light', UsedThreshold)
* 8.5像素半径开运算去除毛刺和小孔洞
opening_circle (Foreground, FinalRegion, 8.5)
* 特征提取
* 计算区域内部孔洞总面积(关键缺陷指标)
area_holes (FinalRegion, AreaHoles)
* 计算区域矩形度(1为完美矩形,值越小变形越严重)
rectangularity (FinalRegion, Rectangularity)
* 显示原始图像
dev_display (Image)
* 质量判定逻辑
* 孔洞超标或形状变形时显示红色报警
if (AreaHoles > 300 or Rectangularity < 0.92)
dev_set_color ('red')
Text := 'Not OK'
* 合格产品显示绿色轮廓
else
dev_set_color ('forest green')
Text := 'OK'
endif
* 显示检测结果
dev_display (FinalRegion)
* 在窗口左上角显示OK/NG状态
disp_message (WindowHandle, Text, 'window', 12, 12, '', 'false')
* 非最后一张图像时暂停观察
if (Index < 2)
* 显示继续检测提示
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 模拟产线节拍控制
endif
endfor
示例2:鳍片检测程序(fin.hdev) 利用形态学分析与差异模型检测

两张边缘有凸出的图片:


通过提取白色背景区域,然后进行闭运算将区域边缘小凸出闭合,然后与原始区域做个差异,得到缺陷位置,在进行开运算,消除多提出来的边的区域。

结果图:

实例代码:
* *************************************************************
* 鳍片检测程序(fin.hdev)
* 功能:通过形态学处理检测金属鳍片缺陷
* 检测逻辑:
* 1. 二值化分离前景
* 2. 闭运算填充结构间隙
* 3. 差异检测潜在缺陷区域
* 4. 开运算去除噪声
* 工业应用:散热器制造质检
* *************************************************************
* 关闭窗口自动刷新(提升执行效率)
dev_update_window ('off')
* 读取鳍片图像序列(fin2, fin3)
read_image (Fins, 'fin' + [2:3])
* 初始化显示窗口
get_image_size (Fins, Width, Height)
dev_close_window ()
* 创建与图像等大的黑色背景窗口
dev_open_window (0, 0, Width[0], Height[0], 'black', WindowID)
* 设置等宽字体便于信息对齐
set_display_font (WindowID, 14, 'mono', 'true', 'false')
* 遍历处理3个检测对象(实际图像为2张,索引从1开始)
for I := 1 to 2 by 1
* 选择当前处理对象
select_obj (Fins, Fin, I)
* 显示原始图像
dev_display (Fin)
* 步骤1:二值化分割(最大化前景背景可分性)
binary_threshold (Fin, Background, 'max_separability', 'light', UsedThreshold)
* 蓝色显示初始分割结果
dev_set_color ('blue')
dev_set_draw ('margin')
dev_set_line_width (4)
dev_display (Background)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* 质检员确认阶段结果
* 步骤2:大半径闭运算填充结构间隙
closing_circle (Background, ClosedBackground, 250)
* 绿色显示填充后区域
dev_set_color ('green')
dev_display (ClosedBackground)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* 确认形态学处理效果
* 步骤3:差异检测(理想结构与实际结构对比)
difference (ClosedBackground, Background, RegionDifference)
* 步骤4:开运算去除微小噪声
opening_rectangle1 (RegionDifference, FinRegion, 5, 5)
* 显示最终检测结果
dev_display (Fin)
* 原始图像背景
dev_set_color ('red')
* 红色高亮缺陷
dev_display (FinRegion)
* 叠加缺陷区域
* 计算缺陷区域特征
area_center (FinRegion, FinArea, Row, Column)
* 非最后一张图像时暂停
if (I < 2)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* 模拟产线节拍等待
endif
endfor
示例3:塑料网缺陷检测程序 使用动态阈值检测塑料网中的异常纹理区域 原图与均值图比对 提取出比均值图还暗的多的缺陷区域出来

两张测试的原图:


实例代码:
* *************************************************************
* 塑料网缺陷检测程序
* 功能:使用动态阈值检测塑料网中的异常纹理区域
* 检测逻辑:
* 1. 图像平滑处理消除纹理干扰
* 2. 动态阈值分割异常区域
* 3. 连通域分析与面积筛选
* 工业应用:塑料编织品质量检测
* *************************************************************
* 关闭窗口自动更新(提升执行效率)
dev_update_window ('off')
* 读取塑料网基准图像(用于窗口初始化)
read_image (Image, 'plastic_mesh_'+[1])
* 初始化显示窗口
dev_close_window ()
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowHandle)
* 设置可视化参数
* 等宽字体便于信息对齐
set_display_font (WindowHandle, 18, 'mono', 'true', 'false')
* 轮廓显示模式(节省显示资源)
dev_set_draw ('margin')
* 设置检测结果轮廓线宽
dev_set_line_width (3)
* 处理两张塑料网图像序列
for J := 1 to 2 by 1
* 读取当前检测图像(文件名格式:plastic_mesh_1.bmp~plastic_mesh_2.bmp)
read_image (Image, 'plastic_mesh_' + J+'.bmp')
* 图像预处理:49x49均值滤波(消除高频纹理干扰)
mean_image (Image, ImageMean, 49, 49)
* 动态阈值分割(检测比背景暗5个灰度级的异常区域)
dyn_threshold (Image, ImageMean, RegionDynThresh, 5, 'dark')
* 连通域分析(分离独立缺陷区域)
connection (RegionDynThresh, ConnectedRegions)
* 面积筛选(过滤500像素以下的噪声)
select_shape (ConnectedRegions, ErrorRegions, 'area', 'and', 500, 99999)
* 统计缺陷数量
count_obj (ErrorRegions, NumErrors)
* 显示原始图像和检测结果
dev_display (Image)
dev_set_color ('red')
* 红色高亮缺陷
dev_display (ErrorRegions)
* 判定结果输出
if (NumErrors > 0)
* 显示NG标识(位置:第24行,第12列)
disp_message (WindowHandle, 'Mesh not OK', 'window', 24, 12, 'black', 'true')
else
* 显示OK标识
disp_message (WindowHandle, 'Mesh OK', 'window', 24, 12, 'black', 'true')
endif
* 非最后一张图像时显示继续提示
if (J < 2)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 模拟产线节拍控制
endif
endfor
结果图:


划痕检测的还可以看看这篇surface_scratche.hdev:



OK,这里先写这几个,还有更多的都在halcon的官方案例集里,右边那一堆都是。

二.空域和频域结合的缺陷检测
这里主要的案例都来自halcon程序集的快速傅里叶变换,有兴趣详细了解的,就可以去看看。就如我一直在说的,halcon里的实例就是自己最好的老师。

先大概了解一下这个东西:
read_image (Image, 'plastics_01.jpg') * 读取塑料件表面图像
* 执行FFT(空间域→频域)
fft_image (Image, ImageFFT) * 输出是复数图像(实部+虚部)
* 生成高斯低通滤波器(抑制背景纹理)
gen_gauss_filter (Filter, 20, 20, 0, 'none', 'rft', Width, Height)
* 频域相乘(保留高频=缺陷,抑制低频=背景)
convol_fft (ImageFFT, Filter, FilteredFFT)
* 逆FFT(频域→空间域)
fft_image_inv (FilteredFFT, ImageFiltered) * 得到增强后的图像
threshold (ImageFiltered, Defects, 120, 255) * 阈值分割
connection (Defects, ConnectedRegions) * 连通区域分析
optimize_rft_speed函数优化处理速度。gen_gauss_filter(抑制高频噪声)。gen_derivative_filter(增强边缘)。power_real (ImageFFT, PowerSpectrum) * 计算功率谱
dev_display (PowerSpectrum) * 显示频域能量分布
亮点表示强频率成分(如周期性纹理)。
dev_update_off ()
read_image (Image, 'plastics_01.jpg')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
* FFT转换到频域
fft_image (Image, ImageFFT)
* 设计高斯滤波器(抑制低频背景)
gen_gauss_filter (Filter, 15, 15, 0, 'none', 'rft', Width, Height)
convol_fft (ImageFFT, Filter, FilteredFFT)
* 逆FFT转回空间域
fft_image_inv (FilteredFFT, ImageFiltered)
* 缺陷分割与显示
threshold (ImageFiltered, Defects, 100, 255)
connection (Defects, ConnectedRegions)
dev_display (Image)
dev_set_color ('red')
dev_display (ConnectedRegions)
power_real可视化频域,调整滤波器参数观察缺陷检测效果。
OK,接下来学习一下主要运用到的算子
1.空域转频域算子fft_image(Image : ImageFFT : : )详解:
Image:输入图像(必须为单通道灰度图像)。ImageFFT:频域图像(复数形式,包含实部和虚部)。复数图像结构:
ImageFFT包含两个通道:可通过get_image_size查看通道数:Channels := 2
频域特性:
* 1. 读取图像并预处理
read_image (Image, 'plastics_01.jpg')
rgb1_to_gray (Image, GrayImage) * 确保输入是灰度图
* 2. 优化FFT计算速度(关键步骤!)
optimize_rft_speed (Width, Height, 'standard') * 自动填充至最优尺寸
* 3. 执行FFT转换到频域
fft_image (GrayImage, ImageFFT)
* 4. 频域滤波(示例:高斯带阻滤波)
gen_gauss_filter (GaussFilter, 15, 15, 0, 'none', 'rft', Width, Height)
convol_fft (ImageFFT, GaussFilter, FilteredFFT)
* 5. 逆FFT转回空间域
fft_image_inv (FilteredFFT, ImageFiltered)
* 6. 缺陷检测
threshold (ImageFiltered, Defects, 100, 255)
connection (Defects, ConnectedRegions)
optimize_rft_speed自动填充至最优尺寸。get_image_size (Image, Width, Height)
optimize_rft_speed (Width, Height, 'standard') * 第三个参数可选:
* 'standard'(平衡速度/内存)
* 'explore'(深度优化)
byte、uint2或real类型。real类型避免精度损失:convert_image_type (GrayImage, ImageReal, 'real')
fft_image (ImageReal, ImageFFT)
* 大σ值高斯滤波器(σ=20)
gen_gauss_filter (LowPassFilter, 20, 20, 0, 'none', 'rft', Width, Height)
高频增强(提取缺陷):
* 高斯带阻滤波(抑制特定频率)
gen_gauss_filter (BandStopFilter, 10, 10, 0, 'none', 'rft', Width, Height)
power_real (ImageFFT, PowerSpectrum) * 计算功率谱(实部² + 虚部²)
dev_display (PowerSpectrum) * 显示亮度表示能量强度
ImageFFT为什么是乱码?fft_image (Image, ImageFFT)
power_real (ImageFFT, PowerSpectrum)
dev_display (PowerSpectrum)
optimize_rft_speed优化尺寸。fft_generic的快速模式:fft_generic (Image, ImageFFT, 'to_freq', 'explore', 'complex', Width)
fft_image将图像转换到频域,使周期性纹理和微小缺陷更易分离。通过合理设计滤波器,您可以在频域中“过滤”掉不需要的信息,显著提升缺陷检测的准确性。
2.生成高斯滤波器算子gen_gauss_filter( : ImageGauss : Sigma1, Sigma2, Phi, Norm, Mode, Width, Height : )详解:
|
参数 | 类型 | 说明 | 工业检测调参建议 |
|---|---|---|---|
ImageGauss |
输出对象 | 生成的高斯滤波器图像 | - |
Sigma1 |
实数 | X方向的标准差(控制滤波器的横向扩展) | 根据目标特征尺寸设置(例:缺陷宽度=20像素 → Sigma1=10) |
Sigma2 |
实数 | Y方向的标准差(控制滤波器的纵向扩展) | 通常与Sigma1相同(各向同性滤波) |
Phi |
实数 | 滤波器的旋转角度(弧度) | 0(无旋转)或根据纹理方向设置(如45°=0.785 rad) |
Norm |
字符串 | 标准化模式:'none':不标准化'n':归一化到单位能量 |
频域滤波用'none',空域滤波用'n' |
Mode |
字符串 | 滤波器模式:'rft':频域滤波器(复数)'dc_center':空域滤波器 |
频域处理必选'rft' |
Width |
整数 | 滤波器宽度(需与待处理图像等宽) | 通过get_image_size获取原图尺寸 |
Height |
整数 | 滤波器高度(需与待处理图像等高) | 同上 |
get_image_size (Image, Width, Height)
gen_gauss_filter(..., Width, Height)
* 1. 读取图像并转换为灰度
read_image (Image, 'plastic_mesh_01.jpg')
rgb1_to_gray (Image, GrayImage)
* 2. 获取图像尺寸
get_image_size (GrayImage, Width, Height)
* 3. 生成高斯带阻滤波器(抑制网状纹理)
Sigma1 := 25.0 * 抑制低频(对应网状纹理周期50像素)
Sigma2 := 3.0 * 保留高频(划痕特征)
gen_gauss_filter (GaussFilter, Sigma1, Sigma2, 0, 'none', 'rft', Width, Height)
* 4. 频域滤波处理
fft_image (GrayImage, ImageFFT)
convol_fft (ImageFFT, GaussFilter, FilteredFFT)
fft_image_inv (FilteredFFT, ImageFiltered)
* 5. 检测划痕
threshold (ImageFiltered, Scratches, 50, 255)
dev_display (Scratches)
* 查看频域滤波器形状
power_real (GaussFilter, PowerSpectrum)
dev_display (PowerSpectrum) * 显示为中央暗区(抑制低频)+周边亮环(保留高频)
D(像素)Sigma = D/2* 检测到划痕方向为60度
Phi := rad(60) * 转换为弧度
gen_gauss_filter(..., Phi, ...) * 生成旋转滤波器
* 组合不同Sigma值检测多尺寸缺陷
for Sigma := [5, 10, 20] do
gen_gauss_filter(..., Sigma, Sigma, ...)
convol_fft(...)
* 各尺度结果融合
endfor
* 生成两个高斯滤波器相减
gen_gauss_filter (Gauss1, 30, 30, ...)
gen_gauss_filter (Gauss2, 10, 10, ...)
sub_image (Gauss1, Gauss2, BandPassFilter, 1, 0)
| 参数 | 调整策略 |
|---|---|
| Sigma1 | 根据背景纹理周期设置,越大抑制的低频越多 |
| Sigma2 | 根据缺陷尺寸设置,越小保留的高频细节越多 |
| Phi | 沿缺陷方向设置(需先进行方向分析) |
| Norm | 频域滤波始终用'none',空域滤波用'n' |
| 尺寸 | 必须与输入图像等大(通过get_image_size获取) |
通过合理设置高斯滤波器参数,可以有效分离背景纹理与目标缺陷,提升工业视觉检测的准确性和鲁棒性。建议配合power_real可视化频域滤波器特性,进行参数调优验证。
3.频域卷积算子convol_fft(ImageFFT, ImageFilter : ImageConvol : : )详解:
| 参数 | 类型 | 说明 | 工业检测注意事项 |
|---|---|---|---|
ImageFFT |
输入 | 经过FFT变换的输入图像(复数形式,实部+虚部) | 必须通过fft_image生成 |
ImageFilter |
输入 | 频域滤波器(需与ImageFFT同尺寸,复数形式) |
常用高斯滤波器gen_gauss_filter生成 |
ImageConvol |
输出 | 卷积结果(复数频域图像) | 需逆FFT转换回空间域使用 |
* 1. 读取图像并转换到频域
read_image (Image, 'metal_surface_01.jpg')
rgb1_to_gray (Image, GrayImage)
fft_image (GrayImage, ImageFFT) * 转换到频域
* 2. 生成高通高斯滤波器(增强高频缺陷)
gen_gauss_filter (Filter, 5, 5, 0, 'none', 'rft', Width, Height)
* 3. 频域卷积(等效于空域滤波)
convol_fft (ImageFFT, Filter, ImageConvol)
* 4. 逆FFT转回空间域
fft_image_inv (ImageConvol, ImageFiltered)
* 5. 检测划痕
threshold (ImageFiltered, Scratches, 80, 255)
dev_display (Scratches)
ImageFFT包含金属纹理(低频中心亮区)+ 划痕(高频边缘)。| 滤波器类型 | 生成方法 | 适用场景 |
|---|---|---|
| 低通 | gen_gauss_filter大Sigma(如30) |
抑制高频噪声(如电子元件毛刺) |
| 高通 | 1 - 低通滤波器 |
增强边缘/划痕 |
| 带阻 | 高斯1 - 高斯2(不同Sigma) | 消除特定频率干扰(如网格纹理) |
| 带通 | 高斯低通 - 高斯高通 | 提取特定尺寸特征 |
ImageFFT和ImageFilter尺寸相同(通过get_image_size验证)。optimize_rft_speed (Width, Height, 'standard') * 自动填充至最优尺寸
* 使用渐变高斯滤波器(边缘平滑)
gen_gauss_filter (Filter, 15, 15, 0, 'none', 'rft', Width, Height)
power_real (ImageConvol, PowerSpectrum)
dev_display (PowerSpectrum) * 确认缺陷频率是否保留
| 特性 | 频域卷积 (convol_fft) | 空域卷积 (convol_image) |
|---|---|---|
| 速度 | O(n log n) → 快(大核优势) | O(n²m²) → 慢(m为滤波器尺寸) |
| 适用场景 | 大尺寸滤波器(>15x15) | 小尺寸滤波器(<15x15) |
| 内存占用 | 较高(需存储复数图像) | 较低(实数运算) |
| 功能扩展 | 支持复杂频域操作(如带阻滤波) | 限于简单核(高斯、Sobel等) |
dev_update_off ()
read_image (Image, 'fabric_01.jpg')
get_image_size (Image, Width, Height)
optimize_rft_speed (Width, Height, 'standard') * 尺寸优化
* 频域转换
fft_image (Image, ImageFFT)
* 设计带阻滤波器(抑制织物纹理)
gen_gauss_filter (LowPass, 40, 40, 0, 'none', 'rft', Width, Height)
gen_gauss_filter (HighPass, 5, 5, 0, 'none', 'rft', Width, Height)
sub_image (LowPass, HighPass, BandStopFilter, 1, 0)
* 频域卷积
convol_fft (ImageFFT, BandStopFilter, ImageConvol)
* 逆变换与检测
fft_image_inv (ImageConvol, ImageFiltered)
threshold (ImageFiltered, Defects, 70, 255)
connection (Defects, ConnectedRegions)
select_shape (ConnectedRegions, FinalDefects, 'area', '>', 50)
| 操作要点 | 工业检测意义 |
|---|---|
| 正确设计滤波器Sigma值 | 决定缺陷与背景的分离效果 |
| 功率谱可视化调试 | 快速定位频率干扰源 |
结合optimize_rft_speed |
提升产线实时检测速度(尤其4K以上图像) |
| 频域+空域联合处理 | 复杂缺陷检测(如同时存在划痕和孔洞) |
通过合理使用convol_fft,您可以在半导体、汽车零部件、纺织品等行业中,高效解决复杂背景下的微观缺陷检测难题。
4.频域转空间域算子fft_image_inv(Image : ImageFFTInv : : )详解:
| 参数 | 类型 | 说明 | 工业检测注意事项 |
|---|---|---|---|
Image |
输入 | 频域图像(复数形式,实部+虚部) | 必须经过fft_image或convol_fft处理 |
ImageFFTInv |
输出 | 逆变换后的空间域图像(实数类型) | 需进行后续阈值分割或形态学操作 |
* 1. 读取图像并转灰度
read_image (Wafer, 'wafer_01.tiff')
rgb1_to_gray (Wafer, GrayWafer)
* 2. 优化FFT尺寸
get_image_size (GrayWafer, Width, Height)
optimize_rft_speed (Width, Height, 'standard')
* 3. 转换到频域
fft_image (GrayWafer, WaferFFT)
* 4. 高通滤波(增强缺陷)
gen_gauss_filter (HighPassFilter, 5, 5, 0, 'none', 'rft', Width, Height)
convol_fft (WaferFFT, HighPassFilter, FilteredFFT)
* 5. 逆FFT转回空间域
fft_image_inv (FilteredFFT, ProcessedWafer) * 关键步骤!
* 6. 检测缺陷
threshold (ProcessedWafer, Defects, 120, 255)
dev_display (Defects)
fft_image或convol_fft生成。get_image_size检查)。real类型),值域可能为负。scale_image调整亮度:scale_image (ProcessedWafer, ScaledImage, 10, 0) * 放大10倍便于显示
* 检查滤波器功率谱
power_real (HighPassFilter, PowerFilter)
dev_display (PowerFilter) * 应有非零区域
multiply_image (FilteredFFT, WindowFunction, FilteredFFT, 1, 0)
* 重新计算均值并校正
mean_image (ProcessedWafer, MeanImage)
sub_image (ProcessedWafer, MeanImage, CorrectedImage, 1, 0)
dev_update_off ()
read_image (LCD, 'lcd_panel_01.png')
get_image_size (LCD, Width, Height)
optimize_rft_speed (Width, Height, 'explore') * 深度优化
* 频域转换与滤波
fft_image (LCD, LCD_FFT)
gen_gauss_filter (BandStop, 50, 50, 0, 'none', 'rft', Width, Height)
convol_fft (LCD_FFT, BandStop, FilteredFFT)
* 逆FFT转换
fft_image_inv (FilteredFFT, FilteredLCD)
* 增强对比度并检测亮点缺陷
emphasize (FilteredLCD, EnhancedLCD, Width, Height, 1.5)
threshold (EnhancedLCD, Defects, 200, 255)
connection (Defects, ConnectedRegions)
select_shape (ConnectedRegions, FinalDefects, 'circularity', '>', 0.85)
| 操作步骤 | 工业检测意义 | 参数调整建议 |
|---|---|---|
fft_image_inv |
将频域处理结果可视化 | 确保输入为正确滤波后的复数图像 |
| 动态范围调整 | 使缺陷更易观察 | 使用scale_image或emphasize增强对比度 |
| 振铃抑制 | 提高检测准确性 | 应用窗函数或渐变滤波器 |
| 尺寸优化 | 提升实时检测速度 | 必用optimize_rft_speed |
通过合理使用fft_image_inv,您可以在电子元件、液晶面板、金属加工等领域,高效还原频域处理结果,实现高精度的缺陷检测。
5.傅里叶变换算子rft_generic(Image : ImageFFT : Direction, Norm, ResultType, Width : )详解:
fft_image更灵活,可控制变换方向、归一化方式及窗函数。| 参数 | 类型 | 说明 | 工业检测推荐值 |
|---|---|---|---|
Image |
输入 | 输入图像(实数类型) | 需为单通道灰度图(byte/real) |
ImageFFT |
输出 | 频域图像(复数或实数形式) | 根据ResultType选择输出类型 |
Direction |
字符串 | 变换方向:'to_freq'(空域→频域)'from_freq'(频域→空域) |
'to_freq'(正向变换) |
Norm |
字符串 | 归一化方式:'none'(无)'sqrt'(平方根)'n'(单位能量) |
频域滤波用'none',分析用'n' |
ResultType |
字符串 | 输出类型:'complex'(复数)'real'(实数) |
滤波操作选'complex',功率谱分析选'real' |
Width |
整数 | 图像宽度(需与输入图像一致) | 通过get_image_size获取 |
| 模式 | 使用场景 |
|---|---|
'to_freq' |
空域→频域,用于滤波、频率分析(95%工业应用场景) |
'from_freq' |
频域→空域,恢复处理后的图像(需与'to_freq'成对使用) |
| 模式 | 数学公式 | 适用场景 |
|---|---|---|
'none' |
无缩放 | 频域滤波(保持能量不变) |
'sqrt' |
输出值乘以1/√N | 图像重建(防止能量溢出) |
'n' |
输出值乘以1/N | 频谱分析(确保能量守恒) |
| 类型 | 数据格式 | 典型应用 |
|---|---|---|
'complex' |
复数(实部+虚部) | 频域滤波、相位分析 |
'real' |
实数(幅度或实部) | 功率谱可视化、简单频域操作 |
| 窗函数 | 特性 | 适用场景 |
|---|---|---|
'none' |
矩形窗(无衰减) | 快速检测,边缘信息重要时 |
'hann' |
平滑衰减,减少频谱泄漏 | 大多数工业检测(推荐默认) |
'hamming' |
类似Hann,但首尾不归零 | 需要更高频率分辨率时 |
'hann'窗,平衡频谱泄漏抑制和边缘保留。'none'窗避免边缘模糊。
| 参数/操作 | 工业检测最佳实践 |
|---|---|
| Direction | 'to_freq'用于滤波,'from_freq'用于重建 |
| Norm | 滤波用'none',分析用'n' |
| Window | 默认'hann',边缘敏感场景用'none' |
| ResultType | 滤波操作选'complex',简单分析选'real' |
| 性能优化 | 必用optimize_rft_speed,大图启用多线程 |
通过合理配置rft_generic参数,您可以在半导体、汽车零部件、纺织品等行业的复杂检测场景中,高效实现背景纹理抑制与微小缺陷增强,提升检测系统的准确性和鲁棒性。
接下来看一些实战案例,基本都在halcon的程序集里
示例1:塑料表面纹理缺陷检测程序(基于频域分析)

两张原图:

这张有个小点 看出来没?

实例代码:
* *************************************************************
* 塑料表面纹理缺陷检测程序(基于频域分析)
* 检测原理:
* 1. 构造高斯带阻滤波器消除正常纹理
* 2. FFT频域卷积增强缺陷特征
* 3. 形态学处理定位异常区域
* 工业应用:注塑件表面质量检测
* 支持文件格式:BMP格式工业图像(推荐8bit灰度)
* 硬件要求:500万像素以上工业相机,同轴照明系统
* 检测精度:最小缺陷检测尺寸0.1mm²(200dpi下约4像素)
* *************************************************************
* *************** 检测流程示意图 ***************
* 原始图像
* → FFT频域变换(使用优化算法加速)
* → 高斯带阻滤波(抑制背景纹理)
* → 逆FFT变换(获取滤波后图像)
* → 局部对比度增强(突出缺陷边缘)
* → 动态阈值分割(自适应亮度变化)
* → 形态学优化(去噪+区域合并)
* → 缺陷标记与结果输出
* *************** 系统初始化模块 ***************
* 关闭窗口自动更新(提升大图像处理时的执行效率)
dev_update_off ()
* 清理可能存在的残留窗口
dev_close_window ()
* 加载基准图像(用于获取系统参数)
read_image (Image, 'plastics/plastics_01')
* 获取图像尺寸参数(用于窗口创建和滤波器设计)
get_image_size (Image, Width, Height)
* 创建与图像等大的显示窗口(黑色背景利于缺陷观察)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
* 配置显示字体(等宽字体确保字符对齐,14号字适合1080P显示)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
* 设置绘制模式为轮廓显示(节省GPU显存资源)
dev_set_draw ('margin')
* 设置轮廓线宽(3像素宽度确保缺陷标记明显可见)
dev_set_line_width (3)
* 设置默认报警颜色为红色(符合工业标准报警色)
dev_set_color ('red')
* *************** FFT性能优化模块 ***************
* 根据特定图像尺寸优化FFT计算(选择最优的FFT算法实现)
* 参数说明:
* 'standard' - 平衡模式(兼顾速度和内存使用)
* 其他可选模式:'explore'深度优化(耗时)/'estimate'快速估算
optimize_rft_speed (Width, Height, 'standard')
* *************** 滤波器设计模块 ***************
* 构建复合高斯带阻滤波器(消除周期性背景纹理)
* Sigma1: 低频截止参数(控制背景纹理抑制范围)
* - 推荐值 = 正常纹理周期/2(例如纹理间隔20像素则设10)
* - 当前值10.0适用于0.5mm间距网格纹理(200dpi下)
Sigma1 := 10.0
* Sigma2: 高频截止参数(控制缺陷特征保留范围)
* - 推荐值 = 最小缺陷尺寸/2(例如6像素缺陷设3.0)
* - 当前值3.0对应0.3mm²微小缺陷检测
Sigma2 := 3.0
* 生成低频抑制高斯滤波器(大σ值滤波器)
* 参数说明:
* GaussFilter1 - 输出滤波器对象
* 10.0 - X方向σ值(与Sigma1对应)
* 10.0 - Y方向σ值(各向同性滤波)
* 0.0 - 滤波器旋转角度(0度表示无旋转)
* 'none' - 无标准化
* 'rft' - 频域滤波器类型
* Width, Height - 滤波器尺寸(必须与图像一致)
gen_gauss_filter (GaussFilter1, Sigma1, Sigma1, 0.0, 'none', 'rft', Width, Height)
* 生成高频保留高斯滤波器(小σ值滤波器)
gen_gauss_filter (GaussFilter2, Sigma2, Sigma2, 0.0, 'none', 'rft', Width, Height)
* 合成带阻滤波器(Gauss1 - Gauss2)
* 效果:抑制低频(背景纹理)同时保留高频(缺陷)
* 参数说明:
* 1 - 缩放因子(保持滤波器强度范围)
* 0 - 偏移量(不做亮度调整)
sub_image (GaussFilter1, GaussFilter2, Filter, 1, 0)
* *************** 主检测流程模块 ***************
* 定义检测图像数量(支持批量处理)
NumImages := 2
* 开始多图像批处理循环
for Index := 1 to NumImages by 1
* *************** 图像采集与预处理模块 ***************
* 读取当前检测图像(支持序列号补零命名格式)
* 文件名示例:plastics_01.bmp, plastics_02.bmp...
read_image (Image, 'plastics_' + Index+'.bmp')
* 转换为灰度图像(兼容彩色相机输入)
* 注意:使用rgb1_to_gray保持亮度线性转换
rgb1_to_gray (Image, Image)
* *************** 频域处理模块 ***************
* 执行FFT正变换(空间域→频域)
* 参数说明:
* 'to_freq' - 正变换方向
* 'none' - 不进行窗函数处理
* 'complex' - 输出复数格式频域数据
rft_generic (Image, ImageFFT, 'to_freq', 'none', 'complex', Width)
* 频域卷积运算(应用预设计滤波器)
* 原理:F(f*h) = F(f)·F(h)(频域乘法等效空域卷积)
convol_fft (ImageFFT, Filter, ImageConvol)
* 执行FFT逆变换(频域→空间域)
* 参数说明:
* 'from_freq' - 逆变换方向
* 'n' - 无标准化(保持动态范围)
* 'real' - 输出实数图像
rft_generic (ImageConvol, ImageFiltered, 'from_freq', 'n', 'real', Width)
* *************** 后处理与缺陷提取模块 ***************
* 计算局部灰度范围(增强缺陷对比度)
* 参数说明:
* 10x10邻域窗口(需大于缺陷尺寸)
* 效果:突出缺陷边缘与纹理异常
gray_range_rect (ImageFiltered, ImageResult, 10, 10)
* 计算图像灰度极值(用于动态阈值设定)
* 参数说明:
* 0 - 忽略边界像素(避免边缘效应影响)
min_max_gray (ImageResult, ImageResult, 0, Min, Max, Range)
* 动态阈值分割(双阈值保护机制)
* 阈值逻辑:取固定阈值5.55和最大值的80%中较大者
* 设计目的:既防止低对比度缺陷漏检,又避免噪声干扰
threshold (ImageResult, RegionDynThresh, max([5.55,Max * 0.8]), 255)
* 连通域分析(分离独立缺陷区域)
connection (RegionDynThresh, ConnectedRegions)
* 初级面积筛选(过滤4像素以下噪声)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 4, 99999)
* 区域合并(防止同一缺陷被分割为多个区域)
union1 (SelectedRegions, RegionUnion)
* 闭运算处理(填充微小孔洞,平滑缺陷边缘)
* 参数说明:
* 10像素结构元(确保相邻缺陷合并)
closing_circle (RegionUnion, RegionClosing, 10)
* 二次连通域分析
connection (RegionClosing, ConnectedRegions1)
* 最终面积筛选(确认有效缺陷区域)
select_shape (ConnectedRegions1, SelectedRegions1, 'area', 'and', 10, 99999)
* 计算缺陷质心坐标(为后续定位提供数据)
area_center (SelectedRegions1, Area, Row, Column)
* *************** 可视化与结果输出模块 ***************
* 显示原始图像(保持背景参考)
dev_display (Image)
* 统计缺陷数量
Number := |Area|
* 生成缺陷标记图形(30像素半径红色圆圈)
if (Number)
* 创建圆形轮廓对象(XLD格式)
* 参数说明:
* 30 - 圆环半径(根据缺陷尺寸调整)
* 0 - 起始角度(完整圆环)
* rad(360) - 结束角度
* 'positive' - 顺时针方向
* 1 - 相邻点间距(高分辨率绘制)
gen_circle_contour_xld (ContCircle, Row, Column, gen_tuple_const(Number,30), gen_tuple_const(Number,0), gen_tuple_const(Number,rad(360)), 'positive', 1)
* 构造报警信息(显示缺陷数量)
ResultMessage := ['Not OK',Number + ' defect(s) found']
Color := ['red', 'black']
* 多颜色信息显示
dev_display (ContCircle)
else
* 合格品显示绿色OK标识
ResultMessage := 'OK'
Color := 'forest green'
* 工业标准通过色
endif
* 在图像左上角显示检测结果(坐标12,12避开检测区域)
disp_message (WindowHandle, ResultMessage, 'window', 12, 12, Color, 'true')
* 非最后一张时显示继续提示(模拟产线节拍控制)
if (Index != NumImages)
* 显示标准继续提示(底部右对齐)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 暂停等待操作员确认
endif
endfor
* *************** 参数说明表(供工程调试参考) ***************
* | 参数 | 作用 | 工业调参建议 |
* |-----------------------|----------------------------------------|--------------------------|
* | Sigma1=10.0 | 控制背景纹理抑制范围 | 根据正常纹理周期调整 |
* | | 公式:Sigma1 ≈ 纹理周期/2 | 使用FFT频谱分析确定周期 |
* | Sigma2=3.0 | 控制缺陷特征保留范围 | 根据最小缺陷尺寸调整 |
* | | 公式:Sigma2 ≈ 最小缺陷半径 | 需考虑点扩散函数影响 |
* | gray_range_rect(10,10)| 局部对比度增强窗口 | 窗口尺寸=2×缺陷直径 |
* | threshold(5.55/0.8Max)| 动态双阈值机制 | 5.55对应3σ噪声水平(8bit) |
* | closing_circle(10) | 缺陷区域平滑参数 | 结构元直径=允许缺陷间距 |
结果图:

示例2:划痕检测
原图:

实例代码:
* 关闭图像更新和已有窗口,提升执行效率 dev_update_off () dev_close_window () * 【1. 读取图像】 read_image (Image, 'find_scratches_1') * 读取表面划痕图像 * 【2. 图像预处理】 invert_image (Image, ImageInverted) * 反转图像(若划痕是深色,反转后更易处理) * 获取图像尺寸并打开显示窗口 get_image_size (Image, Width, Height) dev_open_window (0, 0, Width, Height, 'black', WindowHandle) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') * 显示原始图像 dev_display (Image) * 【3. 频域处理核心流程】 * ----------------------------------------------------- * 【3.1 生成正弦带通滤波器】 * 参数0.4: 中心频率(0-1范围),保留中高频信息(划痕对应高频) gen_sin_bandpass (ImageBandpass, 0.4, 'none', 'rft', Width, Height) * 【3.2 执行RFT正变换】 * 将空间域图像转换到频域,输出复数图像 rft_generic (ImageInverted, ImageFFT, 'to_freq', 'none', 'complex', Width) * 【3.3 频域卷积滤波】 * 用带通滤波器增强划痕特征,抑制背景低频信息 convol_fft (ImageFFT, ImageBandpass, ImageConvol) * 【3.4 执行RFT逆变换】 * 将滤波结果转换回空间域,输出字节类型图像 rft_generic (ImageConvol, Lines, 'from_freq', 'n', 'byte', Width) * 【4. 形态学后处理】 * ----------------------------------------------------- * 【4.1 阈值分割】 * 提取灰度值>5的像素(增强后的划痕区域) threshold (Lines, Region, 5, 255) * 【4.2 连通域分析】 * 分离不连续的候选区域 connection (Region, ConnectedRegions) * 【4.3 区域筛选】 * 保留面积5-5000像素的候选区域(过滤噪声和大面积背景) select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5, 5000) * 【4.4 圆形膨胀】 * 合并相邻区域,半径5.5平衡连接性和细节保留 dilation_circle (SelectedRegions, RegionDilation, 5.5) * 【4.5 区域合并】 * 将所有候选区域合并为一个整体 union1 (RegionDilation, RegionUnion) * 【4.6 ROI提取】 * 在原始图像上裁剪出候选区域 reduce_domain (Image, RegionUnion, ImageReduced) * 【4.7 高斯线检测】 * 参数0.8: 高斯平滑系数,检测暗色条状特征 lines_gauss (ImageReduced, LinesXLD, 0.8, 3, 5, 'dark', 'false', 'bar-shaped', 'false') * 【4.8 合并共线轮廓】 * 40: 最大角度差(度),3: 最大距离差,合并断裂线段 union_collinear_contours_xld (LinesXLD, UnionContours, 40, 3, 3, 0.2, 'attr_keep') * 【4.9 轮廓筛选】 * 选择长度15-1000像素的轮廓(滤除短噪声) select_shape_xld (UnionContours, SelectedXLD, 'contlength', 'and', 15, 1000) * 【4.10 生成最终区域】 * 将XLD轮廓转为填充区域 gen_region_contour_xld (SelectedXLD, RegionXLD, 'filled') * 【4.11 最终区域合并与膨胀】 * 合并所有区域并用10.5半径膨胀强化显示 union1 (RegionXLD, RegionUnion) dilation_circle (RegionUnion, RegionScratches, 10.5) * 【5. 结果显示】 * ----------------------------------------------------- dev_set_draw ('margin') * 轮廓显示模式 dev_set_line_width (3) * 设置线宽 dev_set_colored (12) * 使用12种颜色区分区域 dev_display (Image) * 显示原始图像 dev_display (RegionScratches) * 叠加显示划痕检测结果
结果图:

示例3:皮革表面缺陷检测
原图:


实例代码:
* 关闭窗口和自动更新,提升执行效率
dev_close_window ()
dev_update_off ()
* 【1. 读取初始图像】
read_image (Image, 'detect_mura_1.bmp')
* 获取图像尺寸并打开显示窗口
get_image_size (Image, Width, Height)
dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
* 设置显示参数:轮廓模式/线宽/颜色
dev_set_draw ('margin')
* 轮廓显示模式
dev_set_line_width (3)
* 设置轮廓线宽
dev_set_color ('red')
* 默认红色显示缺陷
* 【2. 循环处理两张图像】
for F := 1 to 2 by 1
* 读取当前循环的图像(detect_mura_1.bmp和detect_mura_2.bmp)
read_image (Image, 'detect_mura_'+F+'.bmp')
* 【3. 图像预处理】
* 分解RGB通道(Mura缺陷通常在B通道更明显)
decompose3 (Image, R, G, B)
* 【4. 背景光照估计与消除】
* 功能:通过频域滤波估计背景光照(低频成分)
* 原理:Mura缺陷属于低频特征,需分离背景与缺陷
estimate_background_illumination (B, ImageFFT1)
* 原图减去背景光照(增强缺陷对比度)
* 参数:2(比例因子),100(偏移量)- 提升对比度
sub_image (B, ImageFFT1, ImageSub, 2, 100)
* 【5. 中值滤波平滑纹理】
* 参数:'circle'(圆形核),9(半径)- 抑制高频纹理噪声
median_image (ImageSub, ImageMedian, 'circle', 9, 'mirrored')
* 【6. 分水岭分割与阈值处理】
* 功能:将图像分割为多个盆地(Basins),阈值设为20
* 输出:Basins为各区域的标记图像
watersheds_threshold (ImageMedian, Basins, 20)
* 【7. 基于纹理特征的缺陷检测】
* 计算灰度共生矩阵特征(能量、相关性、同质性、对比度)
* 参数:6(灰度级数),0(方向-0度)
cooc_feature_image (Basins, ImageMedian, 6, 0, Energy, Correlation, Homogeneity, Contrast)
* 【8. 特征筛选】
* 能量特征筛选:Mura缺陷区域能量低(Energy <= 0.05)
Mask := Energy [<=] 0.05
select_mask_obj (Basins, Defects, Mask)
* 根据掩膜筛选区域
* 【9. 结果显示】
dev_display (Image)
* 显示原始图像
dev_display (Defects)
* 叠加显示缺陷轮廓
count_obj (Defects, NDefects)
* 统计缺陷数量
* 显示检测结果文本(红色字体)
disp_message (WindowHandle, NDefects + ' \'mura\' defects detected', 'window', 12, 12, 'red', 'true')
* 处理第一张图后暂停,按F5继续
if (F < 2)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor
结果图:


三.光度立体法
先大概介绍一下什么是光度立体法:
光度立体法是一种通过多幅不同光照条件下的图像来恢复物体表面三维形状和表面法线的技术。其核心思想是利用光照变化与表面反射的物理关系,推导表面几何信息。
工业应用场景:

2.光照方向说明(参考博客:https://www.cnblogs.com/xyf327/p/14871414.html):
对于采集的多张图像中的每一幅图,照明方向必须指定Slants和Tilts两个参数角度,其描述了相对于当前场景的光照角度。为了更好的理解这两个参数含义,我们假定光源射出的光束是平行光,镜头是远心镜头,相机垂直于物体表面。


这个角度是以图像为准的,比如光从图像右侧打过来,角度就是0°,从上面打过来,角度是90°,从左面打过来,角度是180°,下边打过来是270°。
正常情况下一般都是至少采集三张不同方向打光的图。但对于一些特殊的产品,因为阴影的原因,三个方向打光不能很好的表征缺陷特征,造成重建的图像特征不明显,这个时候就需要在原来基础上增加打光方向,避免死角。随着打光方向增加采集图像也跟着增加,那么算法处理时间也变长。根据经验:
3.输入准备

* 示例:定义4个光源方向(需根据实际光源位置计算)
LightDirections := [
[0.2, 0.3, 1], // 光源1
[-0.5, 0.1, 1], // 光源2
[0.1, -0.6, 1], // 光源3
[0.4, 0.4, 1] // 光源4
]
接下来认识一下几个算子:
1.重建表面高度算子photometric_stereo(Images : HeightField, Gradient, Albedo : Slants, Tilts, ResultType, ReconstructionMethod, GenParamName, GenParamValue : )详解:
函数原型:
photometric_stereo(
Images : // 输入图像数组(多光源下的图像)
HeightField, // 输出高度场(表面高度)
Gradient, // 输出梯度场(表面梯度 p, q)
Albedo : // 输出反射率图(排除光照后的表面属性)
Slants, // 光源倾斜角数组(弧度,与光轴的夹角)
Tilts, // 光源方位角数组(弧度,绕光轴的旋转角)
ResultType, // 指定输出类型(如 'all' 或 'height')
ReconstructionMethod, // 重建方法('poisson'/'frankot')
GenParamName, // 通用参数名称(如平滑系数)
GenParamValue // 通用参数值
:
)
Slants 和 Tilts(光源方向)
ResultType(输出类型)'all':输出高度场、梯度场和反射率。'height':仅输出高度场。'gradient':输出梯度场和反射率。ReconstructionMethod(重建方法)'poisson'**:基于泊松方程的重建,适合封闭区域。'frankot'**:频域积分法,适合开放边界,但可能引入周期性误差。GenParamName 和 GenParamValue)'lambda':泊松重建的正则化系数(默认 0.1),值越大结果越平滑。'iterations':迭代次数(仅对某些方法有效)。'smooth':梯度平滑强度(例如 'smooth', 0.5)。检测金属表面划痕,使用四个不同角度的光源,已知每个光源的倾斜角和方位角。
读取图像并定义光源角度:
* 读取图像
read_image (Image1, 'light1.png')
read_image (Image2, 'light2.png')
read_image (Image3, 'light3.png')
read_image (Image4, 'light4.png')
Images := [Image1, Image2, Image3, Image4]
* 定义光源角度(弧度)
Slants := [rad(30), rad(45), rad(30), rad(60)] // 倾斜角:30°,45°,30°,60°
Tilts := [rad(0), rad(90), rad(180), rad(270)] // 方位角:0°,90°,180°,270°
2.执行光度立体法:
* 运行算法(使用泊松重建,设置平滑系数 lambda=0.2)
photometric_stereo(
Images,
HeightField,
Gradient,
Albedo,
Slants,
Tilts,
'all',
'poisson',
['lambda'],
[0.2],
[]
)
3.结果后处理(检测划痕):
* 高度图阈值分割(划痕处高度突变)
threshold (HeightField, Scratches, -20, 0) // 假设划痕凹陷深度在0~-20范围内
connection (Scratches, ConnectedRegions)
* 显示结果
dev_display (HeightField)
dev_set_color ('red')
dev_display (ConnectedRegions)
Slants 和 Tilts 转换为三维光源方向。'poisson':适用于大多数工业场景,通过 'lambda' 控制平滑度。'frankot'。 * 反射率图中检测异物
threshold (Albedo, Contaminants, 200, 255)
'lambda' 值(如从 0.1 调整到 0.5)。'frankot' 方法,或裁剪感兴趣区域(ROI)。GenParamName 中启用阴影抑制参数(如 'shadow_threshold')。| 参数/操作 | 工业最佳实践 |
|---|---|
| 光源角度 | 使用标定球精确测量 Slants 和 Tilts |
| 重建方法 | 默认 'poisson',开放边界用 'frankot' |
| 平滑系数 | 初始设为 'lambda', 0.1,噪声大时增大至 0.5 |
| 输出类型 | 检测几何缺陷用 'height',分析材质用 'all' |
| 后处理 | 结合高度图和反射率图,阈值分割 + 连通区域分析 |
通过合理配置 photometric_stereo,可在无需3D传感器的情况下,实现高精度的表面缺陷检测,尤其适用于反光表面或微观几何分析。
derivate_vector_field(
VectorField : // 输入矢量场(包含X/Y分量的图像)
Result : // 输出结果(单通道或多通道图像)
Sigma, // 高斯平滑系数(抑制噪声)
Component // 指定导数的计算分量(如 'x', 'y', 'gradient')
)
| 参数 | 类型 | 说明 |
|---|---|---|
VectorField |
输入 | 矢量场图像(需为2通道图像,通道1=X方向分量,通道2=Y方向分量) |
Result |
输出 | 导数计算结果(单通道或多通道,取决于Component) |
Sigma |
实数 | 高斯平滑系数(单位:像素),值越大平滑越强,噪声抑制效果越好 |
Component |
字符串 | 指定导数的分量类型(如 'x', 'y', 'xx', 'yy', 'xy', 'gradient') |
Component 可选值:X:X分量在X方向的导数(水平应变)
Y:Y分量在Y方向的导数(垂直应变)
XX:X分量的二阶X导数
YY:Y分量的二阶Y导数
XY:
| XY: | 交叉导数(剪切应变) |
gradient:
gradient: |
完整变形梯度张量 |
| 参数 | 推荐值 | 说明 |
|---|---|---|
**Sigma** |
1.0~3.0 | 根据噪声水平调整: - 低噪声(激光测量):1.0 - 高噪声(DIC):3.0 |
**Component** |
'gradient' |
需要完整变形信息时选择,后续通过通道分离获取特定分量 |
注意事项
VectorField 必须为2通道图像,可通过以下方式创建:
* 从X/Y分量图像合成矢量场
compose2 (VxImage, VyImage, VectorField)
Sigma会降低空间分辨率,需在噪声抑制和细节保留间权衡。
总结
Sigma控制平滑强度,Component决定分析的物理量类型。vector_field_to_real将结果转换为应变张量,用于有限元仿真验证。
3.区域生长分割算子regiongrowing(Image : Regions : RasterHeight, RasterWidth, Tolerance, MinSize : )详解:
函数原型:
regiongrowing(
Image : // 输入图像(灰度图)
Regions : // 输出分割后的区域集合
RasterHeight, // 垂直方向网格步长(像素)
RasterWidth, // 水平方向网格步长(像素)
Tolerance, // 灰度差异容忍度
MinSize // 最小区域面积(像素)
)
| 参数 | 类型 | 说明 |
|---|---|---|
| RasterHeight | 整数 | 垂直方向网格步长(将图像划分为小网格,每个网格作为种子区域启动生长) |
| RasterWidth | 整数 | 水平方向网格步长(通常与RasterHeight相同) |
| Tolerance | 整数 | 允许的相邻像素灰度差异(若差异≤Tolerance,则合并到同一区域) |
| MinSize | 整数 | 分割后的区域最小面积(小于此值的区域会被合并或丢弃) |
RasterWidth x RasterHeight 的网格,每个网格中心作为种子点。Tolerance,则合并到当前区域。MinSize 的区域。regiongrowing (Image, Regions, 10, 10, 5, 100)
MinSize=100:过滤噪声引起的微小区域。
regiongrowing (TextImage, Regions, 20, 20, 15, 500)
MinSize=500:保留大块纹理区域。
| 参数 | 推荐值 | 调整策略 |
|---|---|---|
| Raster | 5~20像素 | 目标区域小 → Raster小(密集网格) 目标区域大 → Raster大(稀疏网格) |
| Tolerance | 5~20(灰度级) | 目标与背景差异小 → 低值(如5) 光照不均严重 → 高值(如20) |
| MinSize | 目标最小面积 | 根据实际目标尺寸设定,通常为预期最小区域面积的50%~80% |
| 方法 | 适用场景 | 与regiongrowing对比 |
|---|---|---|
| 阈值分割 | 高对比度目标 | 无法处理渐变灰度区域 |
| 边缘检测 | 锐利边缘目标 | 对模糊边缘效果差 |
| 深度学习分割 | 复杂纹理/多类别目标 | 需要大量标注数据,regiongrowing无需训练 |
Raster密度与计算效率,根据目标尺寸设定MinSize,通过Tolerance控制灵敏度。
接下来看案例:药品包装质量检测
四张不同光照角度的原图如下




实例代码:
* *************************************************************
* 本程序演示使用光度立体法检测药品泡罩背面缺陷
* 工业应用:药品包装质量检测(泡罩完整性检查)
* 核心原理:通过多光源图像重建表面梯度,分析曲率异常区域
* 输入:4张不同光照方向的泡罩背面图像
* 输出:缺陷在反照率图和曲率图中的定位
* *************************************************************
* 初始化系统设置
* ------------------------------------------------------------
* 关闭所有图形窗口并创建512x512显示窗口
dev_close_window ()
dev_update_off ()
* 禁止窗口自动更新以提升性能
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
* 设置显示字体为等宽14号字(便于对齐检测结果)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
* 显示操作引导信息
Message := 'Inspect the backside of a blister'
Message[1] := 'using photometric stereo. In this case four'
Message[2] := 'different light orientations were used.'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 暂停等待操作员确认
* 加载并展示输入图像序列
* ------------------------------------------------------------
* 读取4张不同光照方向的泡罩图像(文件名格式:blister_back_01~04)
read_image (Images, 'blister_back_0' + [1:4])
* 循环显示输入图像(模拟多光源采集过程)
for I := 1 to 4 by 1
Message := 'Acquire image ' + I + ' of 4'
* 生成采集状态提示
select_obj (Images, ObjectSelected, I)
* 选择当前帧图像
dev_display (ObjectSelected)
* 显示图像
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
wait_seconds (0.5)
* 模拟0.5秒采集间隔(产线节奏控制)
endfor
* 执行光度立体法重建
* ------------------------------------------------------------
* 光源方位参数(需根据实际光源标定结果设置)
Tilts := [6.1, 95.0, -176.1, -86.8]
* 光源倾斜角(单位:度)
Slants := [41.4, 42.6, 41.7, 40.9]
* 光源天顶角(单位:度)
ResultType := ['gradient', 'albedo']
* 输出梯度场和反照率图
* 核心重建算法(Poisson方程法重建表面高度)
photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ResultType, 'poisson', [], [])
* 显示反照率图(材质反射率分布)
* ------------------------------------------------------------
dev_display (Albedo)
disp_message (WindowHandle, 'Albedo image', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 暂停供操作员检查反照率特征
* 计算高斯曲率并检测缺陷
* ------------------------------------------------------------
* 通过梯度场计算高斯曲率(表面凹凸特征量化)
derivate_vector_field (Gradient, GaussCurvature, 1, 'gauss_curvature')
* 缺陷检测流程
* ------------------------------------------------------------
* 步骤1:分割药片区域(排除正常区域干扰)
regiongrowing (GaussCurvature, Regions, 1, 1, 0.001, 250)
* 区域生长分割
* 筛选符合药片尺寸的区域(宽高150-200像素范围)
select_shape (Regions, TabletRegions, ['width', 'height'], 'and', [150, 150], [200, 200])
shape_trans (TabletRegions, TabletRegions, 'convex')
* 凸包填充
union1 (TabletRegions, TabletRegions)
* 区域合并
erosion_circle (TabletRegions, TabletRegions, 3.5)
* 3.5像素腐蚀去毛刺
* 步骤2:在药片区域内检测异常曲率
reduce_domain (GaussCurvature, TabletRegions, ImageReduced)
* ROI裁剪
abs_image (ImageReduced, ImageAbs)
* 取绝对值
* 阈值分割(曲率>0.03判定为异常,需根据实际产品调整)
threshold (ImageAbs, Region, 0.03, 255)
closing_circle (Region, RegionClosing, 10.5)
* 10.5像素闭运算连接碎片
connection (RegionClosing, ConnectedRegions)
* 分离连通区域
* 筛选面积>10像素的缺陷区域(过滤噪声)
select_shape (ConnectedRegions, Defects, 'area', 'and', 10, 99999)
* 步骤3:计算缺陷中心并生成标记
area_center (Defects, Area, Row, Column)
* 获取缺陷中心坐标
gen_circle (Circle, Row, Column, gen_tuple_const(|Row|,20.5))
* 生成20.5像素半径的圆标记
* 可视化检测结果
* ------------------------------------------------------------
* 在曲率图上显示缺陷(红色轮廓)
dev_set_draw ('margin')
* 轮廓显示模式
dev_set_color ('red')
* 报警颜色
dev_set_line_width (2)
* 轮廓线宽
dev_display (GaussCurvature)
* 显示高斯曲率图
dev_display (Circle)
* 叠加缺陷标记
Message := 'The defect can easily be detected'
Message[1] := 'in the surface curvature image'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
stop ()
* 暂停观察曲率检测结果
* 在反照率图上显示缺陷(红色轮廓)
dev_set_draw ('margin')
dev_set_color ('red')
dev_display (Albedo)
* 显示反照率图
dev_display (Circle)
* 叠加缺陷标记
disp_message (WindowHandle, 'Defect in albedo image', 'window', 12, 12, 'black', 'true')
显示反照率图:

显示结果图:


未完待续。。。。。。。。。。。。
| ∂x∂Vy | 交叉导数(剪切应变) |