当前位置
主页 > 产品中心 > 产品四类 >
「正点原子FPGA连载第十章基于OV5640的直方图平衡实验
2023-06-13 05:05
本文摘要:1)摘自【正点原子】领航者ZYNQ之HLS 开发指南2)实验平台:正点原子领航者ZYNQ开发板3)平台购置地址:https://item.taobao.com/item.htm?#34;hls_video.h2 3 #define MAX_HEIGHT 800 //图像最大高度4 #define MAX_WIDTH 1024 //图像最大宽度5 6 typedef hls::streamap_axiu24,1,1,1 AXI_STREAM;7 typedef hls::Ma

半岛真人

1)摘自【正点原子】领航者ZYNQ之HLS 开发指南2)实验平台:正点原子领航者ZYNQ开发板3)平台购置地址:https://item.taobao.com/item.htm?&id=6061601087614)全套实验源码+手册+视频下载:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)对正点原子FPGA感兴趣的同学可以加群讨论:8767449006)正点原子资料更新和新品公布,请加正点原子民众号:正点原子关注方法:微信→添加挚友→民众号→输入:正点原子第十章基于OV5640的直方图平衡实验直方图是图像空间域处置惩罚技术的基础,对图像的直方图操作可用于图像增强。图像直方图中的固有信息在图像处置惩罚相关的应用中很是有用,如图像压缩与支解。由于直方图统计在软件中盘算简朴,有助于商用硬件实现,因此已经成为一种盛行的实时图像处置惩罚工具。

本章我们将在HLS中实现图像的直方图平衡算法。本章包罗以下几个部门:1010.1简介10.2实验任务10.3HLS设计10.4IP验证10.5下载验证10.1简介直方图是一种统计陈诉图,大家可以简朴地明白成“柱状图”。图像的直方图反映了一幅图像中各灰度级泛起的个数,如下图所示:图 10.1.1 图像的直方图图 10.1.1左边是一幅数字图像的示意图,分辨率为7x7(即7行7列)。

每个像素点由一个方格表现,格中的数字代表该像素点的灰度值,共有16个灰度级(1~16)。我们通过统计各灰度级在图像中泛起的次数,就可以获得该图像的灰度直方图,即上图右侧的二维离散图。

其中横坐标代表一幅图像的灰度品级,纵坐标代表各灰度级在该幅图像中泛起的个数。通过视察直方图的漫衍我们可以获得图像的明暗、对比度等信息。如下图所示:图 10.1.2 图像的亮度与直方图图 10.1.2左侧是花粉的电子显微图像,已经放大了近700倍,右侧是图像对应的直方图。

从图中可以看出,对于较亮的图像,它的直方图分量主要漫衍在直方图的右侧,即灰度级较高的区域;而在暗图像中,直方图分量则集中在灰度级的低端(左侧)。下面我们再来视察一下图像的对比度与直方图的关系,如下图所示:图 10.1.3 图像的对比度与直方图从图 10.1.3中可以看到,低对比度图像具有较窄的直方图,且集中于灰度级的中部。

直方图越窄,说明图像中像素点所占据的灰度级越少,而且比力集中。这样就导致像素点之间的灰度差异不大,看上去像是图像被冲淡了一样,像这种低对比度的图像倒霉于肉眼视察分析图像的细节。而高对比度图像中,直方图的分量笼罩了很宽的灰度级规模,而且在差别的灰度级上像素的漫衍比力匀称。也就是说,如果一幅图像的像素倾向于占据整个可能的灰度级而且匀称漫衍,则该图像的对比度更高。

最终效果将是一幅灰度细节富厚且动态规模较大的图像。从上面的例子中我们可以得出结论,如果想要增强图像对比度,那么就需要使图像中的像素占据尽可能多的灰度级。也就是说使图像的直方图像图 10.1.3右下角那样“匀称漫衍”,直方图平衡化 (Histogram Equalization)算法就可以实现这样的效果,它是一种增强图像对比度(Image Contrast)的方法。顾名思义,它可以将一副图像的直方图漫衍酿成近似匀称漫衍(平衡),从而增强图像的对比度。

