基于Vivado HLS的OpenCV开发原理(简单)
*本文是对Xilinx官方教学视频部分内容的提炼和简单整理
原视频地址:http://v.elecfans.com/video/ysp-v2.html
1 HLS视频库与OpenCV
OpenCV是可以直接在ARM架构上运行的计算机视觉库,但是在FPGA上不能直接处理。
在HLS中对OpenCV的开发过程可以看作分成两个部分:输入输出模块(模块A和D)以及处理模块(模块B和C)。其中输入输出部分是软件完成的,将数据转换成AXIvideo格式并将OpenCV的函数转换为相应的HLS可综合的函数,使得算法可综合并用FPGA硬件加速算法。第二步的转换过程AXIvideo2HLS是转成MAT格式(相当于OpenCV的矩阵形式)或Stream格式(数据流的形式)来处理图像数据。流架构的设计优势是性能更高,功耗更低。
前面提到OpenCV代码是不可综合的,原因在于OpenCV的很多函数是采用动态内存分配的;函数运算都是基于浮点数运行的;且其默认图像总是在外部存储器中修改的。而对于FPGA来说,图像是从DDR中导入在内部进行处理的。
HLS视频库(HLS Video Library)是对OpenCV许多函数的替换,使其变成基于FPGA优化处理的替代OpenCV的函数。比如,最基本的就是其运算是定点运算,而不是浮点运算。其部分函数如下:
具体的函数功能在UG902文档中均有介绍。需要注意的是这些视频库函数是在hls命名空间中的,不要忘记声明头文件。
2 HLS视频库C++代码详解
下图为使用HLS视频库函数的具体例子,包括各个环节的对应代码。其中,hls_video.h中的内容都是可综合的,而hls_opencv.h中的内容是不可综合的。
可以看到在上述代码中有很多pragma语句,是对编译器的约束指令。
2.1 #pragma约束详解
//将“input”指定为以“INPUT_STREAM”命名的AXI4 Stream格式 #pragma HLS RESOURCE variable=input core=AXIS metadata="-bus_bundle INPUT_STREAM" //将控制接口分配到AXI4-Lite接口 #pragma HLS RESOURCE variable=return core=AXI_SLAVE metadata="-bus_bundle CONTROL_BUS" //指定“row”(像素行数,即图片宽度尺寸)可通过AXI4-Lite接口进行访问 #pragma HLS RESOURCE variable=rows core=AXI_SLAVE metadata="-bus_bundle CONTROL_BUS" //声明在函数执行过程中“row”参数不会改变 #pragma HLS INTERFACE ap_stable port=rows //启用流媒体数据流优化 #pragma HLS dataflow
2.2 以快速角点算法为例演示HLS数据流的处理特性
下图中的代码不是以数据流的形式编写的,因为以数据流的形式不能直接用std::vector以及cvRectangle等方法,也是不能画矩形框的。
3 延迟处理
src1对快速角点算法检测位置对应矩形框的绘制的数据流,要与算法检测位置的数据流延迟相匹配,这也是#pragma中设置“depth=20000”的理由:
ug902-vivado-high-level-synthesis文档地址: