基于canny的边缘检测算法:

本文详细介绍了图像处理中一种边缘检测算法的核心步骤,包括图像加载、二级尺度高斯函数生成、梯度求取及图像边界检测等关键环节。通过算法实现,能够准确识别图像中的边缘特征。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

clear all;
close all;
%%%%%%%%%%%%%%载入图像%%%%%%%%%%%%%%
I=imread('rice','BMP');
% I=imnoise(I,'gaussian',0,0.01);
X=double(I);
[Ix,Iy]=size(X);           %图像长宽
%%%%%%%%%%%%%%二级尺度%%%%%%%%%%%%%%   
m=1.0;
delta=2^m;
%%%%%%%%%高斯函数X,Y方向的偏导%%%%%%%
N=20;                     %长度和幅度
A=-1/sqrt(2*pi);
phi_x=zeros(N,N);
phi_y=zeros(N,N);
for i=1:N                 %偏导
    for j=1:N
        x=i-(N+1)/2;
        y=j-(N+1)/2;
        phi_x(i,j)=A*(x/delta^2).*exp(-(x*x+y*y)/(2*delta^2));
        phi_y(i,j)=A*(y/delta^2).*exp(-(x*x+y*y)/(2*delta^2));
    end
end
%%%%%%%%%图象行、列卷积%%%%%%%%%%%%%%
W_x=conv2(X,phi_x,'same');
W_y=conv2(X,phi_y,'same');
%%%%%%%%%%%%求梯度%%%%%%%%%%%%%%%%%%%
Mod_G=zeros(Ix,Iy);
for i2=1:Ix
    for j2=1:Iy
        Mod_G(i2,j2)=sqrt(W_x(i2,j2)*W_x(i2,j2)+W_y(i2,j2)*W_y(i2,j2));
    end
end
M=fix(Mod_G);
%%%%%%%%%%%%求幅角%%%%%%%%%%%%%%%%%%%
Arg=zeros(Ix,Iy);
for i3=1:Ix
    for j3=1:Iy
        angle=atan(W_y(i3,j3)/W_x(i3,j3))*180/pi;      %求反正切
        if ((W_x(i3,j3)>0)&&(W_y(i3,j3)>0))            %第一象限
            angle=angle+0;
        elseif ((W_x(i3,j3)<0)&&(W_y(i3,j3)>0))        %第二象限
            angle=angle+180;
        elseif ((W_x(i3,j3)<0)&&(W_y(i3,j3)<0))        %第三象限
            angle=angle+180;
        elseif ((W_x(i3,j3)>0)&&(W_y(i3,j3)<0))        %第四象限
            angle=angle+360;                       
        elseif (abs(W_y(i3,j3)/W_x(i3,j3))>100000000)  %大值90度
            angle=90;
        elseif (abs(W_y(i3,j3)/W_x(i3,j3))==0)         %零值0度
            angle=0;
        end
        if(angle>180)                                  %幅角限制在0-180                        
            angle=angle-180;
        end
        Arg(i3,j3)=angle;
    end
end
%%%%%%%%%%%%图像边界%%%%%%%%%%%%%%%%%%%%
%沿着梯度方向检测小波变换系数模的局部极大%
%%%%%%%%值点即可得到图像的边缘点%%%%%%%%%
Edge=zeros(Ix,Iy);
for i4=2:(Ix-1)
    for j4=2:(Iy-1)
        if ((Arg(i4,j4)>=0&&Arg(i4,j4)<=22.5))
            if (Mod_G(i4,j4)>Mod_G(i4+1,j4)&&Mod_G(i4,j4)>Mod_G(i4-1,j4))%水平
                Edge(i4,j4)=Mod_G(i4,j4);
            end
        elseif ((Arg(i4,j4)>=(90-22.5)&&Arg(i4,j4)<=(90+22.5)))
            if (Mod_G(i4,j4)>Mod_G(i4,j4+1)&&Mod_G(i4,j4)>Mod_G(i4,j4-1))%45度
                Edge(i4,j4)=Mod_G(i4,j4);
            end
        elseif ((Arg(i4,j4)>=(45-22.5)&&Arg(i4,j4)<=(45+22.5)))
            if (Mod_G(i4,j4)>Mod_G(i4+1,j4+1)&&Mod_G(i4,j4)>Mod_G(i4-1,j4-1))%垂直
                Edge(i4,j4)=Mod_G(i4,j4);
            end
        else  
            if (Mod_G(i4,j4)>Mod_G(i4+1,j4-1)&&Mod_G(i4,j4)>Mod_G(i4-1,j4+1))%135度
                Edge(i4,j4)=Mod_G(i4,j4);
            end
        end
    end
end
MAX_E=max(Edge(:));
if (MAX_E>0)
    Edge=Edge/MAX_E;                           %归一化
end
%%%%%%%%%%%根据直方图获取高低阈值%%%%%%%%%%
count=0;                                       %累计直方图统计可能是边缘点的个数
hist=zeros(1,1024);
for k1=1:Ix
    for k2=1:Iy
        if (Edge(k1,k2)~=0)
            hist(1,M(k1,k2)+1)=hist(1,M(k1,k2)+1)+1;
            count=count+1;
        end
    end
end
for k3=1:1024
    if hist(1,k3)~=0
        nmaxmag=k3;
    end
end
p=0.7;
dot=ceil(p*count);
k4=1;
nedgenb=hist(1,1);
while (k4<(nmaxmag-1)&&(nedgenb<dot))
    k4=k4+1;
    nedgenb=nedgenb+hist(1,k4);
end
k4=k4/1000;
high=k4;                                       %高阈值
low=0.4*high;                                  %低阈值,一般高为低的2.5倍
%%%%%%%%%%%%边缘点判定%%%%%%%%%%%%%%%%%%
for i5=1:Ix
    for j5=1:Iy
        if (Edge(i5,j5)>=high)                 %高于高阈值一定是边缘
            Edge(i5,j5)=1;
        elseif (Edge(i5,j5)<=low)              %低于高阈值一定是边缘
            Edge(i5,j5)=0;
        else                                   %高低阈值之间判断8邻域是否高于阈值否则不是边缘
            if((Edge(i5-1,j5)>high)&&(Edge(i5,j5-1)>high)&&(Edge(i5+1,j5)>=high)&&(Edge(i5,j5+1)>=high)...
                    &&(Edge(i5-1,j5-1)>high)&&(Edge(i5+1,j5-1)>high)&&(Edge(i5-1,j5+1)>high)&&(Edge(i5+1,j5+1)>high))
               Edge(i5,j5)=1;
            else
               Edge(i5,j5)=0;
            end
        end
    end
end
% high=mean2(Edge);
% for i5=1:Ix
%     for j5=1:Iy
%         if (Edge(i5,j5)>high)
%             Edge(i5,j5)=1;
%         else
%             Edge(i5,j5)=0;
%         end
%     end
% end
%%%%%%%%%%%%%%%显示%%%%%%%%%%%%%%%%%%%%
figure(1);imshow(I);title('原图像')
figure(2);imshow(Edge);title('边缘')
% figure(1);subplot(1,2,1);imshow(I);title('原图像加噪')
% subplot(1,2,2);imshow(Edge);title('边缘')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值