高斯濾波詳解 附python和matlab高斯濾波代碼


一. 高斯濾波

        高斯濾波是一種線性平滑濾波器,對於服從正態分布的噪聲有很好的抑制作用。在實際場景中,我們通常會假定圖像包含的噪聲為高斯白噪聲,所以在許多實際應用的預處理部分,都會采用高斯濾波抑制噪聲。

        高斯濾波和均值濾波一樣,都是利用一個掩膜和圖像進行卷積求解。不同之處在於:均值濾波器的模板系數都是相同的,為1。而高斯濾波器的模板系數,隨着距離模板中心距離的增大,系數減小(服從二維高斯分布)。所以,高斯濾波器相比於均值濾波器而言,對圖像模糊程度較小,更能保持圖像的整體細節。

二維高斯分布

        我們不必糾結於系數\frac{1}{(\sqrt{2*π}*\sigma)^2   } ,因為它只是一個常數!並不會影響互相之間的比例關系,而且最終都要進行歸一化,所以在實際計算時我們忽略它而只計算后半部分 e^{-((x-ux)^2+(y-uy)^2)/2\sigma ^2}

        其中(x,y)為掩膜內任一點的坐標,(ux,uy)為掩膜內中心點的坐標,在圖像處理中可認為是整數;σ是標准差。

        例如:要產生一個3×3的高斯濾波器模板,以模板的中心位置為坐標原點進行取樣。(x軸水平向右,y軸豎直向下)  


模板在各個位置的坐標,如上圖所示↑

        這樣,將各個位置的坐標帶入到高斯函數中,得到的值就是濾波器的系數。

        如果窗口模板的大小為 (2k+1)×(2k+1),則:

窗口模板中各個元素的計算公式

        這樣計算出來的模板有兩種形式:小數和整數。

        小數形式的模板,就是直接計算得到的值,沒有經過任何的處理;

        整數形式的模板,需要進行歸一化處理,將模板左上角的值歸一化為1。使用整數的模板時,需要在模板的前面加一個系數,系數為模板中元素和的倒數。

        例如,標准差 \sigma =1.3 的 3*3 的整數形式的高斯濾波器如下:


標准差 \sigma  =1.3 的8近鄰高斯濾波器如圖  

        σ的意義及選取

        通過上述的實現過程,不難發現,高斯濾波器模板的生成最重要的參數就是高斯分布的標准差σ。標准差代表着數據的離散程度,如果σ較小,那么生成的模板的中心系數較大,而周圍的系數較小,這樣對圖像的平滑效果就不是很明顯;反之,σ較大,則生成的模板的各個系數相差就不是很大,比較類似均值模板,對圖像的平滑效果比較明顯。


高斯分布的概率分布密度圖

        可以看到:σ越小分布越瘦高,σ越大分布越矮胖。

        由於圖像的長寬可能不是濾波器大小的整數倍,因此我們需要在圖像的邊緣補0,這種方法叫做 zero padding 。


二. python實現高斯濾波

        算法流程:①對圖像進行zero padding ②根據高斯濾波器的核大小和標准差大小實現高斯濾波器 ③使用高斯濾波器對圖像進行濾波(相乘再相加)④輸出高斯濾波后的圖像

        代碼如下:

import cv2

import numpy as np

# Gaussian filter

def gaussian_filter(img, K_size=3, sigma=1.3):

    if len(img.shape) == 3:

        H, W, C = img.shape

    else:

        img = np.expand_dims(img, axis=-1)

        H, W, C = img.shape

    ## Zero padding

    pad = K_size // 2

    out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float)

    out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)

    ## prepare Kernel

    K = np.zeros((K_size, K_size), dtype=np.float)

    for x in range(-pad, -pad + K_size):

        for y in range(-pad, -pad + K_size):

            K[y + pad, x + pad] = np.exp( -(x ** 2 + y ** 2) / (2 * (sigma ** 2)))

    K /= (2 * np.pi * sigma * sigma)

    K /= K.sum()

    tmp = out.copy()

    # filtering

    for y in range(H):

        for x in range(W):

            for c in range(C):

                out[pad + y, pad + x, c] = np.sum(K * tmp[y: y + K_size, x: x + K_size, c])

    out = np.clip(out, 0, 255)

    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)

    return out

# Read image

img = cv2.imread("../paojie.jpg")

# Gaussian Filter

out = gaussian_filter(img, K_size=3, sigma=1.3)

# Save result

cv2.imwrite("out.jpg", out)

cv2.imshow("result", out)

cv2.waitKey(0)

cv2.destroyAllWindows()

 


三. python程序輸出結果:


高斯濾波后圖像

原圖

四. opencv函數 cv2.GaussianBlur(img,(3,3),1.3) 實現高斯濾波

        其中,(3,3)為濾波器的大小;1.3為濾波器的標准差,如果標准差這個參數設置為0,則程序會根據濾波器大小自動計算得到標准差。

import cv2

img=cv2.imread('../paojie.jpg')

#(3, 3)表示高斯濾波器的長和寬都為3,1.3表示濾波器的標准差

out=cv2.GaussianBlur(img,(3,3),1.3)

cv2.imwrite('out.jpg',out)

cv2.imshow('result',out)

cv2.waitKey(0)

cv2.destroyAllWindows()

五. opencv函數GaussianBlur濾波結果:


GaussianBlur 函數輸出結果
六. matlab實現高斯濾波

% 高斯濾波器大小為5*5,標准差為10

clear all;close all;clc;

OriImage=imread('F:\image_process\paojie.jpg');    %讀入圖片

sigma1 = 10;      %高斯正態分布標准差

grayImg=rgb2gray(OriImage);    %轉為灰度圖像

gausFilter = fspecial('gaussian',[5 5],sigma1);  %高斯濾波

blur=imfilter(grayImg,gausFilter,'replicate');    %對任意類型數組或多維圖像進行濾波

imshow(blur);

 


七. matlab 高斯濾波輸出結果


matlab 高斯濾波后圖像

八. 參考內容:

https://www.jianshu.com/p/4eaf349de9e9


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM