图像处理:边缘提取算法(边缘提取算子总结)——Matlab代码实现

边缘提取算子

一阶:  Roberts算子、Sobel算子、Prewitt算子、Kirsch算子、Robinson算子

二阶: Laplacian算子、Canny算子、Marr-Hildreth(LoG算子)

 

Roberts 算子

在(i+1/2,j+1/2)处差分

转化为模板即为

Roberts算子,又称罗伯茨算子,是一种最简单的算子,是一种利用局部差分算子寻找边缘的算子。他采用对角线方向相邻两象素之差近似梯度幅值检测边缘。检测垂直边缘的效果好于斜向边缘,定位精度高,对噪声敏感,无法抑制噪声的影响。

Roberts算子检测方法对具有陡峭的低噪声的图像处理效果较好,但是提取边缘的结果是边缘比较粗,因此边缘的定位不是很准确。

 

Sobel算子

Sobel算法是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值。在图像的任何一点使用此算子,将会产生该点对应的梯度矢量或是其法矢量。

 

Prewitt算子

Prewitt算子是一种一阶微分算子边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用。

其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。

Prewitt算子检测方法对灰度渐变和噪声较多的图像处理效果较好。但边缘较宽,而且间断点多。

对数字图像f(x,y),Prewitt算子的定义如下:

G(i)={[f(i-1,j-1)+f(i-1,j)+f(i-1,j+1)]-[f(i+1,j-1)+f(i+1,j)+f(i+1,j+1)]}

G(j)={[f(i-1,j+1)+f(i,j+1)+f(i+1,j+1)]-[f(i-1,j-1)+f(i,j-1)+f(i+1,j-1)]}

则P(i,j)=max[G(i),G(j)]或 P(i,j)=G(i)+G(j)

 

Kirsch算子

Kirsch算子是R.Kirsch提出来一种边缘检测算法,它采用8个3*3的模板对图像进行卷积,这8个模板代表8个方向,并取最大值作为图像的边缘输出,8个模板如下,它在保持细节和抗噪声方面都有较好的效果。

 

 

Robinson算子

规则同上,也是8个模板。

 

Laplacian算子

Laplacian算子法对噪声比较敏感,所以很少用该算子检测边缘,而是用来判断边缘像素视为与图像的明区还是暗区。

Laplacian 算子是n维欧几里德空间中的一个二阶微分算子,定义为梯度grad的散度div。可使用运算模板来运算这定理定律。

函数的拉普拉斯算子也是该数的黑塞矩阵的迹,可以证明,它具有各向同性,即与坐标轴方向无关,坐标轴旋转后梯度结果不变。

Laplacian 算子对噪声比较敏感,所以图像一般先经过平滑处理,因为平滑处理也是用模板进行的,所以,通常的分割算法都是把Laplacian 算子和平滑算子结合起来生成一个新的模板。

如果邻域系统是4 邻域,Laplacian 算子的模板为:

如果邻域系统是8 邻域,Laplacian 算子的模板为:

 

Canny算子

Canny方法不容易受噪声干扰,能够检测到真正的弱边缘。

优点在于,使用两种不同的阈值分别检测强边缘和弱边缘,并且当弱边缘和强边缘相连时,才将弱边缘包含在输出图像中。

该算子效果较好,但是它实现起来较为麻烦,Canny算子是一个具有滤波,增强,检测的多阶段的优化算子,在进行处理前,Canny算子先利用高斯平滑滤波器来平滑图像以除去噪声,Canny分割算法采用一阶偏导的有限差分来计算梯度幅值和方向,在处理过程中,Canny算子还将经过一个非极大值抑制的过程,最后Canny算子还采用两个阈值来连接边缘。

Canny边缘检测算法

step1: 用高斯滤波器平滑图象;

step2: 用一阶偏导的有限差分来计算梯度的幅值和方向;

step3: 对梯度幅值进行非极大值抑制

step4: 用双阈值算法检测和连接边缘

参考:

https://blog.csdn.net/fengye2two/article/details/79190759

https://blog.csdn.net/jiachen0212/article/details/80078685

https://www.cnblogs.com/zhuifeng-mayi/p/9563947.html

https://www.cnblogs.com/techyan1990/p/7291771.html

 

Marr-HildrethLoG算子

LoG可以看成是一个高斯模板的拉普拉斯变换   Laplace of Gaussian

(图像的高斯拉普拉斯(LoG),可利用差分高斯(DoG)近似)

参考:

好:LOG高斯-拉普拉斯算子 https://blog.csdn.net/touch_dream/article/details/62237018 

DoG算子和LoG算子 https://blog.csdn.net/dreamguard/article/details/83988814

好:LoG算子 https://blog.csdn.net/songzitea/article/details/12851079

LOG边缘检测--Marr-Hildreth边缘检测算法 https://blog.csdn.net/bettyshasha/article/details/51757185  

好:SIFT特征点检测,特征点描述,特征点匹配理解 https://blog.csdn.net/ds0529/article/details/79617619

