1.1圖像濾波理論html
圖像濾波即在儘可能保留圖像細節特徵的條件下對目標圖像的噪聲進行抑制,是圖像預處理中不可缺乏的操做。消除圖像中的噪聲又叫作圖像濾波或平滑,濾波的目的有兩個,一是突出特徵以方便處理,二是抑制噪聲。編程
空間域濾波就是在圖像平面上對像素進行操做。空間域濾波大致分爲兩類:平滑、銳化。函數
平滑濾波:模糊處理,用於減少噪聲,其實是低通濾波,典型的濾波器是高斯濾波。學習
銳化濾波:提取邊緣突出邊緣及細節、彌補平滑濾波形成的邊緣模糊。其實是高通濾波。測試
空間域處理可由下式表示:優化
g(x,y)=T[f(x,y)]spa
式中,f(x,y)是輸入圖像,g(x,y)是處理後的圖像,T是在點(x,y)的鄰域上定義的關於f的一種算子,算子可應用於單幅圖像或圖像集合。.net
1.2鄰域濾波算子3d
1)空間濾波器由一個鄰域(一般是一個較小的矩形)和對該鄰域所包圍圖像像素執行的預約義操做組成。對預約義的點(x,y)爲中心的領域內的像素進行計算。code
2)濾波產生一個新像素,用計算後的新像素值代替點(x,y)的值。
3)循環步驟1和2,濾波器的中心遍歷圖像中的每一個像素後,就生成了濾波後的圖像。
4)若是在圖像像素上執行的是線性操做,則該濾波器稱爲線性空間濾波器,不然,稱爲非線性空間濾波器。
通常來講,使用大小爲 m×n的濾波器對大小爲 M×N的圖像進行線性空間濾波,可由下式表示:
濾波處理分爲兩大類:線性濾波和非線性濾波。OpenCV裏有這些濾波的函數,使用起來很是方便。
線性濾波:
1.方框濾波BoxBlur:模糊圖像
2.均值濾波Blur:模糊圖像
3.高斯濾波GaussianBlur:信號的平滑處理,去除符合正太分佈的噪聲
非線性濾波:
1.中值濾波mediaBlur:去除椒鹽噪聲
2.雙邊濾波BilateralFilter:保邊去噪
3.1平滑濾波
通常來講,圖像具備局部連續的性質,即相鄰的像素的值相近,而噪聲使得噪點處產生像素跳躍,因此經過平滑噪點能夠減小噪聲,去除圖像中的不相關細節。
方框濾波BoxBlur和均值濾波Blur都是對鄰域內作平均值來濾波,屬於平滑濾波。濾波的輸出是包含在濾波器模板鄰域內的像素的平均值,方框濾波作歸一化以後就變爲均值濾波,這兩個濾波器都是低通濾波器。
函數原型以下:
CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), bool normalize=true, int borderType=BORDER_DEFAULT ); CV_EXPORTS_W void blur( InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT );
3.2高斯濾波
高斯濾波對於圖像來講就是一個低通濾波,普遍用於消除高斯噪聲,高速濾波就是一種加權濾波,只不過模板中的係數由高斯分佈來肯定的,高斯濾波器根據高斯函數的形狀來選擇濾波模板權值的線性平滑濾波器。高斯平滑濾波器對於抑制服從正態分佈的噪聲很是有效。
CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT );
3.3測試實驗
Mat img; Mat img1, img2, img3; int gBoxFilterValue = 3; int gMeanBlurValue = 3; int gGaussianBlurValue = 3; static void OnBoxFilter(int filterSz, void *) { boxFilter(img, img1, -1, Size(filterSz +1, filterSz +1)); imshow("方框濾波", img1); } static void OnMeaanBlur(int filterSz, void *) { blur(img, img2, Size(filterSz + 1, filterSz + 1)); imshow("均值濾波", img2); } static void OnGaussinanBlur(int filterSz, void *) { GaussianBlur(img, img3, Size(filterSz*2 + 1, filterSz*2 + 1), 0, 0); imshow("高斯濾波", img3); } int main() { img = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic2.bmp"); img1 = img.clone(); img2 = img.clone(); img3 = img.clone(); imshow("原圖", img); namedWindow("方框濾波", 1); createTrackbar("內核值", "方框濾波", &gBoxFilterValue, 40, OnBoxFilter); OnBoxFilter(gBoxFilterValue, 0); namedWindow("均值濾波", 1); createTrackbar("內核值", "均值濾波", &gMeanBlurValue, 40, OnMeaanBlur); OnMeaanBlur(gMeanBlurValue, 0); namedWindow("高斯濾波", 1); createTrackbar("內核值", "高斯濾波", &gGaussianBlurValue, 40, OnGaussinanBlur); OnGaussinanBlur(gGaussianBlurValue, 0); waitKey(0); }
輸出結果以下圖。
4.1中值濾波
中值濾波屬於非線性濾波,其思想用濾波模板鄰域內的像素的平均值來代替像素點的灰度值。中值濾波器是一種統計排序濾波器,圖像上點(x,y),中值濾波以該點爲中心,領域內全部像素的統計排序中值做爲此點的響應,中值濾波是非線性濾波。相比與均值濾波和高斯濾波,中值濾波能夠有效的下降隨機噪聲,直接忽略掉噪聲點,把噪聲引發的模糊降到最低。線性濾波器在濾波的同時會形成圖像細節模糊,中值濾波能夠避免這個問題,其典型的應用就是中值濾波消除斑點噪聲、椒鹽噪聲。
CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );
使用中值濾波,濾除椒鹽噪聲例子以下。
img = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic2.bmp"); salt(img, 1000); img1 = img.clone(); img2 = img.clone(); img3 = img.clone(); imshow("原圖", img); namedWindow("高斯濾波", 1); createTrackbar("內核值", "高斯濾波", &gGaussianBlurValue, 40, OnGaussinanBlur); OnGaussinanBlur(gGaussianBlurValue, 0); namedWindow("中值濾波", 1); createTrackbar("內核值", "中值濾波", &gMedianBlurValue, 40, OnMedianBlur); OnMedianBlur(gMedianBlurValue, 0); waitKey(0); }
輸出結果以下圖。高斯濾波在濾除噪點的同時也形成了圖像模糊,若是增大內核則會形成嚴重模糊失真,而中值濾波對椒鹽噪聲有很好的抑制做用。
4.2雙邊濾波
高斯濾波屬於加權平均濾波,距離中心點越近的點越有較大權重,這種方法符合圖像的平滑變化的特徵,可是在邊緣區域,像素值出現突變,這種方法反而會濾掉邊緣輪廓,損失掉有用的邊緣信息。邊緣保護濾波方法,雙邊濾波就是最經常使用的邊緣保護濾波方法,就是爲了處理這種狀況而發明的。
雙邊濾波(Bilateral filter)是一種非線性的濾波方法,是結合圖像的空間鄰近度和像素值類似度的一種折衷處理,同時考慮空域信息和灰度類似性,達到保邊去噪的目的。雙邊濾波將高斯濾波中經過各個點到中心點的空間臨近度計算的各個權值進行優化,將其優化爲空間臨近度計算的權值和像素值類似度計算的權值的乘積,優化後的權值再與圖像做卷積運算,從而達到保邊去噪的效果。
CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT );
InputArray src: 輸入圖像,能夠是Mat類型,圖像必須是8位或浮點型單通道、三通道的圖像。
OutputArray dst: 輸出圖像,和原圖像有相同的尺寸和類型。
int d: 表示在過濾過程當中每一個像素鄰域的直徑範圍。若是這個值是非正數,則函數會從第五個參數sigmaSpace計算該值。
double sigmaColor: 顏色空間過濾器的sigma值,這個參數的值越大,更大的值域空間影響結果。
double sigmaSpace: 座標空間中濾波器的sigma值,若是該值較大,更大的定義域空間影響結果。
int borderType=BORDER_DEFAULT:邊界模式,有默認值BORDER_DEFAULT.
static void OnBilateralFilter(int filterSz, void *) { bilateralFilter(img, img3, filterSz, filterSz * 2, filterSz / 2); imshow("雙邊濾波", img3); } namedWindow("雙邊濾波", 1); createTrackbar("內核值", "雙邊濾波", &gMedianBlurValue, 40, OnBilateralFilter); OnBilateralFilter(gMedianBlurValue, 0);
輸出效果以下圖。雙邊濾波在較大的參數範圍內都保持了很好的噪聲抑制特性,而且沒有形成邊緣模糊。
調節中值濾波的滑動條時,出現異常。
vs報錯:
未經處理的異常:
0x00007FF835C09159 處(位於 Day1.exe 中)有未經處理的異常: Microsoft C++ 異常: cv::Exception,位於內存位置 0x000000F29FAFE138 處。
解決方法:
中值濾波的參數ksize須要爲偶數。
@param src input 1-, 3-, or 4-channel image; when ksize is 3 or 5, the image depth should be CV_8U, CV_16U, or CV_32F, for larger aperture sizes, it can only be CV_8U. @param dst destination array of the same size and type as src. @param ksize aperture linear size; it must be odd and greater than 1, for example: 3, 5, 7 ... @sa bilateralFilter, blur, boxFilter, GaussianBlur */ CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );
使用例子:
static void OnMedianBlur(int filterSz, void *) { if (filterSz % 2 == 0) filterSz += 1; medianBlur(img, img2, filterSz); imshow("中值濾波", img2); }
測試效果圖以下:
一、《OpenCV3 編程入門》,電子工業出版社,毛星雨著
二、《學習OpenCV》,清華大學出版社,Gary Bradski, Adrian kaehler著
三、OpenCV雙邊濾波詳解及實代碼實現
https://blog.csdn.net/qq_36359022/article/details/80198890
四、Bilateral Filtering for Gray and Color Images
https://users.soe.ucsc.edu/~manduchi/Papers/ICCV98.pdf
五、Smoothing Images
https://docs.opencv.org/4.1.2/dc/dd3/tutorial_gausian_median_blur_bilateral_filter.html
六、OpenCV圖像處理之濾波
https://blog.csdn.net/qq_30815237/article/details/86690190
尊重原創技術文章,轉載請註明。