Canny边缘算法
边缘检测的核心思想就是因为一幅图像的边缘往往是灰度值剧烈变化的地方,通过确定这些地方来确定边缘。
第一步:去噪
理所当然的,除了边缘会产生灰度值剧变,出现噪声的地方同样会发生灰度值剧烈变化。我们往往采用高斯滤波来处理噪声,使得图像更平滑。
第二步:求导求梯度
通过求导来表示灰度值的变化程度,应该是一个很理所当然的想法。因为图像中的坐标是离散的,所以对于图像的求导是通过求差分。求导的选择有很多,例如经典的Sobel,Laplacian。
我们仅仅使用Sobel,Laplacian一样能够检测出边缘,各有优缺点。需要根据各自的特点来选择。
Sobel之后的边缘会变粗,或者说边缘扩大了一圈
而Laplacian因为是一个二阶导数算子,在边缘处会产生双边缘响应。
上面的是原理,下面是一张实验图
显而易见的在边缘处产生了双边缘,所以只能通过零交叉点(在逻辑上来说本例的零交叉点就是105.5)来粗略的确认边缘位置,不过这都是很微观的操作,尽管不是十分精确,对于肉眼来说其实完全没有区别。
而Canny算法应该是Sobel的一种加强版。他的求导使用Sobel掩模。
第三步:非极大值抑制
这一步就是Canny算法的优化了,书上说的简直不是人话。我们在第二步的时候会产生2个矩阵。一个是导数矩阵记录对应位置上该像素点的导数,一个是梯度矩阵记录对应位置上该像素点的梯度方向。梯度方向会近似为0°,45°,90°,135°0°,45°,90°,135°0°,45°,90°,135°这4个方向
如果梯度方向近似为45°45°45°那么就会比较3-5-7,如果5在不是这3个中的极大值则灰度值设为0,这就是非极大值抑制。非极大值抑制应该是为了边缘瘦身,因为Sobel会让边缘变粗。
而如果追求精度的话,则需要用到线性插值来估计**gn**灰度值后,再进行比较。
第四步:阈值处理
设置2个阈值maxVal和minVal
如果梯度值>>>maxVal那么这个点被确定为边缘点&#xff0c;如果梯度值<<<minVal那么这个点就被认为不是边缘。如果
minVal<<<梯度值<<<maxVal&#xff0c;那么这个点就需要进行确认。同样的按照上面的9宫格&#xff0c;在5周围的8邻域如果存在一个超过了maxVal&#xff0c;那么就认为该点与边缘相关&#xff0c;标记为边缘点。如果8邻域内没有一个超过maxVal&#xff0c;那么该点就被舍弃了。最后剩下的结果就是边缘了。