【OPENCV入門之六】非線性濾波(中值濾波、雙邊濾波)


參考網站:

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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM