halcon学习拓展系列—弱边缘缺陷检测方法汇总之空域方法(二)

50 篇文章 381 订阅 ¥99.90 ¥299.90
本文是Halcon学习系列的一部分,主要探讨空域中的边缘检测方法,包括图像增强、照明度增强、直方图均衡化等,并通过实例代码展示其效果,最后对比分析了各种方法在弱边缘检测中的优劣。
摘要由CSDN通过智能技术生成

上一专题《halcon学习拓展系列—弱边缘缺陷检测方法汇总之频域方法(一)》,该专题主要讲解频域检测边缘,本专栏主要讲空域边缘检测,总目录如下:

***************************弱边缘缺陷检测方法汇总之空域方法*******************************
一、算法实现
1、图像增强部分
1)对比度增强(emphasize)
2)照明度增强(illuminate)
3)直方图均衡化(equ_histo_image)
4)灰度线性变换(scale_image,scale_image_max)
5)灰度非线性指数变换(exp_image)
6)灰度非线性对数变换(log_image)
7)局部灰度范围统计(gray_range_rect)
8)局部灰度熵统计(entropy_image)
9)局部灰度值标准方差(deviation_image)
10)局部最大灰度值统计(gray_dilation_rect)
11)高通滤波(highpass_image)
12)sobel幅值边缘检测(sobel_amp)
13)sobel幅值和方向边缘检测(sobel_dir)

2、边缘/区域分割部分
1)自动阈值—由直方图确定的阈值分割图像(auto_threshold)
2)动态阈值—由局部动态阈值分割(dyn_threshold)
3)滞后阈值分割(hysteresis_threshold)
4)骨架分割(skeleton)
5)二阶导数(lines_gauss)

二、总结

written by guke
****************************************************************************************

下面开始...

 

一、基础知识

1、图像增强部分

1)对比度增强(emphasize)

emphasize(Image : ImageEmphasize : MaskWidthMaskHeightFactor : )    增强图像对比度

和频域对比度增强原理类似:

res := round((orig - mean) * Factor) + orig

测试代码:

read_image (Image, 'surface_scratch')
get_image_size (Image, Width, Height)
emphasize (Image, ImageEmphasize, 7, 7, 1.5)

测试结果:

 

2)照明度增强(illuminate)

illuminate(Image : ImageIlluminate : MaskWidthMaskHeightFactor : )    照明度增强

** 光照增强公式
** 图像中非常暗的部分被“照亮”得更强烈,非常亮的部分被“暗化”
new = round ( (val - mean) * Factor + orig )

测试代码:

**光照增强
read_image (Image, 'surface_scratch')
illuminate (Image, ImageIlluminate, 101, 101, 0.7)

测试效果:

 

3)直方图均衡化(equ_histo_image)

equ_histo_image(Image : ImageEquHisto : : )    直方图均衡化

测试代码:

**直方图均衡化
read_image (Image, 'surface_scratch')
equ_histo_image (Image, ImageEquHisto)

测试效果:

显然,直方图均衡化不太适合刮伤、划伤、毛丝和异物等检测

 

4)线性灰度变换(scale_image,scale_image_max)

scale_image(Image : ImageScaled : MultAdd : )    灰度线性变换

** scale_image公式
g' := g * Mult + Add

测试代码:

**线性灰度变换
read_image (Image, 'surface_scratch')
scale_image (Image, ImageScaled, 1, 20)
scale_image_max (Image, ImageScaleMax)

测试效果:

 

5)非线性灰度指数变换(exp_image)

exp_image(Image : ExpImage : Base : )    灰度指数变换

测试代码:

**exp图像增强
read_image (Image, 'surface_scratch')
exp_image (Image, ExpImage, 1.1)

测试效果:

显然,图像灰度指数变换太适合刮伤、划伤、毛丝和异物等检测,更适合灰阶较多的图像

 

6)非线性灰度对数变换(log_image)

log_image(Image : LogImage : Base : )    灰度对数变换

测试代码:

**log图像增强
read_image (Image, 'surface_scratch')
log_image (Image, LogImage, 'e')

测试效果:

 

7)局部灰度范围统计(gray_range_rect)

