相关博文:
https://www.cnblogs.com/techyan1990/p/7291771.html
https://www.cnblogs.com/mmmmc/p/10524640.html
https://www.cnblogs.com/sdu20112013/p/11614059.html
https://blog.csdn.net/weixin_40647819/article/details/91411424
https://blog.csdn.net/qq_22222449/article/details/100072824
总结一下, Canny边缘检测算法可分为以下5个步骤:
1) 高斯滤波平滑图像,降低噪声对边缘提取的影响。
2) 利用Sobel算子计算每个像素点的梯度值和方向。
3) 通过非极大值抑制,对边缘稀疏化,在梯度方向上只保留局部梯度值最大的点,缩小边缘宽度。
4) 设定双阈值,检测真实的(强边缘)和潜在的(弱边缘)边缘点,滤除非边缘的点。
5) 抑制孤立的弱边缘点,使边缘更干净;连接非孤立的弱边缘点,使边缘更完整连续。
其中,会用到之前博客中提到的三个FPGA方案。
使用高斯滤波器与图像卷积可以平滑图像,减少噪声对边缘检测的影响。实际应用中,一般使用3×3或5×5大小的高斯算子即可。
设计要点:
1、将高斯算子系数的分子部分近似为2的整次幂,或拆分为若干2的整次幂的和。用移位及加法操作代替乘法运算。
2、将高斯算子系数的分母部分近似为2的整次幂,用移位操作代替除法运算。
3、高斯卷积求和使用并行加法树,提高逻辑时序性能。
在3×3窗口使用Sobel算子可以分别获得某点X和Y方向的梯度向量,然后利用向量求和的思想计算出梯度值和梯度方向。
由于在图像中,3×3 窗口内中心像素点周围的8个像素相对于中心像素点的方向只有水平(0°)、垂直(90°)、对角(45°和135°)4个方向,而且后续非极大值抑制步骤也是将3×3 窗口内某一梯度正负方向的像素点的梯度值进行比较,因此梯度方向也只需要近似到4个方向即可。
设计要点:
1、求梯度值G利用绝对值求和计算代替平方和求根计算,避免乘法运算和开方运算。虽然会引入误差,但对于边缘提取的结果影响较小。
2、梯度方向只近似到0°、45°、90°、135°四个方向,计算时只要将|Gy/Gx|与tan22.5°,tan67.5°进行比较,并结合Gy和Gx的正负即可判断,无需进行求反正切arctan运算。
3、梯度方向只有4个方向,因此模块输出的梯度方向grad angle用2bit的变量表示即可。
在以当前像素为中心的3×3的窗口中,将当前像素的梯度值与其正负梯度方向上的两个像素点的梯度值进行比较。如果当前像素的梯度值与另外两个像素相比最大,则该像素点被保留为边缘,进入后续双阈值检测,否则被排除。
双阈值检测通过设置梯度的高、低阈值,将像素点分为强边缘、弱边缘和非边缘三类。
设计要点:
1、非极大值抑制和双阈值检测在算法中分为前后2个步骤,实际在FPGA中实现可合并到同一个模块,将非极大值抑制的结果立即通过双阈值检测。
3、双阈值检测的高、低阈值需要通过外部输入进行设定。
2、由于经过双阈值检测的边缘点只有强边缘、弱边缘和非边缘三类,因此输出结果edge flag用2bit的变量表示即可。
在以当前弱边缘点为中心的3×3的窗口中,在其周围的8个邻域像素中,若至少存在一个强边缘点,则该弱边缘点就被保留为真实的边缘,否则被当作为非边缘点。
设计要点:
1、输出边缘edge用1bit的变量表示即可。
将其设计成一个参数可配的通用模块,类似于IP核,可考虑实现如下功能。