机器视觉halcon7-缺陷检测

发布于:2025-07-31 ⋅ 阅读:(16) ⋅ 点赞:(0)

机器视觉halcon7-缺陷检测

注塑吸嘴缺口检测

在这里插入图片描述

******************************************第一步  初始化**************************************************
*读取一张图像
read_image (Hull, 'hull')

*获取图像大小
get_image_size (Hull, Width, Height)

*关闭已经打开的窗口
dev_close_window ()

*打开一个新的窗口
dev_open_window (0, 0, Width, Height, 'black', WindowID)

*显示图像
dev_display (Hull)
 
******************************************第二步  图像处理**************************************************
*阈值操作,分割出吸嘴
threshold (Hull, Dark, 0, 80)

*补集运算,获取背景区域
difference (Hull, Dark, Light)

*对背景区域进行连通处理
connection (Light, ConnectedRegions)

*过滤出背景区域
select_shape (ConnectedRegions, NoHullCand, 'area', 'and', 50000, 9999999)

*对过滤的背景区域进行闭运算,填充背景间隙和平滑背景边界
closing_circle (NoHullCand, NoHull, 13.5)

*补集运算,获取吸嘴区域
difference (Hull, NoHull, Region)

*对吸嘴区域开运算
opening_circle (Region, RegionOpening, 2.5)

*对吸嘴区域进行连通处理
connection (RegionOpening, ConnectedRegions)

*过滤出吸嘴区域
select_shape (ConnectedRegions, RegionHull, 'area', 'and', 5000, 9999999)

*将吸嘴区域转换为凸包区域
shape_trans (RegionHull, ConvexHull, 'convex')

*补集运算,获取吸嘴的缺口
difference (ConvexHull, RegionHull, Region)

*对吸嘴缺口区域进行连通处理
connection (Region, ConnectedRegions)

*过滤出吸嘴缺口
select_shape (ConnectedRegions, LargeHoles, 'area', 'and', 2000, 99999)
select_shape (LargeHoles, Holes, 'convexity', 'and', 0, 0.85)

*显示图像
dev_display (Hull)

*设置输出对象的线宽度
dev_set_line_width (5)

*设置区域的填充方式
dev_set_draw ('margin')

*设置输出对象显示颜色为红色
dev_set_color ('red')

*显示吸嘴缺口
dev_display (Holes)

这段Halcon代码主要用于检测图像中吸嘴的缺口,结合阈值分割、形态学操作、区域处理等技术实现目标区域的定位与分析。以下是分步详解:

第一步 初始化

读取图像并初始化窗口

read_image (Hull, ‘hull’) // 读取名为’hull’的图像
get_image_size (Hull, Width, Height) // 获取图像尺寸
dev_close_window () // 关闭已打开的窗口
dev_open_window (0, 0, Width, Height, ‘black’, WindowID) // 打开新窗口
dev_display (Hull) // 显示图像

作用:初始化环境,加载图像并打开适配窗口。dev_open_window的参数设置窗口位置和背景色为黑色。

第二步 图像处理

阈值分割与背景提取

threshold (Hull, Dark, 0, 80) // 分割暗区(灰度值0-80)
difference (Hull, Dark, Light) // 取补集,获取背景区域

threshold:分割出灰度值较低的暗区(吸嘴部分可能较暗)。

difference:原图减去暗区,得到背景区域(Light),即非吸嘴部分。
背景区域优化

connection (Light, ConnectedRegions) // 连通域分割
select_shape (ConnectedRegions, NoHullCand, ‘area’, ‘and’, 50000, 9999999) // 筛选大区域
closing_circle (NoHullCand, NoHull, 13.5) // 闭运算填充间隙

connection:将背景区域分割为独立连通域。

select_shape:过滤面积在5万像素以上的区域(保留背景主体)。

closing_circle:使用半径13.5的圆形结构进行闭运算,填充背景中的小孔洞并平滑边界。
吸嘴区域提取

difference (Hull, NoHull, Region) // 原图减去背景,得到吸嘴候选区域
opening_circle (Region, RegionOpening, 2.5) // 开运算去除噪声
connection (RegionOpening, ConnectedRegions) // 连通域分割
select_shape (ConnectedRegions, RegionHull, ‘area’, ‘and’, 5000, 9999999) // 筛选吸嘴区域

difference:通过背景补集重新定位吸嘴区域。

