基于FPGA的圖像直方圖實時顯示 騰訊鏈接:https://share.weiyun.com/5GQyKKc 百度網盤鏈接:https://pan.baidu.com/s/1M7PLzRs-yMJv7NFJE8GVAw 提取碼:qr0t ![]() 如圖所示,這是整個視頻采集系統的原理框圖。
![]() 上電初始,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液晶顯示器上,可以看到左側圖像是原始的圖像,右側圖像是經過歸一化處理的直方圖圖像。 工程文件夾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的乘法器資源,用移位累加來實現。 在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實際統計結果的數值可能不一樣,但是從比對圖上看,他們的趨勢和分布完全一致。
![]() 在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裝配說明![]() 如圖所示,這是STAR開發板和攝像頭轉接板、攝像頭模塊、VGA模塊的連接示意圖。SF-AT7開發板的連接位置也是一樣的。 ![]() 本實例對應at7_img_ex09實例工程,做好裝配連接,上電,將at7_img_ex09\at7.runs\impl_1文件夾下的at7.bit文件燒錄到板子上,可以看到VGA顯示器同時顯示左右兩個圖像,左側圖像為原始圖像,右側圖像為直方圖。 實物效果如下圖所示。
![]() AT7_Xilinx開發板(USB3.0+LVDS)資料共享 騰訊鏈接:https://share.weiyun.com/5GQyKKc 百度網盤鏈接:https://pan.baidu.com/s/1M7PLzRs-yMJv7NFJE8GVAw 提取碼:qr0t |