赞
踩
本人是参考赛灵思官方文档核例程、网上相关教程和内容,所有参考、转载会标明出处,希望文章对大家有所帮助,感谢各位!
创建项目、添加示例代码和Project Settings等操作请参考本人其他文章,链接:https://blog.csdn.net/m0_49474265/article/details/123759085
使用到AXI,需要修改 xf_headers.h 和 xf_config_params.h 文件,可参考下载的xfopencv库里的HLS_Use_Model,或者参考本人的文章,链接:https://blog.csdn.net/m0_49474265/article/details/124106562
使用 Vivado HLS 实现一个图像处理的 IP 核,该 IP 核能利用 xfopencv 将 OV5640 摄像头产生的 RGB 彩色图像转换成灰度图像,进一步利用大津法实现二值化图像,并在 Vivado 中对 IP 核进行验证,最后通过 HDMI 实时显示。
在第一部分已经完成仿真的部分,第二部分主要完成HLS综合、IP核的导出与验证。自己在实验的过程中,在文章下面 Part 2 想使用threshold 函数调用 otsuthreshold 函数生成的阈值进行二值化,虽然仿真验证通过,但是IP核验证并未成功,目前正在找原因。Part 1 为直接利用threshold 函数进行二值化处理(thresh=104,maxval=245),IP核验证成功。
代码请参考Part 2,删除与 otsuthreshold 相关的文件,并在xf_threshold_config.h 增加了2行宏定义,如下:
#define THRESH 104
#define MAXVAL 245
综合报告如下:
可以另存之前的项目工程,添加IP核等步骤不再赘述。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "xil_types.h" #include "xil_cache.h" #include "xparameters.h" #include "xaxivdma.h" #include "xaxivdma_i.h" #include "display_ctrl_hdmi/display_ctrl.h" #include "vdma_api/vdma_api.h" #include "emio_sccb_cfg/emio_sccb_cfg.h" #include "ov5640/ov5640_init.h" #include "xotsuthreshold_ip_accel.h"//****需要修改 by Du****改成IP核的名字 //宏定义 #define DYNCLK_BASEADDR XPAR_AXI_DYNCLK_0_BASEADDR //动态时钟基地址 #define VDMA_ID XPAR_AXIVDMA_0_DEVICE_ID //VDMA器件ID #define DISP_VTC_ID XPAR_VTC_0_DEVICE_ID //VTC器件ID //全局变量 //frame buffer的起始地址 unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x1000000); XAxiVdma vdma; DisplayCtrl dispCtrl; VideoMode vd_mode; XOtsuthreshold_ip_accel otsuthreshold_ip_accel_inst;//***需要修改 by Du**** int main(void) { u32 status; u16 cmos_h_pixel; //ov5640 DVP 输出水平像素点数 u16 cmos_v_pixel; //ov5640 DVP 输出垂直像素点数 u16 total_h_pixel; //ov5640 水平总像素大小 u16 total_v_pixel; //ov5640 垂直总像素大小 cmos_h_pixel = 1280; //设置OV5640输出分辨率为1280*720 cmos_v_pixel = 720; total_h_pixel = 2570; total_v_pixel = 980; emio_init(); //初始化EMIO status = ov5640_init( cmos_h_pixel, //初始化ov5640 cmos_v_pixel, total_h_pixel, total_v_pixel); if(status == 0) xil_printf("OV5640 detected successful!\r\n"); else xil_printf("OV5640 detected failed!\r\n"); vd_mode = VMODE_1280x720; // XOtsuthreshold_ip_accel_Initialize(&otsuthreshold_ip_accel_inst, XPAR_XOTSUTHRESHOLD_IP_ACCEL_0_DEVICE_ID);//****需要修改 by Du****ip核名称改大写 //配置的行数 XOtsuthreshold_ip_accel_Set_height(&otsuthreshold_ip_accel_inst, vd_mode.height); //配置的列数 XOtsuthreshold_ip_accel_Set_width(&otsuthreshold_ip_accel_inst, vd_mode.width); //配置VDMA run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height, frame_buffer_addr,0,0,BOTH); //初始化Display controller DisplayInitialize(&dispCtrl, DISP_VTC_ID, DYNCLK_BASEADDR); //设置VideoMode DisplaySetMode(&dispCtrl, &vd_mode); DisplayStart(&dispCtrl); return 0; }
threshold
otsuthreshold_ip_accel 代码如下:
#include "xf_threshold_config.h" #include "xf_otsuthreshold_config.h" #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 otsuthreshold_accel(xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPPC> &imgInput, unsigned char &Otsuval); void threshold_accel(xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPIX> &_src,xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPIX> &_dst,unsigned char thresh,unsigned char maxval); void otsuthreshold_ip_accel(hls::stream< ap_axiu<24,1,1,1> >& _src,hls::stream< ap_axiu<24,1,1,1> >& _dst,int height,int width,uint8_t maxval) { #pragma HLS INTERFACE axis register both port=_src #pragma HLS INTERFACE axis register both port=_dst #pragma HLS INTERFACE s_axilite port=height #pragma HLS INTERFACE s_axilite port=width #pragma HLS INTERFACE s_axilite port=maxval #pragma HLS INTERFACE ap_ctrl_none port=return uint8_t Otsuval; xf::Mat<XF_8UC3, HEIGHT, WIDTH, NPC1> imgInput1(height,width); xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> imgGrayIn(height,width); xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> imgGrayOut(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=imgGrayIn.data dim=1 depth=1 #pragma HLS stream variable=imgGrayOut.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,imgGrayIn); otsuthreshold_accel(imgGrayIn,Otsuval); threshold_accel(imgGrayIn,imgGrayOut,Otsuval,MAXVAL); cvtcolor_gray2rgb(imgGrayOut,imgOutput1); xf::xfMat2AXIvideo(imgOutput1, _dst); }
xf_config_params.h 代码如下:
/* set the optimisation type*/
#define NO 1 // Normal Operation
#define RO 0 // Resource Optimized
/* set the type of thresholding*/
#define THRESH_TYPE XF_THRESHOLD_TYPE_BINARY
//added parts by du
// Set Conversion type
#define RGB2GRAY 0
#define GRAY2RGB 0
xf_headers.h 代码如下:
#ifndef _XF_HEADERS_H_ #define _XF_HEADERS_H_ #include <stdio.h> #include <stdlib.h> //added parts by du #include <stdint.h> #include "ap_int.h" #include "hls_stream.h" #if __SDSCC__ #undef __ARM_NEON__ #undef __ARM_NEON #include "opencv2/opencv.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #define __ARM_NEON__ #define __ARM_NEON #else #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 #include "common/xf_sw_utils.h" //added parts by du #include "common/xf_axi.h" #endif//_XF_HEADERS_H_
xf_threshold_config.h 代码如下:
#ifndef _XF_THRESHOLD_CONFIG_H_ #define _XF_THRESHOLD_CONFIG_H_ #include "hls_stream.h" #include "ap_int.h" #include "common/xf_common.h" #include "common/xf_utility.h" #include "imgproc/xf_threshold.hpp" #include "xf_config_params.h" typedef ap_uint<8> ap_uint8_t; typedef ap_uint<64> ap_uint64_t; //modified part by du //config width and height #define WIDTH 1024 #define HEIGHT 800 #define MAXVAL 200 #if RO #define NPIX XF_NPPC8 #endif #if NO #define NPIX XF_NPPC1 #endif void threshold_accel(xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPIX> &_src,xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPIX> &_dst,unsigned char thresh,unsigned char maxval); #endif // end of _XF_THRESHOLD_CONFIG_H_
xf_otsuthreshold_config.h 代码如下:
#ifndef _XF_OTSUTHRESHOLD_CONFIG_H_ #define _XF_OTSUTHRESHOLD_CONFIG_H_ #include "ap_int.h" #include "hls_stream.h" #include "common/xf_common.h" #include "common/xf_utility.h" #include "common/xf_infra.h"//added part by du #include "imgproc/xf_otsuthreshold.hpp" #include "xf_config_params.h" typedef unsigned int uint32_t; typedef unsigned short uint16_t; //added part by du typedef unsigned char uint8_t;//Unsigned char means unsigned, representing a range of 0~255(0~2^8-1) //modified part by du //config width and height #define WIDTH 1024 #define HEIGHT 800 #if NO #define NPPC XF_NPPC1 #define IN_TYPE ap_uint<8> #define NPC1 0 #endif #if RO #define NPPC XF_NPPC8 #define IN_TYPE ap_uint<64> #define NPC1 3 #endif void otsuthreshold_accel(xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPPC> &imgInput, unsigned char &Otsuval); void otsuthreshold_ip_accel(hls::stream< ap_axiu<24,1,1,1> >& _src,hls::stream< ap_axiu<24,1,1,1> >& _dst,int height,int width,uint8_t maxval); #endif
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 //modified part by du //config width and height #define WIDTH 1024 #define HEIGHT 800 /*xf_config_params.h头文件针对下面的设置*/ #include "xf_config_params.h" #if NO #define NPC1 XF_NPPC1 #else #define NPC1 XF_NPPC8 #endif //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); //modified part by du //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_
其余代码如下:
//xf_otsuthreshold_accel.cpp #include "xf_otsuthreshold_config.h" void otsuthreshold_accel(xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPPC> &imgInput, unsigned char &Otsuval) { xf::OtsuThreshold<XF_8UC1, HEIGHT, WIDTH, NPPC>(imgInput, Otsuval); } //xf_rgb2gray_accel.cpp #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); } //xf_threshold_accel.cpp #include "xf_threshold_config.h" void threshold_accel(xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPIX> &_src,xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPIX> &_dst,unsigned char thresh,unsigned char maxval) { xf::Threshold<THRESH_TYPE,XF_8UC1,HEIGHT, WIDTH,NPIX>(_src, _dst,thresh,maxval); }
综合报告如下:
对于Part 2 出现的问题,可能自己的功力还不够,继续努力…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。