特权同学

基于FPGA的图像直方图实时显示

0
阅读(1594)

基于FPGA的图像直方图实时显示

AT7_Xilinx开发板(USB3.0+LVDS)资料共享

腾讯链接:https://share.weiyun.com/5GQyKKc

百度网盘链接:https://pan.baidu.com/s/1M7PLzRs-yMJv7NFJE8GVAw

提取码:qr0t

1.jpg

1系统概述

如图所示,这是整个视频采集系统的原理框图。

2.jpg

上电初始,FPGA需要通过IIC接口对CMOS Sensor进行寄存器初始化配置。这些初始化的基本参数,即初始化地址对应的初始化数据都存储在一个预先配置好的FPGA片内ROM中。在初始化配置完成后,CMOS Sensor就能够持续输出标准RGB的视频数据流,FPGA通过对其同步信号,如时钟、行频和场频进行检测,从而从数据总线上实时的采集图像数据。MT9V034摄像头默认初始化数据就能输出正常的视频流,因此FPGA中实际上未作任何IIC初始化配置。

在FPGA内部,采集到的视频数据先通过一个FIFO,将原本25MHz频率下同步的数据流转换到50MHz的频率下。接着将这个数据再送入写DDR3缓存的异步FIFO中,这个FIFO中的数据一旦达到一定数量,就会通过AXI HP0总线写入DDR3中。与此同时,AXI HP0总线也会读取DDR3中缓存的图像数据,缓存到FIFO中,并最终送往LCD驱动模块进行显示。LCD驱动模块不断的发出读图像数据的请求,并驱动液晶显示器显示视频图像。

本实例除了前面提到对原始图像做DDR3缓存和显示,还会在原始图像缓存到DDR3之前,会对当前图像做直方图统计(以帧为单位做统计),统计后的直方图结果做归一化处理,便于后续液晶屏显示的直方图绘制,归一化的直方图结果取值范围是0~448,用256个10bit数据表示,存入双口RAM中。根据LCD显示模块的请求,从双口RAM读取实时图像的归一化直方图统计结果进行显示。最终在VGA液晶显示器上,可以看到左侧图像是原始的图像,右侧图像是经过归一化处理的直方图图像。

2直方图统计与归一化处理

工程文件夹at7_img_ex09\at7.srcs\sources_1\new下的histogram_calculation.v模块实现了图像的直方图统计与归一化处理。该模块有一个包含6个状态的状态机,以这个状态机为主轴的设计思路如下:

1上电初始状态STATE_IDLE,复位结束后即进入下一状态STATE_HIST。

2STATE_HIST状态下,进行实时图像的256级直方图统计,统计结果存放在寄存器histogram_cnt[255:0][19:0]中;图像接收信号i_image_ddr3_frame_end拉高时,切换到下一个状态STATE_FMAX。

3STATE_FMAX状态下,遍历一遍直方图统计结果寄存器histogram_cnt[255:0][19:0],找出最大值存放在寄存器max_histogramcnt[19:0]中;找到最大值后,切换到下一状态STATE_CNTC。

4STATE_CNTC状态下,直接转换到下一个状态STATE_OUTP;该状态主要为了清零计数器dlycnt。

5STATE_OUTP状态下,依次将256个直方图统计结果乘以448(=256+128+64),作为被除数,实际乘以448是通过3个移位结果进行累加实现。而max_histogramcnt[19:0]则作为除数,依次输出256个进行除法归一化后的直方图统计结果(o_image_hc_wren拉高时o_image_hc_wrdb[9:0]有效)。完成后进入下一状态STATE_WAIT。

6STATE_WAIT状态下,直接切换到STATE_IDLE。

在第5步进行的归一化处理,其基本思想是找到256个直方图统计结果的最大值,作为归一化的1(其他值都小于1);而其他结果都会以此为标准获取对应的归一化值;例如最大值若为40000,那么归一化后为1,某个统计结果是1000,那么归一化后是0.025;而实际我们需要将这个归一化后的直方图结果显示到液晶屏上,液晶屏上我们可以希望最高的直方图可以取448pix来显示,那么我们用448乘以归一化后的结果即可。

