參考網站:
http://blog.csdn.net/poem_qianmo/article/details/23184547
在很多情況下,比如在噪聲是散粒噪聲而不是高斯噪聲時(圖像偶爾會出現很大的值的時候),在這種情況下,用高斯濾波器對圖像進行模糊的話,噪聲是不會被去除的,它們只是轉換為更為柔和但仍然可見的散粒。而用非線性濾波會更好些。
1、中值濾波(Median filter)——medianBlur函數
該方法在去除脈沖噪聲、斑點噪聲(speckle noise)、椒鹽噪聲(salt-and-pepper noise)、圖像掃描噪聲,的同時又能保留凸圖像邊緣細節。
中值濾波與均值濾波比較:
優勢是,在均值濾波器中,由於噪聲成分被放入平均計算中,所以輸出受到了噪聲的影響;而在中值濾波其中,噪聲成分很難選上,所以幾乎不會影響到輸出。
劣勢是,中值濾波花費的時間是均值濾波的5倍以上。
注意:中值濾波雖然可以克服線性濾波器所帶來的圖像細節模糊,但是在線、尖頂等細節多的圖像不宜用中值濾波。
void medianBlur(InputArray src,
OutputArray dst,
int ksize) //孔徑的線性尺寸(aperture linear size),參數必須是大於1的奇數,比如3,5,7,9
1 //載入原圖 2 Mat image=imread("1.jpg"); 3 //進行中值濾波操作 4 Mat out; 5 medianBlur( image, out, 7);
2、雙邊濾波(Bilateral filter)——bilateralFilter函數
其實結合圖像的空間領近度和像素值相似度的一種折中處理,同時考慮空域信息和灰度相似性,達到保邊去噪的目的。具有簡單、非迭代、局部的特點。
優點是,可以做邊緣保存(edge preserving)。
缺點是,保存了過多的高頻信息,對彩色圖像里的高頻噪聲,不能夠干凈的濾掉,只能夠對於低頻信息進行較好的濾波。
void bilateralFilter(InputArray src,
OutputArraydst,
int d, //過濾過程中每個像素領域的直徑
double sigmaColor, //顏色空間濾波器的sigma值。這個參數越大,表明該像素領域內有更寬廣的顏色會被混合到一起,
產生較大的半相等顏色區域
double sigmaSpace, //坐標空間中濾波器的sigma值,坐標空間的標注方差。這個數值越大,表明越遠的像素會相互影響,
從而使更大的區域足夠相似的顏色獲取相同的顏色。
int borderType=BORDER_DEFAULT)
1 //載入原圖 2 Mat image=imread("1.jpg"); 3 //進行雙邊濾波操作 4 Mat out; 5 bilateralFilter( image, out, 25, 25*2, 25/2 );
3、綜合實踐:
1 //******************************【程序說明】***************************** 2 // 程序名稱:非線性濾波(中值濾波、雙邊濾波) 3 // opencv版本:2.4.13 4 // 日期:2017/9/21 5 //********************************************************************** 6 7 8 //******************************【頭文件包含部分】***************************** 9 // 描述:包含程序所依賴的頭文件 10 //***************************************************************************** 11 #include <opencv2/core/core.hpp> 12 #include <opencv2/highgui/highgui.hpp> 13 #include <opencv2/imgproc/imgproc.hpp> 14 #include <iostream> 15 16 17 //******************************【命名空間聲明部分】***************************** 18 // 描述:包含程序所使用的命名空間 19 //***************************************************************************** 20 using namespace std; 21 using namespace cv; 22 23 24 //******************************【全局變量聲明部分】***************************** 25 // 描述:全局變量聲明 26 //***************************************************************************** 27 Mat g_srcImage,g_dstImage1, g_dstImage2, g_dstImage3, g_dstImage4, g_dstImage5; //存儲圖片的Mat類型 28 int g_nBoxFilterValue = 6; //方框濾波參數值 29 int g_nMeanBlurValue = 10; //均值濾波參數值 30 int g_nGaussianBlurValue = 6; //高斯濾波參數值 31 int g_nMedianBlurValue = 10; //中值濾波參數值 32 int g_nBilateralFilterValue = 10; //雙邊濾波參數值 33 34 35 //******************************【全局函數聲明部分】***************************** 36 // 描述:全局函數聲明 37 //***************************************************************************** 38 //軌跡條的回調函數 39 static void on_BoxFilter(int, void* ); //方框濾波 40 static void on_MeanBlur(int, void*); //均值濾波 41 static void on_GaussianBlur(int, void*); //高斯濾波 42 static void on_MedianBlur(int, void*); //中值濾波 43 static void on_BilateralFilter(int, void*); //雙邊濾波 44 45 46 //******************************【main()部分】***************************** 47 // 描述:控制台應用程序的入口函數,我們的程序從這里開始 48 //***************************************************************************** 49 int main() 50 { 51 //【0】初始化 52 system("color 5E"); 53 54 //【1】讀取原圖 55 g_srcImage = imread( "1.jpg", 1 ); 56 if(!g_srcImage.data) { printf("Oh,no,讀取srcImage錯誤!!!!\n"); return false; } 57 58 //【2】克隆原圖到三個Mat類型中 59 g_dstImage1 = g_srcImage.clone(); 60 g_dstImage2 = g_srcImage.clone(); 61 g_dstImage3 = g_srcImage.clone(); 62 g_dstImage4 = g_srcImage.clone(); 63 g_dstImage5 = g_srcImage.clone(); 64 65 //【3】顯示原圖 66 namedWindow("【<0>原圖窗口】", 1 ); 67 imshow("【<0>原圖窗口】", g_srcImage ); 68 69 //【4】濾波操作處理 70 //***********************【<1>方框濾波】******************* 71 namedWindow("【<1>方框濾波】", 1); 72 createTrackbar("內核值:", "【<1>方框濾波】", &g_nBoxFilterValue, 40, on_BoxFilter); 73 on_BoxFilter(g_nBoxFilterValue, 0); 74 imshow("【<1>方框濾波】", g_dstImage1); 75 76 //***********************【<2>均值濾波】******************* 77 namedWindow("【<2>均值濾波】", 1); 78 createTrackbar("內核值:", "【<2>均值濾波】", &g_nMeanBlurValue, 40, on_MeanBlur); 79 on_MeanBlur(g_nMeanBlurValue, 0); 80 imshow("【<2>均值濾波】", g_dstImage2); 81 82 //***********************【<3>高斯濾波】******************* 83 namedWindow("【<3>高斯濾波】", 1); 84 createTrackbar("內核值:", "【<3>高斯濾波】", &g_nGaussianBlurValue, 40, on_GaussianBlur); 85 on_GaussianBlur(g_nGaussianBlurValue, 0); 86 imshow("【<3>高斯濾波】", g_dstImage3); 87 88 //***********************【<4>中值濾波】******************* 89 namedWindow("【<4>中值濾波】", 1); 90 createTrackbar("內核值:", "【<4>中值濾波】", &g_nMedianBlurValue, 40, on_MedianBlur); 91 on_MedianBlur(g_nMedianBlurValue, 0); 92 imshow("【<4>中值濾波】", g_dstImage4); 93 94 //***********************【<5>雙邊濾波】******************* 95 namedWindow("【<5>雙邊濾波】", 1); 96 createTrackbar("內核值:", "【<5>雙邊濾波】", &g_nBilateralFilterValue, 40, on_BilateralFilter); 97 on_BilateralFilter(g_nBilateralFilterValue, 0); 98 imshow("【<5>雙邊濾波】", g_dstImage5); 99 100 //【5】輸出一些有幫助的信息 101 cout<<endl<<"\t嗯。好了,請調整滾動條觀察圖像效果~\n\n" 102 <<"\t按下“q”鍵時,程序退出~!\n"; 103 104 //【6】按下“q”鍵時,程序退出 105 while(char(waitKey(1) != 'q')){} 106 107 return 0; 108 } 109 110 111 //******************************【on_BoxFilter()部分】***************************** 112 // 描述:方框濾波操作的回調函數 113 //***************************************************************************** 114 static void on_BoxFilter(int, void* ) 115 { 116 boxFilter(g_srcImage, g_dstImage1, -1, Size(g_nBoxFilterValue+1, g_nBoxFilterValue+1)); 117 imshow("【<1>方框濾波】", g_dstImage1); 118 } 119 120 121 //******************************【on_MeanBlur()部分】***************************** 122 // 描述:均值濾波操作的回調函數 123 //***************************************************************************** 124 static void on_MeanBlur(int, void*) 125 { 126 blur(g_srcImage, g_dstImage2, Size(g_nMeanBlurValue+1, g_nMeanBlurValue+1), Point(-1, -1)); 127 imshow("【<2>均值濾波】", g_dstImage2); 128 } 129 130 131 //******************************【on_GaussianBlur()部分】***************************** 132 // 描述:高斯濾波操作的回調函數 133 //***************************************************************************** 134 static void on_GaussianBlur(int, void*) 135 { 136 GaussianBlur(g_srcImage, g_dstImage3, Size(g_nGaussianBlurValue*2+1, g_nGaussianBlurValue*2+1), 0, 0); 137 imshow("【<3>高斯濾波】", g_dstImage3); 138 } 139 140 141 //******************************【on_MedianBlur()部分】***************************** 142 // 描述:中值濾波操作的回調函數 143 //***************************************************************************** 144 static void on_MedianBlur(int, void*) 145 { 146 medianBlur(g_srcImage, g_dstImage4, g_nMedianBlurValue*2+1); 147 imshow("【<4>中值濾波】", g_dstImage4); 148 } 149 150 //******************************【on_BilateralFilter()部分】***************************** 151 // 描述:雙邊濾波操作的回調函數 152 //***************************************************************************** 153 static void on_BilateralFilter(int, void*) 154 { 155 bilateralFilter(g_srcImage, g_dstImage5, g_nBilateralFilterValue, g_nBilateralFilterValue*2, g_nBilateralFilterValue/2); 156 imshow("【<5>雙邊濾波】", g_dstImage5); 157 }