gray_range_rect(Image : ImageResult : MaskHeightMaskWidth : )    局部矩形内灰度范围统计

测试代码:

**局部灰度统计
read_image (Image, 'surface_scratch')
gray_range_rect (LogImage, ImageResult, 11, 11)

测试效果:

 

8)局部灰度熵统计(entropy_image)

entropy_image(Image : ImageEntropy : WidthHeight : )     局部灰度熵统计

测试代码:

**局部灰度熵统计
read_image (Image, 'surface_scratch')
entropy_image (Image, ImageEntropy, 9, 9)

测试效果:

 

9)局部灰度值标准方差(deviation_image)

deviation_image(Image : ImageDeviation : WidthHeight : )

测试代码:

**局部灰度标准方差统计
read_image (Image, 'surface_scratch')
deviation_image (Image, ImageDeviation,7, 7)

测试效果:

 

10)局部最大灰度值统计(gray_dilation_rect)

gray_dilation_rect(Image : ImageMax : MaskHeightMaskWidth : )

测试代码:

**局部灰度最大值统计
read_image (Image, 'surface_scratch')
gray_dilation_rect (Image, ImageMax, 11, 11)

测试效果:

显然,局部最大灰度值统计不适合检测黑对象,我们将图像反转一下:

测试代码:

**局部灰度最大值统计
read_image (Image, 'surface_scratch')
invert_image (Image, ImageInvert)
gray_dilation_rect (ImageInvert, ImageMax, 11, 11)

测试效果:

 

11)高通滤波(highpass_image)

highpass_image(Image : Highpass : WidthHeight : )

测试代码:

**高通滤波
read_image (Image, 'surface_scratch')
highpass_image (Image, Highpass, 15, 15)

测试效果:

 

12)sobel幅值边缘检测(sobel_amp)

sobel_amp(Image : EdgeAmplitude : FilterTypeSize : )

测试代码:

**sobel_amp
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)
sobel_amp (ImageEmphasize, EdgeAmplitude, 'sum_abs', 3)

测试效果:

 

13)sobel幅值和方向边缘检测(sobel_dir)

sobel_dir(Image : EdgeAmplitudeEdgeDirection : FilterTypeSize : )

测试代码:

**sobel_dir
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)
sobel_dir (Image, EdgeAmplitude, EdgeDirection, 'sum_abs', 3)
nonmax_suppression_dir (EdgeAmplitude, EdgeDirection, ImageResult, 'nms')
dev_display (ImageResult)

测试效果:

效果不好啊,sobel_dir对弱边缘效果一般!

 

2、边缘/区域分割部分

为了比较分析,我们统一用illumination和emphasize的结果ImageEmphasize

1)自动阈值—由直方图确定的阈值分割图像(auto_threshold)

auto_threshold(Image : Regions : Sigma : )

测试代码:

**auto_threshold
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)
auto_threshold (ImageEmphasize, Regions, 0.5)
intensity (Regions, ImageEmphasize, Mean, Deviation)
intensity (ImageEmphasize, ImageEmphasize, MeanWhole, Deviation1)
tuple_sort_index (Mean, Indices)
tuple_less_equal_elem (Mean, MeanWhole, Lesseq)
tuple_find (Lesseq, 1, IndicesLess)
select_obj (Regions, ObjectSelected, Indices[IndicesLess]+1)
closing_circle (ObjectSelected, RegionClosing1, 6)
connection (RegionClosing1, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['area','max_diameter'], 'and', [1,1], [99999,99999999])
union1 (SelectedRegions, RegionUnion)
dev_display (ImageEmphasize)
dev_display (RegionUnion)

测试效果:

分割效果太散了!不建议利用auto_threshold检测比较细的线状缺陷特征,优于用于区域块状的Blob分析,一是比较灵活,二是稳定性较好

 

2)动态阈值—由局部动态阈值分割(dyn_threshold)

dyn_threshold(OrigImageThresholdImage : RegionDynThresh : OffsetLightDark : )    动态阈值

测试代码:

