1. 程式人生 > >opencv學習(二十)之高斯濾波GaussianBlur()

opencv學習(二十)之高斯濾波GaussianBlur()

高斯濾波是一種線性平滑濾波,對於除去高斯噪聲有很好的效果。在其官方文件中形容高斯濾波為”Probably the most useful filter”,同時也指出高斯濾波並不是效率最高的濾波演算法。高斯演算法在官方文件給出的解釋是高斯濾波是通過對輸入陣列的每個點與輸入的高斯濾波模板執行卷積計算然後將這些結果一塊組成了濾波後的輸出陣列,通俗的講就是高斯濾波是對整幅影象進行加權平均的過程,每一個畫素點的值都由其本身和鄰域內的其他畫素值經過加權平均後得到。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描影象中的每一個畫素,用模板確定的鄰域內畫素的加權平均灰度值去替代模板中心畫素點的值。
在影象處理中高斯濾波一半有兩種實現方式:一種是用離散化視窗滑窗卷積,另一種是通過傅立葉變換。最常見的就是第一種滑窗實現,只有當離散化的視窗非常大,用滑窗計算量非常大的情況下會考慮基於傅立葉變換的方法。
我們在參考其他文章的時候可能會出現高斯模糊和高斯濾波兩種說法,其實這兩種說法是有一定區別的。我們知道濾波器分為高通、低通、帶通等型別,高斯濾波和高斯模糊就是一句濾波器是低通濾波器還是高通濾波器來區分的。比如低通濾波器,畫素能量低的通過,而對於畫素能量高的部分將會採取加權平均的方法重新計算畫素的值,將能量畫素的值程式設計能量較低的值,我們知道對於影象而言其高頻部分展現影象細節,所以經過低通濾波器之後整幅影象變成低頻造成影象模糊,這就被稱為高斯模糊;相反高通濾波是允許高頻通過而過濾掉低頻,這樣將低頻畫素進行銳化操作,影象變的更加清晰,被稱為高斯濾波。說白了很簡單就是:高斯濾波是指用高斯函式作為濾波函式的濾波操作而高斯模糊是用高斯低通濾波器。
高斯濾波在影象處理中常用來對影象進行預處理操作,雖然耗時但是數字影象用於後期應用但是其噪聲是最大的問題,噪聲會造成很大的誤差而誤差在不同的處理操作中會累積傳遞,為了能夠得到較好的影象,對影象進行預處理去除噪聲也是針對數字影象處理的無奈之舉。
高斯濾波器是一類根據高斯函式的形狀來選擇權值的線性平滑濾波器,高斯濾波器對於服從正太分佈的噪聲非常有效,一維高斯函式如下:

這裡寫圖片描述

二維高斯函式如下:

這裡寫圖片描述

opencv提供了GaussianBlur()函式對圖形進行高斯濾波,其原型如下:

C++: void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )

引數解釋:
. InputArray src: 輸入影象,可以是Mat型別,影象深度為CV_8U、CV_16U、CV_16S、CV_32F、CV_64F。
. OutputArray dst: 輸出影象,與輸入影象有相同的型別和尺寸。
. Size ksize: 高斯核心大小,這個尺寸與前面兩個濾波kernel尺寸不同,ksize.width和ksize.height可以不相同但是這兩個值必須為正奇數,如果這兩個值為0,他們的值將由sigma計算。
. double sigmaX: 高斯核函式在X方向上的標準偏差
. double sigmaY: 高斯核函式在Y方向上的標準偏差,如果sigmaY是0,則函式會自動將sigmaY的值設定為與sigmaX相同的值,如果sigmaX和sigmaY都是0,這兩個值將由ksize.width和ksize.height計算而來。具體可以參考

getGaussianKernel()函式檢視具體細節。建議將size、sigmaX和sigmaY都指定出來。
. int borderType=BORDER_DEFAULT: 推斷影象外部畫素的某種便捷模式,有預設值BORDER_DEFAULT,如果沒有特殊需要不用更改,具體可以參考borderInterpolate()函式。

