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)
少年不被楼层误,余生不羁尽自由。
加油,加油!