图像处理中的边缘检测就是把一幅图片的边缘给提取出来,为特征分割或形态学处理做准备,其核心操作就是一个卷积的过程;再直白点说就是创建一个小矩阵(有时也可为向量,即单行矩阵),和原图像的每个像素点(逐像素)及其邻域(图片中的一个像素点的周边上下左右的像素点称为该中心像素点的邻域)作乘积,且此邻域尺寸与小矩阵尺寸大小相同;同时这个小矩阵还得具有与在图片中图像轮廓边缘上的像素点及其邻域作卷积运算时,卷积运算为一个较大的值,并把该值作为一个新空白图像(即与原图像相同大小的输出图像)中相同位置的像素点的值;而对于图像中的平滑区域,小矩阵与这其中的像素点邻域乘积应为零或为较小值;这样,输出的图像便是一幅原图像边缘部分被像素值较大,其他区域像素值较小或为零的灰度图像。
综上,我们不难发现,由于一幅待处理图像其实可看作一个常量,所以边缘检测结果好坏的关键在于与之进行运算的小矩阵的构造,而通常这样的小矩阵我们学术的(形容词)将其称为算子,在滤波操作中又被称为滤波器、模板等。但是,我们如何根据自己的需要构造出满足要求的边缘检测算子呢?首先,正如物理学中在涉及到速度的变化问题时老师所扯淡的,单位时间内,速度变化越快,那么加速度也就越大;同理,我们在寻找图像边缘的时候也运用到同样的原理,即对于一幅图像来说,边缘地区肯定是几个像素点间的像素值相差较大的地区。好,在此基础上,再给图像处理零基础的同学说明一下,一幅图像可由二元离散函数f(x,y)表示;因此,我们对f(x,y)求导(离散函数求导为作差分,就是diff那个玩意儿),得到的值越大,说明在原图像中该处的边缘越明显,反之若求导值为0或很小,说明此处为平滑规整图像区域。对于二元离散函数f(x,y)求导,我们用差分来代替求导,可表示为下列等式:
至于为什么二元函数求导等于
是由高等数学中梯度知识推导出来的,此处不再说明,不懂的记住这个结论即可。在此基础上,再结合其他操作,就能得到各种不同效果的边缘检测算子了。
在Matlab中,目前支持如下算子:
1.Prewitt算子
Prewitt算子就是上述思想的一个直接体现,通过算子形式我们可看出(a)为x的差分,(b)为y的差分,其大小为3×3,:
BW =
edge(I,'prewitt')
BW =
edge(I,'prewitt',thresh)
thresh为一个阈值,当上述的Prewitt模板与每个像素点进行运算之后,将其得到的值与thresh比较,若>thresh,则视为边缘像素点,若
当输入此命令时还可将matlab算出的thresh输出
[BW,thresh] =
edge(I,'prewitt',)
BW =
edge(I,'prewitt',thresh,direction)
Direction表示检测方向,与每个像素点进行运算既可沿着竖直方向运算也可沿着水平方向运算,也可两个方向都进行,于是direction有如下命令:
'horizontal'
or'vertical'edges,
or'both'(默认情况为both).
BW =
edge(I,'prewitt',OPTIONS)
OPTIONS提供两个操作'nothinning'、
'thinning','nothinning'是对得到的边缘检测图像不进行细化处理,'thinning'则是进行细化处理,因为边缘检测后的图像难免会因为原始图像中的边缘部分灰度过渡问题而出现过渡区域全被视为边缘部分,'thinning'操作后能得到单像素线的边缘检测图像。
Matlab中的源码程序主体如下:
function eout = edgeinprewitt(I)
a = I;
kx = 1;%
ky = 1;%kx
ky均为1,检测方式为both
%Transform to a double precision intensity image if
necessary
if ~isa(a,'double')
&&~isa(a,'single')
a=
im2single(a);
end
op = fspecial('prewitt')/6; % Prewitt approximation
toderivative
x_mask = op';
y_mask = op;
%compute the gradient in x and y direction
bx = imfilter(a,x_mask,'replicate');
by = imfilter(a,y_mask,'replicate');
%compute the magnitude
b = kx*bx.*bx +
ky*by.*by;%将沿竖直方向边缘检测和沿水平方向边缘检测得到的边缘图像叠加在一起
cutoff =
4*mean2(b);%用边缘检测后的图像的平均值来近似表示信噪比
%
if thinning
%
e
=computeedge(b,bx,by,kx,ky,int8(offset),100*eps,cutoff);
%边缘细化算法,由于computeedge为内部MEX函数,故此处将其注释掉,输出的便是具有粗边缘的图像
%