如下图所示:图 10.1.4 直方图平衡化图 10.1.4左侧为原始图像及其直方图,右侧是经由直方图平衡化之后的图像和它的直方图。可以看出,直方图平衡化使得原始图像的直方图趋向于在整个灰度级中匀称漫衍,反映在图像上面就是图像的对比度获得了很大的提升。

10.2实验任务本节的实验任务是使用Vivado HLS实现一个图像处置惩罚的IP核,该IP核能够将OV5640摄像头发生的RGB彩色图像转换成灰度图像,并对灰度图像举行直方图平衡化。10.3HLS设计我们在电脑中的“F:ZYNQHigh_Level_Synthesis”目录下新建一个名为ov5640_equalize_histogram的文件夹,作为本次实验的工程目录。

然后打开Vivado HLS 2018.3,建立一个新的工程“ov5640_equalize_histogram”,选择工程路径为刚刚建立的文件夹。需要注意的是,工程名以及路径只能由英文字母、数字和下划线组成,不能包罗中文、空格以及其他特殊字符。

如下图所示:图 10.3.1 工程设置界面设置好工程名及路径之后,点击“Next”,进入如下界面设置顶层函数:图 10.3.2 设置顶层函数然后选择ZYNQ器件所对应的型号,如下图所示:图 10.3.3 设置时钟周期和器件型号工程建立完成后,在工程面板中的“source”目录上点击右键,然后在打开的列表中选择“New File”新建源文件,在弹出的对话框中输入源文件的名称“ov5640_equalize_histogram.cpp”,如下图所示。源文件默认的生存路径为HLS工程目录,为利便源文件的治理,我们在工程目录下新建一个名为“src”的文件下,将源文件生存在src目录下。

图 10.3.4 输入源文件名我们输入的源文件的后缀名为“.cpp”,纵然用C++语言举行设计。“ov5640_equalize_histogram.cpp”文件源代码如下:1 #include "hls_video.h"2 3 #define MAX_HEIGHT 800 //图像最大高度4 #define MAX_WIDTH 1024 //图像最大宽度5 6 typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM;7 typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC3> RGB_IMAGE;8 typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC1> GRAY_IMAGE;9 10 void ov5640_equalize_histogram(AXI_STREAM & INPUT_STREAM,11 AXI_STREAM & OUTPUT_STREAM,12 int rows,13 int cols14 ){15 16 #pragma HLS INTERFACE axis port=INPUT_STREAM17 #pragma HLS INTERFACE axis port=OUTPUT_STREAM18 #pragma HLS INTERFACE s_axilite port=rows19 #pragma HLS INTERFACE s_axilite port=cols20 #pragma HLS INTERFACE ap_ctrl_none port=return21 #pragma HLS dataflow22 23 //hls::mat花样变量24 RGB_IMAGE img_0(rows,cols);25 GRAY_IMAGE img_1(rows,cols);26 GRAY_IMAGE img_2(rows,cols);27 RGB_IMAGE img_3(rows,cols);28 29 //将AXI4 Stream数据转换成hls::mat花样30 hls::AXIvideo2Mat(INPUT_STREAM,img_0);31 32 //将RGB888花样的彩色数据转换成灰度数据33 hls::CvtColor<HLS_RGB2GRAY,HLS_8UC3,HLS_8UC1>(img_0,img_1);34 35 //对灰度图像举行直方图平衡36 hls::EqualizeHist<HLS_8UC1,HLS_8UC1,MAX_HEIGHT,MAX_WIDTH>(img_1,img_2);37 38 //将灰度数据转换成三个通道的灰度图像39 hls::CvtColor<HLS_GRAY2RGB,HLS_8UC1,HLS_8UC3>(img_2,img_3);40 41 42 //将hls::mat花样数据转换成AXI4 Stream花样43 hls::Mat2AXIvideo(img_3,OUTPUT_STREAM);44 }代码的主体部门与《OV5640摄像头灰度显示实验》很是类似,只是在代码的36行多了一个直方图平衡化的函数hls::EqualizeHist()。

它是HLS视频库中的函数,可以对输入的图像举行直方图平衡化,从而提高图像的对比度。在本次实验中,OV5640摄像头输入的RGB888花样的彩色数据经由hls::CvtColor()函数转成灰度图像,然后函数hls::EqualizeHist()对转换获得的灰度图像举行直方图平衡,最后重新由hls::CvtColor()函数将单通道的灰度图像转成三个通道的灰度图像。