opening_circle:半径2.5的开运算去除细小噪声(如毛刺)。

select_shape:保留面积大于5000像素的区域,排除误分割的小目标。
缺口检测

shape_trans (RegionHull, ConvexHull, ‘convex’) // 转换为凸包区域
difference (ConvexHull, RegionHull, Region) // 凸包与原区域差集,获取缺口
connection (Region, ConnectedRegions) // 连通域分割
select_shape (ConnectedRegions, LargeHoles, ‘area’, ‘and’, 2000, 99999) // 筛选大缺口
select_shape (LargeHoles, Holes, ‘convexity’, ‘and’, 0, 0.85) // 根据凸度筛选

shape_trans:将吸嘴区域转换为凸包(凸包是包含所有区域点的最小凸形)。

difference:凸包与原区域的差集即为凹陷或缺口区域。

select_shape:

筛选面积大于2000像素的缺口。

通过凸度(convexity)过滤不规则区域(凸度≤0.85表示非凸形,适合检测缺口)。

第三步 结果可视化

dev_display (Hull) // 显示原图
dev_set_line_width (5) // 设置线宽为5像素
dev_set_draw (‘margin’) // 仅显示区域边界
dev_set_color (‘red’) // 设置显示颜色为红色
dev_display (Holes) // 高亮显示检测到的缺口

作用:通过高亮红色边界突出显示缺口,便于视觉确认。

关键技术与应用场景

形态学操作:

closing_circle和opening_circle分别用于填充孔洞和去噪,是工业检测中修复区域形态的常用手段。
凸包变换:

通过计算凸包差集定位缺口,适用于检测机械部件的磨损或破损。
区域筛选:

结合面积、凸度等特征过滤,提高检测精度。

参数优化建议

闭运算半径(13.5):若背景间隙较大,可适当增大半径。

开运算半径(2.5):若吸嘴边缘噪声较多,可微调以平衡去噪与细节保留。

凸度阈值(0.85):根据实际缺口形状调整,值越小允许的凹陷越深。

铣刀刀口破损缺陷检测

在这里插入图片描述

OTSU

OTSU,是一种自适应阈值确定的方法,又叫大津法,简称OTSU,是一种基于全局的二值化算法,它是根据图像的灰度特性,将图像分为前景和背景两个部分。当取最佳阈值时,两部分之间的差别应该是最大的,在OTSU算法中所采用的衡量差别的标准就是较为常见的最大类间方差。前景和背景之间的类间方差如果越大,就说明构成图像的两个部分之间的差别越大;

记T为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1,图像的总平均灰度为u,前景和背景图象的方差,则有:
在这里插入图片描述

示例代码

*****************************************************************************第一 图像预处理********************************************************
*读取一张图像
read_image(Image,'1.bmp')

*对图像的灰度值在0255范围内拉伸
scale_image_max (Image, ImageScaleMax)

*反选像素的位
bit_not (ImageScaleMax, ImageNot)

*生成一个椭圆元素
gen_disc_se (SE, 'byte', 45,45, 0)

*黑帽运算,分割比临近暗的区域
gray_bothat (ImageNot, SE, ImageBotHat)

*生成ROI1
gen_rectangle1 (ROI_0, 574.119, 268.867, 644.104, 337.728)
*生成ROI2
gen_rectangle1 (TMP_Region, 87.9029, 783.297, 179.989, 809.627)
*合并两个ROI
union2 (ROI_0, TMP_Region, ROI_0)
*生成ROI3
gen_rectangle1 (TMP_Region, 743.558, 937.222, 839.327, 997.981)
*合并ROI
union2 (ROI_0, TMP_Region, ROI_0)
*将合并ROI区域的图像剪切
reduce_domain (ImageBotHat, ROI_0, TemplateImage)

*设置区域填充方式 
dev_set_draw ('margin')
*获取图像的数据,类型,高度,宽度
get_image_pointer1 (TemplateImage, Pointer, Type, Width, Height)
*显示图像
dev_display (TemplateImage)

