前面介紹了雙邊濾波器(bilateral filter,LBF),然而BF的權值是不穩定的,是以在邊緣附近會出現一些翻轉。此外BF計算複雜度是O(r^2);為了改善BF權值的穩定性,引入了聯合雙邊濾波器(joint bilateral filter ,LBF)。兩者之間的差别就是JBF用了一個導向圖作為值域權重的計算依據。下面我們通過數學公式展示二者的不同:
先看BF的,如(1)所示,

再次解釋一下公式中的符号意義,其中I表示輸入圖像,p、q表示像素在圖像中的坐标,Ip表示對應位置的像素值,J表示輸出, f、g是權重分布函數,一般為高斯函數。這種濾波的結果就是周邊像素的權值不僅和距離有關還和那個位置的像素值有關。
再看JBF,如(2)所示,
如果在值域的權重計算過程引入另外一幅圖像,如下式,則稱之為聯合雙邊濾波。 ~I 就是引入的另外一幅圖像。該圖像 必須與待處理的圖像相似。
JBF的原理圖,如圖(1)所示。
圖(1)JBF原理圖
聯合雙邊濾波上采樣技術也很簡單,一種便于了解的也便于寫代碼的方式就是把下采樣并進行處理過後的小圖按照最近鄰插值的方式放大到原圖大小,然後再用原圖的資料和這個放大的結果進行聯合雙邊濾波處理 。
下面粘貼了JBF的matlab代碼供大家學習參考。
function B = jbfltGray(D,C,w,sigma_d,sigma_r)
% D should be a double precision matrix of size NxMx1 (i.e., grayscale) with normalized values in the
% closed interval [0,1].
% C should be similar to D, from which the weights are calculated, with normalized values in the
% closed interval [0,1].
% Pre-compute Gaussian distance weights.
[X,Y] = meshgrid(-w:w,-w:w);
G = exp(-(X.^2+Y.^2)/(2*sigma_d^2));
% Apply bilateral filter.
dim = size(D);
B = zeros(dim);
for i = 1:dim(1)
for j = 1:dim(2)
% Extract local region.
iMin = max(i-w,1);
iMax = min(i+w,dim(1));
jMin = max(j-w,1);
jMax = min(j+w,dim(2));
I = D(iMin:iMax,jMin:jMax);
% To compute weights from the color image
J = C(iMin:iMax,jMin:jMax);
% Compute Gaussian intensity weights according to the color image
H = exp(-(J-C(i,j)).^2/(2*sigma_r^2));
% Calculate bilateral filter response.
F = H.*G((iMin:iMax)-i+w+1,(jMin:jMax)-j+w+1);
B(i,j) = sum(F(:).*I(:))/sum(F(:));
end
end
----------------------------------------------以上原理轉載自: pplong的部落格----------------------------------------------
OpenCV 3.x.x的擴充子產品(ximgproc. Extended Image Processing) 也添加了JBF的 API :
OpenCV的代碼:
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <ximgproc.hpp>
int main()
{
cv::Mat src = cv::imread("data/dp.png", 1); // 原始帶噪聲的深度圖
cv::Mat joint = cv::imread("data/teddy.png", 0);
cv::Mat dst;
int64 begin = cvGetTickCount();
cv::ximgproc::jointBilateralFilter(joint, src, dst, -1, 3, 9);
int64 end = cvGetTickCount();
float time = (end - begin) / (cvGetTickFrequency() * 1000.);
printf("time = %fms\n", time);
imshow("src", src);
imshow("joint", joint);
imshow("jointBilateralFilter", dst);
cv::waitKey(0);
return 0;
}
效果如圖:
延伸閱讀:
導向濾波器(Guided Filter)