**dyn_threshold
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)
mean_image (ImageEmphasize, ImageMean1, 2, 2)
mean_image (ImageEmphasize, ImageMean2, 12, 12)
dyn_threshold (ImageMean1, ImageMean2, RegionDynThresh, 10, 'dark')
closing_circle (RegionDynThresh, RegionClosing1, 3)
connection (RegionClosing1, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['area','max_diameter'], 'and', [25,30], [99999,99999999])
dev_display (ImageEmphasize)
dev_display (SelectedRegions)

测试效果:

 

3)滞后阈值分割(hysteresis_threshold)

hysteresis_threshold(Image : RegionHysteresis : LowHighMaxLength : )    滞后阈值

测试代码:

**hysteresis_threshold
**illumination和emphasize增强后图像
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)

hysteresis_threshold (EdgeAmplitude, RegionHysteresis, 25, 55, 10)
connection (RegionHysteresis, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['area','max_diameter'], 'and', [10,15], [99999,99999999])
dev_display (ImageEmphasize)
dev_display (SelectedRegions)


**sobel_amp增强后图像
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)
sobel_amp (ImageEmphasize, EdgeAmplitude, 'sum_abs', 3)

hysteresis_threshold (EdgeAmplitude, RegionHysteresis, 25, 55, 10)
connection (RegionClosing1, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['area','max_diameter'], 'and', [10,15], [99999,99999999])
dev_display (EdgeAmplitude)
dev_display (SelectedRegions)

测试效果:

 

4)骨架分割(skeleton)

skeleton(Region : Skeleton : : )

测试代码:

**skeleton
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)
threshold (ImageEmphasize, Region, 0, 115)
closing_circle (Region, RegionClosing1, 3)
connection (RegionClosing1, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['area','max_diameter'], 'and', [10,10], [99999,99999999])

skeleton (SelectedRegions, Skeleton)
dev_display (ImageEmphasize)
dev_display (Skeleton)

测试效果:

skeleton是对分割好的region进行骨架提取,前提是分割好,所以这里简单用了threshold,与其他分割效果无法进行对比,这里知道skeleton能够对Reigon进行骨架提取即可(像素级)

 

5)二阶导数(lines_gauss)

测试代码:

**lines_gauss
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)

lines_gauss (ImageEmphasize, Lines, 1.5, 3, 8, 'dark', 'true', 'bar-shaped', 'true')
union_adjacent_contours_xld (Lines, UnionContours, 10, 1, 'attr_keep')
select_contours_xld (UnionContours, SelectedContours, 'contour_length', 50, 2000, -0.5, 0.5)
dev_display (ImageEmphasize)
dev_display (SelectedContours)

测试效果:

我们修改一下参数:

**lines_gauss
read_image (Image, 'surface_scratch')
mean_image (Image, ImageMean, 1, 1)
illuminate (ImageMean, ImageIlluminate, 101, 101, 0.7)
emphasize (ImageIlluminate, ImageEmphasize, 11, 11, 1.5)

lines_gauss (ImageEmphasize, Lines, 1.5, 2, 5, 'dark', 'true', 'bar-shaped', 'true')
union_adjacent_contours_xld (Lines, UnionContours, 10, 1, 'attr_keep')
select_contours_xld (UnionContours, SelectedContours, 'contour_length', 30, 2000, -0.5, 0.5)
dev_display (ImageEmphasize)
dev_display (SelectedContours)

效果很好!

 

二、总结

1、不管频域还是空域,需要根据缺陷形态特征和灰阶特征,来选择合适的图像增强方式,然后选择合适的缺陷分割算法

2、图像增强对比分析总结:

1)对于较细划痕:频域对干扰的过滤效果要优于空域

2)频域正弦带通滤波器空域illumination&&emphasize滤波,要优于空域sobel滤波,如下图:

               1频域正弦带通滤波器滤波                     2-空域sobel滤波                         3-空域illumination和emphasize滤波

有兴趣的同学可以尝试一下,对频域图像增强后的图片进行缺陷分割,这个不再添加,测试效果也很好

3、分割对比分析总结:空域的dyn_threshold和lines_gauss对弱边缘由较好的分割效果,lines_gauss效果更为突出

4、还有其他好的方法,后面继续添加

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谷棵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值