前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >无纺布折痕检测(1)· 基于构造方向滤波器的折痕检测

无纺布折痕检测(1)· 基于构造方向滤波器的折痕检测

作者头像
threeQing
发布2019-07-08 12:58:17
1.9K0
发布2019-07-08 12:58:17
举报

原图来自Ihalcon论坛

中间有一条对比度不明显的垂直折痕

(图片来源:http://www.ihalcon.com/read-4226.html)

发此帖子的楼主已经给出解决方案,如下:

1. 设计一个滤波器

2. 用convol_image算子来增强特定方向的纹理

3. 再用Gray_Range_Rect做图像变换

4. 最终用线高斯提取目标折痕

我们沿着楼主的解决思路走一遍。

首先介绍下相关理论点:卷积、如何构造方向滤波器。

1

卷积

提到卷积,想起大学时被《信号与系统分析》支配的恐惧了。对于图像处理的卷积,首先需要构造一个滤波矩阵,即卷积核,并将卷积核翻转180°,然后对于图像的每一个像素点,计算它的邻域像素和翻转后卷积核的对应元素的乘积,再加起来,作为该像素位置的值,即完成了卷积。还有一种滤波方式为协相关,其核矩阵不需要绕中心点翻转180°,平时接触的卷积核大都是关于x轴和y轴对称的,所以卷积和协相关在这种情况下没什么区别。

对于整幅图像,采用滑动卷积核的策略,如下图。

经过滑动卷积后,图像大小会变小,为避免这种问题,需要进行边界填充,主要有以下几种方式。

2

方向滤波器

若需检测水平边缘,需要在竖直方向上进行梯度运算,若需检测垂直边缘,需要在水平方向进行梯度运算。所以在检测垂直线条时,所构造的滤波器能在水平方向构成梯度差分运算,如一维水平滤波器[-1,0,1],若要扩展成3*3矩阵形式,可构成Prewitt的水平梯度卷积核。

如果所要检测线条比较宽,可以将3*3的卷积核扩展成5*5,7*7等。

通常情况,线条边缘灰度值会成渐变规律的,将卷积模板更改如下

使用此模板计算时,会将一些灰度值均匀分布的地方全部置0,如果我们不想要只得到的线条的效果,还需要原来的灰度值保持不变,这就需要将卷积模板所有值,相加等于1。

如果需要考虑锚点(中心点)周围所有像素的影响,则需要将其8邻域像素要参与计算。

此时,计算出的像素灰度值会偏大,所有值相加不等于1,需要在模板前乘以对应权值。

至此,我们滤波器构造完毕,在进行试验之前,先了解下Halcon使用构造滤波器的格式,见帮助文档中的如下说明。

大致意思是,我们可生成一个文本文件,文件内容可按照如下格式描述滤波器,文件扩展名为:.fil。

另一种方法可以以元组Tuple的格式描述滤波器,格式为:[模板高,模板宽,模板权重倒数,模板元素行排列],程序中使用的是此格式。

当然,从水平滤波器,也可以联想到垂直滤波器,或者一些特定曲线滤波器。

3

使用Sobel水平滤波器检测折痕

在使用构造滤波器之前,先使用sobel滤波器进行处理,如果前人总结一些经典的先验知识,秉承着”拿来主义“,使用一些已知的、经典的方法,来解决一些未知的、陌生的问题,这种处理思路是极力推崇的。

Sobel算子的处理过程,是分别在水平和垂直方向对图像进行卷积,再讲二者结果结合求得没一点的梯度值。下图为Soble算子的水平、垂直滤波器。

读入图像,将Sobel水平滤波器转换为Halcon的Tuple形式。

代码语言:javascript
复制
filter1 :=[3,3,1,-1,0,1,-2,0,2,-1,0,1]

Sobel水平滤波器与图像卷积后如下图,可以看见一条比较长的竖直线条。

Sobel算子已经做了灰度变换,Gray_Range_Rect可以不再使用,也可以使用做灰度增强,Sobel检测程序无用到。

关于lines_gauss的参数是比较难调,尤其是高低阈值,此处使用算子calculate_lines_gauss_parameters基本可以实现自适应参数条件,只需要设置所检测线条最大宽度与对比即可。

代码语言:javascript
复制
MaxLineWidth := 4
Contrast := 30
calculate_lines_gauss_parameters (MaxLineWidth, [Contrast,0], Sigma, Low, High)
lines_gauss (ImageResult, Lines, Sigma, Low, High, 'light', 'true', 'parabolic', 'true')
select_contours_xld (Lines, SelectedContours, 'contour_length', 180, 250, -0.5, 0.5)

检测结果如下图

干扰线还是比较多的,使用特征筛选可以排除。

4

使用构造方向滤波器检测折痕

将构造滤波器转为halcon的Tuple形式

代码语言:javascript
复制
filter :=[5,5,5,-1,-5,1,5,1,-1,-5,1,5,1,-1,-5,1,5,1,-1,-5,1,5,1,-1,-5,1,5,1]

与原图卷积后

垂直线条明显被加强

使用Gray_Range_Rect做灰度变换

排除垂直纹理以外的干扰

增强对比度

使用线高斯提取目标

干扰线减少些

特征筛选,检测折痕

基于构造滤波器的折痕检测程序

代码语言:javascript
复制
read_image (Image1030179715f15e264af3b, 'C:/Users/SWD-AR02/Desktop/10_3017_9715f15e264af3b.png')
*构造滤波器
filter :=[5,5,5,-1,-5,1,5,1,-1,-5,1,5,1,-1,-5,1,5,1,-1,-5,1,5,1,-1,-5,1,5,1]
*图像卷积
convol_image (Image1030179715f15e264af3b, ImageResult, filter, 'mirrored')
*灰度变换
gray_range_rect (ImageResult, ImageResult1, 6, 6)
*线高斯提取目标
MaxLineWidth := 8
Contrast := 50
calculate_lines_gauss_parameters (MaxLineWidth, [Contrast,0], Sigma, Low, High)
lines_gauss (ImageResult1, Lines, Sigma, Low, High, 'light', 'true', 'parabolic', 'true')
*选取折痕
select_contours_xld (Lines, SelectedContours, 'contour_length', 180, 250, -0.5, 0.5)
*结果显示
gen_region_contour_xld (SelectedContours, Region, 'margin')
dilation_rectangle1 (Region, RegionDilation, 11, 1)
dev_set_draw ('margin')
dev_display (Image1030179715f15e264af3b)
dev_display (RegionDilation)

目前,使用sobel的水平滤波器和构造滤波器都能检测出折痕,但是只是针对此幅图像,对于实际项目当中,构造滤波器可以根据不同情况进行设计,柔性更强、鲁棒性更好,相反地,复杂度也会增加。

后续,我们在此帖楼主的解决方案的框架下,尝试另外两种方法,敬请期待。

后台回复“折痕”可获取原图以及源代码。



本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器视觉那些事儿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档