其他分享
首页 > 其他分享> > CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

作者:互联网

一、定义

图像边缘检测 即 寻找图像目标的轮廓

二、图像的梯度与卷积介绍

1、数字图像表示——矩阵
在这里插入图片描述

2、数学中的梯度含义

函数的一维梯度——求导:of(x)/ox
函数的多维梯度——求导:of(x)/ox、of(y)/oy

3、数字图像的梯度近似——差分
在这里插入图片描述

差分近似梯度: Gx=f[i,j+1]-f[i,j] Gy=f[i,j]-f[i+1,j](注意y轴方向是小 - 大)
5的水平梯度转化为差分:4 - 5 = -1
5的垂直梯度转化为差分:5 - 9 = -4

4、梯度的两个性质——大小与方向

记 Gx=of(x)/ox, Gy=of(y)/oy
大小:欧式距离——(Gx2+Gy2)1/2 棋盘距离——|Gx|+|Gy|
方向:arctan(Gy/Gx)

5、图像的卷积

  1. 输入的图像矩阵:
    在这里插入图片描述

  2. 使用的卷积模板:
    在这里插入图片描述

  3. 用卷积模板对5进行卷积,则卷积模板对应的元素为蓝色框
    卷积计算的结果为:0*5+(-1)*4+*9+0*10=5

三、实现算子

一阶差分:Roberts算子、Prewitt算子、Sobel算子
二阶差分:拉普拉斯算子、高斯-拉普拉斯算子(LoG)、Canny算子

四、算子原理介绍

Roberts算子——交叉梯度

  1. 卷积模板(Gx,Gy)
    在这里插入图片描述
    在这里插入图片描述

  2. 检测方向135°和45°

Prewitt算子

  1. 卷积模板(Gx,Gy)
    在这里插入图片描述
    在这里插入图片描述

  2. 检测方向0°和90°

Sobel算子

  1. 卷积模板(Gx,Gy)
    在这里插入图片描述
    在这里插入图片描述

  2. 检测方向0°和90°

拉普拉斯算子——两种模板

  1. 卷积模板(Gx与Gy合并)
    在这里插入图片描述

  2. 梯度幅值——欧式距离 (Gx2+Gy2)1/2
    Gx=f[i,j+1]-f[i,j]+f[i,j-1]-f[i,j]
    Gy=f[i+1,j]-f[i,j]+f[i-1,j]-f[i,j]

  3. 考虑对角线的卷积模板(Gx与Gy合并+两对角线模型)
    在这里插入图片描述
    在这里插入图片描述

  4. 梯度幅值——欧式距离 (Gx2+Gy2)1/2

高斯-拉普拉斯算子(LoG)

拉普拉斯算子高斯函数 处理——如下图
在这里插入图片描述

Canny算子——使用最广泛

1、算法步骤

  1. 高斯平滑
  2. 计算一阶差分Gx与Gy
  3. 计算梯度幅值与方向
  4. 非极大值抑制
  5. 双阈值挑选边缘点

2、如何实现非极大值抑制?

  1. 模块梯度方向分为4个,垂直,水平,正对角线,副对角线
  2. 模块梯度方向离散化
    -22.5~22.5为0
    22.5~67.5 为1
    67.5~112.5 为2
    112.5~157为3
    以此类推
    0代表水平,1代表副对角,2代表垂直,3代表正对角
  3. 梯度方向两边比较
    p大于自身梯度方向两邻点的梯度,则保留,否则去除;

3、如何实现双阈值挑选边缘点?

  1. 设置两个阈值,一个高阈值,一个低阈值
  2. 根据高阈值的边缘点梯度方向,进行边缘连接,找不到点去低阈值找
  3. 从高阈值对应的点到低阈值图像的8领域找,找到就将其选为边缘点

四、基础实验——单独实现每个算子

matlab函数介绍

所使用到的matlab中edge()函数介绍

% roberts算子  
BW = edge(I,'roberts') 
BW = edge(I,'roberts',THRESH)   
BW = edge(I,'roberts',THRESH,DIRECTION) 
BW = edge(I,'roberts',THRESH,DIRECTION,OPTIONS) 
[BW,thresh] = edge(I,'roberts',...) 
THRESH表示梯度幅值大于全局的多少为边缘监测点 
DIRECTION可取'horizontal'、'vertical'、'both'表示45°,135°,以及两者综合   
OPTIONS可取'nothinning'、'thinning'表示不使用边缘细化,使用边缘细化 
[BW,thresh]形式还会返回系统自动选择的阈值

