边缘是图像最基本的特征,其在计算机视觉、图像分析等应用中起着重要的作用,这是因为图像的边缘包含了用于识别的有用信息,是图像分析和模式识别的主要特征提取手段。
1.何为“图像边缘”?
在图像中,“边缘”指的是临界的意思。一幅图像的“临界”表示为图像上亮度显著变化的地方,边缘指的是一个区域的结束,也是另一个区域的开始。“边缘点”指的是图像中具有坐标[x,y],且处在强度显著变化的位置上的点。
2.如何表示边缘检测?
在数学上,用导数来表示改变的快慢。基于此,有许多方法用于边缘检测,他们绝大部分可以划分为两类:基于查找的一类和基于零穿越的一类。基于查找的方法通过寻找图像一阶导数中的最大值和最小值来检测边界,通常将边界定位在梯度最大的方向(想想一阶导数的含义是图像变化的速度,最大的自然就是变化最显著的)。基于零穿越的方法通过寻找图像二阶导数零穿越来寻找边界,通常是Laplacian过零点或者非线性差分表示的过零点。
图像在数学上可看做是二维离散函数,图像梯度就是这个二维离散函数的求导。函数f(x,y)在(x,y)处的梯度为一个向量:
计算这个向量的大小为:通常为了提高效率,常近似表示为:
梯度的方向角为:
差分通常是微分在离散的函数中的等效运算,所以计算图像的梯度常使用差分。
3.Sobel算子
索贝尔算子(Sobel
operator)是图像处理中的算子之一,主要用于边缘检测。在技术上,它是一离散型差分算子,用来运算图像亮度函数的梯度之近似值
。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。
公式
该算子包含两组3X3的矩阵,分别为横向和纵向,将其与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如下:
具体计算如下:
Gx = (-1)*f(x-1, y-1) + 0*f(x,y-1) + 1*f(x+1,y-1)
+(-2)*f(x-1,y) + 0*f(x,y)+2*f(x+1,y)
+(-1)*f(x-1,y+1) + 0*f(x,y+1) + 1*f(x+1,y+1)
= [f(x+1,y-1)+2*f(x+1,y)+f(x+1,y+1)]-[f(x-1,y-1)+2*f(x-1,y)+f(x-1,y+1)]
Gy =1* f(x-1, y-1) + 2*f(x,y-1)+ 1*f(x+1,y-1)
+0*f(x-1,y) 0*f(x,y) + 0*f(x+1,y)
+(-1)*f(x-1,y+1) + (-2)*f(x,y+1) + (-1)*f(x+1, y+1)
= [f(x-1,y-1) + 2f(x,y-1) + f(x+1,y-1)]-[f(x-1, y+1) + 2*f(x,y+1)+f(x+1,y+1)]
其中f(a,b)表示图像(a,b)点的灰度值。
再由Gx和Gy求出▽f,如果▽f大于某一阈值,则认为点(x,y)为边缘点。
4.实践效果
我在vs2013中使用opencv库中的cvSobel()函数对输入图像进行了边缘检测。效果如下:
原图:
因为Sobel算子适用于灰度化后的图像,所以还需将原图灰度化:
Gx、Gy可以检测到边的存在,以及从暗到亮,从亮到暗的变化。仅计算|Gx|,产生最强的响应是正交与X轴的边,即得到垂直边缘;仅计算|Gy|,产生最强的响应是正交于Y轴的边,即得到水平边缘。
仅作水平方向求导(Gx):
可以看到得到很多垂直边缘。
仅作垂直方向求导(Gy):
可以看到得到很多水平边缘。
利用Gx和Gy求出▽f,即梯度向量,以其大小|▽f|画出的图如下:
当然,因为边缘检测对图像噪声比较敏感,最好对原图用高斯滤波器进行平滑处理再进行灰度化。我这里没有做这一步。
由于是新浪博客,相关的代码贴不出来,不过也都是些简单的调用而已,查查opencv的API手册就知道如何使用了。