使用sobel、prewitt、拉普拉斯算子、差分法提取图像的边缘

参考:
https://www.cnblogs.com/dengdan890730/p/6145585.html
https://blog.csdn.net/touch_dream/article/details/62447801
https://blog.csdn.net/xiahn1a/article/details/42141429
https://blog.csdn.net/swj110119/article/details/51777422

什么是边缘?

边缘一般是指图像中某一局部强度剧烈变化的区域。强度变化一般有2中情况,阶跃效应和屋顶效应。而边缘检测的任务就是找到具有阶跃变化或者屋顶变化的像素点的集合。

阶跃效应

那么什么是阶跃效应?
用图表示就是下图展示的那样,其中坐标轴的横轴表示空间变化,纵轴表示灰度变化,虚线表示边缘。
这里写图片描述

屋顶效应

这里写图片描述

边缘检测的原理

边缘检测基本原理:
既然边缘是灰度变化最剧烈的位置,最直观的想法就是求微分。
(1)对于第一种情况:一阶微分的峰值为边缘点,二阶微分的零点为边缘点。
具体来说,从阶跃效应的那张图可以看到边缘处的斜率(一阶导)最大,所以一阶微分的峰值是边缘点,而斜率是先增大后减小的,即边缘点的二阶导为0处。
(2)对于第二种情况:一阶微分的零点为边缘点,二阶微分的峰值为边缘点。

一阶导与二阶导提取边缘的差别

拉普拉斯提取边缘属于使用二阶导提取边缘,而sobel,prewitt,Roberts,差分法都是属于一阶导数求边缘。那么自然我们要问,一阶导数和二阶导数提取的边缘有什么不同呢?
(1)一阶导数通常会产生较粗的边缘。
(2)二阶导数对精细细节,如细线、孤立点和噪声有较强的响应。
(3)二阶导数在灰度斜坡和灰度台阶过渡处会产生双边沿响应。
(4)二阶导数的符号可以确定边缘的过渡是从亮到暗还是从暗到亮。
(5)二阶导数对细节更敏感。
一般的,提取边缘之前最好先做下图像平滑处理,因为导数对噪声比较敏感。

拉普拉斯算子提取边缘

拉普拉斯提取边缘属于使用二阶导提取边缘,它是一种各向同性的边缘提取算子。各向同性就是指使用这一个算子,就能对任何走向的界线和线条进行锐化,无方向性。而像sobel等,它们在提取x、y方向的边缘都是使用不同的算子来实现的。这拉普拉斯算子区别于其他一阶微分算子的优点。但是它的缺点相比较于一阶微分就是对噪声敏感。它对孤立像素的响应要比对边缘或线的响应要更强烈,因此只适用于无噪声图像。正因为拉普拉斯算子对孤立点和噪声敏感。我们在使用拉普拉斯算子提取边缘之前,先使用高斯平滑图像,这一过程就是Laplacian-Gauss(LOG)算子。它把的高斯平滑滤波器和Laplacian锐化滤波器结合了起来,先平滑掉噪声,再进行边缘检测,所以效果会更好。
它的公式有2种表示形式,如下图,它们都是等价的。(1)这里写图片描述
其对应的矩阵形式如下:
这里写图片描述
————————————————————————————————————
(2)这里写图片描述
其对应的矩阵形式如下:
这里写图片描述
但是需要注意的是,将原图像与拉普拉斯二阶导数求得的图像合并的时候,必须考虑符号上的差别。也就是原图像和拉普拉斯二阶导求出的图像之间到底用加号还是减号,与中心点f(x,y)的系数有关。具体来说,如果中心像素前面的系数是负的,原图像就要减去拉普拉斯二阶导数图像。如果是正的,原图像就要加上拉普拉斯二阶导数图像。
倘若使用了中心系数为正,仍像中心系数为负的那样使用原图减去拉普拉斯算子卷积后的图像,你会发现图像会变得模糊。
此外在平时的使用中还有以下2种扩展形式的拉普拉斯算子。
这里写图片描述

拉普拉斯算子增强图像(matlab代码)

clc;
clear;
close all;

