加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶(hù)
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 一、實(shí)現(xiàn)步驟:
    • 二、實(shí)現(xiàn)過(guò)程:
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

FPGA verilog HDL實(shí)現(xiàn)中值濾波

05/08 11:30
1502
閱讀需 15 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

大俠好,歡迎來(lái)到FPGA技術(shù)江湖,江湖偌大,相見(jiàn)即是緣分。大俠可以關(guān)注FPGA技術(shù)江湖,在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源,或者一起煮酒言歡。

今天給大俠簡(jiǎn)單帶來(lái)FPGA verilog HDL實(shí)現(xiàn)中值濾波,話(huà)不多說(shuō),上貨。

一、實(shí)現(xiàn)步驟:

1、查看了中值濾波實(shí)現(xiàn)相關(guān)的網(wǎng)站和paper;

2、按照某篇paper的設(shè)計(jì)思想進(jìn)行編程實(shí)現(xiàn);

3、對(duì)各個(gè)模塊進(jìn)行語(yǔ)法檢查、波形仿真、時(shí)序設(shè)計(jì)、調(diào)試驗(yàn)證;

4、與matlab的中值濾波結(jié)果進(jìn)行比較。

二、實(shí)現(xiàn)過(guò)程:

1、查看了中值濾波實(shí)現(xiàn)相關(guān)的網(wǎng)站和paper;

在網(wǎng)上看了很多中值濾波的設(shè)計(jì),也有一些代碼可以下載,也有一片講解的,只是感覺(jué)講解的比較模糊而且不完整,最后看了幾篇碩士論文,論文竟然主要做了中值濾波的工作,發(fā)現(xiàn)了一些設(shè)計(jì)思路,然后就按照自己的想法進(jìn)行設(shè)計(jì)。

2、按照某篇paper的設(shè)計(jì)思想進(jìn)行編程實(shí)現(xiàn);

整個(gè)中值濾波模塊分為幾個(gè)小的模塊:3*3窗口生成模塊、計(jì)數(shù)器控制模塊、3*3中值濾波模塊、頂層模塊以及最后的測(cè)試模塊testbench的編寫(xiě)。整個(gè)框架的設(shè)計(jì)如下圖所示(使用visio畫(huà)的框架圖):

各個(gè)模塊的設(shè)計(jì):1)ROM IP核的生成,用于存儲(chǔ)原始灰度圖像的數(shù)據(jù)。

使用matlab生成.coe圖像數(shù)據(jù)文件,然后使用Xilinx ISE工具將.coe文件添加到ROM核進(jìn)行數(shù)據(jù)初始化,按步驟得到ROM模塊,參考生成的.v文件在頂層模塊直接調(diào)用即可。

rom_512by512 rom_512by512_inst (   .clka(CLK),          //input clka;   .addra(rom_addr),   //input-from    .douta(rom_data)     //output-to  );

注意ROM的存儲(chǔ)空間的大小;

2)3*3窗口生成模塊,用于生成濾波的滑動(dòng)窗口,得到窗口內(nèi)的所有元素?cái)?shù)據(jù)。

功能:

(1)根據(jù)中心像素點(diǎn)得到所在其所在的行、列位置;

(2)根據(jù)該模塊的開(kāi)始信號(hào)設(shè)計(jì)得到獲取數(shù)據(jù)的有效時(shí)間序列;

(3)在讀取數(shù)據(jù)的有效時(shí)序內(nèi),得到窗口內(nèi)的所有元素?cái)?shù)據(jù);

(4)窗口數(shù)據(jù)的獲取按照一定的時(shí)序順序來(lái)獲得,類(lèi)似于黑金推薦的“仿順序操作”,這個(gè)比較適合my style;不過(guò)后來(lái)發(fā)現(xiàn)調(diào)試的過(guò)程中被項(xiàng)目組的硬件人員改動(dòng)了一些,甚至說(shuō)不好,感覺(jué)可能是本人還沒(méi)有理解掌握吃透“仿順序操作”的精髓吧。

