图像降噪算法——中值滤波/均值滤波/高斯滤波/双边滤波
圖像降噪算法——中值濾波/均值濾波/高斯濾波/雙邊濾波
- 圖像降噪算法——中值濾波/均值濾波/高斯濾波/雙邊濾波
- 1. 基本原理
- 2. C++代碼實現
- 3. 結論
圖像降噪算法——中值濾波/均值濾波/高斯濾波/雙邊濾波
空間域濾波器是最傳統最簡單的一類圖像降噪算法,簡單到我都有點不太想做寫這篇博客(傲嬌了…),但是為了內容的完整性,我還是在此總結下,空間域濾波器可以分為局部濾波器和非局部濾波器,其中局部濾波器又分為線性濾波器和非線性濾波器。本博客介紹幾種比較經典的局部濾波器:中值濾波、均值濾波、高斯濾波、雙邊濾波。其中均值濾波和高斯濾波為線性濾波器,中值濾波和雙邊濾波為非線性濾波。
1. 基本原理
因為這些濾波器原理相對都比較簡單,因為以我的理解簡單描述下:
(1) 中值濾波
以目標像素周圍3×33\times33×3的鄰域為例,就是將3×33\times33×3鄰域中九個像素灰度值進行排序,將中間灰度值作為目標像素的灰度值。椒鹽噪聲影響的像素的灰度值通常都非常大或者非常小,因此通過排序會被消除掉。
(2) 均值濾波
同樣以目標像素周圍3×33\times33×3的鄰域為例,就是將3×33\times33×3鄰域中九個像素灰度值的平均值作為目標像素的灰度值
(3) 高斯濾波
高斯濾波就是將均值濾波中的平局值改為高斯加權平均值,鄰域中年距離目標像素越遠的像素灰度值權重越小,通常通過生成一個高斯模板實現
(4) 雙邊濾波
雙邊濾波是在高斯濾波的基礎上在權重設計中進一步考慮了像素灰度梯度的影響,首先考慮高斯部分權重(下圖中的Spatial weight):wd(i,j,k,l)=exp?(?(i?k)2+(j?l)22σd2)w_ze8trgl8bvbq(i, j, k, l)=\exp \left(-\frac{(i-k)^{2}+(j-l)^{2}}{2 \sigma_ze8trgl8bvbq^{2}}\right)wd?(i,j,k,l)=exp(?2σd2?(i?k)2+(j?l)2?)然后考慮像素灰度梯度部分權重(下圖中的Range weight):wr(i,j,k,l)=exp?(?∥f(i,j)?f(k,l)∥22σr2)w_{r}(i, j, k, l)=\exp \left(-\frac{\|f(i, j)-f(k, l)\|^{2}}{2 \sigma_{r}^{2}}\right)wr?(i,j,k,l)=exp(?2σr2?∥f(i,j)?f(k,l)∥2?)其中(i,j)(i,j)(i,j)為模板中鄰域像素坐標,(i,j)(i,j)(i,j)為模板中心像素坐標,f(i,j)f(i,j)f(i,j)為坐標(i,j)(i,j)(i,j)處的像素值,σd\sigma_dσd?和σr\sigma_rσr?分別為兩個權重的方差,將兩部分權重相乘即獲得雙邊濾波的權重:w(i,j,k,l)=wd(i,j,k,l)?wr(i,j,k,l)=exp?(?(i?k)2+(j?l)22σd2?∥f(i,j)?f(k,l)∥22σr2)w(i, j, k, l)=w_ze8trgl8bvbq(i, j, k, l) * w_{r}(i, j, k, l)=\exp \left(-\frac{(i-k)^{2}+(j-l)^{2}}{2 \sigma_ze8trgl8bvbq^{2}}-\frac{\|f(i, j)-f(k, l)\|^{2}}{2 \sigma_{r}^{2}}\right)w(i,j,k,l)=wd?(i,j,k,l)?wr?(i,j,k,l)=exp(?2σd2?(i?k)2+(j?l)2??2σr2?∥f(i,j)?f(k,l)∥2?)可以參看下圖進行理解:
2. C++代碼實現
下面是基于OpenCV對以上四種濾波器的實現:
Mat Denoise::MedeanFilter(const Mat &src, int size) {Mat dst = src.clone();int start = size/2;for(int i = start; i < dst.rows-start; i++){for(int j = start; j < dst.cols-start; j++){vector<uchar> model;for(int m = i-start; m <= i+start; m++){for(int n = j-start; n <= j+start; n++){model.push_back(src.at<uchar>(m,n));}}sort(model.begin(), model.end());dst.at<uchar>(i,j) = model[size*size/2];}}return dst; }//均值濾波 Mat Denoise::MeanFilter(const Mat &src, int size) {Mat dst = src.clone();int start = size/2;for(int i = start; i < dst.rows-start; i++){for(int j = start; j < dst.cols-start; j++){int sum = 0;for(int m = i-start; m <= i+start; m++){for(int n = j-start; n <= j+start; n++){sum += src.at<uchar>(m,n);}}dst.at<uchar>(i,j) = (uchar)(sum/size/size);}}return dst; }//高斯濾波 Mat Denoise::GaussianFilter(const Mat &src, int size, double sigma) {vector<vector<double>> gaussianTemplate = GaussianTemplate(size, sigma);Mat dst = src.clone();int start = size/2;for(int i = start; i < dst.rows-start; i++){for(int j = start; j < dst.cols-start; j++){int sum = 0;for(int m = i-start; m <= i+start; m++){for(int n = j-start; n <= j+start; n++){sum += src.at<uchar>(m,n)*gaussianTemplate[m-i+start][n-j+start];}}dst.at<uchar>(i,j) = (uchar)sum;}}return dst; }vector<vector<double>> Denoise::GaussianTemplate(int size, double sigma) {vector<vector<double>> temp;double base = 1.0 / 2.0 / CV_PI / sigma / sigma;for(int i = 0; i < size; i++){vector<double> vec;for(int j = 0; j < size; j++){double a = (pow(i - size/2, 2) + pow(j - size/2, 2)) / 2.0 / sigma / sigma;double b = base * exp(-a);vec.push_back(b);}temp.push_back(vec);}return temp; }//雙邊濾波 Mat Denoise::BilateralFilter(const Mat &src, int size, double sigmaD, double sigmaR) {vector<vector<double>> tempD;vector<double> tempR;Mat dst = src.clone();//生成定義域模板for(int i = 0; i < size; i++){vector<double> vec;for(int j = 0; j < size; j++){double a = (pow(i - size/2, 2) + pow(j - size/2, 2)) / 2.0 / sigmaD / sigmaD;double b = exp(-a);vec.push_back(b);}tempD.push_back(vec);}//生成值域模板for(int i = 0; i < 256; i++){double a = (i * i / 2.0 / sigmaR / sigmaR);double b = exp(-a);tempR.push_back(b);}int start = size/2;for(int i = start; i < dst.rows-start; i++){for(int j = start; j < dst.cols-start; j++){double sum = 0;double weightSum = 0;for(int m = i-start; m <= i+start; m++){for(int n = j-start; n <= j+start; n++){double weight = tempD[m-i+start][n-j+start] * tempR[abs(src.at<uchar>(m,n)-src.at<uchar>(i,j))];sum += src.at<uchar>(m,n)*weight;weightSum += weight;}}dst.at<uchar>(i,j) = (uchar)sum/weightSum;}}return dst; }運行結果如下:
首先,原圖如下圖所示:
我們首先看看中值濾波對椒鹽噪聲的效果:
添加椒鹽噪聲后圖像如下:
中值濾波后效果如下:
然后我們來對比下均值濾波、高斯濾波和雙邊濾波對高斯噪聲的效果:
添加高斯噪聲的圖像如下:
均值濾波后效果如下:
高斯濾波后效果如下:
雙邊濾波效果如下:
3. 結論
有問題歡迎交流~
此外,這里我寫一個各種算法的總結目錄圖像降噪算法——圖像降噪算法總結,對圖像降噪算法感興趣的同學歡迎參考
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的图像降噪算法——中值滤波/均值滤波/高斯滤波/双边滤波的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像降噪算法——图像噪声模型
- 下一篇: 图像降噪算法——非局部均值降噪算法