hls::EqualizeHist()函数的声明如下所示:图 10.3.5直方图平衡函数声明在上图中,函数EqualizeHist()有两个参数,_src表现输入的图像,_dst为直方图平衡化之后的图像,它们的花样为hls::Mat。尖括号<>内部为函数EqualizeHist()的模板,其中前两个参数SRC_T和DST_T划分表现输入和输出图像像素数据的类型。

该数据类型仅支持HLS_8UC1类型,即只支持单通道8位的视频数据。后面两个参数ROW和COL划分表现输入图像的行数和列数。由于代码的其他部门与《OV5640摄像头灰度显示实验》基底细同,在这里就不再赘述。

如果大家不清楚的话,可以参考《正点原子HLS开发指南》的相应章节。接下来点击工具栏中向右的绿色三角形对设计举行综合,综合完成后,会自动打开综合效果(solution)的陈诉。在综合陈诉中还给出了设计的性能评估、资源评估以及接口等信息。

本次实验中,我们重点关注综合工具为我们生成的接口信息,如下图所示:图 10.3.7 接口信息1图 10.3.6 接口信息2从图中可以看出,设计综合出了一个“AXI4-Lite”从接口和两个“AXI4-Stream”接口(一个输入,一个输出)。其中“AX4-Lite”总线接口用于控制视频处置惩罚的分辨率,而两个“AXI4-Stream”总线接口划分用于输入待处置惩罚的视频以及输出处置惩罚之后的视频流。

在综合效果正确的情况下,在工具栏中点击黄色的“田”字按钮,导出RTL。在导出RTL竣事之后,我们到工程目录所指向的文件夹中可以看到以ZIP压缩文件形式存在的IP核,如下图所示:图 10.3.18 文件夹中的IP核HLS设计竣事之后,我们将在Vivado中对导出的IP核举行验证。10.4IP验证在IP验证环节,我们会使用Vivado工具的IP集成器将生成的IP核添加到Block Design中,然后完成设计后将法式下载到领航者开发板上举行验证。

用于IP验证的底层硬件可以在《领航者ZYNQ之嵌入式开发指南》第二十三章“OV5640 摄像头 LCD 显示”实验的基础上举行。参考《正点原子HLS开发指南》“OV5640摄像头灰度显示实验”中的下载验证部门,将生成的IP插入到“OV5640 摄像头 LCD 显示”实验底层硬件中的Block Design中。最终的设计如下图所示:图 10.4.1 用于验证直方图平衡IP核的最终设计在图 6.4.7中,ov5640_capture_data模块获取OV5640摄像头收罗的图像,然后通过Video In to AXI4-Stream模块将摄像头图像转换成AXI4-Stream花样的视频流。

该视频流输入HLS生成的中值滤波IP核ov5640_equalize_hist_0,将RGB888花样的彩色图像转换成灰度图像,并对灰度图像举行直方图平衡化,然后同样以AXI4-Stream花样将处置惩罚后的视频流输出给VDMA。如果大家对设计中其他各模块的功效不相识的话,请大家参考《领航者ZYNQ之嵌入式开发指南》第二十三章“OV5640 摄像头 LCD 显示”实验。到这里我们的Block Design就设计完成了,在Diagram窗口空缺处右击,然后选择“Validate Design”验证设计。验证完成后弹出对话框提示“Validation Successful”讲明设计无误,点击“OK”确认。

最后按快捷键“Ctrl + S”生存设计。接下来在Source窗口中右键点击Block Design设计文件“system.bd”,然后依次执行“Generate Output Products”和“Create HDL Wrapper”。最后在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG,点击该选项中的“Generate Bitstream”,对设计举行综合、实现、并生成Bitstream文件。在生成 Bitstream 之后,在菜单栏中选择 File > Export > Export hardware 导出硬件,并在弹出的对话框 中,勾选“Include bitstream”。