(5)根據(jù)中心像素點(diǎn)的行、列位置信息得到每個(gè)窗口元素的ROM地址,根據(jù)某一時(shí)刻ROM地址,下一時(shí)刻調(diào)用ROM模塊得到對(duì)應(yīng)的元素?cái)?shù)據(jù),下一時(shí)刻將數(shù)據(jù)鎖存,然后再讀取該地址的數(shù)據(jù);所以要注意地址和數(shù)據(jù)的獲取不是在同一時(shí)刻,而是需要延遲兩個(gè)時(shí)刻;

(6)還需要注意的是圖像的邊界問(wèn)題的特殊化處理;一般圖像處理都會(huì)遇到邊界問(wèn)題,這個(gè)需要謹(jǐn)慎;

(7)對(duì)matlab的中值濾波函數(shù)medfilt2原理的深入掌握對(duì)我們編寫(xiě)這一模塊非常重要。matlab并沒(méi)有主要過(guò)程的代碼,看注釋默認(rèn)情況下邊界元素設(shè)置為0,這也可以通過(guò)結(jié)果反推回去發(fā)現(xiàn)的。

3)計(jì)數(shù)器控制模塊,主要用于獲得中心像素點(diǎn)的地址信息。

(1)系統(tǒng)模塊開(kāi)始信號(hào)之后開(kāi)始獲取第一個(gè)中心像素點(diǎn),注意初始化信號(hào)值和系統(tǒng)開(kāi)始的信號(hào)值的區(qū)別;

(2)該時(shí)刻得到的的數(shù)據(jù)將在下一個(gè)時(shí)刻產(chǎn)生結(jié)果,該時(shí)刻的數(shù)據(jù)并沒(méi)有改變;

(3)注意中心像素點(diǎn)的行、列位置信息的計(jì)算;

4) 3*3中值濾波模塊

功能:得到某一中心像素點(diǎn)的3*3滑窗區(qū)域的灰度值的中值,作為中心像素點(diǎn)的值;

中值濾波原理,網(wǎng)上有很多,大家可以查看一下。

本項(xiàng)目采用的是快速中值濾波的方法。

(1)若是3*3窗口生成模塊完成之后就計(jì)算下一個(gè)中心像素點(diǎn),需要將該中心像素點(diǎn)的窗口元素鎖存起來(lái),以防計(jì)算過(guò)程中將這些元素掩蓋,不能正確進(jìn)行中值濾波的計(jì)算;

(2)需要在時(shí)序的有效區(qū)域內(nèi)進(jìn)行計(jì)算,怎么設(shè)計(jì)信號(hào)的有效性;

(3)仿順序操作可以分開(kāi)進(jìn)行;每一個(gè)時(shí)刻只進(jìn)行一個(gè)操作,這樣可能更明了(代碼中沒(méi)有這樣做);

(4)verilog編程調(diào)用函數(shù)的方法,指出輸入信號(hào),函數(shù)內(nèi)可以使用其他定義聲明的信號(hào),最后的輸出信號(hào)作為調(diào)用函數(shù)的結(jié)果(突然想起來(lái),如果輸出信號(hào)有多個(gè)元素呢,又該怎么辦呢?大家可以想想);

該模塊的代碼:

5)頂層模塊

用于將低層的各個(gè)功能/控制模塊銜接起來(lái),得到結(jié)果;注意輸入輸出信號(hào),以及不同模塊之間是如何進(jìn)行連線的。信號(hào)的名稱(chēng)盡量有其特別的意義,不要重復(fù)使用同一個(gè)信號(hào)名稱(chēng),容易造成混亂;

區(qū)別wire和reg類(lèi)型數(shù)據(jù)的使用情況;

6)測(cè)試模塊

如何將數(shù)據(jù)寫(xiě)入文件,需要定義文件的名稱(chēng)和類(lèi)型;

