基于FPGA的圖像FFT濾波處理
AT7_Xilinx開發板(USB3.0+LVDS)資料共享
1
昨天?11:39 上傳
關于傅里葉變換
關于傅里葉變換,這么一個神奇的變換,其基本原理和應用在教科書、網絡上漫天飛舞,這里就不贅述了,以免有湊字數的嫌疑。前面的例子我們已經使用Matlab和Vivado的FFT IP核進行了初步的驗證,掌握的FFT/IFFT IP核的脾氣,那么接下來我們要玩點真的了,基于我們STAR/SF-AT7板采集到的MT9V034圖像,我們要進行每個行的FFT和IFFT變換,當然,生成的FFT結果我們可以進行必要的濾波,然后再進行IFFT查看濾波效果。
2基于Matlab的FFT濾波
使用at7_img_ex06matlab文件夾下的Matlab源碼image_1D_fft_ifft.m或L1024_of_image_1D_fft_ifft.m(將640個點擴展為1024個點進行FFT變換,擴展的點以0填充,模擬FPGA的FFT IP核實際工作狀況),對測試圖像test進行FFT變換,進行必要的濾波,然后IFFT逆變換。
測試圖像為彩色圖像,原始圖像如下。
首先進行彩色轉灰度的變換,灰度圖像如下。
提取出其中1行進行FFT變換后的圖像頻譜如下。很明顯,大部分高頻分量集中在前面幾個點,而后面的點幾乎頻率都很小。
放大頻譜圖,看到細節如下。這里繪制了一條取值為300的直線,有將近50%的頻譜集中在這條線以下。若是做圖像壓縮,其實我們可以把這些低頻分量忽略了,那么數據量可能會大大降低,當然了,副作用是圖像可能會有一定程度的失真,有失必有得嘛。濾除這些低頻分量,也會使圖像更銳一些。話說做FFT變換的目的可遠不止這些,在一些特殊的應用場景中,我們總是希望從原始圖像中提取出一些和應用直接相關的特征信息,那么做了FFT后的圖像常常非常有益于這些操作。為了演示,這里我們的代碼里面就將這些低于300的點都濾除,即取0。
從頻譜圖上看,如圖所示,右側的濾波后明顯圖像偏黑(很多值取0了)了。
我們重新把原圖放到這里,和FFT濾波并IFFT以后的圖像做比對,圖像整體仍然保持不變,但是查看細節,可以發現處理后的圖像明顯銳了一些。
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 ', 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,
= fft(II(i,
);%fft(I(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,
= real(ifft(J(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');
3FPGA仿真
在Sources面板中,展開Simulation Sources à sim_1,將sim_fft.v文件設置為top module。同樣是對前面的測試圖像,經過FFT和IFFT變換后存儲在image_view0.txt文本中(仿真測試結果位于at7_img_ex06at7.simsim_1ehav文件夾下)。為了確認FFT和IFFT IP核運算的精度和效果,這里沒有做任何的濾波處理。
使用draw_image_from_FPGA_result.m腳本(at7_img_ex06matlab文件夾下)導入image_view0.txt文本的圖像,和原始圖像比對如下所示。看到圖像幾乎沒有任何失真。
4 基于FPGA的圖像平滑處理
工程文件夾at7_img_ex06zstar.srcssources_1 ew下的image_fft_filter.v模塊以及3個子模塊image_fft_controller.v、image_filter.v和image_ifft_controller.v實現了圖像的FFT變換、濾波和IFFT變換處理。FPGA設計的功能框圖如下。
image_fft_controller.v模塊例化FFT IP核,將采集的圖像留以行為單位輸入到FFT IP核,輸出FFT頻域數據。
image_filter.v模塊對FFT頻域數據計算絕對值并進行必要的濾波處理,假設FFT結果的實部值為a,虛部值為b,那么其絕對值abs =sqrt(a^2+b^2)。如下代碼,注釋部分可以濾除低頻分量,當前例程中為了驗證FFT和IFFT變換后精度沒有損失,未作濾波。
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結果進行IFFT變換,圖像轉回時域值,供后續模塊緩存DDR3并顯示。
評論
查看更多