VIVADO HLS 学习之路之图像的resize

**

VIVADO HLS 学习之路之图像的resize

**
算下来接触vivado已经有半年了,学习fpga也满打满一年半了,零零碎碎的的笔记做过一些,但是记下了却没有复习,基本上等于没有。以后的学习尽量多做笔记,就先从HLS开始吧!
在学习HLS之前,最好先把两个文档过一遍UG871、UG902。
然后开始——:1.新建工程
VIVADO HLS 学习之路之图像的resize_第1张图片

2.工程名和工程储存路径,点击继续
VIVADO HLS 学习之路之图像的resize_第2张图片

3.top-fuction和testbench可以暂时先不管,继续
VIVADO HLS 学习之路之图像的resize_第3张图片

4.(1)solution名字就用solution1;
(2)时钟周期就默认10ns;
(3)选择器件,我这里是7010;
VIVADO HLS 学习之路之图像的resize_第4张图片
VIVADO HLS 学习之路之图像的resize_第5张图片

5.进入后主界面123分别是添加程序源文件和头文件、c代码的测试激励文件、solution的附属文件
VIVADO HLS 学习之路之图像的resize_第6张图片
6.在source中添加一个top.cpp的函数文件,代码如下:

#include "top.h"
#define HLS_INTER_LINEAR 1
void my_hls_resize(AXI_STREAM& src_axi, AXI_STREAM& dst_axi, int src_rows, int src_cols,int dst_rows,int dst_cols)
{
#pragma HLS INTERFACE axis port=src_axi
#pragma HLS INTERFACE axis port=dst_axi

#pragma HLS RESOURCE core=AXI_SLAVE variable=src_rows metadata="-bus_bundle CONTROL_BUS"
#pragma HLS RESOURCE core=AXI_SLAVE variable=src_cols metadata="-bus_bundle CONTROL_BUS"

#pragma HLS RESOURCE core=AXI_SLAVE variable=dst_rows metadata="-bus_bundle CONTROL_BUS"
#pragma HLS RESOURCE core=AXI_SLAVE variable=dst_cols metadata="-bus_bundle CONTROL_BUS"

#pragma HLS RESOURCE core=AXI_SLAVE variable=return metadata="-bus_bundle CONTROL_BUS"

#pragma HLS INTERFACE ap_stable port=src_rows
#pragma HLS INTERFACE ap_stable port=src_cols
#pragma HLS INTERFACE ap_stable port=dst_rows
#pragma HLS INTERFACE ap_stable port=dst_cols

        int interpolation;
            SRC_IMAGE       imag_0(src_rows,src_cols);
            DST_IMAGE       imag_1(dst_rows, dst_cols);
            #pragma HLS dataflow
            hls::AXIvideo2Mat(src_axi, imag_0);
            hls::Resize(imag_0,imag_1,interpolation=HLS_INTER_LINEAR );
            hls::Mat2AXIvideo(imag_1, dst_axi);
}
其中:top.h是自定义的头文件,包含一些必要的常数和参数;
HLS_INTER_LINEAR是resize的参数,表示使用双线性内插方法进行运算,还有其他如最邻近插值,三线性内插等算法;
my_hls_resize是top-fuction,是相当于c中的main函数,是主程序入口。其中参数AXI_STREAM& src_axi, AXI_STREAM& dst_axi,表示输入输出图像流使用AXI的STREAM类型接口,int src_rows, int src_cols,int dst_rows,int dst_cols则表示传入的源图像宽高和resize后图像宽高;
pragma HLS INTERFACE axis port=src_axi,#pragma指令,可以轻松实现接口连接。 这些指令将输入和输出流暴露为AXI4流接口。
pragma HLS RESOURCE core=AXI_SLAVE variable=src_rows metadata="-bus_bundle CONTROL_BUS"则是把传入参数src_rows绑定为axi的slave接口;
pragma HLS INTERFACE ap_stable port=src_rows行和列输入被指定为稳定的输入,因为块预计会重复处理相同大小的图像;
pragma HLS dataflow选择数据流模式,可以同时执行各种处理功能,像素从一个块流向另一个块;
SRC_IMAGE和DST_IMAGE是在top.h中定义的Mat类型;
hls::AXIvideo2Mat(src_axi, imag_0);该语句是将输入的AXI视频流转为Mat型数据进行计算;
hls::Resize(imag_0,imag_1,interpolation=HLS_INTER_LINEAR );调用HLS自带的resize函数对输入图像进行放缩,输入imag_0,输出imag_1,使用双线性插值算法;
hls::Mat2AXIvideo(imag_1, dst_axi);将Mat型数据转为AXI视频流数据输出;
然后添加一个top,h的头文件,代码如下:
#ifndef _TOP_H_
#define _TOP_H_
#include "hls_video.h"
#include "ap_int.h"

