圖像處理領域的線性濾波器主要包括均值濾波和高斯濾波等平滑濾波器,此外,還有Sobel算子、Laplas算子和梯度運算等銳化濾波器。線性濾波通常的處理方法是利用一個指定尺寸的掩模(mask)對圖像進行卷積,通常,這個掩模(mask)也可以稱為濾波器(filter)、 核(kernel)、模板(template)和窗(window) 等。這里給出線性濾波器的定義如下:設r為處理窗口的半徑,f(i,j) 為窗口內模板的灰度值, I(x, y)為輸入像素值,g(x,y)
為輸出像素值,則有如下定義:
令g(x,y)滑過整幅圖像,即對整幅圖像做一個 卷積處理,就得到最后的濾波結果。由卷積定理可以得到,在頻域將模板直接與圖像進行像素相乘也可以達到相同的目的。
均值濾波是典型的線性濾波算法,主要方法為鄰域平均法,即用一個圖像區域的各個像素的平均值來代替原圖像的各個像素值。均值濾波的主要作用是減小圖像灰度值的“尖銳”變化從而達到減小噪聲的目的。但是,由於圖像邊緣在一般情況下也是由圖像灰度尖銳化引起的,因此,均值濾波也存在邊緣模糊的問題。
一、理論分析
一般來說, 圖像具有局部連續性質,即相鄰像素的數值相近,而噪聲的存在使得在噪聲點處產生灰度跳躍,但- -般我們可以合理地假設偶爾出現的噪聲影響並沒有改變圖像局部連續的性質,例如下面的局部圖像 f _sub,灰色底紋標識的為噪聲點,在圖像中表現為亮區中的 2 個暗點:

對 f 用 3X3 的平均模板進行平滑濾波后,得到的平滑后圖像 g_ sub:

顯然,通過平滑濾波原局部圖像 f_sub 中噪聲點的灰度值得到了有效修正,像這樣將每一個點用周圍點的平均替代從而達到減少噪聲影響的過程就稱為平滑或模糊。隨着模板的增大,濾波過程在平滑更多噪聲的同時也使得圖像變得越來越模糊,這是由平均模板的工作機理決定的。當圖像細節與濾波器模板大小相近時,圖像細節就會受到比較大的影響,尤其當它們的灰度值比較接近時,混合效應導致的圖像模糊會更明顯。隨着模板地進一步增大,很多細節都會被當作噪聲平滑掉。因此,我們在確定模板尺寸時應仔細考慮要濾除的噪聲點的大小,有針對性地進行濾波。
以 3x3 為例,均值濾波說白了就是將圖像數據生成3x3的矩陣,對這九個數求個平均值代替中間的那個數。在FPGA中我們為了簡便運算只將目標像素周圍八個點求和然后除以8,取代中間像素點。

二、MATLAB實現
clc; clear all; close all; RGB = imread('flower.bmp'); %讀取圖片 imgn = imnoise(RGB,'salt & pepper',0.05); %椒鹽密度0.05 gray = im2double(rgb2gray(imgn)); %灰度圖 [ROW,COL, DIM] = size(gray); %得到圖像行列數 %-------------------------------------------------------------------------- % Mean Filter 均值濾波 %-------------------------------------------------------------------------- Mean_Img = zeros(ROW,COL); for r = 2:1:ROW-1 for c = 2:1:COL-1 Mean_Img(r,c) = (gray(r-1, c-1) + gray(r-1, c) + gray(r-1, c+1) + gray(r, c-1) + gray(r, c) + gray(r, c+1) + gray(r+1, c-1) + gray(r+1, c) + gray(r+1, c+1)) / 9; end end %-------------------------------------------------------------------------- % Show Image %-------------------------------------------------------------------------- subplot(2,2,1); imshow(RGB); title('原圖'); subplot(2,2,2); imshow(imgn); title('椒鹽噪聲'); subplot(2,2,3); imshow(gray); title('灰度圖'); subplot(2,2,4); imshow(Mean_Img); title('均值濾波'); % 由實驗可知: % 1、均值濾波會使得圖像模糊,其實是做了平滑處理,像素值高的會被拉低,像素值低的會被拉高,趨向於一個平均值。 % 2、椒鹽噪聲就是黑白噪聲,均值濾波對椒鹽噪聲基本無作用,必須使用中值濾波才行。
點擊運行,得到如下結果:

