您好,登錄后才能下訂單哦!
本篇文章為大家展示了bilateral filter雙邊濾波器的實現原理是什么,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
1. 雙邊濾波(Bilateral filter)的原理
雙邊濾波器之所以能夠做到在平滑去噪的同時還能夠很好的保存邊緣(Edge Preserve),是由于其濾波器的核由兩個函數生成:空間域核和值域核
(1)空間域核:由像素位置歐式距離決定的模板權值
為模板窗口的其他系數的坐標;其中
為模板窗口的中心坐標點;
為高斯函數的標準差。 使用該公式生成的濾波器模板和高斯濾波器使用的模板是沒有區別的。
在一些博客和教程里,這個權值稱為定義域核,也稱為空間系數,或空間域(spatial domain S)
。顯示由的計算公式可知,它是計算臨近點到中心點臨近程度,因此定義域核是用于衡量空間臨近的程度。
(2)值域核:由像素值的差值決定的模板權值
其中,為模板窗口的其他系數的坐標,表示圖像在點處的像素值;為模板窗口的中心坐標點,對應的像素值為;為高斯函數的標準差。
一般將權值稱為值域核,或像素值域(range domain R)
,不管是值域核還是空間域核,其大小都在[0 1]之間
(3)將上述兩個模板相乘就得到了雙邊濾波器的模板權值:
因此,雙邊濾波器的數據公式可以表示如下:
雙邊濾波(Bilateral filter)其綜合了高斯濾波器(Gaussian Filter)和α-截尾均值濾波器(Alpha-Trimmed mean Filter)的特點,同時考慮了空間域與值域的差別,而Gaussian Filter和α均值濾波分別只考慮了空間域和值域差別。高斯濾波器只考慮像素間的歐式距離,其使用的模板系數隨著和窗口中心的距離增大而減小;α-截尾均值濾波器則只考慮了像素灰度值之間的差值,去掉α%的最小值和最大值后再計算均值。
2.1 空域權重和值域權重的意義:
空域權重衡量的是 兩點之間的距離,距離越遠權重越低;
值域權重衡量的是兩點之間的像素值相似程度,越相似權重越大
這里從圖像的平坦區域和邊緣區域定性分析雙邊濾波的降噪效果
在平坦區域,臨近像素的像素值的差值較小,對應值域權重接近于1,此時空域權重起主要作用,相當于直接對此區域進行高斯模糊。因此,平坦區域相當于進行高斯模糊。
在邊緣區域,臨近像素的像素值的差值較大,對應值域權重接近于0,導致此處核函數下降(因),當前像素受到的影響就越小,從而保持了原始圖像的邊緣的細節信息。
opencv中提供了bilateralFilter()函數來實現雙邊濾波操作,其原型如下:
void cv::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值,如果該值較大,則意味著越遠的像素將相互影響,從而使更大的區域中足夠相似的顏色獲取相同的顏色。當d>0時,d指定了鄰域大小且與sigmaSpace無關,否則d正比于sigmaSpace. (這個參數可以理解為空間域核的)
int borderType=BORDER_DEFAULT: 用于推斷圖像外部像素的某種邊界模式,有默認值BORDER_DEFAULT.
雙邊濾波器可以很好的保存圖像邊緣細節而濾除掉低頻分量的噪音,但是雙邊濾波器的效率不是太高,花費的時間相較于其他濾波器而言也比較長。
對于簡單的濾波而言,可以將兩個sigma值設置成相同的值,如果值<10,則對濾波器影響很小,如果值>150則會對濾波器產生較大的影響,會使圖片看起來像卡通。
示例代碼:
#include <iostream> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> using namespace std; using namespace cv; //定義全局變量 const int g_ndMaxValue = 100; const int g_nsigmaColorMaxValue = 200; const int g_nsigmaSpaceMaxValue = 200; int g_ndValue; int g_nsigmaColorValue; int g_nsigmaSpaceValue; Mat g_srcImage; Mat g_dstImage; //定義回調函數 void on_bilateralFilterTrackbar(int, void*); int main() { g_srcImage = imread("lena.jpg"); //判斷圖像是否加載成功 if(g_srcImage.empty()) { cout << "圖像加載失敗!" << endl; return -1; } else cout << "圖像加載成功!" << endl << endl; namedWindow("原圖像", WINDOW_AUTOSIZE); imshow("原圖像", g_srcImage); //定義輸出圖像窗口屬性和軌跡條屬性 namedWindow("雙邊濾波圖像", WINDOW_AUTOSIZE); g_ndValue = 10; g_nsigmaColorValue = 10; g_nsigmaSpaceValue = 10; char dName[20]; sprintf(dName, "鄰域直徑 %d", g_ndMaxValue); char sigmaColorName[20]; sprintf(sigmaColorName, "sigmaColor %d", g_nsigmaColorMaxValue); char sigmaSpaceName[20]; sprintf(sigmaSpaceName, "sigmaSpace %d", g_nsigmaSpaceMaxValue); //創建軌跡條 createTrackbar(dName, "雙邊濾波圖像", &g_ndValue, g_ndMaxValue, on_bilateralFilterTrackbar); on_bilateralFilterTrackbar(g_ndValue, 0); createTrackbar(sigmaColorName, "雙邊濾波圖像", &g_nsigmaColorValue, g_nsigmaColorMaxValue, on_bilateralFilterTrackbar); on_bilateralFilterTrackbar(g_nsigmaColorValue, 0); createTrackbar(sigmaSpaceName, "雙邊濾波圖像", &g_nsigmaSpaceValue, g_nsigmaSpaceMaxValue, on_bilateralFilterTrackbar); on_bilateralFilterTrackbar(g_nsigmaSpaceValue, 0); waitKey(0); return 0; } void on_bilateralFilterTrackbar(int, void*) { bilateralFilter(g_srcImage, g_dstImage, g_ndValue, g_nsigmaColorValue, g_nsigmaSpaceValue); imshow("雙邊濾波圖像", g_dstImage); }
上述內容就是bilateral filter雙邊濾波器的實現原理是什么,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。