Canny算子边缘检测原理以及实现

文章转载于:https://blog.csdn.net/liuzhuomei0911/article/details/51345591

基本原理

  • 须满足条件:抑制噪声;精确定位边缘。
  • 从数学上表达了三个准则[信噪比准则(低错误率)、定位精度准则、单边缘响应准则],并寻找表达式的最佳解。
  • 属于先平滑后求导的方法。

算法基本步骤

1使用高斯滤波平滑图像

f(x,y)G(x,y)fs(x,y)

Guess
  • 用坐标点(x,y)3×3(0,0)中,得到一个权重矩阵,归一化权重矩阵(矩阵中各个点除以权重之和),得到标准的权重矩阵,即高斯模板。
  • 计算高斯模糊。设在一幅图像中的3×3区域内,用各像素点的灰度值乘以对应点的权重。


  • 将得到的9个值求和,就是中心点的高斯模糊值。



    具体过程http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html
  • 卷积过程
    • 简单来说就是使用Guess模板在原始图像中进行移位、相乘、相加的过程。

    2计算梯度的幅值图像,角度图像

    补充:求变化率时,对于一元函数,即求导;对于二元函数,求偏导。

    数字图像处理中,用一阶有限差分近似求取灰度值的梯度值(变化率)
    (即:使差商(Δf/Δx)(f/x)xyxy
    如下图表示了中心点的梯度向量、方位角以及边缘方向。(任一点的边缘与梯度向量正交)



    注意

    • gx,gy,M(x,y)α(x,y)

    Canny

    3对幅值图像进行应用非极大值抑制

    • 首先将角度划分成四个方向范围:水平(0°)45°(90°)+45°区域的四个基本边缘方向进行非极大值抑制。



      做法:若中心点(即:访问点)在沿其方向上邻域的梯度幅值最大,则保留;否则,抑制。

    4双阈值检测和连接边缘

    • 选取高阈值THTL2:13:1TH=0.3/0.2,TL=0.1

    注意:双阈值做法是将候选像素点拼接成轮廓,轮廓的形成时对这些像素运用滞后性阈值。

    算法实现

    Matlab代码
    clear all;
    clc;
    
    I = imread('rice.png');%读图
    % I = rgb2gray(I);%灰度转换
    I = double(I);%转化为双精度
    [H,W] = size(I);%获取图像大小
    
    %%  Step1:使用高斯滤波平滑图像
    
    B = [1 2 1;2 4 2;1 2 1];%高斯滤波系数
    B = 1/16.*B;%高斯滤波模板 方差=0.8
    A = conv2(I,B,'same');%使用高斯模板进行卷积.计算二维卷积,结果与原图像大小相同 
    
    %%  Step2:计算梯度的幅值图像,角度图像.
    
    %Prewitt梯度模板
    dx = [-1 0 1;-1 0 1;-1 0 1];%x方向的梯度模板
    dy = [1 1 1; 0 0 0;-1 -1 -1];%y方向的梯度模板
    gx = conv2(A,dx,'same');%获取x方向的梯度图像.使用梯度模板进行二维卷积,结果与原图像大小相同
    gy = conv2(A,dy,'same');%获取y方向的梯度图像.使用梯度模板进行二维卷积,结果与原图像大小相同
    M = sqrt((gx.^2) + (gy.^2));%获取幅值图像.大小与原图像相等.(.^)表示数组乘方
    a = atan2(gy,gx);%获取弧度,范围:-pi~pi
    a = a*180/pi;%将弧度转换为角度,得到角度图像,与原图像大小相等.
    
    %%  Step3:对幅值图像进行应用非极大值抑制
    
    %首先将角度划分成四个方向范围:水平(0°)、-45°、垂直(90°)、+45°
    for i = 1:H
        for j = 1:W
            if((a(i,j) >= -22.5) && (a(i,j) < 0)||(a(i,j) >= 0) && (a(i,j) < 22.5) || (a(i,j) <= -157.5) && (a(i,j) >= -180)||(a(i,j) >= 157.5)&&(a(i,j) <= 180))
                a(i,j) = 0;
            elseif((a(i,j) >= 22.5) && (a(i,j) < 67.5) || (a(i,j) <= -112.5) && (a(i,j) > -157.5))
                a(i,j) = -45;
            elseif((a(i,j) >= 67.5) && (a(i,j) < 112.5) || (a(i,j) <= -67.5) && (a(i,j) >- 112.5))
                a(i,j) = 90;
            elseif((a(i,j) >= 112.5) && (a(i,j) < 157.5) || (a(i,j) <= -22.5) && (a(i,j) > -67.5))
                a(i,j) = 45;  
            end
        end
    end
    %讨论对3x3区域的四个基本边缘方向进行非极大值抑制.获取非极大值抑制图像
    Nms = zeros(H,W);%定义一个非极大值图像
    for i = 2:H-1
        for j= 2:W-1
            if (a(i,j) == 0 && M(i,j) == max([M(i,j), M(i,j+1), M(i,j-1)]))
                Nms(i,j) = M(i,j);
            elseif (a(i,j) == -45 && M(i,j) == max([M(i,j), M(i+1,j-1), M(i-1,j+1)]))
                Nms(i,j) = M(i,j);
            elseif (a(i,j) == 90 && M(i,j) == max([M(i,j), M(i+1,j), M(i-1,j)]))
                Nms(i,j) = M(i,j);
            elseif (a(i,j) == 45 && M(i,j) == max([M(i,j), M(i+1,j+1), M(i-1,j-1)]))
                Nms(i,j) = M(i,j);
            end;
        end;
    end;
    
    %%  Step4:双阈值检测和连接边缘
    
    DT = zeros(H,W);%定义一个双阈值图像
    TL = 0.1 * max(max(Nms));%低阈值
    TH = 0.3 * max(max(Nms));%高阈值
    for i = 1  : H
        for j = 1 : W
            if (Nms(i, j) < TL)
                DT(i,j) = 0;
            elseif (Nms(i, j) > TH)
                DT(i,j) = 1 ;
            %对TL < Nms(i, j) < TH 使用8连通区域确定
            elseif ( Nms(i+1,j) < TH || Nms(i-1,j) < TH || Nms(i,j+1) < TH || Nms(i,j-1) < TH || Nms(i-1, j-1) < TH || Nms(i-1, j+1) < TH || Nms(i+1, j+1) < TH || Nms(i+1, j-1) < TH)
                DT(i,j) = 1;
            end;
        end;
    end;
    figure, imshow(DT); %最终的边缘检测为二值图像
    


    效果图



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值