matlab代码

 

matlab自带edge函数

matlab中edge函数提供了很多算子,函数原型和算子包括:

matlab自带edge函数 使用代码:

clear;clc;

%读取图像
I=imread('Lena512.png');
%I=rgb2gray(I);
figure;imshow(I,[]);title('Original Image');

%sobel----------------------
sobelBW = edge(I,'sobel',0.06);  %可以省去0.06,系统会默认。
figure;imshow(sobelBW,[]);title('Sobel 0.06')

%roberts----------------------
robertsBW=edge(I,'roberts');
figure;imshow(robertsBW);title('Roberts Edge');

%prewitt----------------------
prewittBW=edge(I,'prewitt');
figure;imshow(prewittBW);title('Prewitt Edge');

%Laplacian----------------------
logBW=edge(I,'log');
figure;imshow(logBW);title('Laplasian of Gaussian Edge');

%canny----------------------
cannyBW=edge(I,'canny');
figure;imshow(cannyBW);title('Canny Edge');

%高斯滤波 再 canny ----------------------
h=fspecial('gaussian',5);%高斯滤波
I2=imfilter(I,h,'replicate');
GcannyBW=edge(I2,'canny');%高斯滤波后使用Canny算子进行边缘检测
figure;imshow(GcannyBW);title('Gaussian & Canny Edge');

 

非matlasb自带 :梯度法、roberts算子、prewitt算子、sobel算子、krisch算子、LoG算子

%% 非matlasb自带 :梯度法、roberts算子、prewitt算子、sobel算子、krisch算子、LoG算子
clear;clc;close all
f=imread('Lena512.png');
T=20;%阈值
[m,n]=size(f);
%------梯度法-------
f_g=zeros(m,n);
for i=2:m-1
    for j=2:n-1
        f_g(i,j)=abs(f(i+1,j)-f(i,j))+abs(f(i,j+1)-f(i,j));
        if f_g(i,j)<T
            f_g(i,j)=0;
        else
            f_g(i,j)=255;
        end
    end
end
figure(1);
subplot(2,3,1);imshow(uint8(f_g));title('梯度法');
%------roberts算子-------
f_r=zeros(m,n);
for i=2:m-1
    for j=2:n-1
        f_r(i,j)=abs(f(i+1,j+1)-f(i,j))+abs(f(i,j+1)-f(i+1,j));
        if f_r(i,j)<T
            f_r(i,j)=0;
        else
            f_r(i,j)=255;
        end
    end
end
%f_r=imbinarize(imfilter(f,r),T);
subplot(2,3,2);imshow(uint8(f_r));title('Roberts算子');
 
%------prewitt算子-------
f_p=zeros(m,n);
for i=2:m-1
    for j=2:n-1
        f_p(i,j)=abs(f(i-1,j-1)+f(i,j-1)+f(i+1,j-1)-f(i-1,j+1)-f(i,j+1)-f(i+1,j+1))+abs(f(i+1,j-1)+f(i+1,j)+f(i+1,j+1)-f(i-1,j-1)-f(i-1,j)-f(i-1,j+1));
        if f_p(i,j)<15
            f_p(i,j)=0;
        else
            f_p(i,j)=255;
        end
    end
end
subplot(2,3,3);imshow(uint8(f_p));title('Prewitt算子');
 
%------sobel算子-------
f_s=zeros(m,n);
for i=2:m-1
    for j=2:n-1
        f_s(i,j)=abs(f(i-1,j-1)+2*f(i,j-1)+f(i+1,j-1)-f(i-1,j+1)-2*f(i,j+1)-f(i+1,j+1))+abs(f(i+1,j-1)+2*f(i+1,j)+f(i+1,j+1)-f(i-1,j-1)-2*f(i-1,j)-f(i-1,j+1));
        if f_s(i,j)<T
            f_s(i,j)=0;
        else
            f_s(i,j)=255;
        end
    end
end
subplot(2,3,4);imshow(uint8(f_s));title('Sobel算子');
 
%------krisch算子-------
k(:,:,1)=[-3,-3,-3;
    -3,0,5;
    -3,5,5];
k(:,:,2)=[-3,-3,5;
    -3,0,5;
    -3,-3,5];
k(:,:,3)=[-3,5,5;
    -3,0,5;
    -3,-3,-3];
k(:,:,4)=[-3,-3,-3;
    -3,0,-3;
    5,5,5];
k(:,:,5)=[5,5,5;
    -3,0,-3;
    -3,-3,-3];
k(:,:,6)=[-3,-3,-3;
    5,0,-3;
    5,5,-3];
k(:,:,7)=[5,-3,-3;
    5,0,-3;
    5,-3,-3];
k(:,:,8)=[5,5,-3;
    5,0,-3;
    -3,-3,-3];
kk=zeros(size(f));
I=double(f);
for i=1:8
    f_k(:,:,i)=conv2(I,k(:,:,i),'same');
    kk=max(kk,f_k(:,:,i));