% img = imread('images/lena_gray.jpg');
img = imread('images/lena.jpg');
img =im2double(img);
% 拉普拉斯算子形式1
% lapla =[0,-1,0;-1,4,-1;0,-1,0];
% 拉普拉斯算子形式2
lapla =[0,1,0;1,-4,1;0,1,0];
img_lapla = imfilter(img,lapla,'replicate','same');
figure;imshow(img_lapla);title('拉普拉斯');
% 使用形式1时要相加
% img_f = img +img_lapla;
% 使用形式2时要相减
img_f = img -img_lapla;
%使用下面的语句会使图像变得模糊而不是增强
%img_f = img +img_lapla;
figure;imshow(img_f);title('增强后');

sobel、prewitt、roberts算子

(1)roberts算子边缘定位准,但是对噪声敏感。适用于边缘明显且噪声较少的图像分割。同所有的一阶导数的算子一样,roberts产生的结果也是一个宽响应。roberts算子形式如下:
这里写图片描述
(2)prewitt算子对噪声有抑制作用,抑制噪声的原理是通过像素平均,但是像素平均相当于对图像的低通滤波,低通滤波会造成高频的信息丢失,从而使图像模糊,无论这种程度或大或小,这种操作后的结果是存在的,所以Prewitt算子对边缘的定位不如Roberts算子。
这里写图片描述
(3)sobel算子是prewitt算子的改进形式,改进之处在于sobel算子认为,邻域的像素对当前像素产生的影响不是等价的,所以距离不同的像素具有不同的权值,对算子结果产生的影响也不同。一般来说,距离越远,产生的影响越小。正因为Sobel算子对于像素的位置的影响做了加权,与Prewitt算子、Roberts算子相比因此效果更好。相比较Prewitt算子,Sobel模板能够较好的抑制(平滑)噪声。 sobel要比prewitt更能准确检测图像边缘。
这里写图片描述

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
% % % 使用各种简单且常用的算子来进行边缘检测,需要明白的是
% % % 这些方法提取的都是粗略的边缘,还需要后处理,才能得到
% % % 更加准确的边缘。
% % % 
% % % 拉普拉兹算子是2阶微分算子,也就是说,相当于求取2次微分,
% % % 它的精度还算比较高,但对噪声过于敏感(有噪声的情况下效果很差)是它的重大缺点,
% % % 所以这种算子并不是特别常用.sobel算子是最常用的算子之一(它是一种一阶算子),
% % % 方法简单效果也不错,但提取出的边缘比较粗,要进行细化处理。
% % % 
% % % Sobel算子是在Prewitt算子的基础上改进的,在中心系数上使用一个权值2,
% % % 相比较Prewitt算子,Sobel模板能够较好的平滑噪声。 
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
clc;
clear;
close all;

img = imread('images/lena.jpg');
img = im2double(img);
[height,width,ch] = size(img);
% if ch ==3
%     img = rgb2gray(img);
% end
%% 使用拉普拉斯算子提取边缘
lapla = [0,1,0;1,-4,1;0,1,0];
img_log = imfilter(img,lapla,'replicate','same');
figure;imshow(img_log);title('拉普拉斯');
%% 使用sobel算子
hx = fspecial('sobel');
imgx = imfilter(img,hx,'replicate','same');
hy = hx';
imgy = imfilter(img,hy,'replicate','same');
imgxy = sqrt(imgx.^2+imgy.^2);
figure;imshow(imgxy,[]);title('sobel提取边缘');
%% 使用prewitt算子
hx = fspecial('prewitt');
imgx = imfilter(img,hx,'replicate');
hy = hx';
imgy = imfilter(img,hy,'replicate');
imgxy = sqrt(imgx.^2+imgy.^2);
figure;imshow(imgxy,[]);title('prewitt算子提取边缘');
%% 使用差分
Ix = [diff(img,1,1);img(1,:,:)-img(end,:,:)];
Iy = [diff(img,1,2),img(:,1,:)-img(:,end,:)];
imgxy = sqrt(Ix.^2 + Iy.^2);
figure;imshow(imgxy,[]);title('差分法求边缘');

猜你喜欢

转载自blog.csdn.net/chaolei3/article/details/79809703