integer fouti;

需要在初始化部分打開(kāi)文件:

fouti = $fopen("medfilter2_re.txt");

代碼如下:

整體的代碼就是這樣的。

3、對(duì)各個(gè)模塊進(jìn)行語(yǔ)法檢查、波形仿真、時(shí)序設(shè)計(jì)、調(diào)試驗(yàn)證;

本人覺(jué)得原理清楚之后按部就班的編寫(xiě)代碼還好,只是剛接觸波形仿真和調(diào)試的時(shí)候是真心不順心,還好有其他人幫忙調(diào)試;在調(diào)試的過(guò)程中其實(shí)會(huì)學(xué)習(xí)到很多東西,很多經(jīng)驗(yàn),以及很簡(jiǎn)單的但你之前就是不知道的知識(shí),這就是一個(gè)實(shí)踐的過(guò)程,有時(shí)候你根本不知道錯(cuò)誤在哪里,這怎么會(huì)是錯(cuò)誤的呢,為什么不可以這樣寫(xiě),我覺(jué)得這樣寫(xiě)才是正確的,這些就是在調(diào)試過(guò)程中本人的真實(shí)心情寫(xiě)照呀??墒牵瑳](méi)有那么多為什么,verilog就是這樣編程的,只是你不知道而已!這才是最傷人的,因?yàn)槟悴恢溃?/p>

仿真調(diào)試的過(guò)程中遇到的問(wèn)題以及解決方法有空專(zhuān)門(mén)寫(xiě)一篇,調(diào)試的過(guò)程中最好是一個(gè)一個(gè)模塊的測(cè)試,特別是關(guān)鍵信號(hào)的數(shù)值,最好搞懂整體模塊和各個(gè)模塊的時(shí)序設(shè)計(jì)過(guò)程,推薦使用TimeDesigner進(jìn)行波形的設(shè)計(jì);另外還需要有關(guān)聯(lián)的兩個(gè)甚至多個(gè)不同模塊信號(hào)的交叉仿真驗(yàn)證。

4、與matlab的中值濾波結(jié)果進(jìn)行比較

使用matlab編程基于自帶的中值濾波函數(shù)得到處理之后的圖像與數(shù)據(jù),并將verilog得到的濾波數(shù)據(jù)轉(zhuǎn)換為圖像,將二者進(jìn)行比較

使用matlab自帶的中值濾波函數(shù)medfilt2生成原圖像的灰度圖像的濾波數(shù)據(jù);

% mcode to median filter for one jpg image, and create a image data filesrc = imread('lena.jpg');gray = rgb2gray(src);medfilt2im = medfilt2( gray );[m, n] = size( medfilt2im );                  % m行 n列N = m*n;                               %%數(shù)據(jù)的長(zhǎng)度,即存儲(chǔ)器深度。word_len = 8;                          %%每個(gè)單元的占據(jù)的位數(shù),需自己設(shè)定lena_gray = reshape(gray', 1, N);% 1行N列lena_medfilt = reshape(medfilt2im', 1, N);% 1行N列fid_gray=fopen('lena_gray.txt', 'wt');       %打開(kāi)文件fid_medfilt=fopen('lena_medfilt.txt', 'wt');       %打開(kāi)文件% fprintf(fid, 'MEMORY_INITIALIZATION_RADIX=16;n');% fprintf(fid, 'MEMORY_INITIALIZATION_VECTOR=n');for i = 1 : N-1fprintf(fid_gray, '%d,n', lena_gray(i));%使用%x表示十六進(jìn)制數(shù)endfprintf(fid_gray, '%d;n', data(N));                 %%輸出結(jié)尾,每個(gè)數(shù)據(jù)后面用逗號(hào)或者空格或者換行符隔開(kāi),最后一個(gè)數(shù)據(jù)后面加分號(hào)fclose(fid_gray);                            %%關(guān)閉文件for i = 1 : N-1fprintf(fid_medfilt, '%d,n', lena_medfilt(i));%使用%x表示十六進(jìn)制數(shù)endfprintf(fid_medfilt, '%d;n', lena_medfilt(N));                 %%輸出結(jié)尾,每個(gè)數(shù)據(jù)后面用逗號(hào)或者空格或者換行符隔開(kāi),最后一個(gè)數(shù)據(jù)后面加分號(hào)fclose(fid_medfilt);                            %%關(guān)閉文件

