【OpenCV入門教程之九】 非線性濾波專場:中值濾波副渴、雙邊濾波
一铸磅、非線性濾波概述
線性濾波器:兩個信號之和的響應(yīng)和他們各自響應(yīng)之和相等。換句話說溅潜,每個像素的輸出值是一些輸入像素的加權(quán)和,線性濾波器易于構(gòu)造薪伏,并且易于從頻率響應(yīng)角度來進行分析滚澜。
其實在很多情況下,使用鄰域像素的非線性濾波也許會得到更好的效果嫁怀。比如在噪聲是散粒噪聲而不是高斯噪聲设捐,即圖像偶爾會出現(xiàn)很大的值的時候。在這種情況下塘淑,用高斯濾波器對圖像進行模糊的話萝招,噪聲像素是不會被去除的,它們只是轉(zhuǎn)換為更為柔和但仍然可見的散粒存捺。
二槐沼、中值濾波
中值濾波(Median filter)是一種典型的非線性濾波技術(shù),基本思想是用像素點鄰域灰度值的中值來代替該像素點的灰度值,該方法在去除脈沖噪聲岗钩、椒鹽噪聲的同時又能保留圖像邊緣細節(jié)逸爵。
2.1 中值濾波與均值濾波器比較
優(yōu)勢:在均值濾波器中,由于噪聲成分被放入平均計算中凹嘲,所以輸出受到了噪聲的影響师倔,但是在中值濾波器中,由于噪聲成分很難選上周蹭,所以幾乎不會影響到輸出趋艘。因此同樣用3x3區(qū)域進行處理,中值濾波消除的噪聲能力更勝一籌凶朗。**中值濾波無論是在消除噪聲還是保存邊緣方面都是一個不錯的方法瓷胧。 **
劣勢:中值濾波花費的時間是均值濾波的5倍以上。一個求平均值棚愤,一個排序搓萧。
中值濾波在一定條件下,可以克服線性濾波器(如均值濾波等)所帶來的圖像細節(jié)模糊宛畦,而且對濾除脈沖干擾即圖像掃描噪聲最為有效瘸洛。在實際運算過程中并不需要圖像的統(tǒng)計特性,也給計算帶來不少方便次和。但是對一些細節(jié)多反肋,特別是線、尖頂?shù)燃毠?jié)多的圖像不宜采用中值濾波踏施。
2.2 medianBlur 函數(shù)
void medianBlur( InputArray src, OutputArray dst, int ksize );
-
int ksize
必須為奇數(shù)
2.3 實例
核心代碼
medianBlur(src, dst, ksize);
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
// trackbar要求是整數(shù)
int ksize = 5;
Mat src;
Mat dst;
static void onKSizeChange(int, void *) {
if (ksize % 2 == 0) ksize++; // 保證為奇數(shù)
cout << ksize << endl;
medianBlur(src, dst, ksize);
imshow("中值濾波", dst);
}
int main() {
src = imread("../pics/me.jpg");
namedWindow("原圖");
imshow("原圖", src);
namedWindow("中值濾波");
createTrackbar("ksize", "中值濾波", &ksize, 100, onKSizeChange);
onKSizeChange(ksize, 0);
waitKey(0);
}
ksize = 5
ksize = 17
ksize = 45
ksize = 99
三石蔗、雙邊濾波
3.1 概念
雙邊濾波(Bilateral filter)是一種非線性的濾波方法,是結(jié)合圖像的空間鄰近度和像素值相似度的一種折衷處理畅形,同時考慮空域信息和灰度相似性养距,達到保邊去噪的目的。具有簡單日熬、非迭代棍厌、局部的特點。
雙邊濾波器的好處是可以做邊緣保存(edge preserving)碍遍,一般過去用的維納濾波或者高斯濾波去降噪定铜,都會較明顯地模糊邊緣,對于高頻細節(jié)的保護效果并不明顯怕敬。
雙邊濾波器顧名思義比高斯濾波多了一個高斯方差揣炕,它是基于空間分布的高斯濾波函數(shù),所以在邊緣附近东跪,離的較遠的像素不會太多影響到邊緣上的像素值畸陡,這樣就保證了邊緣附近像素值的保存鹰溜。但是由于保存了過多的高頻信息,對于彩色圖像里的高頻噪聲丁恭,雙邊濾波器不能夠干凈的濾掉曹动,只能夠?qū)τ诘皖l信息進行較好的濾波。
在雙邊濾波器中牲览,輸出像素的值依賴于鄰域像素值的加權(quán)值組合:
-
i, j
表示行列 -
k, l
表示鄰域的大小 -
g(i, j)
表示輸出像素 -
f(k, l)
表示像素(i, j)
附近的點墓陈,鄰域內(nèi)的點
而加權(quán)系數(shù)w(i,j,k,l)
取決于 定義域核 和 值域核 的乘積。
其中 定義域核 表示如下:
定義域濾波對應(yīng)圖示:
值域核 表示為:
值域濾波對應(yīng)圖示:
兩者相乘后第献,就會產(chǎn)生依賴于數(shù)據(jù)的雙邊濾波權(quán)重函數(shù):
3.2 bilateralFilter 函數(shù)
void bilateralFilter( InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType = BORDER_DEFAULT );
-
int d
表示在過濾過程中每個像素鄰域的直徑贡必。如果這個值我們設(shè)其為非正數(shù),那么OpenCV會從第五個參數(shù) sigmaSpace 來計算出它來庸毫。 -
double sigmaColor
顏色空間濾波器的sigma值仔拟。數(shù)值越大,就表明該像素鄰域內(nèi)有更寬廣的顏色會被混合到一起飒赃,產(chǎn)生較大的半相等顏色區(qū)域利花。 -
double sigmaSpace
坐標空間中濾波器的sigma值,坐標空間的標注方差载佳。數(shù)值越大炒事,意味著越遠的像素會相互影響,從而使更大的區(qū)域足夠相似的顏色獲取相同的顏色刚盈。當(dāng)d>0羡洛,d指定了鄰域大小且與sigmaSpace無關(guān)挂脑。否則藕漱,d正比于sigmaSpace。
3.3 實例
核心代碼
bilateralFilter(src, dst, d, sigmaColor, sigmaSpace);
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
// trackbar要求是整數(shù)
int d = 25;
int sigmaColor = 50;
int sigmaSpace = 12;
Mat src;
Mat dst;
static void onNeighborhoodChange(int, void *) {
bilateralFilter(src, dst, d, sigmaColor, sigmaSpace);
imshow("雙邊濾波", dst);
}
static void onsigmaColorChange(int, void *) {
bilateralFilter(src, dst, d, sigmaColor, sigmaSpace);
imshow("雙邊濾波", dst);
}
static void onsigmaSpaceChange(int, void *) {
bilateralFilter(src, dst, d, sigmaColor, sigmaSpace);
imshow("雙邊濾波", dst);
}
int main() {
src = imread("../pics/me.jpg");
namedWindow("原圖");
imshow("原圖", src);
namedWindow("雙邊濾波");
createTrackbar("鄰域直徑", "雙邊濾波", &d, 100, onNeighborhoodChange);
onNeighborhoodChange(d, 0);
createTrackbar("sigmaColor", "雙邊濾波", &sigmaColor, 100, onsigmaColorChange);
onsigmaColorChange(sigmaColor, 0);
createTrackbar("sigmaSpace", "雙邊濾波", &sigmaSpace, 100, onsigmaSpaceChange);
onsigmaSpaceChange(sigmaSpace, 0);
waitKey(0);
}
通過調(diào)整3個參數(shù)崭闲,發(fā)現(xiàn) d
和 sigmaColor
對圖像影響最大肋联。
- d 越大圖像整個越模糊,臉上的黑點會漸漸消失刁俭,就像去掉椒噪聲
- sigmaColor 越大圖像更廣的顏色混合在一起橄仍,圖像看起來更柔和,像蒙上了一層薄紗牍戚,沒有尖銳的顏色變化侮繁。