*****************************************************************************第二 自动寻找最佳阈值********************************************************
* 最大方差初始化为0
MaxVariance := 0.0
* 最佳分割灰度阈值从1遍历到255,初始阈值的选取可以取图像平均灰度值
for ImgThreshold := 1 to 255 by 1
    dev_display (TemplateImage)
    * 前景区域分割
    threshold (TemplateImage, Region, ImgThreshold, 255)
    * 获得前景区域像素个数
    area_center (Region, Area, Row, Column)
    * 获得前景区域均值和方差
    intensity (Region,TemplateImage, Mean, Deviation)
    
    *对前景区域进行反选
    complement (Region, RegionComplement)
    *获取背景区域的面积和坐标
    area_center (RegionComplement, Area1, Row1, Column1)
    *获得背景区域像素个数、均值和方差
    intensity (RegionComplement,TemplateImage, Mean1, Deviation1)
    * 计算类间方差
    Otsu := Area*1.0/[Width*Height]*Area1*1.0/[Width*Height]*pow(Mean-Mean1,2)
    * 获取最大类间方差最佳阈值
    if (Otsu>MaxVariance)
        MaxVariance := Otsu
        BestThreshold := ImgThreshold
    endif
endfor
dev_display (TemplateImage)
dev_set_color ('green')
dev_set_draw ('fill')
 
*****************************************************************************第三 分割缺陷目标********************************************************
* 阈值操作,选取高亮目标,即为缺陷
threshold (TemplateImage, Region1, BestThreshold, 255)
* 对缺陷区域进行连通处理
connection(Region1, ConnectedRegions)
* 根据面积过滤出大的缺陷
select_shape (ConnectedRegions, SelectedRegions1, 'area', 'and', 261.07, 1971)
* 填充缺陷内部间隙
fill_up(SelectedRegions1, RegionFillUp)
* 显示图像
dev_display(Image)
* 显示缺陷区域
dev_display(RegionFillUp)

stop()

以下是代码的详细分步解释,结合Halcon图像处理技术背景:

一、图像预处理模块

图像增强

*读取图像
read_image(Image,'1.bmp')             // 读取原始图像
*灰度拉伸
scale_image_max (Image, ImageScaleMax) // 将图像灰度扩展到0-255范围,增强对比度
*像素位反转
bit_not (ImageScaleMax, ImageNot)     // 反色处理(黑变白、白变黑),便于后续黑帽运算

形态学预处理

*生成椭圆结构元素
gen_disc_se (SE, 'byte', 45,45, 0)   // 创建45x45圆形结构元素,用于形态学操作
*黑帽运算
gray_bothat (ImageNot, SE, ImageBotHat) // 检测比周围更暗的缺陷区域

ROI区域处理

*生成并合并ROI
gen_rectangle1 (ROI_0, 574, 268, 644, 337) // 定义矩形区域1(左上角坐标+右下角坐标)
gen_rectangle1 (TMP_Region, 87, 783, 179, 809) // 区域2(可能为刀口特征区域)
union2 (ROI_0, TMP_Region, ROI_0)    // 合并两个矩形区域
gen_rectangle1 (TMP_Region, 743, 937, 839, 997) // 区域3(补充关键检测区域)
union2 (ROI_0, TMP_Region, ROI_0)    // 最终合并三个ROI区域
*裁剪ROI图像
reduce_domain (ImageBotHat, ROI_0, TemplateImage) // 仅保留ROI内的图像数据

二、Otsu阈值自动选择模块

*遍历所有灰度阈值
for ImgThreshold := 1 to 255 by 1    // 穷举法寻找最佳分割阈值
    *分割前景区域
    threshold (TemplateImage, Region, ImgThreshold, 255) // 当前阈值分割
    *计算前景属性
    area_center (Region, Area, Row, Column) // 获取面积和中心坐标
    intensity (Region, TemplateImage, Mean, Deviation) // 计算前景均值/标准差
    
    *计算背景属性
    complement (Region, RegionComplement) // 反选得到背景区域
    area_center (RegionComplement, Area1, Row1, Column1)
    intensity (RegionComplement, TemplateImage, Mean1, Deviation1)
    
    *Otsu类间方差计算
    Otsu := AreaArea1/(WidthHeight)^2 * (Mean-Mean1)^2 // 类间方差公式
    if (Otsu>MaxVariance)            // 记录最大方差对应的阈值
        BestThreshold := ImgThreshold
    endif
endfor

三、缺陷检测模块

*阈值分割
threshold (TemplateImage, Region1, BestThreshold, 255) // 应用最佳阈值
*区域后处理
connection(Region1, ConnectedRegions) // 连通域分割
select_shape (ConnectedRegions, SelectedRegions1, ‘area’, ‘and’, 261, 1971) // 过滤小噪点
fill_up(SelectedRegions1, RegionFillUp) // 填充孔洞(确保缺陷完整性)
*结果显示
dev_display(Image) // 显示原图
dev_display(RegionFillUp) // 叠加红色缺陷区域