#define SRC_WIDTH  512
#define SRC_HEIGHT 512

#define DST_WIDTH  1280
#define DST_HEIGHT 720
//#define INPUT_IMAGE           "lena_gray.jpg"

typedef hls::stream24,1,1,1> >               AXI_STREAM;

typedef hls::Mat     SRC_IMAGE;
typedef hls::Mat     DST_IMAGE;

void my_hls_resize(AXI_STREAM& src_axi, AXI_STREAM& dst_axi, int src_rows, int src_cols,int dst_rows,int dst_cols);

#endif

在top.h中定义IP核输入输出流的位宽和数据类型,使用typedef hls::stream >语句表示IP核接口的数据位宽为24位;
使用Mat类定义操作图像的大小即类型,HLS_8UC3表示8位无符号三通道的数据类型;
然后重新申明顶层函数my_hls_resize;
建立好top.h和top.cpp后,要先进行综合,没有报错之后,就要开始最重要的C仿真了。C仿真的存在是为了验证其代码设计的正确性,在形成RTL的IP核之前,仿真是必要的。
新建一个top_tb.cpp文件在testbench目录下,添加如下代码:
#include "top.h"
#include "hls_opencv.h"
#include "iostream"
#include 

using namespace std;
using namespace cv;

#define INPUT_IMAGE         "lena.bmp"
int main (int argc, char** argv)
{

 IplImage* src = cvLoadImage(INPUT_IMAGE);//,CV_LOAD_IMAGE_ANYCOLOR);

 IplImage*dst= cvCreateImage(cvSize(DST_WIDTH,DST_HEIGHT),src->depth,src->nChannels);

 AXI_STREAM src_axi, dst_axi;

 IplImage2AXIvideo(src, src_axi);

 my_hls_resize(src_axi,dst_axi,SRC_HEIGHT, SRC_WIDTH,DST_HEIGHT, DST_WIDTH);

 AXIvideo2IplImage(dst_axi, dst);

 cvShowImage("src",src);

 cvShowImage( "dst",dst);

 cvWaitKey(0);
定义测试的输入图像lena.bmp:#define INPUT_IMAGE         "lena.bmp";
使用载入图像函数cvLoadImage载入测试图像,在此之前,要将lena.bmp这个bmp图片放到testbench目录下。仿真文件流程是:使用IplImage函数定义输入输出图像,定义AXI_STREAM数据流接口,然后将图片数据输入转为流数据,调用top-fuction执行主体代码,最后将结果再次转换成图片,然后显示保存。
仿真结果图:

VIVADO HLS 学习之路之图像的resize_第7张图片
VIVADO HLS 学习之路之图像的resize_第8张图片
这是第一次做HLS的图像处理,不得不说,效率比使用Verilog代码编写快得多,
但是相对来说资源也消耗得更多。C仿真通过之后就是封装成RTL的IP核,然后添加到工程中去。我在这个工程中,成功实现了将OV7725摄像头640*480的像素分辨率resize到1280*720,说实话,效果还是不错的。

你可能感兴趣的:(VIVADO HLS 学习之路之图像的resize)