欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【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('边缘提取');

运行结果
【MATLAB图像融合】[12]canny边缘检测简易版
运行效果感觉有点问题,幅值好像没有被很好抑制,边缘过粗。运行发现错误的话还请斧正,谢谢。