Bootstrap

FPGA图像处理HLS实现RGB转灰度,提供HLS工程和vivado工程源码

一、图像RGB转灰度原理

图像rgb转灰度图有固定的公式,具体公式csdn一大堆,这里不用多说,而且公式是公理,不需要去理解为什么,也不需要记住,要用时搜一下就行。

二、HLS方案实现

图像rgb转灰度图本身很简单,用verilog代码实现也就十几行代码的事儿,那为啥还要用HLS实现呢?因为简单,可以作为HLS图像处理入门的例程,通过图像rgb转灰度图试验,可以让我们很好的入门HLS的开发,跟着我做一遍后你就会发现HLS其实没想象中的那么复杂;
HLS工程如下:
在这里插入图片描述
头文件如下:

#ifndef _HELAI_RGB2GRAY_H
#define _HELAI_RGB2GRAY_H

#include "hls_video.h"	//包含hls图像处理库头文件

#define INPUT_IMAGE        "lena.jpg"
#define OUTPUT_IMAGE       "lena_gray.jpg"

#define MAX_HEIGHT 1080		//图像最大高度
#define MAX_WIDTH  1920		//图像最大宽度

typedef hls::stream<ap_axiu<24,1,1,1> >  AXI_STREAM;	//定义一个24bit位宽的AXI_STREAM的类
typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC3> RGB_IMAGE;	//定义一个无符号24bit位宽的RGB_IMAGE图像的类
typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC1> GRAY_IMAGE;	//定义一个无符号8bit位宽的灰度图像的类

void helai_rgb2gray(AXI_STREAM&INPUT_STREAM,AXI_STREAM&OUTPUT_STREAM,int rows,int cols);

#endif

源文件的核心代码如下:

	hls::AXIvideo2Mat(INPUT_STREAM,img_0);						//将输入的AXIS视频数据转换为Mat,结果放入image_0
	hls::CvtColor<HLS_RGB2GRAY,HLS_8UC3,HLS_8UC1>(img_0,img_1);	//RGB转GRAY,即image_0-->image_1
	hls::CvtColor<HLS_GRAY2RGB,HLS_8UC1,HLS_8UC3>(img_1,img_2);	//GRAY转RGB,即image_1-->image_2
	hls::Mat2AXIvideo(img_2,OUTPUT_STREAM);

源文件里的代码都有详细注释,只要稍微有点软件基础的应该都能看懂,实在看不懂也可以私我问问。。。。具体源码私我吧兄弟。。。

三、HLS在线仿真并导出IP

仿真源文件如下:

#include "helai_rgb2gray.h"
#include "hls_opencv.h"

int main(){
	//获取图像数据
	IplImage* src = cvLoadImage(INPUT_IMAGE);
	IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

	//使用HLS库进行处理
	AXI_STREAM src_axi,dst_axi;	//定义输出输出图片格式为AXIS
	IplImage2AXIvideo(src,src_axi);	//将输入源图片转换为AXIS格式
	helai_rgb2gray(src_axi,dst_axi,src->height,src->width);	//运行rgb2gray函数
	AXIvideo2IplImage(dst_axi,dst);	//将处理后的图片由AXIS转换为RGB

	cvSaveImage(OUTPUT_IMAGE,dst);	//保存图像
	cvShowImage(INPUT_IMAGE,src);	//显示源图像
	cvShowImage(OUTPUT_IMAGE,dst);	//显示输出图像
	cv::waitKey(0);	//等待用户按下键盘上的任一按键
}

话不多说直接看仿真结果:
在这里插入图片描述
在这里插入图片描述

仿真完整成功后即可综合再导出IP:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、Kintex7开发板vivado工程验证

开发板:Xilinx Kintex7开发板;
开发环境:HLS2019.1;vivado2019.1;
输入:OV5640摄像头,输入分辨率1280x720;
输出:HDMI,输出分辨率1280x720;
工程BD如下:
在这里插入图片描述
生成顶层RTL如下:
在这里插入图片描述
SDK主函数源码如下:

#include <stdio.h>
#include "xgpio.h"
#include "oak_iic.h"
#include "unistd.h"
#include "helai_vdma.h"
#include "helai_color_back.h"
#include "helai_hls_rgb2gray.h"
//#include "sleep.h"

XGpio_Config *XGpioCfg;
XGpio led_gpio;

#define	AXI_GPIO_DEVICE_ID	XPAR_GPIO_0_DEVICE_ID

int main(){
	XGpioCfg = XGpio_LookupConfig(AXI_GPIO_DEVICE_ID);
	XGpio_CfgInitialize(&led_gpio, XGpioCfg, XGpioCfg->BaseAddress);
	XGpio_SetDataDirection(&led_gpio, 1, 0);	//output
	XGpio_DiscreteWrite(&led_gpio, 1, 0);
	oak_i2c_init(OV5640_IIC_BASEADDR, 1000000, 0x78>>1, IIC_REG_LEN16, IIC_DATA_LEN8);
	OV5640_Init(OV5640_IIC_BASEADDR,1280,720);
	helai_hls_rgb2gray(720,1280);
	helai_vdma();
	while(1){
		usleep(500000);
		XGpio_DiscreteWrite(&led_gpio, 1, 1);
		usleep(500000);
		XGpio_DiscreteWrite(&led_gpio, 1, 0);
	}
}

五、zynq7100开发板vivado工程验证

开发板:Xilinx zynq7100开发板;
开发环境:HLS2019.1;vivado2019.1;
输入:OV5640摄像头,输入分辨率1280x720;
输出:HDMI,输出分辨率1280x720;
工程BD如下:
在这里插入图片描述
生成顶层RTL如下:
在这里插入图片描述
SDK主函数源码如下:

#include "I2C_16bit.h"
#include "xiicps.h"
#include "xil_io.h"
#include "xparameters.h"
#include "helai_vdma.h"
#include "helai_hls_rgb2gray.h"

void main()
{
	// Initialize OV5640 regesiter
	I2C_config_init();
	helai_hls_rgb2gray(720,1280);
	helai_vdma();
	while (1) ;
}

六、板级调试验证

K7开发板和zynq开发板实物连接如下:图中K7为连接状态
在这里插入图片描述
运行结果静态展示:
在这里插入图片描述
下载程序后运行结果如下:以K7开发板为例,持续运行48小时无问题

HLS实现图像rgb转灰度

七、福利:工程源码获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
工程源码下载链接:https://download.csdn.net/download/qq_41667729/87391195
K7开发板网盘资料如下:
在这里插入图片描述
zynq开发板网盘资料如下:
在这里插入图片描述

;