然后在菜单栏选择 File > Launch SDK,启动 SDK 软件。在Vivado SDK中新建空的应用工程,工程名为“ov5640_rgb2gray_lcd”。然后找到《领航者ZYNQ之嵌入式开发指南》第二十三章“OV5640 摄像头 LCD 显示”实验的Vivado工程目录,将“21_ov7725_lcdov7725_lcd.sdkov7725_lcd”目录下的src文件夹拷贝到新建的应用工程目录下。

在SDK中刷新src目录,然后将“main.c”的代码修改为如下所示:1 #include <stdio.h>2 #include <stdlib.h>3 #include <string.h>4 #include "xil_types.h"5 #include "xil_cache.h"6 #include "xparameters.h"7 #include "xgpio.h"8 #include "xaxivdma.h"9 #include "xaxivdma_i.h"10 #include "display_ctrl/display_ctrl.h"11 #include "vdma_api/vdma_api.h"12 #include "emio_sccb_cfg/emio_sccb_cfg.h"13 #include "ov5640/ov5640_init.h"14 #include "xov5640_equalize_histogram.h"15 16 //宏界说17 #define BYTES_PIXEL 3 //像素字节数,RGB888占3个字节18 #define FRAME_BUFFER_NUM 3 //帧缓存个数319 #define DYNCLK_BASEADDR XPAR_AXI_DYNCLK_0_BASEADDR //动态时钟基地址20 #define VDMA_ID XPAR_AXIVDMA_0_DEVICE_ID //VDMA器件ID21 #define DISP_VTC_ID XPAR_VTC_0_DEVICE_ID //VTC器件ID22 //PL端 AXI GPIO 0(lcd_id)器件 ID23 #define AXI_GPIO_0_ID XPAR_AXI_GPIO_0_DEVICE_ID 24 //使用AXI GPIO(lcd_id)通道125 #define AXI_GPIO_0_CHANEL 1 26 27 //全局变量28 //frame buffer的起始地址29 unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR30 + 0x1000000);31 XAxiVdma vdma;32 DisplayCtrl dispCtrl;33 XGpio axi_gpio_inst; //PL端 AXI GPIO 驱动实例34 VideoMode vd_mode;35 36 //PL端XOv5640_equalize_histogram驱动实例37 XOv5640_equalize_histogram equ_his_inst; 38 39 unsigned int lcd_id;40 41 int main(void)42 {43 u32 status;44 u16 cmos_h_pixel; //ov5640 DVP 输出水平像素点数45 u16 cmos_v_pixel; //ov5640 DVP 输出垂直像素点数46 u16 total_h_pixel; //ov5640 水平总像素巨细47 u16 total_v_pixel; //ov5640 垂直总像素巨细48 49 //获取LCD的ID50 XGpio_Initialize(&axi_gpio_inst, AXI_GPIO_0_ID);51 lcd_id = LTDC_PanelID_Read(&axi_gpio_inst,AXI_GPIO_0_CHANEL);52 xil_printf("lcd_id = %xnr",lcd_id);53 54 //凭据获取的LCD的ID号来举行ov5640显示分辨率参数的选择55 switch(lcd_id){56 case 0x4342 : //4.3寸屏,480*272分辨率57 cmos_h_pixel = 480;58 cmos_v_pixel = 272;59 total_h_pixel = 1800;60 total_v_pixel = 1000;61 break;62 case 0x4384 : //4.3寸屏,800*480分辨率63 cmos_h_pixel = 800;64 cmos_v_pixel = 480;65 total_h_pixel = 1800;66 total_v_pixel = 1000;67 break;68 case 0x7084 : //7寸屏,800*480分辨率69 cmos_h_pixel = 800;70 cmos_v_pixel = 480;71 total_h_pixel = 1800;72 total_v_pixel = 1000;73 break;74 case 0x7016 : //7寸屏,1024*600分辨率75 cmos_h_pixel = 1024;76 cmos_v_pixel = 600;77 total_h_pixel = 2200;78 total_v_pixel = 1000;79 break;80 case 0x1018 : //10.1寸屏,1280*800分辨率81 cmos_h_pixel = 1280;82 cmos_v_pixel = 800;83 total_h_pixel = 2570;84 total_v_pixel = 980;85 break;86 default :87 cmos_h_pixel = 480;88 cmos_v_pixel = 272;89 total_h_pixel = 1800;90 total_v_pixel = 1000;91 break;92 }93 94 emio_init(); //初始化EMIO95 status = ov5640_init( cmos_h_pixel, //初始化ov564096 cmos_v_pixel,97 total_h_pixel,98 total_v_pixel);99 if(status == 0)100 xil_printf("OV5640 detected successful!rn");101 else102 xil_printf("OV5640 detected failed!rn");103 104 //凭据获取的LCD的ID号来举行video参数的选择105 switch(lcd_id){106 case 0x4342 : vd_mode = VMODE_480x272; break; //4.3寸屏,480*272分辨率107 case 0x4384 : vd_mode = VMODE_800x480; break; //4.3寸屏,800*480分辨率108 case 0x7084 : vd_mode = VMODE_800x480; break; //7寸屏,800*480分辨率109 case 0x7016 : vd_mode = VMODE_1024x600; break; //7寸屏,1024*600分辨率110 case 0x1018 : vd_mode = VMODE_1280x800; break; //10.1寸屏,1280*800分辨率111 default : vd_mode = VMODE_800x480; break;112 }113 114 //初始化直方图平衡IP核115 XOv5640_equalize_histogram_Initialize(&equ_his_inst,116 XPAR_OV5640_EQUALIZE_HIST_0_DEVICE_ID);117 //设置灰度转换IP核OV5640_RGB2GRAY的行数118 XOv5640_equalize_histogram_Set_rows(&equ_his_inst, vd_mode.height);119 //设置灰度转换IP核OV5640_RGB2GRAY的行数120 XOv5640_equalize_histogram_Set_cols(&equ_his_inst, vd_mode.width);121 122 //设置VDMA123 run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height,124 frame_buffer_addr,0,0,BOTH);125 //初始化Display controller126 DisplayInitialize(&dispCtrl, DISP_VTC_ID, DYNCLK_BASEADDR);127 //设置VideoMode128 DisplaySetMode(&dispCtrl, &vd_mode);129 DisplayStart(&dispCtrl);130 131 return 0;132 }在代码的第14行引入了"xov5640_equalize_histogram.h"头文件,这个头文件是Vivado HLS工具生成的,内里声明晰直方图平衡IP核的驱动函数。首先在代码的37行界说了直方图平衡IP核的驱动实例equ_his_inst,该变量会在后面临IP核举行设置时用到。然后在代码的第115行通过“XOv5640_equalize_histogram_Initialize()”函数来初始化Vivado HLS生成的直方图平衡IP核;在代码的第118行通过传入“vd_mode.height”形参来设置直方图平衡IP核的行数,在代码的第120行通过传入“vd_mode.width”形参来设置列数。

