使用VIVADO HLS工具封装ORB算法

来源:互联网 发布:营养师配餐软件 编辑:程序博客网 时间:2024/06/07 08:18

        第一篇博文,是个匆忙的开始。原因简单,时间紧,任务重。写下这些,一是记录自己的成长经历,二是和大家分享一些薄见。

HLS这个异类,支持硬件的软件可编程,有很大希望在未来发展壮大。最近赛灵思为了迎合客户,连reVision的开发包都放出来,可以看出这个公司的战略魄力。跟着这种公司,结局不会太差。
        使用vivado HLS已经有半年了,主要完成OPENCV中大多数常用算法和CNN的封装,最近加班不忙的时间慢慢放出。HLS对C++的要求不算太高,主要是对硬件的理解和对算法的理解。由于对OPENCV理解有限,对图像处理也不熟,所以我的工作时间中有一半是用来读懂算法难过。硬件理解,就是大家做过Verilog或者VHDL的或者对数电熟的都没太大问题。
ORB算法是OPENCV3.0版本中,比较成体系的一个算法类,封装时主要考虑封装computeKeyPoints和computeOrbDescriptors算法,在OPENCV3.0版本之前貌似叫detect和Descriptors总之就是叫法略有不同。
第一步我习惯做一个基于OPENCV的黄金模型,因此采用了与官方功能相同的NumKeyPoint函数实现特征点的定位,computeDescribe求得特征点描述字,这两个算法实现可以参考http://blog.csdn.net/bleakie/article/details/53172343?locationNum=14&fps=1。

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.csdn.net/fsfengqingyangheihei/article/details/73571898,欢迎加我QQ交流