opencv學習(二十二)之雙邊濾波bilateralFilter

雙邊濾波是一種非線性的濾波方法,是結合圖像的空間鄰近度和像素值相似度的一種折衷處理,同時考慮空間與信息和灰度相似性,達到保邊去噪的目的,具有簡單、非迭代、局部處理的特點。之所以能夠達到保邊去噪的濾波效果是因爲濾波器由兩個函數構成:一個函數是由幾何空間距離決定濾波器係數,另一個是由像素差值決定濾波器係數。
雙邊濾波器中,輸出像素的值依賴於鄰域像素的值的加權組合,其公式如下:
這裏寫圖片描述
權重係數w(i,j,k,l)取決於定義域核
這裏寫圖片描述
和值域核
這裏寫圖片描述
的乘積,也就是
這裏寫圖片描述

通俗來講就是雙邊濾波模板主要有兩個模板生成,第一個是高斯模板,第二個是以灰度級的差值作爲函數係數生成的模板,然後這兩個模板點乘就得到了最終的雙邊濾波模板,第一個模板是全局模板,所以只需要生成以西,第二個模板需要對每個像素都計算一次。雙邊濾波器比高斯濾波器多了一個高斯方差sigma-d,它是基於空間分佈的高斯濾波函數,所以在邊緣附近,離的較遠的像素不會太多影響到邊緣上的像素,這樣就能對邊緣附近的像素值予以保存,但是由於保存過多的高頻信息,對於彩色圖像裏的高頻噪聲,雙邊濾波器不能夠乾淨的濾掉,只能夠對於低頻信息進行較好的濾除。

opencv中提供了bilateralFilter()函數來實現雙邊濾波操作,其原型如下:

C++: void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )

參數解釋:
. InputArray src: 輸入圖像,可以是Mat類型,圖像必須是8位或浮點型單通道、三通道的圖像。
. OutputArray dst: 輸出圖像,和原圖像有相同的尺寸和類型。
. int d: 表示在過濾過程中每個像素鄰域的直徑範圍。如果這個值是非正數,則函數會從第五個參數sigmaSpace計算該值。
. double sigmaColor: 顏色空間過濾器的sigma值,這個參數的值月大,表明該像素鄰域內有月寬廣的顏色會被混合到一起,產生較大的半相等顏色區域。
. double sigmaSpace: 座標空間中濾波器的sigma值,如果該值較大,則意味着顏色相近的較遠的像素將相互影響,從而使更大的區域中足夠相似的顏色獲取相同的顏色。當d>0時,d指定了鄰域大小且與sigmaSpace五官,否則d正比於sigmaSpace.
. int borderType=BORDER_DEFAULT: 用於推斷圖像外部像素的某種邊界模式,有默認值BORDER_DEFAULT.

雙邊濾波器可以很好的保存圖像邊緣細節而濾除掉低頻分量的噪音,但是雙邊濾波器的效率不是太高,花費的時間相較於其他濾波器而言也比較長。
對於簡單的濾波而言,可以將兩個sigma值設置成相同的值,如果值<10,則對濾波器影響很小,如果值>150則會對濾波器產生較大的影響,會使圖片看起來像卡通。
示例代碼:

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

//定義全局變量
const int g_ndMaxValue = 100;
const int g_nsigmaColorMaxValue = 200;
const int g_nsigmaSpaceMaxValue = 200;
int g_ndValue;
int g_nsigmaColorValue;
int g_nsigmaSpaceValue;

Mat g_srcImage;
Mat g_dstImage;

//定義回調函數
void on_bilateralFilterTrackbar(int, void*);

int main()
{
    g_srcImage = imread("lena.jpg");

    //判斷圖像是否加載成功
    if(g_srcImage.empty())
    {
        cout << "圖像加載失敗!" << endl;
        return -1;
    }
    else
        cout << "圖像加載成功!" << endl << endl;

    namedWindow("原圖像", WINDOW_AUTOSIZE);
    imshow("原圖像", g_srcImage);

    //定義輸出圖像窗口屬性和軌跡條屬性
    namedWindow("雙邊濾波圖像", WINDOW_AUTOSIZE);
    g_ndValue = 10;
    g_nsigmaColorValue = 10;
    g_nsigmaSpaceValue = 10;

    char dName[20];
    sprintf(dName, "鄰域直徑 %d", g_ndMaxValue);

    char sigmaColorName[20];
    sprintf(sigmaColorName, "sigmaColor %d", g_nsigmaColorMaxValue);

    char sigmaSpaceName[20];
    sprintf(sigmaSpaceName, "sigmaSpace %d", g_nsigmaSpaceMaxValue);

    //創建軌跡條
    createTrackbar(dName, "雙邊濾波圖像", &g_ndValue, g_ndMaxValue, on_bilateralFilterTrackbar);
    on_bilateralFilterTrackbar(g_ndValue, 0);

    createTrackbar(sigmaColorName, "雙邊濾波圖像", &g_nsigmaColorValue,
                     g_nsigmaColorMaxValue, on_bilateralFilterTrackbar);
    on_bilateralFilterTrackbar(g_nsigmaColorValue, 0);

    createTrackbar(sigmaSpaceName, "雙邊濾波圖像", &g_nsigmaSpaceValue,
                    g_nsigmaSpaceMaxValue, on_bilateralFilterTrackbar);
    on_bilateralFilterTrackbar(g_nsigmaSpaceValue, 0);

    waitKey(0);

    return 0;
}

void on_bilateralFilterTrackbar(int, void*)
{
    bilateralFilter(g_srcImage, g_dstImage, g_ndValue, g_nsigmaColorValue, g_nsigmaSpaceValue);
    imshow("雙邊濾波圖像", g_dstImage);
}

程序運行結果如下:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章