技术原理与应用

黑帽运算:通过gray_bothat检测比周围暗的缺陷(如刀口崩缺),结构元素尺寸需大于缺陷尺寸

Otsu算法:通过最大化前景/背景的类间方差实现自适应阈值选择,避免手动调参

ROI策略:聚焦关键检测区域(如刀具刃口),减少计算量并提升精度

形态学过滤:面积筛选+填充操作可排除噪声干扰,确保缺陷区域完整

参数优化建议(基于实际应用场景)

结构元素尺寸:若缺陷尺寸变化,需调整gen_disc_se的45x45参数

面积阈值:261-1971范围需根据刀具尺寸重新标定

ROI位置:需通过实际刀具图像校准矩形坐标

显示效果:可通过dev_set_color(‘red’)修改缺陷显示颜色

网状产品表面破损检测

在这里插入图片描述


*关闭程序计数器,图形变量更新,窗口图形更新
dev_update_window ('off')

*读取一张图像
read_image (Image, 'plastic_mesh/plastic_mesh_01')

*关闭打开的窗口
dev_close_window ()

*获取图像大小
get_image_size (Image, Width, Height)

*创建一个新窗口
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowHandle)


*设置字体信息:字体大小为16,字体为mono,粗体,斜体
set_display_font (WindowHandle, 18, 'mono', 'true', 'false')

*设置区域的填充方式
dev_set_draw ('margin')

*设置线宽度
dev_set_line_width (3)


for J := 1 to 14 by 1
    *读取一张图像
    read_image (Image, 'plastic_mesh/plastic_mesh_' + J$'02')
    
    *均值滤波
    mean_image (Image, ImageMean, 49, 49)
    
    *局部阈值分割图像
    dyn_threshold (Image, ImageMean, RegionDynThresh, 5, 'dark')
    
    *对分割后的区域进行连通处理
    connection (RegionDynThresh, ConnectedRegions)
    
    *过滤出缺陷网孔区域
    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
        disp_message (WindowHandle, 'Mesh not OK', 'window', 24, 12, 'black', 'true')
    else
        *显示产品OK
        disp_message (WindowHandle, 'Mesh OK', 'window', 24, 12, 'black', 'true')
    endif

    stop()
    
endfor

以下是对这段Halcon代码的逐模块解析,结合工业检测场景和图像处理原理:

初始化模块

dev_update_window (‘off’) // 关闭窗口实时更新以提高处理速度
read_image (Image, ‘plastic_mesh/plastic_mesh_01’) // 加载参考图像
dev_close_window () // 关闭旧窗口
get_image_size (Image, Width, Height) // 获取图像尺寸
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowHandle) // 创建适配窗口

关键点:dev_update_window(‘off’)可显著提升处理速度,dev_open_window_fit_image自动调整窗口尺寸适配图像。

显示参数设置

set_display_font (WindowHandle, 18, ‘mono’, ‘true’, ‘false’) // 设置字体为18px粗体
dev_set_draw (‘margin’) // 仅显示区域轮廓
dev_set_line_width (3) // 设置轮廓线宽为3像素

作用:优化结果显示效果,粗线宽和高对比度字体便于缺陷观察。

循环处理模块

for J := 1 to 14 by 1
read_image (Image, ‘plastic_mesh/plastic_mesh_’ + J$‘02’) // 循环读取14张图像

endfor

路径拼接:J$'02’将数字格式化为两位数(如1→"01"),适用于批量处理命名规律的图像。

图像预处理

mean_image (Image, ImageMean, 49, 49) // 49x49均值滤波
dyn_threshold (Image, ImageMean, RegionDynThresh, 5, ‘dark’) // 动态阈值分割

均值滤波:使用49x49大核消除背景纹理(适合网格状目标)。