%prewitt算子
BW = edge(I,'prewitt') 
BW = edge(I,'prewitt',THRESH) 
BW = edge(I,'prewitt',THRESH,DIRECTION)
BW = edge(I,'prewitt',THRESH,DIRECTION,OPTIONS) 
[BW,thresh] = edge(I,'prewitt',...) 
DIRECTION可取'horizontal'、'vertical'、'both'表示0°,90°,以及两者综合  

%sobel算子
BW = edge(I,'sobel') 
BW = edge(I,'sobel',THRESH)
BW = edge(I,'sobel',THRESH,DIRECTION)
BW = edge(I,'sobel',THRESH,DIRECTION,OPTIONS)
[BW,thresh] = edge(I,'sobel',...) 
DIRECTION可取'horizontal'、'vertical'、'both'表示0°,90°,以及两者综合  

%LoG算子
BW = edge(I,'log')
BW = edge(I,'log',THRESH)
BW = edge(I,'log',THRESH,SIGMA)
[BW,thresh] = edge(I,'log',...)
SIGMA表示高斯函数所取的标准差

%canny算子
BW = edge(I,'canny')
BW = edge(I,'canny',THRESH)
BW = edge(I,'canny',THRESH,SIGMA)
[BW,thresh] = edge(I,'canny',...) 
SIGMA表示高斯函数所取的标准差

1、 一阶差分算子——三种一阶差分算子的检测差别

  1. 代码
% 1、图片读取与显示
lena=imread('lena.png');
subplot(2,2,1),imshow(lena),title('原图像');
% 2、roberts算子边缘检测
roberts=edge(lena,'roberts');
subplot(2,2,2),imshow(roberts),title('roberts边缘检测');
% 3、prewitt算子边缘检测
prewitt=edge(lena,'prewitt');
subplot(2,2,3),imshow(prewitt),title('prewitt边缘检测');
% 4、sobel算子边缘检测
sobel=edge(lena,'sobel');
subplot(2,2,4),imshow(sobel),title('Sobel边缘检测');
  1. 结果
    在这里插入图片描述
  2. 结论
    ①roberts检测的是图像45°和135°的综合特征,就图像本身的45°和135°的边缘线会更加清晰,但水平和垂直边缘检测效果断断续续。
    ②prewitt检测的是图像0°和90°的综合特征,就图像本身更多的边缘是在水平和垂直方向的,所以得到的边缘检测结果会比roberts稍好一些。
    ③sobel检测的也是图像0°和90°的综合特征,但是相交prewitt加入了中心权重,我们可以看到眼睛的边缘会得到较好的边缘检测,即眼睛中心位置边缘更加突出,这是其他两个算子没有实现的。

2、LoG算子——不同SIGMA下的结果

  1. 代码
% 1、图片读取与显示
lena=imread('lena.png');
subplot(2,2,1),imshow(lena),title('原图像');
% 2、LoG算子边缘检测 方差为1——阈值统一取0.03
LoG_1=edge(lena,'log',0.03,1);
subplot(2,2,2),imshow(LoG_1),title('LoG边缘检测 方差为1');
% 3、LoG算子边缘检测 方差为0.5——阈值统一取0.03
LoG_05=edge(lena,'log',0.03,0.9);
subplot(2,2,3),imshow(LoG_05),title('LoG边缘检测 方差为0.9');
% 4、LoG算子边缘检测 方差为0.1——阈值统一取0.03
LoG_01=edge(lena,'log',0.03,0.8);
subplot(2,2,4),imshow(LoG_01),title('LoG边缘检测 方差为0.8');

  1. 结果
    在这里插入图片描述
  2. 结论
    随着高斯函数方差的越来越小,算子对图像的边缘提出的效果越来越差,提取到的边缘信息越来越模糊

3、Canny算子——不同THRESH下的结果

  1. 代码
% 1、图片读取与显示
lena=imread('lena.png');
subplot(2,2,1),imshow(lena),title('原图像');
% 2、canny算子边缘检测 阈值为0.1
canny_01=edge(lena,'canny',0.1);
subplot(2,2,2),imshow(canny_01),title('canny边缘检测 阈值为0.1');
% 3、canny算子边缘检测 阈值为0.2
canny_02=edge(lena,'canny',0.2);
subplot(2,2,3),imshow(canny_02),title('canny边缘检测 阈值为0.2');
% 4、canny算子边缘检测 阈值为0.3
canny_03=edge(lena,'canny',0.3);
subplot(2,2,4),imshow(canny_03),title('canny边缘检测 阈值为0.3');
  1. 结果
    在这里插入图片描述

  2. 结论
    随着阈值的不断增大,边缘检测出来的点越来越少边缘越来越细致

五、综合实验——高斯抗噪能力

1、五种算子在原图像的检测能力

% 1、图片读取与显示
lena=imread('lena.png');
subplot(3,3,1),imshow(lena),title('原图像');

% 3、roberts算子边缘检测
roberts=edge(lena,'roberts');
subplot(3,3,4),imshow(roberts),title('roberts边缘检测');
% 4、prewitt算子边缘检测
prewitt=edge(lena,'prewitt');
subplot(3,3,5),imshow(prewitt),title('prewitt边缘检测');
% 5、sobel算子边缘检测
sobel=edge(lena,'sobel');
subplot(3,3,6),imshow(sobel),title('Sobel边缘检测');
% 6、LoG算子边缘检测——方差取1,阈值取0.03
LoG=edge(lena,'log',0.03,1);
subplot(3,3,7),imshow(LoG),title('LoG边缘检测');
% 7、canny算子边缘检测——阈值取0.3
canny=edge(lena,'canny',0.3);
subplot(3,3,8),imshow(canny),title('canny边缘检测');

在这里插入图片描述

2、五种算子在加噪声下的检测能力

% 1、图片读取与显示
lena=imread('lena.png');
subplot(3,3,1),imshow(lena),title('原图像');
% 2、对图像添加高斯噪声——方差默认0.2
lena=imnoise(lena,'gaussian',0.2);
subplot(3,3,1),imshow(lena),title('噪声图像');
% 3、roberts算子边缘检测
roberts=edge(lena,'roberts');
subplot(3,3,4),imshow(roberts),title('roberts边缘检测');
% 4、prewitt算子边缘检测
prewitt=edge(lena,'prewitt');
subplot(3,3,5),imshow(prewitt),title('prewitt边缘检测');
% 5、sobel算子边缘检测
sobel=edge(lena,'sobel');
subplot(3,3,6),imshow(sobel),title('Sobel边缘检测');
% 6、LoG算子边缘检测——方差取1,阈值取0.03
LoG=edge(lena,'log',0.03,1);
subplot(3,3,7),imshow(LoG),title('LoG边缘检测');
% 7、canny算子边缘检测——阈值取0.3
canny=edge(lena,'canny',0.3);
subplot(3,3,8),imshow(canny),title('canny边缘检测');

在这里插入图片描述

3、抗噪结论

算子抗噪能力
Roberts对噪声敏感
Prewitt具有一定的抗噪能力
Sobel具有一定的抗噪能力
LoG对噪声敏感
Canny具有很好的抗噪能力

六、实验收获

  1. 一阶差分与二阶差分相比的优势?
    一阶差分计算成本更低,抗噪能力更强

  2. 那为什么提出二阶差分?
    因为一阶差分检测出来的边缘点太多,可以通过第二次求导选择局部最大值为边缘点

  3. 为什么LoG梯度检测算子的处理结果不需要像Prewitt 等算子那样进行幅度组合?
    因为LoG计算的模块元素没有冲突,可以直接整合为一个大的卷积模块

  4. 实验中所使用的五种算子所得到的边缘有什么异同?

算子解释
Roberts边缘定位准,但是对噪声敏感,适用于边缘明显且噪声较少的图像分割,其利用局部差分算子寻找边缘,处理得到的边缘不是很平滑,因为其在边缘处会有较宽的响应。因此,对其作边缘检测处理后,通常需要增加细化处理,进行更为准确的定位;
Prewitt对噪声有抑制作用,抑制噪声的原理是通过像素平均,但是这样会导致边缘定位不够准确;
Sobel对噪声有抑制作用,抑制噪声的原理是通过像素平均,但是这样会导致边缘定位不够准确;另外,该算子认为不同程度距离的像素对当前像素具有不同的影响,而Prewitt算子则未考虑;
LoG使用二阶导数对图像作边缘处理,但因其对噪声敏感,所以通常需要对图像先作降噪处理,处理后得到的边缘平滑且可以降低计算二阶导数引起的噪声影响;
Canny对噪声有抑制作用,抑制噪声的原理是通过对图像进行高斯平滑,并且考虑了多个方向上的梯度计算,通过双阈值进行边缘点的挑选,使边缘更加流畅

标签:lena,LoG,Sobel,检测,边缘,edge,算子,canny
来源: https://blog.csdn.net/Dedication_/article/details/118443236