end
f_kk=imbinarize(kk,600);
subplot(2,3,5);imshow(f_kk);title('Krisch算子');
 
%------LoG算子-------
log1=[0 0 -1 0 0;
    0 -1 -2 -1 0;
    -1 -2 16 -2 -1;
    0 -1 -2 -1 0;
    0 0 -1 0 0];
 
f_l=conv2(f,log1,'same');
f_ll=imbinarize(abs(f_l),300);
subplot(2,3,6);imshow(f_ll);title('LoG算子');

 

非matlab自带   Kirsch算子

(参考https://blog.csdn.net/u014485485/article/details/78339420

clear;clc;close all

%读取图像
bw1=imread('Lena512.png');
%bw1=rgb2gray(bw1);
figure;imshow(bw1,[]);title('Original Image');

%均值滤波
bw2=filter2(fspecial('average',3),bw1);
%高斯滤波
bw3=filter2(fspecial('gaussian'),bw2);
%利用小波变换对图象进行降噪处理
[thr,sorh,keepapp]=ddencmp('den','wv',bw3);     %获得除噪的缺省参数
bw4=wdencmp('gbl',bw3,'sym4',2,thr,sorh,keepapp);%图象进行降噪处理

%提取图象边缘
t=[0.8 1.0 1.5 2.0 2.5].*10^5 ;     %设定阈值
bw5=double(bw4);            
[m,n]=size(bw5);             
g=zeros(m,n); 
d=zeros(1,8);
%利用Kirsch算子进行边缘提取
for i=2:m-1
   for j=2:n-1
       d(1) =(5*bw5(i-1,j-1)+5*bw5(i-1,j)+5*bw5(i-1,j+1)-3*bw5(i,j-1)-3*bw5(i,j+1)-3*bw5(i+1,j-1)-3*bw5(i+1,j)-3*bw5(i+1,j+1))^2; 
       d(2) =((-3)*bw5(i-1,j-1)+5*bw5(i-1,j)+5*bw5(i-1,j+1)-3*bw5(i,j-1)+5*bw5(i,j+1)-3*bw5(i+1,j-1)-3*bw5(i+1,j)-3*bw5(i+1,j+1))^2; 
       d(3) =((-3)*bw5(i-1,j-1)-3*bw5(i-1,j)+5*bw5(i-1,j+1)-3*bw5(i,j-1)+5*bw5(i,j+1)-3*bw5(i+1,j-1)-3*bw5(i+1,j)+5*bw5(i+1,j+1))^2; 
       d(4) =((-3)*bw5(i-1,j-1)-3*bw5(i-1,j)-3*bw5(i-1,j+1)-3*bw5(i,j-1)+5*bw5(i,j+1)-3*bw5(i+1,j-1)+5*bw5(i+1,j)+5*bw5(i+1,j+1))^2; 
       d(5) =((-3)*bw5(i-1,j-1)-3*bw5(i-1,j)-3*bw5(i-1,j+1)-3*bw5(i,j-1)-3*bw5(i,j+1)+5*bw5(i+1,j-1)+5*bw5(i+1,j)+5*bw5(i+1,j+1))^2; 
       d(6) =((-3)*bw5(i-1,j-1)-3*bw5(i-1,j)-3*bw5(i-1,j+1)+5*bw5(i,j-1)-3*bw5(i,j+1)+5*bw5(i+1,j-1)+5*bw5(i+1,j)-3*bw5(i+1,j+1))^2; 
       d(7) =(5*bw5(i-1,j-1)-3*bw5(i-1,j)-3*bw5(i-1,j+1)+5*bw5(i,j-1)-3*bw5(i,j+1)+5*bw5(i+1,j-1)-3*bw5(i+1,j)-3*bw5(i+1,j+1))^2; 
       d(8) =(5*bw5(i-1,j-1)+5*bw5(i-1,j)-3*bw5(i-1,j+1)+5*bw5(i,j-1)-3*bw5(i,j+1)-3*bw5(i+1,j-1)-3*bw5(i+1,j)-3*bw5(i+1,j+1))^2;      
       g(i,j) = max(d);
    end
end 

%显示边缘提取后的图象
figure(2)
for k=1:5
    for i=1:m
        for j=1:n
            if g(i,j)>t(k)
                bw5(i,j)=255;           
            else
                bw5(i,j)=0;
            end
        end
    end
    subplot(1,5,k)
    imshow(bw5,[])
    title(['Kirsch' '   ' num2str(t(k))])
end

最后我之前自己写的梯度法:

I=imread('1.jpg');
I=rgb2gray(I);
T=10;%阈值
[x,y]=gradient(double(I));   %获取梯度
t=sqrt(x.^2+y.^2);  
I(t>=T)=255;           %梯度提取边缘 画黑
I(t<T)=0;
I=uint8(I);
imshow(I);

imwrite(I,'my开方梯度.jpg');  %保存图像到当前目录

本人水平有限,难免有错误疏漏,还望大佬多多批评指正。

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页