动态阈值:对比原图与滤波图,提取比背景暗的区域('dark’模式),偏移量5过滤细微噪声。

缺陷检测

connection (RegionDynThresh, ConnectedRegions) // 连通域分割
select_shape (ConnectedRegions, ErrorRegions, ‘area’, ‘and’, 500, 99999) // 面积筛选
count_obj (ErrorRegions, NumErrors) // 统计缺陷数量

面积过滤:保留500像素以上的区域,排除小噪点,上限99999防止误检过大异常。

逻辑’and’:确保所有条件同时满足,避免误判。

结果显示

dev_display (Image) // 显示原图
dev_set_color (‘red’) // 设置缺陷显示颜色
dev_display (ErrorRegions) // 叠加缺陷区域
if (NumErrors > 0)
disp_message (WindowHandle, ‘Mesh not OK’, ‘window’, 24, 12, ‘black’, ‘true’)
else
disp_message (WindowHandle, ‘Mesh OK’, ‘window’, 24, 12, ‘black’, ‘true’)
endif

消息显示:在窗口坐标(24,12)位置显示黑色文字,'true’添加橙色背景框。

技术原理与应用场景

动态阈值优势:

通过对比原图与滤波图,有效消除光照不均影响,特别适合网格/纹理背景的缺陷检测(如塑料网孔破损)。
参数选择依据:

均值滤波核尺寸(49x49)需大于网格孔洞尺寸,确保背景平滑但保留缺陷

偏移量5平衡灵敏度与抗噪性,需根据实际缺陷对比度调整
缺陷判断逻辑:

面积筛选是工业检测中排除伪缺陷的常用手段,500像素阈值需根据网孔实际尺寸标定。

优化建议

滤波核调整:若网格孔洞较大,可增大核尺寸(如61x61)以更好平滑背景。

形态学优化:在select_shape前加入closing_circle闭合断裂缺陷区域。

多特征筛选:结合’circularity’或’compactness’排除非孔洞状干扰。

结果存储:在循环内添加write_image保存带缺陷标注的图像用于追溯。

调试注意
stop()会中断流程,批量检测时应移除或改为条件暂停。

路径plastic_mesh/plastic_mesh_XX需确保图像存在且命名连续,否则会触发异常。

手机摄像头图像表面的轻微缺陷检测

在这里插入图片描述
在这里插入图片描述

************************************************第一 窗口初始化****************************************************
*关闭已经打开的窗口
dev_close_window () 

*关闭程序计数器,图形变量更新,窗口图形更新
dev_update_off () 

*读取一张图像
read_image (Image,'2.bmp') 

*获取图像大小
get_image_size (Image, Width, Height) 

*打开新的窗口
dev_open_window (0, 0, 640, 480, 'black', WindowHandle) 

*设置区域填充方式
dev_set_draw ('margin') 

*设置线宽度
dev_set_line_width (2) 

*设置输出对象显示颜色数目
dev_set_colored(12) 


************************************************第二 图像预处理****************************************************
*优化FFT的速度
optimize_rft_speed (Width, Height, 'standard') 
Sigma1 := 10.0 
Sigma2 := 2.0 
*构建高斯滤波器
gen_gauss_filter (GsFilter1, Sigma1, Sigma1, 0.0, 'none', 'rft', Width, Height) 
*构建高斯滤波器
gen_gauss_filter (GsFilter2, Sigma2, Sigma2, 0.0, 'none', 'rft', Width, Height)

*两个滤波器相减
sub_image (GsFilter1, GsFilter2, Filter, 1, 0) 


************************************************第三 开始处理图像****************************************************
* Image Acquisition 01: Code generated by Image Acquisition 01
ImageFiles := []
ImageFiles[0] := '1.bmp'
ImageFiles[1] := '2.bmp'



for Index := 0 to |ImageFiles| - 1 by 1
    
*读取一张图像
read_image (Image, ImageFiles[Index])

*RGB彩色图转化为灰度图
rgb1_to_gray (Image, Image) 

*对灰度图进行反选
invert_image(Image, ImageInvert) 
   
*将图像转化为频域图像
rft_generic (ImageInvert, ImageFFT, 'to_freq', 'sqrt', 'complex', Width) 

*将频域图像和滤波核进行卷积运算
convol_fft (ImageFFT, Filter, ImageConvol) 

*将频域图像转化为空间域图像
rft_generic (ImageConvol, ImageFiltered, 'from_freq', 'n', 'real', Width) 

*创建一个ROI
gen_rectangle1(Rectangle,30,25,450,610) 

*ROI区域的图像剪切
reduce_domain(ImageFiltered, Rectangle, ROI) 

*中值滤波

网站公告

今日签到

点亮在社区的每一天
去签到