赞
踩
本人是参考赛灵思官方文档、正点原子教程和网上相关内容,所有参考、转载会标明出处,希望文章对大家有所帮助,感谢各位!
使用 Vivado HLS 实现一个图像处理的 IP 核,该 IP 核能利用 xfopencv 将 OV5640 摄像头产生的 RGB 彩色图像转换成灰度图像,在 Vivado 中对 IP 核进行验证。因为上海疫情,购买不到LCD屏,最后通过 HDMI 实时显示。
1.Vivado HLS 2019.1
2.xfopencv-2019.1_release.zip
打开 Vivado HLS 2019.1,创建项目 ov5640_rgb2gray。创建好之后,在项目文件夹的根目录下添加一个 src 文件夹。
在 GitHub 上下载 https://github.com/Xilinx/xfopencv
下载之后,解压在 Xilinx 文件下。
如下图所示,打开文件,里面是示例的模板和代码,虽然文件较多,但这是官方固定的代码架构,代码内容不难,可以顺便学习别人的编程风格。
重点:一定要按照这个示例来,否则进行 Synthesis 的时候可能会报错,目前还不清楚原因。
报错的报告如下图所示
下图是本人依照示例编写的该项目代码架构
4.1 xf_headers.h
本人查询了相关的文章,简单的对一些代码进行解释,不一定正确,仅供参考。
#ifndef _XF_HEADERS_H_ #define _XF_HEADERS_H_ /*与C环境相关的头文件*/ #include <stdio.h> #include <stdlib.h> #include <stdint.h> /*与HLS相关的头文件,需要包含HLS的include的path*/ #include "ap_int.h" #include "hls_stream.h" /*针对SDSCC*/ #if __SDSCC__ #undef __ARM_NEON__ #undef __ARM_NEON #include "opencv2/opencv.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #define __ARM_NEON__ #define __ARM_NEON #else //在CSIM中的tb中包含的H文件 #include "opencv2/opencv.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #endif #if __SDSCC__ #include "sds_lib.h" #define TIME_STAMP_INIT unsigned int clock_start, clock_end; clock_start = sds_clock_counter(); #define TIME_STAMP { clock_end = sds_clock_counter(); printf("elapsed time %lu \n", clock_end-clock_start); clock_start = sds_clock_counter(); } #endif /*在CSIM中的tb中包含的H文件*/ #include "common/xf_sw_utils.h" #include "common/xf_axi.h" #endif//_XF_HEADERS_H_
4.2 xf_config_params.h
xf_config_params.h 头文件中的内容似乎可以和 xf_rgb2gray_config.h 合并,但是本人先留下来了。
/* Optimization type */
#define RO 0 // Resource Optimized (8-pixel implementation)
#define NO 1 // Normal Operation (1-pixel implementation)
4.3 xf_rgb2gray_config.h
配置相关参数等的头文件,重要!
#ifndef _XF_RGB2GRAY_CONFIG_H_ #define _XF_RGB2GRAY_CONFIG_H_ /*与HLS相关的头文件,需要包含HLS的include的path*/ #include "hls_stream.h" #include "ap_int.h" /*与xfopencv相关的头文件*/ #include "common/xf_common.h" #include "common/xf_utility.h" #include "common/xf_infra.h" /*与图像处理相关的头文件*/ #include "imgproc/xf_cvt_color.hpp" #include "imgproc/xf_cvt_color_1.hpp" //#include "imgproc/xf_rgb2hsv.hpp" //#include "imgproc/xf_bgr2hsv.hpp" // Has to be set when synthesizing #include "xf_config_params.h" /* config width and height */ #define WIDTH 1024 #define HEIGHT 800 #if NO #define NPC1 XF_NPPC1 #else #define NPC1 XF_NPPC8 #endif /*声明主函数*/ void ov5640_rgb2gray(hls::stream< ap_axiu<24,1,1,1> >& _src,hls::stream< ap_axiu<24,1,1,1> >& _dst,int height,int width); #endif // _XF_RGB2GRAY_CONFIG_H_
4.4 xf_rgb2gray_accel.cpp
cvtcolor_rgb2gray 函数,核心的内置函数,重要!
#include "xf_rgb2gray_config.h"
void cvtcolor_rgb2gray(xf::Mat<XF_8UC3, HEIGHT, WIDTH, NPC1> &imgInput,xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> &imgOutput )
{
xf::rgb2gray<XF_8UC3,XF_8UC1, HEIGHT, WIDTH, NPC1>(imgInput, imgOutput);
}
void cvtcolor_gray2rgb(xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> &imgInput,xf::Mat<XF_8UC3, HEIGHT, WIDTH, NPC1> &imgOutput )
{
xf::gray2rgb<XF_8UC1,XF_8UC3, HEIGHT, WIDTH, NPC1>(imgInput, imgOutput);
}
4.5 ov5640_rgb2gray.cpp
主函数 Top Function,定义变量,调用函数等等。
#include "xf_rgb2gray_config.h" typedef hls::stream< ap_axiu<24,1,1,1> > AXI_STREAM_24; void cvtcolor_rgb2gray(xf::Mat<XF_8UC3, HEIGHT, WIDTH, NPC1> &imgInput,xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> &imgOutput); void cvtcolor_gray2rgb(xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> &imgInput,xf::Mat<XF_8UC3, HEIGHT, WIDTH, NPC1> &imgOutput); void ov5640_rgb2gray(AXI_STREAM_24& _src,AXI_STREAM_24& _dst,int height,int width) { #pragma HLS INTERFACE axis register both port=_src #pragma HLS INTERFACE axis register both port=_dst xf::Mat<XF_8UC3, HEIGHT, WIDTH, NPC1> imgInput1(height,width); xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> imgGray(height,width); xf::Mat<XF_8UC3, HEIGHT, WIDTH, NPC1> imgOutput1(height,width); #pragma HLS stream variable=imgInput1.data dim=1 depth=1 #pragma HLS stream variable=imgGray.data dim=1 depth=1 #pragma HLS stream variable=imgOutput1.data dim=1 depth=1 #pragma HLS dataflow xf::AXIvideo2xfMat(_src, imgInput1); cvtcolor_rgb2gray(imgInput1,imgGray); cvtcolor_gray2rgb(imgGray,imgOutput1); xf::xfMat2AXIvideo(imgOutput1, _dst); }
4.6
在进行综合之前,强烈建议调试和测试。
#include "xf_headers.h" #include "xf_rgb2gray_config.h" int main(int argc, char** argv){ uint16_t img_width; uint16_t img_height; cv::Mat inputimg1, inputimg; cv::Mat error_img0; cv::Mat outputimg,ocv_outputimg; inputimg1 = cv::imread(argv[1], 1); if(!inputimg1.data) { return -1; } cv::cvtColor(inputimg1,inputimg,CV_BGR2RGB); outputimg.create(inputimg.rows, inputimg.cols, CV_8UC1); static xf::Mat<XF_8UC3, HEIGHT, WIDTH, NPC1> imgInput(inputimg.rows,inputimg.cols); static xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> imgOutput(outputimg.rows,outputimg.cols); imgInput.copyTo((unsigned short int*)inputimg.data); #if __SDSCC__ hw_ctr.start(); #endif cvtcolor_rgb2gray(imgInput,imgOutput); #if __SDSCC__ hw_ctr.stop(); uint64_t hw_cycles = hw_ctr.avg_cpu_cycles(); #endif outputimg.data = imgOutput.copyFrom(); //OpenCV reference cv::cvtColor(inputimg,ocv_outputimg,CV_RGB2GRAY,1); cv::imwrite("ocv_out.jpg",ocv_outputimg); cv::imwrite("hls_out.jpg",outputimg); absdiff(outputimg,ocv_outputimg,error_img0); /* ## *************************************************************** ##*/ return 0; }
在Xilinx官方文档ug1233中介绍了相关配置。另外,进行测试的时候,可以在 testbench 中引入库中 example 下 data 文件夹中图片。
Synthesis 设置
Simulation设置
1.C-Sim 结果
在该项目文件目录下可以查看结果
2.Synthesis 成功后,会弹出report ,含有接口等信息。
小问题
Include 后面的引号问题引起重视,中英文下的引号需要注意。
头文件中要声明使用到的函数。
配置的时候粗心,本来2个下划线,写成3个,导致了如下图的error。
Synthesis 过程中产生的问题
cvtcolor_bgr2gray sythesis issue
参考了GitHub上的文章解决了。
参考该链接解决下图所示error https://github.com/Xilinx/xfopencv/issues/82
待解决的警告:
希望有解决方案的大佬评论留言,感激不尽。
D:/Xilinx/xfopencv/include\imgproc/xf_cvt_color.hpp:2171:57: warning: default template arguments for a function template are a C++11 extension [-Wc++11-extensions]
template <int SRC_T, int DST_T, int ROWS, int COLS, int NPC=1>
^ ~
个人理解:之所以用 FPGA 进行图像处理,第一是因为FPGA并行计算和硬件加速的特点可以获得更快的响应。第二是因为有利于减少产品研发时间,快速形成产品,比如车牌识别,目标跟踪等。
Xilinx OpenCV 是一个为 FPGA 高级合成(HLS)优化的模板库,允许以与使用 OpenCV 库相同的方式轻松创建图像处理渠道。
推荐一篇文章,介绍 Xilinx OpenCV ,并且给每段代码进行了解释,值得收藏一看。
Introduction to Xilinx OpenCV
自己不怎么写文章,也有很多不会的地方(如3 和4.2),可能写的不好,欢迎批评、指正和交流。
第二部分 已经更新
https://blog.csdn.net/m0_49474265/article/details/124511504
后续还会更新…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。