一 原理及框架
在经过C语言验证后,具体的原理详情请看 FPGA 图像加速处理之 canny 算法——C语言实现,现在可以用RTL代码来实现canny加速。
RTL canny算法框架如下图:
Maxtri3x3 模块: 接受输入的图像数据,并产生3x3的窗口输出;
Sobel 模块: 实现sobel计算,根据sobel算子,求出梯度 及梯度方向;
maxtri3x3_SobelDir 模块: 接受sobel模块输出的数据,并产生3x3的窗口输出;
NonMaxSupp 模块: 实现canny算法中的非极大值抑制算法;
maxtri3x3_NMS 模块:接受经过非极大值抑制后的数据,并产生3X3的窗口输出;
HystThreshold 模块: 实现滞后阀值(双阀值)处理,并输出最终canny图像;
对应的RTL代码ip 架构如下:
资源使用情况
二 最终输出图像及对比
![](https://i-blog.csdnimg.cn/blog_migrate/6b387d41e37b210a8bc4c88d30424c0d.png)
![fpga_canny](https://i-blog.csdnimg.cn/blog_migrate/a08d53ab538698a3adf9beeb9b9b956a.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/4505ebab8c578823cdadc3e8a466c2ea.png)
以上是640x480测试图,在100mhz时钟下,实现canny算法的时间为 3.8ms;因为是以每一个时钟处理一个像素值,所以对于如 200 万的图像,处理时间为21.73600 nm。因此在实际工程中增加时钟频率,或者增加数据位宽,均可以大大提升处理速度。比如用200mhz时钟,每个时钟处理8个像素(64bit),处理200万图像是当前速度的16倍。及时再加上数据进出DDR的读写时间,这样的速度相对来说已经是很快了。
精确度说明:
1、由于在做梯度方向判断时,tan22.5、tan67.5 的值取到小数点后4位。所以高于小数点后4位的精度达不到,具体表现在每一张FPGA输出的图与OpenCV输出的图上,有个别的几个点不一样。
2、OpenCV中,最后对滞后阀值处理使用了迭代方式,由于在这里没有使用迭代(资源及处理时间的考虑,以后根据需要可以把这部分加上),所以仅对于个别从暗到亮的边缘,其前面暗的部分(低于高阀值)的部分会被忽略。
3、去除以上两点的影响后,图像正确率与OpenCV的相比,可以达到100%;
因能力所限,难免有理解不到位之处,欢迎大家批评指正
更多分享,请关注微信公众号:FPGA历险记