精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

灰度圖像均值濾波算法的HDL實現介紹

FPGA之家 ? 來源:FPGA之家 ? 2023-10-16 09:23 ? 次閱讀

1.1均值濾波算法介紹

首先要做的是最簡單的均值濾波算法。均值濾波是典型的線性濾波算法,它是指在圖像上對目標像素給一個模板,該模板包括了其周圍的臨近像素(以目標象素為中心的周圍8個像素,構成一個濾波模板,即去掉目標像素本身),再用模板中的全體像素的平均值來代替原來像素值。

P11 P12 P13
P21 P23
P31 P32 P33

中值濾波算法可以形象的用上述表格來描述,即對于每個3*3的陣列而言,中間像素的值,等于邊緣8個像素的平均值。算法的理論很簡單,對于C處理器而言,一幅640*480圖像的均值濾波,可以很方便的通過數組獲得3*3的陣列,但對于我們的Verilog HDL而言,著實不易。

1.23*3像素陣列的HDL實現

3*3陣列的獲取,大概有以下三種方式:

(1)通過2個或3個RAM的存儲,來實現3*3像素陣列;

(2)通過2個或3個FIFO的存儲,來實現3*3像素陣列;

(3)通過2行或3行Shift_RAM的移位存儲,來實現3*3像素陣列。

不過經驗告訴大家,最方便的實現方式,非Shift_RAM莫屬了,都感覺Shift_RAM甚至是為實現3*3陣列而生的!

Quartus II中,可以利用下圖方式產生,很方便:

首先介紹一下Shift_RAM,宏定義模塊如下圖所示:

a2f3310c-6b30-11ee-939d-92fbcf53809c.png

圖6?1 QuartusII Shift_RAM IP使用界面

Shift_RAM可定義數據寬度、移位的行數、每行的深度。這里我們固然需要8Bit,640個數據每行,同時移位寄存2行即可(原因看后邊)。同時選擇時鐘使能端口clken。詳細的關于Shift_RAM的手冊參數,可在宏定義窗口右上角Document中查看,如下:

a3083606-6b30-11ee-939d-92fbcf53809c.png

手冊給出了一個非常形象的移位寄存示意圖,如下所示:

a318ddc6-6b30-11ee-939d-92fbcf53809c.png

圖6?2移位寄存示意圖

實現3*3像素陣列的大概的思路是這樣子的,Shift_RAM中存2行數據,同時與當前輸入行的數據,組成3行的陣列。

在Vivado中就沒有類似的IP,但是難不倒我,可以利用成熟的IP核實現類似上訴的移位寄存器

在《Image?06_OV5640_DDR3_Gray_Mean_FilterOV5640_DEMOuserlinebuffer_Wapper》

中實現的就是移位寄存器功能的IP,使用方法類似上訴QuartusII中的使用。

例化方式如下:

代碼6?1

1.//---------------------------------------
2.//moduleofshiftramforrawdata
3.wireshift_clk_en=per_frame_clken;
4.
5.linebuffer_Wapper#
6.(
7..no_of_lines(2),
8..samples_per_line(640),
9..data_width(8)
10.)
11.linebuffer_Wapper_m0(
12..ce(1'b1),
13..wr_clk(clk),
14..wr_en(shift_clk_en),
15..wr_rst(rst_n),
16..data_in(row3_data),
17..rd_en(shift_clk_en),
18..rd_clk(clk),
19..rd_rst(rst_n),
20..data_out({row2_data,row1_data})
21.);

源碼VIP_Matrix_Generate_3X3_8Bit文件中實現8Bit寬度的3*3像素陣列功能。具體的實現步驟如下:

(1)首先,將輸入的信號用像素使能時鐘同步一拍,以保證數據與Shift_RAM輸出的數據保持同步,如下:

代碼6?2

1.//Generate3*3matrix
2.//--------------------------------------------------------------------------
3.//--------------------------------------------------------------------------
4.//--------------------------------------------------------------------------
5.//syncrow3_datawithper_frame_clken&row1_data&raw2_data
6.wire[7:0]row1_data;//framedataofthe1throw
7.wire[7:0]row2_data;//framedataofthe2throw
8.reg[7:0]row3_data;//framedataofthe3throw
9.always@(posedgeclkornegedgerst_n)
10.begin
11.if(!rst_n)
12.row3_data<=?0;??
13.else
14.begin
15.if(per_frame_clken)
16.row3_data<=?per_img_Y;??
17.else
18.row3_data<=?row3_data;??
19.end
20.end

(2)接著,例化并輸入row3_data,此時可從Modelsim中觀察到3行數據同時存在了,HDL如下:

代碼6?3 QuartusII例化移位寄存器代碼

1.//---------------------------------------
2.//moduleofshiftramforrawdata
3.wireshift_clk_en=per_frame_clken;
4.Line_Shift_RAM_8Bit
5.#(
6..RAM_Length(IMG_HDISP)
7.)
8.u_Line_Shift_RAM_8Bit
9.(
10..clock(clk),
11..clken(shift_clk_en),//pixelenableclock
12.//.aclr(1'b0),
13..shiftin(row3_data),//Currentdatainput
14..taps0x(row2_data),//Lastrowdata
15..taps1x(row1_data),//Uparowdata
16..shiftout()
17.);

