图像边缘对图像识别和计算机分析十分有用。边缘能勾画出目标物体,使观察者一目了然;边缘蕴含了丰富的内在信息,是图像识别过程中抽取图像特征的重要属性。从本质上说,图像边缘是图像局部特性不连续性的反映,它标志着一个区域的终结和另一个区域的开始。
边缘检测首先检测出图像局部不连续性,然后将这些不连续的边缘像素连成完备的边界。边缘的特性是沿边缘走向的像素变化平缓,而垂直于边缘方向的像素变化剧烈。所以,从这个意义上说,提取边缘的算法就是检出符合边缘特性的边缘像素的数学算子。
1)卷积。卷积可以简单的看加权求和的过程。卷积时使用一个很小的矩阵来表示,矩阵的大小为奇数,而且与使用的区域大小有关,这种权矩阵叫做卷积核。区域中的每个像素分别与卷积核中的每个元素相乘,所有乘积之和即区域中心像素的新值。比如,对于一个3.3的区域P与卷积核K卷积后,区域P的中心像素P5表示如下:
p 5 = p 1 × k 1 + p 2 × k 2 + . . . + p 8 × k 8 + p 9 × k 9 p_{5}=p_{1}\times k_{1}+p_{2}\times k_{2}+...+p_{8}\times k_{8}+p_{9}\times k_{9} p5=p1×k1+p2×k2+...+p8×k8+p9×k9
其中,
p = [ p 1 p 2 p 3 p 4 p 5 p 6 p 7 p 8 p 9 ] , k = [ k 1 k 2 k 3 k 4 k 5 k 6 k 7 k 8 k 9 ] p=\begin{bmatrix} p_{1} & p_{2} & p_{3}\\ p_{4} & p_{5} & p_{6}\\ p_{7} & p_{8} & p_{9} \end{bmatrix},k=\begin{bmatrix} k_{1} & k_{2} & k_{3}\\ k_{4} & k_{5} & k_{6}\\ k_{7} & k_{8} & k_{9} \end{bmatrix} p=⎣⎡p1p4p7p2p5p8p3p6p9⎦⎤,k=⎣⎡k1k4k7k2k5k8k3k6k9⎦⎤
卷积核中各元素叫卷积系数。卷积核中卷积系数的大小、方向及排列次序决定了卷积的图像处理效果。大多数的卷积核都是3.3的,所有卷积核的行,列都是奇数。进行卷积时会遇到一些较复杂的问题,首先是图像边界的问题。当在图像上逐行移动卷积时,只要卷积核移到了图像边界,即卷积核悬挂在图像边界上时,就会出现计算上的问题。这时在原图像上就不能完整找到与卷积核中卷积系数相对应的9个图像像素。解决这一问题的两个简单方法是:忽略图像边界数据,或者在图像的四周复制图像的边界数据。
2)Sobel边缘检测算子。Sobel边缘检测算子是先做成加权平均,再微分,然后求梯度。以下两个卷积核形成了Sobel边缘检测算子,图中的每个点都用这两个核做卷积,其中一个对垂直边缘影响最大,而另一个对水平边缘影响最大。边缘检测算子的中心与中心像素相对应,进行卷积运算。在边缘检测中,Sobel算子对于像素位置的影响做了加权,加权平均宽度大于等于2个像素,因此效果更好。
[ − 1 − 2 − 1 0 0 0 1 2 1 ] \begin{bmatrix} -1 & -2 & -1\\ 0 & 0 & 0\\ 1 & 2 & 1 \end{bmatrix} ⎣⎡−101−202−101⎦⎤水平边缘检测Sobel [ 1 0 − 1 2 0 − 2 1 0 − 1 ] \begin{bmatrix} 1 & 0 & -1\\ 2 & 0 & -2\\ 1 & 0 & -1 \end{bmatrix} ⎣⎡121000−1−2−1⎦⎤垂直边缘检测Sobel
3)Prewitt边缘检测算子。以下两个卷积核形成Prewitt边缘检测算子。与使用Sobel算子的方法一样,图像中的每个点都用这两个核进行卷积,取最大值作为输出。Prewitt边缘检测算子也产生一幅边缘强度图像。Prewitt边缘检测算子为:
[ − 1 − 1 − 1 0 0 0 1 1 1 ] , [ 1 0 − 1 1 0 − 1 1 0 − 1 ] \begin{bmatrix} -1 & -1 & -1\\ 0 & 0 & 0\\ 1 & 1 & 1 \end{bmatrix},\begin{bmatrix} 1 & 0 &-1 \\ 1 & 0& -1\\ 1 & 0&-1 \end{bmatrix} ⎣⎡−101−101−101⎦⎤,⎣⎡111000−1−1−1⎦⎤
4)Laplace边缘检测算子。
[ 0 1 0 1 − 4 1 0 1 0 ] \begin{bmatrix} 0 &1 & 0\\ 1 & -4 & 1\\ 0 & 1 & 0 \end{bmatrix} ⎣⎡0101−41010⎦⎤
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%函数---图像卷积操作
%Author:Zhu
%time:2022.3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function convImage=Conv(srcImage,wide,height,maskWidth,maskHeight,maskConValue)
convImage = srcImage;
maskCenterX = (maskWidth+1)/2;
maskCenterY = (maskHeight+1)/2;
for i=maskCenterY:1:height-maskHeight+maskCenterY
for j=maskCenterX:1:wide-maskWidth+maskCenterX
%计算像素值
pixelResult = 0;
%遍历模板区域
for k=1:1:maskHeight
for p=1:1:maskWidth
pixelResult = pixelResult +srcImage(i-(maskHeight+1)/2+k,j-(maskWidth+1)/2+p)*maskConValue(k,p);
end
end
%更新像素值,取绝对值
pixelResult = abs(pixelResult);
%判断是否超过了255
if(pixelResult>255)
convImage(i,j) = 255;
else
convImage(i,j) = pixelResult;
end
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%代码--prewitt
%Author:Zhu
%time:2022.3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
image = imread("D:\1.jpg");
image_matrix = image(:,:,1);
image_matrix = double(image_matrix);
[height,width,channels]=size(image);
convPrewittOne=[-1,-1,-1;0,0,0;1,1,1];
convPrewittTwo=[1,0,-1;1,0,-1;1,0,-1];
%调用滤波卷积函数
maskHeight = 3;
maskWidth = 3;
%卷积操作
con_matrix_one = Conv(image_matrix,width,height,maskWidth,maskHeight,convPrewittOne);
con_matrix_two = Conv(image_matrix,width,height,maskWidth,maskHeight,convPrewittTwo);
%求两个卷积操作的最大值
for i=1:height
for j=1:width
if(con_matrix_two(i,j)>con_matrix_one(i,j))
con_matrix_one(i,j)=con_matrix_two(i,j);
end
end
end
%显示图像
image_out = uint8(con_matrix_one);
subplot(1,2,1);
imshow(image);
title("原图");
subplot(1,2,2);
imshow(image_out);
title("prewitt边缘检测");
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Sobel图像边缘检测
%Author:Zhu
%时间:2022.6
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
image = imread("D:\1.jpg");
image_matrix=image(:,:,1);
image_matrix=double(image_matrix);
[height,width,channels]=size(image);
xConv = [-1,-2,-1;0,0,0;1,2,1];
yConv = [1,0,-1;2,0,-2;1,0,-1];
%调用滤波卷积函数
maskHeight = 3;
maskWidth = 3;
con_matrix_one = Conv(image_matrix,width,height,maskWidth,maskHeight,xConv);
con_matrix_two = Conv(image_matrix,width,height,maskWidth,maskHeight,yConv);
%求两幅图像的最大值
for i=1:height
for j=1:width
if(con_matrix_two(i,j)>con_matrix_one(i,j))
con_matrix_one(i,j)=con_matrix_two(i,j);
end
end
end
%显示图
image_out = uint8(con_matrix_one);
subplot(1,2,1);
imshow(image);
subplot(1,2,2);
imshow(image_out);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Laplace图像边缘检测
%Author:Zhu
%时间:2022.6
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
image = imread("D:\1.jpg");
image_matrix=image(:,:,1);
image_matrix=double(image_matrix);
[height,width,channels]=size(image);
image_out = zeros(height,width);
for i=2:height-1
for j=2:width-1
%更新当前像素
image_out(i,j)=image_matrix(i+1,j)+image_matrix(i-1,j)+image_matrix(i,j+1)+image_matrix(i,j-1)-4*image_matrix(i,j);
end
end
%显示图像
image_out = uint8(image_out);
subplot(1,2,1);
imshow(image);
subplot(1,2,2);
imshow(image_out);
*prewitt
prewitt_amp (Image, ImageEdgeAmp)
*边缘抽取
sobel_amp (Image, EdgeAmplitude, 'sum_abs', 3)
*laplace
laplace (Image, ImageLaplace, 'absolute', 3, 'n_4')
Matlab Prewitt效果
Halcon Prewitt效果
Matlab Sobel效果
Halcon Sobel效果
Matlab Laplace效果