圖像的卷積(濾波)運算(二)——高斯濾波

1. 高斯濾波原理

根據數學知識,一維高斯函數能夠描述爲:

在圖像處理中,選定X方向上長度爲3的窗口,令δ=1,中心座標爲1,由上述公式,其卷積核(Xa,X,Xb)能夠以下計算:ios

Xa = exp(-1*(0-1)(0-1)/(2*1*1))= 0.606530659712633
X = exp(-1*(1-1)(1-1)/(2*1*1))= 1
Xb = exp(-1*(2-1)(2-1)/(2*1*1))= 0.606530659712633

能夠看到計算過程沒有用到常數部分,是由於須要歸一化,常數部分能夠省略:算法

Sum = Xa + X + Xb = 2.2130613194252668
Xa = Xa/Sum = 0.274068619061197
X = X/Sum = 0.451862761877606
Xb = Xb/Sum = 0.274068619061197

經過OpenCV驗證下上述結果是否正確,OpenCV能夠經過函數getGaussianKernel()來實現計算高斯核,運行以下代碼,能夠發現二者的計算結果是一致的。函數

Mat kernelX = getGaussianKernel(3, 1);
cout << kernelX <<  endl;

2. 圖像二維卷積

上述的推導過程都是一維的,那麼二維狀況下的卷積核怎麼計算呢,其實很簡單,轉置並相乘就能夠了:學習

Mat kernelX = getGaussianKernel(3, 1);
cout << kernelX <<  endl;

Mat kernelY = getGaussianKernel(3, 1);
Mat G = kernelX * kernelY.t();
cout << G << endl << endl << endl;

運行結果:

在獲得卷積核以後,將其放到圖像中進行二維卷積,對於原圖像中的一個像素P(x,y),有以下卷積過程:

將窗口覆蓋的對應位置的像素值相乘後相加,便可獲得新圖像對應位置的像素值Q(x,y)。當對圖像全部的像素值都這樣作時,就能夠獲得濾波後的圖像。因爲通常狀況下老是順序去卷積的,從左至右,由上而下,因此這個過程就是卷積核的滑動。spa

當滑動到邊界的時候,就會產生一個問題,就是卷積覈對應的位置沒有像素值。這時能夠將邊界像素值捨棄(卷積),或者自動填充爲0(濾波)。.net

3. 具體實現

在OpenCV中,能夠直接使用GaussianBlur()函數實現高斯濾波,可是爲了驗證和學習高斯濾波算法,也能夠本身構建高斯卷積核,使用濾波函數filter2D()進行濾波。其具體實現以下:code

#include <iostream>
#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;

int main()
{   
    //從文件中讀取成灰度圖像
    const char* imagename = "C:\\Data\\imgDemo\\lena.jpg";
    Mat img = imread(imagename, IMREAD_GRAYSCALE);
    if (img.empty())
    {
        fprintf(stderr, "Can not load image %s\n", imagename);
        return -1;
    }

    //直接高斯濾波
    Mat dst1;
    GaussianBlur(img, dst1, Size(3, 3), 1, 1);
    
    //自定義高斯濾波器
    Mat kernelX = getGaussianKernel(3, 1);
    Mat kernelY = getGaussianKernel(3, 1);
    Mat G = kernelX * kernelY.t();
    Mat dst2;
    filter2D(img, dst2, -1, G);
    
    //比較二者的結果
    Mat c;
    compare(dst1, dst2, c, CMP_EQ);

    //
    imshow("原始", img);
    imshow("高斯濾波1", dst1);
    imshow("高斯濾波2", dst2);
    imshow("比較結果", c);
    
    waitKey();

    return 0;
}

能夠看到這裏分別用GaussianBlur()和filter2D()進行了高斯濾波,並經過compare()函數進行比較。運行結果以下所示,二者的濾波結果基本一致,說明構建的卷積核是正確的。
htm

4. 參考資料

1.OpenCV實現二維高斯核GaussianKernel
2.opencv3.2.0圖像處理之高斯濾波GaussianBlur API函數
3.OpenCV高斯濾波器詳解及代碼實現blog

相關文章
相關標籤/搜索