基于FPGA的圖像FFT濾波處理 騰訊鏈接:https://share.weiyun.com/5GQyKKc 百度網(wǎng)盤(pán)鏈接:https://pan.baidu.com/s/1M7PLzRs-yMJv7NFJE8GVAw 提取碼:qr0t ![]() 關(guān)于傅里葉變換,這么一個(gè)神奇的變換,其基本原理和應用在教科書(shū)、網(wǎng)絡(luò )上漫天飛舞,這里就不贅述了,以免有湊字數的嫌疑。前面的例子我們已經(jīng)使用Matlab和Vivado的FFT IP核進(jìn)行了初步的驗證,掌握的FFT/IFFT IP核的脾氣,那么接下來(lái)我們要玩點(diǎn)真的了,基于我們STAR/SF-AT7板采集到的MT9V034圖像,我們要進(jìn)行每個(gè)行的FFT和IFFT變換,當然,生成的FFT結果我們可以進(jìn)行必要的濾波,然后再進(jìn)行IFFT查看濾波效果。 使用at7_img_ex06\matlab文件夾下的Matlab源碼image_1D_fft_ifft.m或L1024_of_image_1D_fft_ifft.m(將640個(gè)點(diǎn)擴展為1024個(gè)點(diǎn)進(jìn)行FFT變換,擴展的點(diǎn)以0填充,模擬FPGA的FFT IP核實(shí)際工作狀況),對測試圖像test進(jìn)行FFT變換,進(jìn)行必要的濾波,然后IFFT逆變換。 測試圖像為彩色圖像,原始圖像如下。
![]() 首先進(jìn)行彩色轉灰度的變換,灰度圖像如下。
![]() 提取出其中1行進(jìn)行FFT變換后的圖像頻譜如下。很明顯,大部分高頻分量集中在前面幾個(gè)點(diǎn),而后面的點(diǎn)幾乎頻率都很小。
![]() 放大頻譜圖,看到細節如下。這里繪制了一條取值為300的直線(xiàn),有將近50%的頻譜集中在這條線(xiàn)以下。若是做圖像壓縮,其實(shí)我們可以把這些低頻分量忽略了,那么數據量可能會(huì )大大降低,當然了,副作用是圖像可能會(huì )有一定程度的失真,有失必有得嘛。濾除這些低頻分量,也會(huì )使圖像更銳一些。話(huà)說(shuō)做FFT變換的目的可遠不止這些,在一些特殊的應用場(chǎng)景中,我們總是希望從原始圖像中提取出一些和應用直接相關(guān)的特征信息,那么做了FFT后的圖像常常非常有益于這些操作。為了演示,這里我們的代碼里面就將這些低于300的點(diǎn)都濾除,即取0。
![]() 從頻譜圖上看,如圖所示,右側的濾波后明顯圖像偏黑(很多值取0了)了。
![]() 我們重新把原圖放到這里,和FFT濾波并IFFT以后的圖像做比對,圖像整體仍然保持不變,但是查看細節,可以發(fā)現處理后的圖像明顯銳了一些。
![]() ![]() Matlab源碼如下: clc;clear `all;close all; IMAGE_WIDTH = 640; IMAGE_HIGHT = 480; %load origin image %I = imread('Lena_gray_niose.bmp'); I = imread('test.bmp'); I = rgb2gray(I); %fclose(fid1); %% output image data in hex file raw_image = reshape(I, IMAGE_HIGHT, IMAGE_WIDTH); raw_image = raw_image'; fid2 = fopen('image_in_hex.txt', 'wt'); fprintf(fid2, '%04x\n', raw_image); fid2 = fclose(fid2); %show origin image figure,imshow(I); title('Original image'); %1D fft base on every image line II = zeros(IMAGE_HIGHT,1024); J = zeros(IMAGE_HIGHT,1024); for i = 1:IMAGE_HIGHT for j = 1:IMAGE_WIDTH II(i,j) = I(i,j); end J(i, ![]() ![]() ![]() end %show 1 linefft result t1 = (0:IMAGE_WIDTH); % Time vector line = ones(IMAGE_WIDTH) * 200; figure; plot(t1(1:IMAGE_WIDTH),abs(J(50,1:IMAGE_WIDTH)),t1(1:IMAGE_WIDTH),line(1:IMAGE_WIDTH)) title(['1 line image in the Frequency Domain']) %show fft of origin image figure,imshow(log(abs(J)),[]); title('1D fft image base on every image line'); %colormap(jet(64)),colorbar; %fftfiter J(abs(J) < 300) = 0; %J(abs(J) > 1000) = 1000; %show fft of fft filter image figure,imshow(log(abs(J)),[]); title('1D fft image after filter'); %1D ifft base on every image line K = zeros(IMAGE_HIGHT,1024); for i = 1:IMAGE_HIGHT K(i, ![]() ![]() end KK = zeros(IMAGE_HIGHT,IMAGE_WIDTH); for i = 1:IMAGE_HIGHT for j = 1:IMAGE_WIDTH KK(i,j) = K(i,j); end end %show ifft image figure,imshow(KK,[]) title('1D ifft image'); 在Sources面板中,展開(kāi)Simulation Sources à sim_1,將sim_fft.v文件設置為top module。同樣是對前面的測試圖像,經(jīng)過(guò)FFT和IFFT變換后存儲在image_view0.txt文本中(仿真測試結果位于at7_img_ex06\at7.sim\sim_1\behav文件夾下)。為了確認FFT和IFFT IP核運算的精度和效果,這里沒(méi)有做任何的濾波處理。
![]() 使用draw_image_from_FPGA_result.m腳本(at7_img_ex06\matlab文件夾下)導入image_view0.txt文本的圖像,和原始圖像比對如下所示?吹綀D像幾乎沒(méi)有任何失真。
![]() 工程文件夾at7_img_ex06\zstar.srcs\sources_1\new下的image_fft_filter.v模塊以及3個(gè)子模塊image_fft_controller.v、image_filter.v和image_ifft_controller.v實(shí)現了圖像的FFT變換、濾波和IFFT變換處理。FPGA設計的功能框圖如下。
![]() image_fft_controller.v模塊例化FFT IP核,將采集的圖像留以行為單位輸入到FFT IP核,輸出FFT頻域數據。 image_filter.v模塊對FFT頻域數據計算絕對值并進(jìn)行必要的濾波處理,假設FFT結果的實(shí)部值為a,虛部值為b,那么其絕對值abs =sqrt(a^2+b^2)。如下代碼,注釋部分可以濾除低頻分量,當前例程中為了驗證FFT和IFFT變換后精度沒(méi)有損失,未作濾波。 always @(posedgeclk or negedgerst_n) if(!rst_n) begin o_image_filter_data_image<= 20'd0; o_image_filter_data_real<= 20'd0; end /*else if(sqrt_fft[19:0] < 20'd300) begin //此處可以做必要的高頻或低頻濾波處理 o_image_filter_data_image<= 20'd0; o_image_filter_data_real<= 20'd0; end*/ else begin o_image_filter_data_image<= r_image_fft_data_image[TOTAL_LATENCY-1]; o_image_filter_data_real<= r_image_fft_data_real[TOTAL_LATENCY-1]; end image_ifft_controller.v模塊將濾波處理后的FFT結果進(jìn)行IFFT變換,圖像轉回時(shí)域值,供后續模塊緩存DDR3并顯示。 AT7_Xilinx開(kāi)發(fā)板(USB3.0+LVDS)資料共享 騰訊鏈接:https://share.weiyun.com/5GQyKKc 百度網(wǎng)盤(pán)鏈接:https://pan.baidu.com/s/1M7PLzRs-yMJv7NFJE8GVAw 提取碼:qr0t |