c++gdal如何在大图像中截取小图像并获取其图像信息_【图像处理】OpenCV系列十 --- 边缘检测之Canny算子...

上一篇我们学习了图像处理形态学相关知识点,相信大家学习之后已经对形态学有了足够的理解了,那么接下来,我们一起来学习一下图像处理中的边缘检测吧!我们将会重点学习边缘检测各种算子和滤波器 --- Canny算子,Sobel算子,Laplace算子以及Scharr滤波器,本篇我们将会学习Canny算子的原理与用法!

一、理论

边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点;图像属性中的显著变化通常反映了属性的重要事件和变化。

这些包括

(i)深度上的不连续

(ii)表面方向不连续

(iii)物质属性变化

(iv)场景照明变化

边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。

边缘检测的一般步骤

1)滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波,即采用离散化的高斯函数产生一组归一化的高斯核(具体见“高斯滤波原理及其编程离散化实现方法”一文),然后基于高斯核函数对图像灰度矩阵的每一点进行加权求和;

2)增强:增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定。

3)检测:经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些点并不是我们要找的边缘点,所以应该采用某种方法来对这些点进行取舍。实际工程中,常用的方法是通过阈值化方法来检测。

二、Canny算子

Canny边缘检测算子是John F.Canny于 1986 年开发出来的一个多级边缘检测算法。更为重要的是 Canny 创立了边缘检测计算理论(Computational theory ofedge detection),解释了这项技术是如何工作的。Canny边缘检测算法以Canny的名字命名,被很多人推崇为当今最优的边缘检测的算法。

其中,Canny 的目标是找到一个最优的边缘检测算法,让我们看一下最优边缘检测的三个主要评价标准:

  • 低错误率: 标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报;
  • 高定位性: 标识出的边缘要与图像中的实际边缘尽可能接近;
  • 最小响应: 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

为了满足这些要求 Canny 使用了变分法,这是一种寻找满足特定功能的函数的方法。最优检测使用四个指数函数项的和表示,但是它非常近似于高斯函数的一阶导数。

(一)Canny算子的检测步骤

1.灰度化

把彩色图像变成灰度图像,该部分是按照Canny算法通常处理的图像为灰度图,如果获取的彩色图像,那首先就得进行灰度化。以RGB格式的彩图为例,通常灰度化采用的公式是:

Gray=0.299R+0.587G+0.114B;

2、高斯滤波

对图像高斯滤波,图像高斯滤波的实现可以用两个一维高斯核分别两次加权实现,也就是先一维X方向卷积,得到的结果再一维Y方向卷积。当然也可以直接通过一个二维高斯核一次卷积实现。也就是二维卷积模板,由于水平有限,只说二维卷积模板怎么算。

3d1e58c45d30ae96b8835efb0fd101cd.png

高斯滤波

模板中每一个点的高斯系数可以由上面的公式计算,这样得到的是不是最终的模板呢?答案不是,需要归一化,也即是每一个点的系数要除以所有系数之和,这样才是最终的二维高斯模板。

这个里面有个小知识点,要想计算上面的系数,需要知道高斯函数的标准差σ (sigma),还需要知道选3x3还是5x5的模板,也就是模板要多大,实际应用的时候,这两者是有关系的,根据数理统计的知识,高斯分布的特点就是数值分布在(μ—3σ,μ+3σ)中的概率为0.9974,也就是模板的大小其实就是6σ这么大就OK了,但是6σ可能不是奇数,因为我们一定要保证有核心。所以模板窗口的大小一般采用1+2ceil(3nSigma) ceil是向上取整函数,例如ceil(0.6)=1;

计算得到模板,那就是直接卷积就OK,卷积的意思就是图像中的点附近的模板大小区域乘以高斯模板区域,得到的结果就是该点卷积后的结果。卷积的核心意义就是获取原始图像中像模板特征的性质。

3.计算梯度幅值和方向

图像的边缘可以指向不同方向,因此经典Canny算法用了四个梯度算子来分别计算水平,垂直和对角线方向的梯度。但是通常都不用四个梯度算子来分别计算四个方向。常用的边缘差分算子(如Rober,Prewitt,Sobel)计算水平和垂直方向的差分Gx和Gy。这样就可以如下计算梯度模和方向:

4411aec9ee5e12caea07f73b201d2af1.png

梯度模和方向

