Halcon编程笔记-(2) 边缘检测-Sobel 算子

边缘检测简介

边缘就是图像上灰度或者颜色变化很大的一系列连续的点。或者说是图像上不同的区域之间的交界处。
图像中边缘的特点就要从这两方向去分析:方向和幅度。在沿着边缘走向的像素值变化比较平缓;而沿着垂直于边缘的走向,像素值则变化得比较大。

边缘检测方法

我们要研究边缘检测的方法,就要从它的特点入手。是否是边缘可以说是来判断一个点在某个方向上的变化是否剧烈。那么我们怎么用数学的方式去描述这种变化特点呢。在数学上,我们一般使用导数或者微分。

导数: 这个很简单,就是连续函数上某点斜率,导数越大表示变化率越大,变化率越大的地方就越是“边缘”。但是,但斜率接近90度的时候,他的斜率就无限大了,在计算机计算的时候就很麻烦了,首先占用空间大,然后就是当斜率过大的时候便无法用常用的数据类型表示了。所以我们一般不用导数来表示
微分: 这个概念需要在大学的时候结束,但也很简单。连续函数上x变化了dx,导致y变化了dy,dy/dx 越大,就可以表示变化率很大了。dx趋向于无限小,dy/dx 就是x在该函数上的导数,所以dy/dx就可以来近似导数,我们成这种方式叫做微分。那这种方式有什么优势呢?当我们固定dx,比较不同点的变化率时只用比较dy就好了,所以计算整幅图像的微分,dy的大小就是边缘的强弱了,我们也称之为梯度。所以我们一般会采用微分的方式。
算子是一个函数空间到另一个函数空间上的映射,表示的是算法中的具体计算方法或者映射方法。习惯在滤波算法使用不同的滤波核,称该算法为某某算子。

类型 具体算子
一阶边缘检测 Roberts 算子、Prewitt算子、Sobel算子 、canny算子
二阶边缘检测 Laplacian算子、Log算子/Marr算子
其他类型 Spacelk算子、Petrou算子、Susan算子、基于机器学习方法

Sobel 算子

Sobel算子是两个Prewitte模板中心像素的权重取2倍的值。是由向量方式确定边缘的两个mask组成的。Sobel算子的这个通用形式缩合了一条坐标轴上最优平滑和另一条坐标轴上的最优差分。换而言之,Sobel
算子有两个,一个是检测水平边缘的 ;另一个是检测垂直边缘的 。它对于象素的位置的影响做了加权,可以降低边缘模糊程度,因此效果更好。

sobel_amp

首先你要明白sobel算子是一个梯度算子,梯度就是所谓的导数,导数在图像中的意义就是边缘和细节等这些灰度值变化剧烈的地方,所以sobel_amp这个算子是用来检测edges,也就是图像的边缘的。

然后amp是amplitude的缩写,中文翻译为幅度,其实就是向量的模,那么你所问的那些Filtertype其实就是不同的计算amplitude的办法,这里你要撇清以前学的那些计算什么距离啊模啊之类的观念,这些数学概念都是人定义的,所以模并不是只有我们以前学到的sqrt(a^2 + b^2)这一种计算方法。所以你也不要纠结这么多滤波器类型选择哪一种了,其实都没有多大的差别,一般情况下你就用默认的那个就行了。

Size就是滤波器的大小啊,比如你要用3 * 3还是5 * 5,这个大小的主要区别在于,如果使用的3 * 3,由于sobel算子的定义就是这个大小,所以直接就按照sobel梯度的计算方式去计算导数,如果使用的size比3 * 3要大,那么就会先对图像进行一个平滑(Gauss平滑,Gauss平滑的模版大小是你在这里选择的size-2),然后再进行梯度的计算,以检测边缘等信息。

那么直接检测和先平滑再检测的区别是什么呢?就是有时候图像会包含一些小的噪声,比如椒盐噪声,如果直接检测,那么这些噪声点也会有很强的响应,也会被检测到。然而这个时候如果对图像先进行一次Gauss平滑除去一定的噪声,那么检测效果是不是就更好了啊!

然后如果从这个模版的size的本质上去理解的话呢,你想啊,size越大,代表我们在处理模版中心的那个像素时所考虑的它周围的邻域越大,也就是这个像素点周围更多的像素被考虑进来,如果这样理解的话,因为是在计算导数,也就是灰度值的变化剧烈程度,那么从原理上来说size越大,对一些粗一些的边缘检测效果更好,反之,size越小,对细一些的边缘效果更好。但是大部分情况下都是用3 * 3或者5 * 5.

read_image (Image, 'C:/Users/ShineZhang/Desktop/img/IMGP8619.JPG') //读入图片
dev_close_window () //关闭已经打开的所有窗口
get_image_size (Image, Width, Height) //得到图片的大小,存入 Width, Height
dev_open_window (0, 0, Width, Height, 'black', WindowHandle) //打开一个新的窗口,句柄为WindowHandle

sobel_amp (Image, EdgeAmplitude, 'thin_sum_abs', 3) //采用sobel算子,得到的边缘图像放在变量EdgeAmplitude中,'thin_sum_abs'表示滤波算法的类型,3表示模版大小为3*3
threshold (EdgeAmplitude, Edges, 30, 255) //对存放边缘图像变量EdgeAmplitude进行二值化,得到阈值范围在30-255之间的区域。
close_edges_length (Edges, EdgeAmplitude, ClosedEdges, 8, 100)//对边缘扩充
dev_set_color ('green')// 图像窗口进行会绘制时采用绿色去绘制线条
dev_display (ClosedEdges)//显示边缘扩展的图像
dev_set_color ('red')//图像窗口进行会绘制时采用红色去绘制线条
dev_display (Edges)//显示需要被延长的边缘图像

原图
原图
边缘二值化之后:
在这里插入图片描述
边缘扩充之后:
在这里插入图片描述
最后的效果图:
在这里插入图片描述
参考文献:
Halcon学习(八)边缘检测(一)
sobel_amp
边缘检测算法综述
边缘检测学习笔记

原创文章 30 获赞 17 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_32939413/article/details/104131970