使用VIVADO HLS工具封装ORB算法
第一篇博文,是个匆忙的开始。原因简单,时间紧,任务重。写下这些,一是记录自己的成长经历,二是和大家分享一些薄见。
1 . ORB的算法原理及分析
ORB特征是将FAST特征点的检测方法与BRIEF特征描述子结合起来,并在它们原来的基础上做了改进与优化。
该算法的旋转不变性、特征点和特征描述字等概念自行百度。
这里主要提供封装思路:
a、对不了解的算法,算法的每一步都要用F10单步一遍,这是最起码的。
b、第一个坑是选择黄金模型,想要与时俱进就选OPENCV3.0及以上的ORB源码做参考,这个看个人。然后选择需要用来加速的函数。并不是所有函数都适合用硬件加速。
c、第二个坑算是NumKeyPoint和computeDescribe的接口,HLS官方用的AXISTREAM这个类型来作为数据接口,好处是和AXI4总线控制线对应,不好的地方是封装太死板,不如用指针或者自己封装的类型灵活。我见过这两方式,其实是都可以实现的。推荐采用官方的模式,毕竟示例比较多。
d、第三个坑就是定义接口的时候,要声明一个结构体hls_KeyPoint对应原算法中的std::vector<KeyPoint>,里面的元素边写算法边加,主要是hls::Point_<float> pt;
e、第四个坑总算开始到函数内部了,就是图像金字塔。。。在HLS提供的hls_opencv库中(去VIVADO安装目录里找)提供了pyrdown,纠结半天发现没啥用,参考意义都没有。然而直接声明一个数组来代替,存储空间又不够。因此要祭出大杀器-----“stream”流处理的思想。就是把问题从代表空间域的数据,转为处理代表时间域的“流数据”,这也是UG902里自己研究出来的。把金字塔拆成8个层图像,每一层分别做NumKeyPoint和computeDescribe。这里剧透的够多了,再说就没有意思了。
f、然后就是getValue,getScale,ICAngles,HarrisResponses,fast,resize,copyMakeBorder,retainBest,GaussianBlur等函数的依次封装。幸运的是,fast,resize,GaussianBlur三个算法HLS已经封装好了,然而仍需要进去遍历一遍,应该学习一下官方的经典写法,尤其是fast中对stream数据的处理,有助于封装ICAngles,HarrisResponses,copyMakeBorder这种输入输出为图像的函数。
g、match函数就不转了,直接调用,结果如下图。查原始数据可知,还是hls::resize这个函数的精度太菜,后面自己再做一个吧
结语:做算法和编程,最好就是从简单开始,一步一步来,再有个好领导,给你时间和空间。这两条件恰好我都具备了,感谢领导。然后小伙伴们并不孤独,有个兄弟在这个过程一直和我讨论,给我建议,并且他用别的思路也实现了ORB,恭喜他。这里是他的博客~http://blog.****.net/fsfengqingyangheihei/article/details/73571898,欢迎加我QQ交流