边缘检测算法

来源:互联网 发布:深圳楼市成交数据 编辑:程序博客网 时间:2024/06/07 13:11

转载自:http://blog.csdn.net/xiahn1a/article/details/42141429

本文简单介绍边缘检测的集中方法,并有matlab做的结果演示。


什么是边缘?

边缘一般是指图像在某一局部强度剧烈变化的区域。强度变化一般有两种情况:

1. 阶跃变化

灰度变化图像如下图所示(横轴表示空间变化,纵轴表示灰度变化,虚线表示边缘):


此图对应的是向亮渐变的过程。

2. 屋顶变化

灰度变化图像如下图所示(横轴表示空间变化,纵轴表示灰度变化,虚线表示边缘):


此图对应得实由暗到亮再变暗的过程。


边缘检测的任务:

找到具有阶跃变化或者屋顶变化的像素点的集合。


边缘检测基本原理:

既然边缘是灰度变化最剧烈的位置,最直观的想法就是求微分。

对于第一种情况:一阶微分的峰值为边缘点,二阶微分的零点为边缘点。

对于第二种情况:一阶微分的零点为边缘点,二阶微分的峰值为边缘点。


采用一阶微分的方法,我们定义一个梯度算子,梯度是一个向量,指出图像灰度变化最剧烈的方向。


梯度的大小:


梯度的方向:



而在实际的图像处理中,可以采用差分的方法来进行计算。但用差分的方法进行边缘检测必须使差分的方向和边缘的方向相垂直,这就需要对图像的不同方向分别进行差分运算,增加了运算量。一般可将边缘分为水平边缘、垂直边缘和对角线边缘。

1. Reberts算子

Roberts 梯度算子利用对角方向相邻两像素值之差作为衡量标准,其计算方法如下:


如果写成卷积运算的形式,卷积核分别为:



2. prewitt算子

prewitt算子结合了差分运算与邻域平均的方法。其卷积模板如下:



3.sobel算子

sobel算子与prewitt算子类似,但考虑到了相邻不同像素点的影响程度是不同的,所以采用加权平均。其卷积模板如下:



4.laplacian算子

laplacian算子是一些使用二阶微分的算子,实际上就是梯度的散度:

二阶微分:



所以写为卷积模板就是:


这就是laplacian算子。


5.canny算子

canny算子是一种求最优边缘检测的一套方法。是一种先平滑再求导的方法。

第一步:

对图像用高斯滤波器进行平滑处理。

高斯滤波用于对图像进行减噪,采用邻域加权平均的方法计算每一个像素点的值。

第二步:

利用一阶差分计算边缘的方向与幅值。

注意卷积模板如下方所示:


该方法在上方一阶微分边缘检测方法中已有介绍,求法相同。也是为了得到边缘的幅值与方向。

第三步:

非极大值抑制。

仅仅求出全局的梯度方向并不能确定边缘的位置。所以需要对一些梯度值不是最大的店进行抑制,突出真正的边缘。

第二步中,求出的梯度的方向可以是360°的,我们将这360°的区域划分为4个空间,如下图所示。


对应到图像中,一个像素点与其相邻的8个像素点,也可以划分为4个区域。


现在需要做的是,判断沿着梯度方向的3个像素点(中心像素点与另外两个梯度方向区域内的像素点),若中心像素点的梯度值不比其他两个像素点的梯度值大,则将该像素点的灰度值置0。

第四步:

双阈值检测。

对上一部处理完成的图像作用两个阈值,th1和th2,满足th1 = 0.4 th2。将梯度值小于阈值的点的灰度值直接置为0,得到两个新的图像,记作图1和图2。图2因为作用的阈值较大,去除了大部分的噪声,同时也有可能去除了有用的边缘信息。图1则保留了较多的边缘信息,我们利用图1来对图2进行补充。

补充的方法:

对图2进行扫描,遇到第一个非零灰度的像素点p(x, y)时,并以p点开始向周边不断扫描连续的非0灰度像素点(得到边缘的轮廓线)。当找到了轮廓线的终点(即扫描不到连续的非零灰度像素点的点,记为q点),每当找到这样的一个q点,就在图1中找到同样位置的像素点,考察其邻近的8个像素点,是否有非0灰度像素点。如果有,则在图2中将该点灰度置为非0,并作为p点,重复整个扫描过程。

当整个过程都无法再继续的时候,我们就认为已经找到了一条边缘的轮廓线。不停重复该过程,直到找到所有的边缘的轮廓线为止。


最后是测试的matlab代码及实验结果:

[plain] view plain copy
 print?
  1. i = imread('lena.png');  
  2. A = fspecial('gaussian');  
  3. i = filter2(A, i) / 255;  
  4. figure;  
  5. imshow(i);  
  6. imwrite(i,'lena_0.jpg');  
  7.   
  8. a = edge(i, 'prewitt');  
  9. figure;  
  10. imshow(a);  
  11. imwrite(a,'lena_1.jpg');  
  12.   
  13. a = edge(i, 'sobel');  
  14. figure;  
  15. imshow(a);  
  16. imwrite(a,'lena_2.jpg');  
  17.   
  18. a = edge(i, 'log');  
  19. figure;  
  20. imshow(a);  
  21. imwrite(a,'lena_3.jpg');  
  22.   
  23. a = edge(i, 'canny');  
  24. figure;  
  25. imshow(a);  
  26. imwrite(a,'lena_4.jpg');  

测试结果:

原图:


prewitt算子:


sobel算子:


laplacian算子:


canny算子: