Canny边缘检测算法
一、边缘检测的步骤
1)滤波: 边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,
因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波、均值滤波等。
2)增强: 增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域
强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定。一般用sobel算子
3)检测: 经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些
点并不是我们要找的边缘点,所以应该采用某种方法来对这些点进行取舍。实际工程中,常用
的方法是通过阈值化方法来检测。细化边缘(找到真正的边缘)
二、最优边缘定义
三、Canny边缘检测算法步骤
1. 对图像进行灰度化
2. 对图像进行高斯滤波
3. 计算梯度幅值和方向(如使用Prewitt,Sobel算子等)
4 对梯度幅值进行非极大值抑制
5 用双阈值算法检测和连接边缘
1、 对图像进行灰度化:
2、 对图像进行高斯滤波:
1、高斯平滑
进行高斯滤波之前,需要先得到一个高斯滤波器(kernel)。如何得到一个高斯滤波器?其实就是将高斯函数离散化,将滤波器中对应的横纵坐标索引代入高斯函数,即可得到对应的值。不同尺寸的滤波器,得到的值也不同,下面是 (2k+1)x(2k+1) 滤波器的计算公式 :

5×5的卷积核 k=2
3.计算梯度幅值和方向(如使用Prewitt,Sobel算子等)
4、根据梯度方向角对梯度幅值进行非极大值抑制
非极大值抑制(Non-Maximum Suppression,NMS): 顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。
理解: 保留局部最大值,抑制非局部最大值的所有值
1、Canny中的非极大值抑制
重点:Canny中的非极大值抑制是沿着梯度方向对幅值进行非极大值抑制,而非边缘方向。
思想:
1)、计算当前点的梯度方向,并在梯度方向连线与邻域交点进行插值(使用梯度值插值而非像素值),获得dTmp1,和dTmp2
其中,dTmp1用g1与g2进行插值,dTmp2用g8与g9进行插值,即使用与交点相邻的两个像素点的 梯度值 进行插值。其中,g1、g2、…、g9表示该点的梯度强度,是梯度幅值。
其他三种情况同理,根据 梯度方向 的不同选择不同点的梯度值进行插值

单线性插值原理如下:
单线性插值化简可得: y =(y1-y0) * [(x-x0)/(x1-x0)] + x0
2) 将当前像素的梯度强度与沿正负梯度方向上的两个梯度插值点dTm1和dTm2进行比较。
3) 如果当前像素的梯度强度与dTm1和dTm2的梯度强度相比是最大的,则该像素点的梯度值保留,作为边缘点,否则该像素点的的梯度值将被抑制(的梯度值置为0)。这样可以抑制非极大值,保留局部梯度最大的点的的梯度值,以得到细化的边缘。

5、用双阈值算法检测和连接边缘
还要进行双阈值处理的原因:
完成非极大值抑制后,会得到一个以梯度局部极小值构成的图像,在图像上显示的就是有许多离散的点点,因此要把真正是边缘的点连接起来,同时去除孤立的噪声点。
思想:
双阈值检测:
算法步骤:

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/208116.html原文链接:https://javaforall.net