將medfilt2函數(shù)和verilog產(chǎn)生的濾波數(shù)據(jù)轉(zhuǎn)換為圖像,并與matlab直接產(chǎn)生的濾波圖像進(jìn)行對(duì)比,代碼如下:

% code to create image data from txt fileclc;clear all;close all;I_rgb = imread('lena.jpg');subplot(2, 3, 1), imshow(I_rgb), title('lena-rgb')
I_gray = rgb2gray(I_rgb);subplot(2, 3, 2), imshow(I_gray), title('lena-gray')
medfilt_m_load = load('.lena_medfilt.txt');%medfilt_m_load = load('.lena.coe');medfilt_v_load = load('.medfilter2_reV1.txt'); % verilog 產(chǎn)生的中值濾波之后數(shù)據(jù)
medfilt2im = medfilt2( I_gray );subplot(2, 3, 3), imshow(medfilt2im), title('lena-medfilt2')
m = 512;n = 512;medfilt_m = reshape(medfilt_m_load, m, n);medfilt_v = reshape(medfilt_v_load, m, n);medfilt_m = uint8(medfilt_m');medfilt_v = uint8(medfilt_v');
aa = medfilt2im - medfilt_m;bb = medfilt2im - medfilt_v;cc = medfilt_m - medfilt_v;
subplot(2, 3, 5), imshow(medfilt_m), title('medfilt-matlab');subplot(2, 3, 6), imshow(medfilt_v), title('medfilt-verilog');

顯示的結(jié)果如下圖所示:

結(jié)果:兩種濾波產(chǎn)生的圖像數(shù)據(jù)完全一致,不過(guò)感覺(jué)函數(shù)直接產(chǎn)生的圖像顏色更深一些,不知道為什么。

這里需要了解一下medfilt2這個(gè)函數(shù)的原理。結(jié)果數(shù)據(jù)表明,默認(rèn)情況下該函數(shù)對(duì)圖像邊界采用的是補(bǔ)0的方法進(jìn)行處理的。

結(jié)論

中值濾波終于告一段落了!簡(jiǎn)單的問(wèn)題還是需要深入進(jìn)去研究的,實(shí)踐的過(guò)程中你才會(huì)發(fā)現(xiàn)自己之前了解的東西是多么的淺薄,對(duì)已知的知識(shí)掌握的是多么的流于表面!最后結(jié)果的數(shù)據(jù)還是很讓人開(kāi)心的!

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
EP3C16F256C8N 1 Intel Corporation Field Programmable Gate Array, 15408 CLBs, 472.5MHz, 15408-Cell, CMOS, PBGA256, 17 X 17 MM, 1.55 MM HEIGHT, 1 MM PITCH, LEAD FREE, FBGA-256
$356.96 查看
EP4CE6U14I7N 1 Altera Corporation Field Programmable Gate Array, 6272-Cell, PBGA256, LEAD FREE, UBGA-256
$19.6 查看
XC3S700A-4FGG400C 1 AMD Xilinx Field Programmable Gate Array, 1472 CLBs, 700000 Gates, 250MHz, 13248-Cell, CMOS, PBGA400, LEAD FREE, FPBGA-400
$48.97 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

任何技術(shù)的學(xué)習(xí)就好比一個(gè)江湖,對(duì)于每一位俠客都需要不斷的歷練,從初入江湖的小白到歸隱山林的隱世高人,需要不斷的自我感悟自己修煉,讓我們一起仗劍闖FPGA乃至更大的江湖。