雙邊濾波原理及Opencv實現
阿新 • • 發佈:2019-01-07
演算法原理
雙邊濾波是一種非線性濾波方法,是結合了影象的鄰近度和畫素值相似度的一種折中,在濾除噪聲的同時可以保留原圖的邊緣資訊。整個雙邊濾波是由兩個函式構成:一個函式是由空間距離決定的濾波器係數,另外一個詩由畫素差值決定的濾波器係數。整個雙邊濾波的公式如下:
,權重係數
取決於定義域核
和值域核
的乘積。
,其中第一個模板是全域性模板,只需要生成就可以了。第二個模板需要對每個畫素點滑動進行計算。雙邊濾波相對於高斯濾波多了一個高斯方差
,它是給予空間分佈的高斯濾波函式,所以在邊緣附近,離得較遠的畫素不會太多影響到邊緣的畫素,所以可以更好的保留邊緣資訊,但是由於保留了過多高頻資訊,對於RGB影象中的高頻噪聲,雙邊濾波不能幹淨的濾掉,只能對低頻噪聲較好的濾除。
演算法實現
OpenCV中提供了雙邊濾波的實現,我們直接呼叫即可。
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.
雙邊濾波的複雜度相對於其他濾波器也是比較高的,我呼叫Opencv實現了一個可以調節雙邊濾波3個可變引數進行濾波的程式放在下面。
程式碼
#include "opencv2/opencv.hpp"
#include "iostream"
#include "algorithm"
#include "vector"
using namespace std;
using namespace cv;
const int g_ndMaxValue = 100;
const int g_nsigmaColorMaxValue = 200;
const int g_nsigmaSpaceMaxValue = 200;
int g_ndValue, g_nsigmaColorValue, g_nsigmaSpaceValue;
Mat src, dst;
void on_bilateralFilterTrackbar(int, void*){
bilateralFilter(src, dst, g_ndValue, g_nsigmaColorValue, g_nsigmaSpaceValue);
imshow("filtering", dst);
}
int main(){
// Mat src = imread("/home/streamax/CLionProjects/Paper/101507_588686279_15.jpg");
// Mat dst;
// bilateralFilter(src, dst, 9, 50, 50);
// imshow("src", src);
// imshow("dst", dst);
// imwrite("../result.jpg", dst);
// waitKey(0);
src = imread("../101507_588686279_15.jpg");
namedWindow("origin", WINDOW_AUTOSIZE);
imshow("origin", src);
g_ndValue = 9;
g_nsigmaColorValue = 50;
g_nsigmaSpaceValue = 50;
namedWindow("filtering", WINDOW_AUTOSIZE);
char dname[20];
sprintf(dname, "Neighborhood diamter %d", g_ndMaxValue);
char sigmaColorName[20];
sprintf(sigmaColorName, "sigmaColor %d", g_nsigmaColorMaxValue);
char sigmaSpaceName[20];
sprintf(sigmaSpaceName, "sigmaSpace %d", g_nsigmaSpaceMaxValue);
//建立軌跡條
createTrackbar(dname, "filtering", &g_ndValue, g_ndMaxValue, on_bilateralFilterTrackbar);
on_bilateralFilterTrackbar(g_ndValue, 0);
createTrackbar(sigmaColorName, "filtering", &g_nsigmaColorValue, g_nsigmaColorMaxValue, on_bilateralFilterTrackbar);
on_bilateralFilterTrackbar(g_nsigmaColorValue, 0);
createTrackbar(sigmaSpaceName, "filtering", &g_nsigmaSpaceValue, g_nsigmaSpaceMaxValue, on_bilateralFilterTrackbar);
on_bilateralFilterTrackbar(g_nsigmaSpaceValue, 0);
waitKey(0);
return 0;
}