首页 > 编程知识 正文

canny边缘检测算法详解,matlab边缘检测算法

时间:2023-05-03 13:30:10 阅读:12472 作者:1207

请参阅此处(带源代码)以实现Canny算法

边缘的概要可被认为是图像中的一定数量的点亮度发生变化的地方。 边缘检测器大致计算该亮度变化的导数,根据导数的大小确定亮度变化的大小,确定目标和背景。 在经典的边缘检测算法中,Roberts运算符、Prewitt运算符、Sobel运算符属于一阶差分运算符、LoG运算符、Canny运算符属于二阶差分运算符。 一阶差分算子通过求出图像灰度变化曲线的导数,可以强调图像中的对象的边缘,二阶差分算子通过求出图像的灰度变化导数的导数,对图像中灰度变化强的地方变得敏感,可以强调图像的纹理结构Canny算子是经典的一阶算子边缘检测方法的思路,同时继承了二阶LOG算子xfdl平滑滤波的思路,提出了基于独特梯度方向将梯度幅度抑制在极大值以外的核心思路,综合了传统边缘检测的优点,使边缘检测效果得到了新的Canny算子的提出已是上个世纪的事,但已广泛应用于当今数字图像处理,被誉为最好的边缘检测算法之一。

Roberts运算符Roberts运算符是最简单的运算符,是使用局部差分方式查找边缘的运算符。

定义水平坡度:

g_x=f(x1,y 1)-f (x,y ) ) )。

对应的操作员模板:

定义垂直坡度:

g_y=f(x1,y )-f (x,y 1) )。

对应的操作员模板:

从算子模板来看,Roberts算子是一种斜偏差梯度计算方法,梯度的大小表示边缘的强度,梯度的方向与边缘的方向垂直正交。

从图像处理的实际效果来看,22模板计算简单,边缘定位准确,但正因为采用了22模板,所以对于使用关于中心点对称的模板来计算边缘方向并不太有用,不会产生噪声适用于边缘清晰、降噪的图像分割。

以下面的图像为例,根据Roberts运算符的原理创建算法以实现函数myRoberts,并将效果图与matlab所具有的edge(I,‘Roberts’)函数的效果进行比较。

function[bw]=my%Roberts(I,th ) Roberts运算符if(Exist )、(var )|isempty ) th=0.08; 如果%阈值th不存在,则默认阈值为0.08endifndims(I )2 grayI=rgb2gray(I ) I; else grayI=I; 判断是否为%灰度,否则转移到end[m,n]=size(Grayi ); newI=grayI; robertsNum=0; forj=1: m-1 fork=1: n-1 Roberts num=ABS (grayi (j,k )-grayI(j ) j1,k 1 ) ) ABS (grayi ) j1,grayi 电子商务(j,k )=0; endendendbw=im2bw(newi ); 前两个if为了提高函数的通用性,一个是设定了默认的边缘阈值,另一个是与rgb图像输入一致。 重点的Roberts算法的实现原理体现在以下双重for循环中。 扫描图像的像素点,根据上述Roberts算子定义的水平方向和垂直方向的梯度计算大小,并与设定的阈值进行比较。 一般而言,想要输入的阈值th在0~1之间,但灰度图像的像素点由8比特即255灰度来表示,所以在比较时th乘以255,如果该点的梯度大于阈值,则将该点判定为梯度变化大的位置的边缘,为255 最后将灰度图像转换为二值图像。

此函数的效果(默认阈值0.08 )如下:

使用matlab中的函数可以获得以下效果:

Prewitt、Sobel Prewitt和Sobel操作符采用33模板操作符,在33模板中:

定义水平差异:

g_x=(z_7z_8z_9)-(Z_1 Z_2 Z_3) ) ) ) ) ) ) ) )

对应的操作员模板:

定义垂直差异:

g_y=(z_3z_6z_9)-(z_1z_4z_7) ) ) ) ) ) ) )

对应的操作员模板:

定义对角线方向的差分:

g_x=(z_2z_3z_6)-(Z_4 Z_7 Z_8) ) ) ) ) ) ) ) )

g_y=(z_6z_9z_8)-)-(Z_2 Z_1 Z_4) ) ) ) ) ) ) )

Sobel运算符基于Prewitt运算符进行了改进,通过在中心系数中使用权重2,与Prewitt运算符相比,Sobel模板可以更好地抑制(平滑)噪声。

由于采用了3*3模板,Prewitt算子的边缘检测结果在水平方向和垂直方向上都比Robert算子明显。 另一方面,Sobel算子将xfdl平滑和一阶差分相结合,在Prewitt算子中增加了权重的概念。 相邻点的距离越近,被认为对当前像素点的影响越不同,距离越近,对应于当前像素的影响越大,实现图像的锐化和边缘轮廓的强调。

有了运算符模板,算法的实现方式与Roberts运算符一致,只需根据模板定义的梯度表达式进行一点修改即可,在此不多做说明。

日志操作符

p>LoG(Laplacian of Gaussain)算法就是先对图像进行xfdl平滑处理,再进行二阶差分的拉普拉斯算子锐化边缘。
xfdl平滑算子:

二阶拉普拉斯方程:
∇^2 f(x,y)=(∂^2 f)/(∂^2 x)+(∂^2 f)/∂y
写成二维离散形式:
∇^2 f(x,y)=f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)-4f(x,y)
对应的二阶拉普拉斯算子模板:

下边仍以上图为例,根据log算子原理编写算法实现函数myLog,将效果图与matlab自带edge(I,‘log’)函数效果对比:

function [BW] = myLog(I,th)if ~exist('th','var') || isempty(th) th = 0.05;%假如阈值th不存在,默认阈值为0.08endif ndims(I) > 2 grayI = rgb2gray(I);else grayI = I;%判断是否为灰度图,不是则转为endgauss = [1 2 1; 2 4 2;1 2 1] / 16; % Gauss平滑模板grayI = conv2(grayI, gauss, 'same'); % 平滑[m,n]=size(grayI);newI=grayI;LogNum=0;for j=2:m-1 for k=2:n-1 LogNum = abs(4*grayI(j,k)-grayI(j-1,k)-grayI(j+1,k)-grayI(j,k+1)-grayI(j,k-1)); if(LogNum > th*255) newI(j,k)=255; else newI(j,k)=0; end endendBW = im2bw(newI);

与上述算子的算法不同点在于遍历像素点之前做了以xfdl平滑算子与图像卷积实现了xfdl平滑滤波。梯度计算时采用的是二阶拉普拉斯算子。
效果图如下;

matlab自带函数效果图如下:

Canny算子

从表面效果上来讲,Canny算法是对Sobel、Prewitt等算子效果的进一步细化和更加准确的定位,同时借鉴了LoG算子先进行xfdl滤波(噪声平滑)再进行图像梯度计算的思想。
关于Canny算法实现请参考我的这篇博文:
基于matlab的Canny算法实现(附源代码)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。