為了能更直觀的觀察到四個變數對濾波的影響,建立四個軌跡條分別調節,所以最後執行結果圖片有點醜,示例程式碼如下:

#include <iostream>
#include <stdio.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> using namespace std; using namespace cv; //定義全域性變數 Mat g_srcImage; //輸入影象 Mat g_dstImage; //輸出影象 //定義軌跡條最大值參量 const int g_nKwidthTrackBarMaxValue = 9; const int g_nKheightTrackBarMaxValue = 9; const int g_nsigmaXTrackBarMaxValue = 5; const int g_nsigmaYTrackBarMaxvalue = 5; //定義每個軌跡條的初始值 int g_nKwidthTrackBarValue = 1; int g_nKheightTrackBarValue = 1; int g_nsigmaXTrackBarValue = 1; int g_nsigmaYTrackBarValue = 1; int g_kernelWidthValue; int g_kernelHeightValue; void on_GaussianBlurTrackbar(int, void*); //定義回撥函式 int main() { g_srcImage = imread("lena.jpg"); //判斷影象是否載入成功 if(!g_srcImage.data) { cout << "影象載入失敗!" << endl; return -1; } else cout << "影象載入成功!" << endl << endl; namedWindow("原影象", WINDOW_NORMAL); //定義視窗顯示屬性 imshow("原影象", g_srcImage); namedWindow("高斯濾波影象", WINDOW_NORMAL); //定義每個軌跡條名字 char widthTrackBarName[20]; sprintf(widthTrackBarName, "核函式width %d", g_nKwidthTrackBarMaxValue); char heightTrackBarName[20]; sprintf(heightTrackBarName,"核函式height %d", g_nKheightTrackBarMaxValue); char sigmaXTrackBarName[20]; sprintf(sigmaXTrackBarName, "核函式sigmaX %d", g_nsigmaXTrackBarMaxValue); char sigmaYTrackBarName[20]; sprintf(sigmaYTrackBarName, "核函式sigmaY %d", g_nsigmaYTrackBarMaxvalue); //建立軌跡條 createTrackbar(widthTrackBarName, "高斯濾波影象", &g_nKwidthTrackBarValue, g_nKwidthTrackBarMaxValue, on_GaussianBlurTrackbar); on_GaussianBlurTrackbar(g_nKwidthTrackBarValue, 0); createTrackbar(heightTrackBarName, "高斯濾波影象", &g_nKheightTrackBarValue, g_nKheightTrackBarMaxValue, on_GaussianBlurTrackbar); on_GaussianBlurTrackbar(g_nKheightTrackBarValue, 0); createTrackbar(sigmaXTrackBarName, "高斯濾波影象", &g_nsigmaXTrackBarValue, g_nsigmaXTrackBarMaxValue, on_GaussianBlurTrackbar); on_GaussianBlurTrackbar(g_nsigmaXTrackBarValue, 0); createTrackbar(sigmaYTrackBarName, "高斯濾波影象", &g_nsigmaYTrackBarValue, g_nsigmaYTrackBarMaxvalue, on_GaussianBlurTrackbar); on_GaussianBlurTrackbar(g_nsigmaYTrackBarValue, 0); waitKey(0); return 0; } void on_GaussianBlurTrackbar(int, void*) { //根據輸入的width和height重新計算ksize.width和ksize.height g_kernelWidthValue = g_nKwidthTrackBarValue * 2 + 1; g_kernelHeightValue = g_nKheightTrackBarValue * 2 + 1; //高斯濾波 GaussianBlur(g_srcImage, g_dstImage, Size(g_kernelWidthValue, g_kernelHeightValue), g_nsigmaXTrackBarValue, g_nsigmaYTrackBarValue); imshow("高斯濾波影象", g_dstImage); }

執行結果:
這裡寫圖片描述