代碼6?4 Vivado例化移位寄存器代碼

22.//---------------------------------------
23.//moduleofshiftramforrawdata
24.wireshift_clk_en=per_frame_clken;
25.
26.linebuffer_Wapper#
27.(
28..no_of_lines(2),
29..samples_per_line(640),
30..data_width(8)
31.)
32.linebuffer_Wapper_m0(
33..ce(1'b1),
34..wr_clk(clk),
35..wr_en(shift_clk_en),
36..wr_rst(rst_n),
37..data_in(row3_data),
38..rd_en(shift_clk_en),
39..rd_clk(clk),
40..rd_rst(rst_n),
41..data_out({row2_data,row1_data})
42.);

在經過Shift_RAMd移位存儲后,我們得到的row0_data,row1_data,row2_data的仿真示意圖如下所示:

a32b811a-6b30-11ee-939d-92fbcf53809c.png

圖6?3ModelSim仿真截圖

數據從row3_data輸入,滿3行后剛好唯一3行陣列的第一。從圖像第三行輸入開始,到圖像的最后一行,我們均可從row_data得到完整的3行數據,基為實現3*3陣列奠定了基礎。不過這樣做有2個不足之處,即第一行與第二行不能得到完整的3*3陣列。但從主到次,且不管算法的完美型,我們先驗證3X3模板實現的正確性。因此直接在行有效期間讀取3*3陣列,機器方便快捷的實現了我們的目的。

(3)Row_data讀取信號的分析及生成

這里涉及到了一個問題,數據從Shift_RAM存儲耗費了一個時鐘,因此3*3陣列的讀取使能與時鐘,需要進行一個clock的偏移,如下所示:

代碼6?5

1.//------------------------------------------
2.//lag2clockssignalsync
3.reg[1:0]per_frame_vsync_r;
4.reg[1:0]per_frame_href_r;
5.reg[1:0]per_frame_clken_r;
6.always@(posedgeclkornegedgerst_n)
7.begin
8.if(!rst_n)
9.begin
10.per_frame_vsync_r<=?0;??
11.per_frame_href_r<=?0;??
12.per_frame_clken_r<=?0;??
13.end
14.else
15.begin
16.per_frame_vsync_r<=???{per_frame_vsync_r[0],??per_frame_vsync};??
17.per_frame_href_r<=???{per_frame_href_r[0],???per_frame_href};??
18.per_frame_clken_r<=???{per_frame_clken_r[0],??per_frame_clken};??
19.end
20.end
21.//Giveupthe1thand2throwedgedatacaculateforsimpleprocess
22.//Giveupthe1thand2thpointof1lineforsimpleprocess
23.wireread_frame_href=per_frame_href_r[0];//RAMreadhrefsyncsignal
24.wireread_frame_clken=per_frame_clken_r[0];//RAMreadenable
25.assignmatrix_frame_vsync=per_frame_vsync_r[1];
26.assignmatrix_frame_href=per_frame_href_r[1];
27.assignmatrix_frame_clken=per_frame_clken_r[1];

(4)Okay,此時根據read_frame_href與read_frame_clken信號,直接讀取3*3像素陣列。讀取的HDL實現如下:

代碼6?6

1. //----------------------------------------------------------------------------
2. //----------------------------------------------------------------------------
3. /******************************************************************************
4. ----------ConvertMatrix----------
5. [P31->P32->P33->]--->[P11P12P13]
6. [P21->P22->P23->]--->[P21P22P23]
7. [P11->P12->P11->]--->[P31P32P33]
8. ******************************************************************************/
9. //---------------------------------------------------------------------------
10. //---------------------------------------------------
11. /***********************************************
12. (1)ReaddatafromShift_RAM
13. (2)CaculatetheSobel
14. (3)SteadydataafterSobelgenerate
15. ************************************************/
16. //wire[23:0]matrix_row1={matrix_p11,matrix_p12,matrix_p13};//Justfortest
17. //wire[23:0]matrix_row2={matrix_p21,matrix_p22,matrix_p23};
18. //wire[23:0]matrix_row3={matrix_p31,matrix_p32,matrix_p33};
19. always@(posedgeclkornegedgerst_n)
20. begin
21. if(!rst_n)
22. begin
23. {matrix_p11,matrix_p12,matrix_p13}<=?24'h0;??
24. {matrix_p21,matrix_p22,matrix_p23}<=?24'h0;??
25. {matrix_p31,matrix_p32,matrix_p33}<=?24'h0;??
26. end
27. elseif(read_frame_href)
28. begin
29. if(read_frame_clken)//Shift_RAMdatareadclockenable
30. begin
31. {matrix_p11,matrix_p12,matrix_p13}<=?{matrix_p12,?matrix_p13,?row1_data};?//1th?shift?input??
32. {matrix_p21,matrix_p22,matrix_p23}<=?{matrix_p22,?matrix_p23,?row2_data};?//2th?shift?input??
33. {matrix_p31,matrix_p32,matrix_p33}<=?{matrix_p32,?matrix_p33,?row3_data};?//3th?shift?input??
34. end
35. else
36. begin
37. {matrix_p11,matrix_p12,matrix_p13}<=?{matrix_p11,?matrix_p12,?matrix_p13};??
38. {matrix_p21,matrix_p22,matrix_p23}<=?{matrix_p21,?matrix_p22,?matrix_p23};??
39. {matrix_p31,matrix_p32,matrix_p33}<=?{matrix_p31,?matrix_p32,?matrix_p33};??
40. end
41. end
42. else
43. begin
44. {matrix_p11,matrix_p12,matrix_p13}<=?24'h0;??
45. {matrix_p21,matrix_p22,matrix_p23}<=?24'h0;??
46. {matrix_p31,matrix_p32,matrix_p33}<=?24'h0;??
47. end
48. end

最后得到的matrix_p11、p12、p13、p21、p22、p23、p31、p32、p33即為得到的3*3像素陣列,仿真時序圖如下所示:

a33c0c92-6b30-11ee-939d-92fbcf53809c.png

前面Shift_RAM存儲耗費了一個時鐘,同時3*3陣列的生成耗費了一個時鐘,因此我們需要人為的將行場信號、像素使能讀取信號移動2個時鐘,如下所示:

assign matrix_frame_vsync =per_frame_vsync_r[1];

assign matrix_frame_href =per_frame_href_r[1];

assign matrix_frame_clken =per_frame_clken_r[1];

至此我們得到了完整的3*3像素陣列的模塊,同時行場、使能時鐘信號與時序保持一致,Modelsim仿真圖如下所示:

a35689dc-6b30-11ee-939d-92fbcf53809c.png

1.3Mean_Filter均值濾波算法的實現

不過相對于3*3像素陣列的生成而言,均值濾波的算法實現反而難度小的多,只是技巧性的問題。

繼續分析上面這個表格。其實HDL完全有這個能力直接計算8個值相加的均值,不過為了提升電路的速度,建議我們需要通過以面積換速度的方式來實現。So這里需要3個步驟:

(1)分別計算3行中相關像素的和;

(2)計算(1)中三個結果的和;

在(2)運算后,我們不能急著用除法去實現均值的運算。記住,能用移位替換的,絕對不用乘除法來實現。這里8個像素,即除以8,可以方便的用右移動3Bit來實現。不過這里更方便的辦法是,直接提取mean_value4[10:3]。

這一步我們不單獨作為一個Step,而是直接作為結果輸出。分析前面的運算,總共耗費了2個時鐘,因此需要將行場信號、像素讀取信號偏移2個時鐘,同時像素時鐘,根據行信號使能,直接讀取mean_value4[10:3],如下所示:

這樣,我們便得到了運算后的時序,實現了均值濾波算法。

最后,在Video_Image_Processor頂層文件中例化Gray_Mean_Filter算法模塊,完成算法的添加。

最后直接將生成的post_img_Y輸入給24Bit的DDR控制器即可。









審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • RAM
    RAM
    +關注

    關注

    8

    文章

    1367

    瀏覽量

    114541
  • HDL
    HDL
    +關注

    關注

    8

    文章

    327

    瀏覽量

    47344
  • 移位寄存器
    +關注

    關注

    2

    文章

    258

    瀏覽量

    22238
  • 濾波算法
    +關注

    關注

    2

    文章

    88

    瀏覽量

    13710
  • FIFO存儲
    +關注

    關注

    0

    文章

    103

    瀏覽量

    5965

原文標題:灰度圖像的均值濾波算法的 HDL 實現

文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    基于FPGA的均值濾波算法實現

      我們為了實現動態圖像濾波算法,用串口發送圖像數據到FPGA開發板,經FPGA進行圖像處理
    發表于 01-02 16:26 ?5107次閱讀

    基于FPGA的HDTV視頻圖像灰度直方圖統計算法設計

    本文介紹了如何在FPGA 中利用Block RAM 的特殊結構實現HDTV 視頻增強算法灰度直方圖統計。灰度直方圖統計
    發表于 05-14 12:37

    請教一種可識別未受污染點的中值/均值濾波matlab程序

    小弟最近需要學習一種關于灰度圖像去噪的改進算法,它需要在原始的中值濾波或者均值濾波器上加以改進,
    發表于 03-30 17:06

    基于FPGA的均值濾波算法實現

    均值濾波如圖所示,我們要進行均值濾波首先要生成一個3x3矩陣。算法運算窗口一般采用奇數點的鄰域來計算中值,最常用的窗口有3X3和5X5模型
    發表于 08-28 11:34

    基于FPGA的中值濾波算法實現

    均值濾波算法實現第五篇:深刻認識Shift RAM學習筆記番外篇:數字圖像處理界標準圖像 Le
    發表于 09-01 07:04

    數字圖像空域濾波算法的FPGA設計與實現

    本文采用的圖像是256×256大小的灰度圖像濾波模板3×3大小。如何設計硬件電路來完成上述空域濾波算法
    發表于 01-18 12:12 ?947次閱讀
    數字<b class='flag-5'>圖像</b>空域<b class='flag-5'>濾波</b><b class='flag-5'>算法</b>的FPGA設計與<b class='flag-5'>實現</b>

    灰度相關和區域特征的圖像拼接算法

    本文提出一種結合灰度特點和區域特征的圖像拼接算法。首先采用灰度直方圖均衡化的方法降低光照條件不同造成的灰度差異;其次為減少匹配塊的計算量,在
    發表于 03-07 15:34 ?60次下載
    <b class='flag-5'>灰度</b>相關和區域特征的<b class='flag-5'>圖像</b>拼接<b class='flag-5'>算法</b>

    一種加權均值濾波的改進算法

    根據椒鹽噪聲污染圖像灰度值取值范圍的變化,提出了一種改進的加權均值濾波算法。實驗結果表明,該方法能有效地去除椒鹽噪聲,同時保留了
    發表于 05-16 17:37 ?49次下載

    均值濾波均值濾波算法程序

    均值濾波是典型的線性濾波算法,它是指在圖像上對目標像素給一個模板,該模板包括了其周圍的臨近像素(以目標像素為中心的周圍個像素,構成一個
    發表于 12-19 15:35 ?6707次閱讀

    基于FPGA灰度圖像高斯濾波算法實現

    FPGA仿真篇-使用腳本命令來加速仿真二 基于FPGA的HDMI高清顯示借口驅動 基于FPGA灰度圖像高斯濾波算法實現 FPGA為什么比C
    發表于 02-20 20:49 ?7598次閱讀
    基于FPGA<b class='flag-5'>灰度</b><b class='flag-5'>圖像</b>高斯<b class='flag-5'>濾波</b><b class='flag-5'>算法</b>的<b class='flag-5'>實現</b>

    如何使用FPGA實現圖像的中值濾波算法

    圖像濾波圖像預處理過程中葦要的組成部分,而基于FPGA的濾波算法相對軟件算法而言具有高度的并行
    發表于 04-01 11:21 ?42次下載
    如何使用FPGA<b class='flag-5'>實現</b><b class='flag-5'>圖像</b>的中值<b class='flag-5'>濾波</b><b class='flag-5'>算法</b>

    如何使用FPGA實現圖像灰度級拉伸算法

    為了調整圖像數據灰度介紹了一種圖像灰度級拉伸算法的FPGA
    發表于 04-01 14:14 ?10次下載
    如何使用FPGA<b class='flag-5'>實現</b><b class='flag-5'>圖像</b><b class='flag-5'>灰度</b>級拉伸<b class='flag-5'>算法</b>

    如何使用FPGA實現圖像灰度級拉伸算法

    為了調整圖像數據灰度介紹了一種圖像灰度級拉伸算法的FPGA
    發表于 04-01 14:14 ?1次下載
    如何使用FPGA<b class='flag-5'>實現</b><b class='flag-5'>圖像</b><b class='flag-5'>灰度</b>級拉伸<b class='flag-5'>算法</b>

    詳解從均值濾波到非局部均值濾波算法的原理及實現方式

    將再啰嗦一次,詳解從均值濾波到非局部均值濾波算法的原理及實現方式。 細數主要的2D降噪
    的頭像 發表于 12-19 16:30 ?1135次閱讀
    詳解從<b class='flag-5'>均值</b><b class='flag-5'>濾波</b>到非局部<b class='flag-5'>均值</b><b class='flag-5'>濾波</b><b class='flag-5'>算法</b>的原理及<b class='flag-5'>實現</b>方式

    高斯濾波均值濾波的區別

    。 高斯濾波的核心思想是對圖像中的每一個像素點,用其鄰域內像素的加權平均灰度值來替代該點的灰度值,權重由高斯函數決定,距離中心像素點越近的像素點權重越高。
    的頭像 發表于 09-29 09:40 ?496次閱讀