基于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格式(数据流的形式)来处理图像数据。流架构的设计优势是性能更高,功耗更低。

基于Vivado HLS的OpenCV开发原理(简单)

前面提到OpenCV代码是不可综合的,原因在于OpenCV的很多函数是采用动态内存分配的;函数运算都是基于浮点数运行的;且其默认图像总是在外部存储器中修改的。而对于FPGA来说,图像是从DDR中导入在内部进行处理的。

基于Vivado HLS的OpenCV开发原理(简单)

HLS视频库(HLS Video Library)是对OpenCV许多函数的替换,使其变成基于FPGA优化处理的替代OpenCV的函数。比如,最基本的就是其运算是定点运算,而不是浮点运算。其部分函数如下:

基于Vivado HLS的OpenCV开发原理(简单)

具体的函数功能在UG902文档中均有介绍。需要注意的是这些视频库函数是在hls命名空间中的,不要忘记声明头文件。

基于Vivado HLS的OpenCV开发原理(简单)

2 HLS视频库C++代码详解

下图为使用HLS视频库函数的具体例子,包括各个环节的对应代码。其中,hls_video.h中的内容都是可综合的,而hls_opencv.h中的内容是不可综合的。

基于Vivado HLS的OpenCV开发原理(简单)

基于Vivado HLS的OpenCV开发原理(简单)

 可以看到在上述代码中有很多pragma语句,是对编译器的约束指令。

   2.1 #pragma约束详解

基于Vivado HLS的OpenCV开发原理(简单)

//将“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等方法,也是不能画矩形框的。 基于Vivado HLS的OpenCV开发原理(简单)

基于Vivado HLS的OpenCV开发原理(简单)

3 延迟处理

src1对快速角点算法检测位置对应矩形框的绘制的数据流,要与算法检测位置的数据流延迟相匹配,这也是#pragma中设置“depth=20000”的理由:

基于Vivado HLS的OpenCV开发原理(简单)

ug902-vivado-high-level-synthesis文档地址: 

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug902-vivado-high-level-synthesis.pdf

相关推荐