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

一、定义

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

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

1、数字图像表示——矩阵
CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

2、数学中的梯度含义

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

3、数字图像的梯度近似——差分
CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

差分近似梯度: 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. 输入的图像矩阵:
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

  2. 使用的卷积模板:
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

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

三、实现算子

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

四、算子原理介绍

Roberts算子——交叉梯度

  1. 卷积模板(Gx,Gy)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

  2. 检测方向135°和45°

Prewitt算子

  1. 卷积模板(Gx,Gy)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

  2. 检测方向0°和90°

Sobel算子

  1. 卷积模板(Gx,Gy)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

  2. 检测方向0°和90°

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

  1. 卷积模板(Gx与Gy合并)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

  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合并+两对角线模型)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

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

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

拉普拉斯算子高斯函数 处理——如下图
CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

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. 结果
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)
  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. 结果
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)
  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. 结果
    CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 Canny算子)

  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边缘检测');

CV——图像边缘检测综合实验(Roberts算子 Prewitt算子 Sobel算子 LoG算子 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边缘检测');

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

3、抗噪结论

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

六、实验收获

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

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

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

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

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


下一篇:C#图像处理-OpenCVSharp教程(十七) OpenCVSharp图像边缘检测--Canny、Sobel、Laplacian