【MATLAB图像融合】[12]canny边缘检测简易版
程序员文章站
2024-01-28 08:39:28
...
Canny简介
1、分别计算x,y两个方向的梯度值。
2、由梯度值可以计算出幅值和梯度方向。
3、幅值是梯度的强度,通过梯度方向可以抑制非极大幅值。
4、设置2个阈值。高于高阈值的幅值点,其像素值置为255,低于低阈值的幅值点,该点像素值赋0;而介于两值之间的幅值,检测其是否连通,若连通赋值255,反之赋值0。
5、输出边缘图像。
代码分享
function re=canny(x,min,max)
[m,n]=size(x);
GX=zeros(m,n); GY=zeros(m,n);
w=1/256*[1;4;6;4;1]*[1,4,6,4,1];
gaosi_x=conv2(x,w,'same');
for i=1:m-1
for j=1:n-1
GX(i,j)=(gaosi_x(i,j+1)- gaosi_x(i,j)+gaosi_x(i+1,j+1)- gaosi_x(i+1,j))/2;
GY(i,j)=(gaosi_x(i+1,j)- gaosi_x(i,j)+gaosi_x(i+1,j+1)- gaosi_x(i,j+1))/2;
end
end
for t=1:m %梯度计算
GX(t,n)=GX(t,n-1);GY(t,n)=GY(t,n-1);
end
for t=1:n
GX(m,t)=GX(m-1,t);GY(t,n)=GY(t,n-1);
end
tfuzhi=zeros(m,n);tpos=zeros(m,n);
for i=1:m
for j=1:n
tem1=(GX(i,j))^2+(GY(i,j))^2;
tem2=(GX(i,j))/(GY(i,j));
tfuzhi(i,j)=sqrt(tem1);
tpos(i,j)=atan(abs(tem2));
end
end
pos=zeros(m+2,n+2);fuzhi=zeros(m+2,n+2); %方向和幅值计算
for i=2:m+1
for j=2:n+1
pos(i,j)=tpos(i-1,j-1);
fuzhi(i,j)=tfuzhi(i-1,j-1);
end
end
ffuzhi=zeros(m,n); %幅值抑制
for i=2:m+1
for j=2:n+1
if (0<=pos(i,j))&&(pos(i,j)<(pi/4))
tem3=fuzhi(i+1,j-1);tem4=fuzhi(i-1,j+1);
elseif((pi/4)<=pos(i,j))&&(pos(i,j)<(pi/2))
tem3=fuzhi(i-1,j);tem4=fuzhi(i+1,j);
elseif((pi/2)<=pos(i,j))&&(pos(i,j)<3*(pi/4))
tem3=fuzhi(i-1,j-1);tem4=fuzhi(i+1,j+1);
elseif(3*(pi/4)<=pos(i,j))&&(pos(i,j)<=pi)
tem3=fuzhi(i,j-1);tem4=fuzhi(i,j+1);
end
if (fuzhi(i-1,j-1)>tem3)&&(fuzhi(i-1,j-1)>tem4)
ffuzhi(i-1,j-1)=fuzhi(i,j);
else
ffuzhi(i-1,j-1)=0;
end
end
end
B=zeros(m,n); %连通检测
for i=2:m-1
for j=2:n-1
if ffuzhi(i,j)>=max
B(i,j)=255;
elseif ffuzhi(i,j)<=min
B(i,j)=0;
else
if ffuzhi(i-1,j-1)>max||ffuzhi(i-1,j)>max||ffuzhi(i-1,j+1)>max||ffuzhi(i,j-1)>max...
||ffuzhi(i,j+1)>max||ffuzhi(i+1,j-1)>max||ffuzhi(i+1,j)>max||ffuzhi(i+1,j+1)>max
B(i,j)=255;
end
end
end
end
re=B;
end
clear;close all;clc;
A=imread('lena.jpg');
A=double(A);
B=canny(A,1,6);
subplot 121;imshow(uint8(A));title('源图像');
subplot 122;imshow(uint8(B));title('边缘提取');
运行结果
运行效果感觉有点问题,幅值好像没有被很好抑制,边缘过粗。运行发现错误的话还请斧正,谢谢。