实际液晶屏是720p的驱动分辨率,最大可以给到720pix的高度,但是因为左侧的原始采集图像显示是640*480,为了显示美观,我们最好给出一个不超过480pix的最高直方图高度显示,而取448其实是考虑到它等于256+128+64,可以不消耗FPGA的乘法器资源,用移位累加来实现。

3 FPGA与Matlab协同仿真验证

3.1直方图统计与归一化结果仿真

在at7_img_ex09\at7.srcs\sources_1\new\testbench文件夹下,测试脚本sim_histogram_calculation.v用于对模块histogram_calculation.v进行仿真。

Vivado打开at7_img_ex09工程,在Sources面板中,展开Simulation Sources à sim_1,将sim_histogram_calculation.v文件设置为top module。在Flow Navigator面板中,展开Simulation,点击Run Simulation,弹出菜单中点击Run Behavioral Simulation进行仿真。

测试脚本中,读取at7_img_ex09\at7.sim文件夹下的640*480图像数据image_in_hex.txt(该文件由at7_img_ex09\matlab文件夹下的image_txt_generation.m产生,原始图像为test.bmp)。一组完整的图像数据经过histogram_calculation.v模块处理后,产生256个归一化直方图结果,写入到histogram_result.txt文本中(仿真测试结果位于project\at7_img_ex09\at7.sim\sim_1\behav文件夹下)。

使用at7_img_ex09\matlab文件夹下的draw_histogram_from_FPGA_result.m脚本,可以同时比对Matlab和FPGA统计的直方图输出结果。由于FPGA统计结果是一个归一化结果,所有和Matlab实际统计结果的数值可能不一样,但是从比对图上看,他们的趋势和分布完全一致。

3.jpg

3.2图像与直方图显示结果仿真

在at7_img_ex09\at7.srcs\sources_1\new\testbench文件夹下,测试脚本sim_at7.v用于对模块histogram_calculation.v、dual_ram_cache.v和lcd_driver.v进行仿真。

Vivado打开at7_img_ex09工程,在Sources面板中,展开Simulation Sources à sim_1,将sim_zstar.v文件设置为top module。在Flow Navigator面板中,展开Simulation,点击Run Simulation,弹出菜单中点击Run Behavioral Simulation进行仿真。

测试脚本中,读取at7_img_ex09\at7.sim文件夹下的640*480图像数据image_in_hex.txt(该文件由at7_img_ex09\matlab文件夹下的image_txt_generation.m产生,原始图像为test.bmp)。一组完整的图像数据经过histogram_calculation.v模块处理后,产生256个归一化直方图结果,缓存到dual_ram_cache.v模块的双口RAM中,lcd_driver.v模块根据显示驱动需要,读取双口RAM中的数据,将直方图显示在液晶屏的右侧。测试脚本中,根据lcd_driver.v模块的显示驱动信号,将一帧的显示图像写入到monitor_display_image.txt文本中(仿真测试结果位于project\at7_img_ex09\at7.sim\sim_1\behav文件夹下)。

使用at7_img_ex09\matlab文件夹下的draw_image_from_FPGA.m脚本,可以打印monitor_display_image.txt文本中输出的图像。这就是最终我们的VGA显示器中将会显示的界面示意,左侧是原始图像,右侧是其直方图分布。可以看到,这个直方图分布情况和前面Matlab计算出来的也是一致的。

4.jpg

4装配说明

如图所示,这是STAR开发板和摄像头转接板、摄像头模块、VGA模块的连接示意图。SF-AT7开发板的连接位置也是一样的。

5.jpg

5板级调试

本实例对应at7_img_ex09实例工程,做好装配连接,上电,将at7_img_ex09\at7.runs\impl_1文件夹下的at7.bit文件烧录到板子上,可以看到VGA显示器同时显示左右两个图像,左侧图像为原始图像,右侧图像为直方图。

实物效果如下图所示。

6.jpg

AT7_Xilinx开发板(USB3.0+LVDS)资料共享

腾讯链接:https://share.weiyun.com/5GQyKKc

百度网盘链接:https://pan.baidu.com/s/1M7PLzRs-yMJv7NFJE8GVAw

提取码:qr0t


Baidu
map