原理 html
平滑也稱模糊, 是一項簡單且使用頻率很高的圖像處理方法。 數組
平滑處理時須要用到一個濾波器。 最經常使用的濾波器是線性濾波器,線性濾波處理的輸出像素值(例如:)是輸入像素值(例如:
)的加權平均: 函數
稱爲核, 它僅僅是一個加權係數。 ui
均值平滑 spa
下面是一個使用blur函數的均值平滑: .net
#include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <stdio.h> using namespace cv; int main( int argc, char** argv ){ Mat image; image = imread( argv[1]); if( argc != 2 || !image.data ){ printf("沒有圖片\n"); return -1; } namedWindow( "平滑處理-輸入" ); namedWindow( "平滑處理-輸出" ); imshow( "平滑處理-輸入", image ); Mat out; blur( image, out, Size(3, 3)); imshow( "平滑處理-輸出", out ); waitKey( 0 ); }
blur函數API資料: code
使用歸一化塊濾波器進行模糊圖片操做。 htm
C++: void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
參數
- src – 輸入圖片,可使是任意通道數,該函數對通道是獨立處理的,可是深度只能是CV_8U,CV_16U, CV_16S, CV_32F or CV_64F。
- dst – 輸出圖片,和輸入圖片相同大小和深度。
- ksize – 模糊內核大小。
- anchor – 錨點,默認值是(-1,-1),也就是錨點在內核的中心。
- borderType – 用於判斷圖像邊界的模式。
該函數對圖片進行平滑處理利用了下面的內核: blog
![]()
調用blur(src, dst, ksize, anchor, borderType)至關於調用boxFilter(src,dst, src.type(), anchor, true, borderType)。 圖片
blur使用的是歸一化塊濾波器,輸出像素值是核窗口內像素值的均值( 全部像素加權係數相等)。
高斯平滑
下面代碼使用了GaussianBlur來實現平滑:
#include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <stdio.h> using namespace std; using namespace cv; int main( int argc, char** argv ){ Mat image; image = imread( argv[1]); if( argc != 2 || !image.data ){ printf("沒有圖片\n"); return -1; } namedWindow( "平滑處理-輸入" ); namedWindow( "平滑處理-輸出" ); imshow( "平滑處理-輸入", image ); Mat out; GaussianBlur( image, out, Size( 3, 3 ), 0, 0 ); imshow( "平滑處理-輸出", out ); waitKey( 0 ); }
GaussianBlur函數API資料:
使用高斯濾波器進行模糊操做
C++: void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT)
參數
- src – 輸入圖片,可使是任意通道數,該函數對通道是獨立處理的,可是深度只能是CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
- dst – 輸出圖片,和輸入圖片相同大小和深度。
- ksize – 高斯內核大小。ksize.width和ksize.height容許不相同但他們必須是正奇數。或者等於0,由參數sigma的伺機決定。
- sigmaX – 高斯內核在X方向的標準誤差。
- sigmaY – 高斯內核在Y方向的標準誤差。若是sigmaY爲0,他將和sigmaX的值相同,若是他們都爲0,那麼他們由ksize.width和ksize.height計算得出。
- borderType – 用於判斷圖像邊界的模式。
最有用的濾波器 (儘管不是最快的)。 高斯濾波是將輸入數組的每個像素點與高斯內核卷積將卷積和看成輸出像素值。
參考一維高斯函數,咱們能夠看見,他是個中間大兩邊小的函數。
因此高斯濾波器其加權數是中間大,四周小的。
其二維高斯函數爲:
其中 爲均值 (峯值對應位置),
表明標準差 (變量
和 變量
各有一個均值,也各有一個標準差)。
中值平滑
使用medianBlur執行中值平滑:
#include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <stdio.h> using namespace std; using namespace cv; int main( int argc, char** argv ){ Mat image; image = imread( argv[1]); if( argc != 2 || !image.data ){ printf("沒有圖片\n"); return -1; } namedWindow( "平滑處理-輸入" ); namedWindow( "平滑處理-輸出" ); imshow( "平滑處理-輸入", image ); Mat out; medianBlur( image, out, 3); imshow( "平滑處理-輸出", out ); waitKey( 0 ); }
medianBlur函數API資料:
使用中值濾波器進行模糊操做
C++: void medianBlur(InputArray src, OutputArray dst, int ksize)
Parameters:
- src – 支持一、三、4通道圖片輸入,當ksize爲3或者5時,圖片的深度只能是CV_8U,,CV_16U,或者 CV_32F,對於其餘大孔徑尺寸只支持深度爲CV_8U。
- dst – 輸出圖片,和輸入圖片相同大小和深度。
- ksize – 線性直徑大小,只能是一個大於1的奇數,例如:3, 5, 7 ...
中值濾波將圖像的每一個像素用鄰域 (以當前像素爲中心的正方形區域)像素的中值代替 。
雙邊平滑
使用bilateralFilter執行雙邊平滑:
#include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <stdio.h> using namespace std; using namespace cv; int main( int argc, char** argv ){ Mat image; image = imread( argv[1]); if( argc != 2 || !image.data ){ printf("沒有圖片\n"); return -1; } namedWindow( "平滑處理-輸入" ); namedWindow( "平滑處理-輸出" ); imshow( "平滑處理-輸入", image ); Mat out; bilateralFilter ( image, out, 3, 3*2, 3/2 ); imshow( "平滑處理-輸出", out ); waitKey( 0 ); }
bilateralFilter的API資料:
對一個圖片應用雙邊濾波器。
C++: void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
Parameters:
- src – 源必須是8位或者浮點數,1或者3通道圖片。
- dst – 輸出圖片,和輸入圖片相同大小和深度。
- d – 在濾波過程當中使用的各像素鄰域直徑,若是這是一個非整數,則這個值由sigmaSpace決定。
- sigmaColor – 顏色空間的標準方差。數值越大,意味着越遠的的顏色會被混進鄰域內,從而使更大的顏色段得到相同的顏色。
- sigmaSpace – 座標空間的標註方差。 數值越大,覺得着越遠的像素會相互影響,從而使更大的區域足夠類似的顏色獲取相同的顏色。當d>0,d指定了鄰域大小且與sigmaSpace無關。不然,d正比於sigmaSpace。
原理可參考:
http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html
目前咱們瞭解的濾波器都是爲了平滑圖像, 問題是有些時候這些濾波器不單單削弱了噪聲, 連帶着把邊緣也給磨掉了。 爲避免這樣的情形 (至少在必定程度上 ), 咱們可使用雙邊濾波。
相似於高斯濾波器,雙邊濾波器也給每個鄰域像素分配一個加權係數。 這些加權係數包含兩個部分, 第一部分加權方式與高斯濾波同樣,第二部分的權重則取決於該鄰域像素與當前像素的灰度差值。
被山寨的原文
Smoothing Images . OpenCV.org
Image Filtering API . OpenCV.org