梯度角度θ范围从弧度-π到π,然后把它近似到四个方向,分别代表水平,垂直和两个对角线方向(0°,45°,90°,135°)。可以以±iπ/8(i=1,3,5,7)分割,落在每个区域的梯度角给一个特定值,代表四个方向之一。

这里选择Sobel算子计算梯度,相对于其他边缘算子,Sobel算子得出来的边缘粗大明亮。

2d4b17399faf9653eae66b442ae0d926.png

sobel算子

这里选择Sobel算子计算梯度,相对于其他边缘算子,Sobel算子得出来的边缘粗大明亮。

4.非极大值抑制

非极大值抑制是进行边缘检测的一个重要步骤,通俗意义上是指寻找像素点局部最大值。沿着梯度方向,比较它前面和后面的梯度值进行了。

2992153ecff42b5195cf7efd25b06927.png

非极大值抑制

上图中左右图:g1、g2、g3、g4都代表像素点,很明显它们是c的八领域中的4个,左图中c点是我们需要判断的点,蓝色的直线是它的梯度方向,也就是说c要是局部极大值,它的梯度幅值M需要大于直线与g1g2和g2g3的交点,dtmp1和dtmp2处的梯度幅值。但是dtmp1和dtmp2不是整像素,而是亚像素,也就是坐标是浮点的,那怎么求它们的梯度幅值呢?线性插值,例如dtmp1在g1、g2之间,g1、g2的幅值都知道,我们只要知道dtmp1在g1、g2之间的比例,就能得到它的梯度幅值,而比例是可以靠夹角计算出来的,夹角又是梯度的方向。

写个线性插值的公式:设g1的幅值M(g1),g2的幅值M(g2),则dtmp1可以很得到:

M(dtmp1)=wM(g2)+(1-w)M(g1)

其中w=distance(dtmp1,g2)/distance(g1,g2)

distance(g1,g2) 表示两点之间的距离。实际上w是一个比例系数,这个比例系数可以通过梯度方向(幅角的正切和余切)得到。

右边图中的4个直线就是4个不同的情况,情况不同,g1、g2、g3、g4代表c的八领域中的4个坐标会有所差异,但是线性插值的原理都是一致的。

5.双阈值的选取

  • 如果某一像素位置的幅值超过 高 阈值, 该像素被保留为边缘像素。
  • 如果某一像素位置的幅值小于 低 阈值, 该像素被排除。
  • 如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于 高 阈值的像素时被保留。
  • 对于Canny函数的使用,推荐的高低阈值比在2:1到3:1之间。

6、滞后边界跟踪

强边缘点可以认为是真的边缘。弱边缘点则可能是真的边缘,也可能是噪声或颜色变化引起的。为得到精确的结果,后者引起的弱边缘点应该去掉。通常认为真实边缘引起的弱边缘点和强边缘点是连通的,而又噪声引起的弱边缘点则不会。所谓的滞后边界跟踪算法检查一个弱边缘点的8连通领域像素,只要有强边缘点存在,那么这个弱边缘点被认为是真是边缘保留下来。

这个算法搜索所有连通的弱边缘,如果一条连通的弱边缘的任何一个点和强边缘点连通,则保留这条弱边缘,否则抑制这条弱边缘。搜索时可以用广度优先或者深度优先算法。

(二)OpenCV中API函数详解

1、函数原型

void Canny(InputArray image,  OutputArray edges,  double threshold1,  double threshold2,  int apertureSize = 3,  bool L2gradient = false)

2、函数功能

Canny函数利用Canny算法来进行图像的边缘检测。

3、参数详解

  • 第一个参数,InputArray类型的image,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位图像;
  • 第二个参数,OutputArray类型的edges,输出的边缘图,需要和源图片有一样的尺寸和类型;
  • 第三个参数,double类型的threshold1,第一个滞后性阈值;
  • 第四个参数,double类型的threshold2,第二个滞后性阈值;
  • 第五个参数,int类型的apertureSize,表示应用Sobel算子的孔径大小,其有默认值3;
  • 第六个参数,bool类型的L2gradient,一个计算图像梯度幅值的标识,有默认值false。

4、实例

#include using namespace cv;int main(){ //载入原始图  Mat src = imread("lena.png"); if (src.empty()) { printf("image error!"); return -1; } Mat src1 = src.clone(); //显示原始图  imshow("【原始图】Canny边缘检测
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值