由結果看出:均值濾波對略去了部分噪聲,但不如上篇的中值濾波效果好。中值濾波后,圖片變的模糊,其實是做了平滑處理,像素值高的會被拉低,像素值低的會被拉高,趨向於一個平均值。
三、FPGA實現
1、形成3x3矩陣
這個在前面的博客花了3篇來解釋,就不多說了,我把3x3矩陣的代碼用一個專門的 .v 文件寫好,這里直接調用即可。輸入是灰度數據,即 YCbCr格式中的 8bit Y分量,輸出是矩陣數據。耗費 1 個時鍾周期。
//========================================================================== //== matrix_3x3_8bit,生成3x3矩陣,輸入和使能需對齊,耗費1clk //========================================================================== //--------------------------------------------------- 矩陣順序 // {matrix_11, matrix_12, matrix_13} // {matrix_21, matrix_22, matrix_23} // {matrix_31, matrix_32, matrix_33} //--------------------------------------------------- 模塊例化 matrix_3x3_8bit #( .COL (480 ), .ROW (272 ) ) u_matrix_3x3_8bit ( .clk (clk ), .rst_n (rst_n ), .din_vld (Y_de ), .din (Y_data ), .matrix_11 (matrix_11 ), .matrix_12 (matrix_12 ), .matrix_13 (matrix_13 ), .matrix_21 (matrix_21 ), .matrix_22 (matrix_22 ), .matrix_23 (matrix_23 ), .matrix_31 (matrix_31 ), .matrix_32 (matrix_32 ), .matrix_33 (matrix_33 ) );
2、均值濾波
本來的均值濾波是周圍8個像素包括自己共9個,相加除以9,FPGA不適合做除法,因此改成只取周圍8個像素,相加除以8,即右移3位,即取高8位。共耗費 2 個時鍾周期。
//mean ---------------------------------------------- reg [10:0] mean1 ; reg [10:0] mean2 ; reg [10:0] mean3 ; reg [10:0] mean4 ; //========================================================================== //== 均值濾波,耗費2clk //========================================================================== //clk 1 //--------------------------------------------------- always @(posedge clk or negedge rst_n) begin if(!rst_n) begin mean1 <= 'd0; mean2 <= 'd0; mean3 <= 'd0; end else begin mean1 <= matrix_11 + matrix_12 + matrix_13; mean2 <= matrix_21 + + matrix_23; mean3 <= matrix_31 + matrix_32 + matrix_33; end end //clk 2 //--------------------------------------------------- always@(posedge clk or negedge rst_n) begin if(!rst_n) mean4 <= 'd0; else mean4 <= mean1 + mean2 + mean3; end assign mean_data = mean4[10:3];
3、信號同步
形成 3x3 矩陣耗費 1clk,均值濾波耗費 2clk,因此行場和使能信號都需要延遲3拍。
//========================================================================== //== 信號同步 //========================================================================== always @(posedge clk or negedge rst_n) begin if(!rst_n) begin Y_de_r <= 3'b0; Y_hsync_r <= 3'b0; Y_vsync_r <= 3'b0; end else begin Y_de_r <= {Y_de_r[1:0], Y_de}; Y_hsync_r <= {Y_hsync_r[1:0], Y_hsync}; Y_vsync_r <= {Y_vsync_r[1:0], Y_vsync}; end end assign mean_de = Y_de_r[2]; assign mean_hsync = Y_hsync_r[2]; assign mean_vsync = Y_vsync_r[2];
四、上板驗證
灰度圖:

均值濾波后:

從實驗結果看出,圖片變得模糊了,其實是平滑了,實驗成功。
我的板子壞了,出現一些不該有的橫條,如果是好的板子則沒有這些鬼東西。
[1] OpenS Lee:FPGA開源工作室(公眾號)
[2] CrazyBingo:基於VIP_Board Mini的FPGA視頻圖像算法(HDL-VIP)開發教程-V1.6
[3] NingHechuan:FPGA圖像處理教程
