课程学习——canny边缘算子

Canny边缘检测基本特征如下:
(1) 必须满足两个条件:①能有效地抑制噪声;②必须尽量精确确定边缘的位置。
(2) 根据对信噪比与定位乘积进行测度,得到最优化逼近算子。这就是Canny边缘检测算子。
(3) 类似与Marr(LoG)边缘检测方法,也属于先平滑后求导数的方法。

Canny边缘检测算法步骤:
步骤1:用高斯滤波器平滑处理原图像;
步骤2:用一阶偏导的有限差分进行计算梯度的幅值和方向;
步骤3:对梯度幅值进行非极大值抑制;
步骤4:用双阈值算法检测和连接边缘。

matlab:C语言逻辑实现canny边缘算子。
代码:

clc;
clear all;
%导入原图
data=imread('C:\Users\Barca\Desktop\234.jpg');
%显示原图
figure(1);
imshow(data);
[m,n,r]=size(data);
%图像灰度化
if r>1
    data1=rgb2gray(data);
else
    data1=data;
end
%显示灰度化图
figure(2);
imshow(data1);
%数据转为double格式
data1=double(data1);

%step1.高斯滤波
%生成一个3*3的高斯模板,标准差为0.8
template=fspecial('gaussian',3,0.8);
%模板滤波
img_filt=imfilter(data1,template);

%step2.计算图像的梯度(幅度和方向)
%x方向上的梯度模板
ax=[-1,-1,-1;0,0,0;1,1,1];
%y方向上的梯度模板
ay=[-1,0,1;-1,0,1;-1,0,1];

grad_x=conv2(data1,ax,'same');
grad_y=conv2(data1,ay,'same');
grad=sqrt((grad_x.^2)+(grad_y.^2));
%获取梯度方向弧度
grad_dir=atan2(grad_y,grad_x);
%转换成角度
grad_dir=grad_dir*180/pi;
%for x=2:m-1
%    for y=2:n-1
%        grad_x=0.0;
%        grad_y=0.0;
%        for x1=-1:1
%            for y1=-1:1
%                %获取x方向的梯度图像,使用梯度模板进行二位卷积,结果与原图像大小相同
%                grad_x=grad_x+data1(x+x1,y+y1)*ax(x1+2,y1+2);
%                %获取y方向的梯度图像,使用梯度模板进行二位卷积,结果与原图像大小相同
%                grad_y=grad_y+data1(x+x1,y+y1)*ay(x1+2,y1+2);
%            end
%        end
%        %计算幅度
%        grad(x,y)=(grad_x^2+grad_y^2)^1/2;
%        %计算角度
%        %获取梯度方向弧度
%        grad_dir=atan2(grad_y,grad_x);
%        %转换成角度
%        grad_dir=grad_dir*180/pi;
%    end
%end
figure,imshow(grad);
title('梯度幅值图')
%step3.对梯度幅值进行非极大值抑制
%将角度划分为四个方向:水平(0°)、-45°、垂直(90°)、+45°
for i=1:m
    for j=1:n
        %水平方向
        if((grad_dir(i,j)>=-22.5&&grad_dir(i,j)<=22.5)||(grad_dir(i,j)>=157.5&&grad_dir(i,j)<=180)||(grad_dir(i,j)<=-157.5&&grad_dir(i,j)>=-180))
            grad_dir(i,j)=0;
         %45°方向
        elseif((grad_dir(i,j)>=22.5&&grad_dir(i,j)<67.5)||(grad_dir(i,j)>157.5&&grad_dir(i,j)<=-112.5))
            grad_dir(i,j)=45;
         %垂直方向
        elseif((grad_dir(i,j)>=67.5&&grad_dir(i,j)<112.5)||(grad_dir(i,j)>-112.5&&grad_dir(i,j)<=-67.5))
            grad_dir(i,j)=90;
          %-45°方向
        elseif((grad_dir(i,j)>=112.5&&grad_dir(i,j)<157.5)||(grad_dir(i,j)>-67.5&&grad_dir(i,j)<=-22.5))
            grad_dir(i,j)=-45; 
        end
    end
end
%讨论3*3区域的四个基本边缘方向进行非极大值抑制,获取非极大值抑制图像
nms=zeros(m,n);
for i=2:m-1
    for j=2:n-1
        %水平方向
        if(grad_dir(i,j)==0&&grad(i,j)==max([grad(i,j),grad(i-1,j),grad(i+1,j)]))
            nms(i,j)=grad(i,j);
        %45°方向
        elseif(grad_dir(i,j)==45&&grad(i,j)==max([grad(i,j),grad(i+1,j-1),grad(i-1,j+1)]))
            nms(i,j)=grad(i,j);
        %竖直方向
        elseif(grad_dir(i,j)==90&&grad(i,j)==max([grad(i,j),grad(i,j-1),grad(i,j+1)]))
            nms(i,j)=grad(i,j);
        %-45°方向
        elseif(grad_dir(i,j)==-45&&grad(i,j)==max([grad(i,j),grad(i-1,j-1),grad(i+1,j+1)]))
            nms(i,j)=grad(i,j);
        end
    end
end
%step4.双阈值检测和连接边缘
img_out=zeros(m,n);%定义阈值输出图像
YZ_L=0.1*max(max(nms));%低阈值
YZ_H=0.3*max(max(nms));%高阈值
for i=1:m
    for j=1:n
        %小于低阈值幅值为0
        if(nms(i,j)YZ_H)
            img_out=1;
        %对于介于低阈值与高阈值之间的,使用8连通域来确定
        elseif(nms(i+1,j)

原图:
灰度化图:

canny算子:
课程学习——canny边缘算子_第1张图片

少年不被楼层误,余生不羁尽自由。
加油,加油!

你可能感兴趣的:(自我学习)