这些数据类型和函数在"xov5640_equalize_histogram.h"头文件中均有声明。10.5下载验证编译完工程之后我们就可以开始下载法式了。将 OV5640 摄像头模块插在领航者 Zynq 开发板的“OLED/CAMERA”插座上,并将 LCD 的排线讨论插入开发板上的 LCD 接线座。

将下载器一端连电脑,另一端与开发板上的 JTAG 端口毗连,毗连电源线并打开电源开关。在 SDK 软件下方的 SDK Terminal 窗口中点击右上角的加号设置并毗连串口。

然后下载本次实验硬件设计历程中所生成的 BIT 文件,来对 PL 举行设置。最后下载软件法式,下载完成后在LCD上就可以看到摄像头收罗的彩色图像被转换成了灰度图像,中间经由了直方图平衡。

需要注意的是,在照明条件下良好的情况下对OV5640摄像头图像举行直方图平衡,效果并不显着。可以在较暗的情况中(如夜间关灯状态下)举行测试,这样场景的亮度很低,可是大家会发现LCD上显示的图像依然像白昼一样明亮。可是由于直方图平衡在增强对比度的同时会放大噪声,因此图像的质量会显着下降,如下图所示:图 10.5.1 黑暗情况中直方图平衡效果。


本文关键词:「,正点,原子,FPGA,连载,第十,章,基于,OV5640,的,半岛体育官方app下载

本文来源:半岛真人-www.fzdyyx.com

联系方式

电话:0546-46950812

传真:018-269339500

邮箱:admin@fzdyyx.com

地址:云南省昆明市大足区和时大楼6989号