p = ( i , j ) p=(i,j) p=(i,j) 表示进行处理的二维像素点。
q = ( k , l ) ∈ S q=(k,l) \in S q=(k,l)∈S 表示 p p p点邻域(滤波核范围内)中的像素点,包括 p p p。
I I I 表示像素点的像素值,即 I p I_p Ip和 I q I_q Iq分别表示像素点 p p p和 q q q的像素值。
W p , q W_{p,q} Wp,q 表示分配给 q q q点的权重值。
W p = ∑ q ∈ S W p , q W_p=\sum_{q \in S}W_{p,q} Wp=∑q∈SWp,q 表示 p p p点的滤波核权重总和。
高斯滤波用一个固定的滤波窗口对其邻域进行计算,输出像素等于滤波核范围内像素点像素值的加权求和平均,即
I p = 1 W p ∑ q ∈ S W p , q I q I_p = \frac{1}{W_p}\sum_{q \in S}{W_{p,q}I_q} Ip=Wp1q∈S∑Wp,qIq
窗口的权重值是固定的。因为高斯滤波在滤波过程中只考虑了位置关系,距离中心越近的点其权重越大。即
W p , q = G σ ( q ) = 1 2 π σ 2 e − ∥ p − q ∥ 2 2 σ 2 = 1 2 π σ 2 e − ( i − k ) 2 + ( j − l ) 2 2 σ 2 W_{p,q}=G_{\sigma}{(q)}=\frac{1}{2\pi\sigma^2}e^{-\frac{{\parallel p-q \parallel}^2}{2\sigma^2}}=\frac{1}{2\pi\sigma^2}e^{-\frac{(i-k)^2+(j-l)^2}{2\sigma^2}} Wp,q=Gσ(q)=2πσ21e−2σ2∥p−q∥2=2πσ21e−2σ2(i−k)2+(j−l)2
其中 σ \sigma σ是参数,可以看出,权重 W p , q W_{p,q} Wp,q只与 q q q和 p p p的相对位置有关,因此滤波核的权重是固定的。
高斯滤波在去噪的同时会模糊边缘,双边滤波在其基础上进行扩展。双边滤波是一种边缘感知的去噪滤波,它在考虑位置关系的同时还考虑像素值关系。和高斯滤波一样,输出像素等于滤波核范围内像素点像素值的加权求和平均:
I p = 1 W p ∑ q ∈ S W p , q I q I_p = \frac{1}{W_p}\sum_{q \in S}{W_{p,q}I_q} Ip=Wp1q∈S∑Wp,qIq
其权重的计算方式如下,
W p , q = G σ s ( ∥ p − q ∥ ) G σ r ( ∥ I p − I q ∥ ) W_{p,q}=G_{\sigma_s}(\parallel p-q \parallel)G_{\sigma_r}(\parallel I_p-I_q \parallel) Wp,q=Gσs(∥p−q∥)Gσr(∥Ip−Iq∥)
其中 G σ ( x ) = e ( − x 2 2 σ 2 ) G_{\sigma}(x)=e^{(-\frac{x^2}{2\sigma^2})} Gσ(x)=e(−2σ2x2), σ s \sigma_s σs和 σ r \sigma_r σr表示输入的参数,因此
W p , q = e ( − ( i − k ) 2 + ( j − l ) 2 2 σ s 2 ) e ( − ( I p − I q ) 2 2 σ r 2 ) W_{p,q}=e^{(-\frac{(i-k)^2+(j-l)^2}{2\sigma_s^2})}e^{(-\frac{(I_p-I_q)^2}{2\sigma_r^2})} Wp,q=e(−2σs2(i−k)2+(j−l)2)e(−2σr2(Ip−Iq)2)
其中 G σ s ( ∥ p − q ∥ ) G_{\sigma_s}(\parallel p-q \parallel) Gσs(∥p−q∥)和 G σ r ( ∥ I p − I q ∥ ) G_{\sigma_r}(\parallel I_p-I_q \parallel) Gσr(∥Ip−Iq∥)分别表示空间域和值域上的关系。
OpenCV中用函数bilateralFilter()实现了双边滤波。
void bilateralFilter( InputArray _src, OutputArray _dst, int d,
double sigmaColor, double sigmaSpace,
int borderType )
// _src和_dst分别表示原图像和滤波后图像,d表示滤波核大小
// sigmaColor表示像素值方差,即simga_R
// sigmaSpace表示距离方差,即sigma_S
对于像素点 p = ( i , j ) p=(i,j) p=(i,j),其滤波值计算过程大致如下:
int radius = d/2;
double gauss_space_coeff = -0.5/(sigma_space*sigma_space);
double gauss_color_coeff = -0.5/(sigma_color*sigma_color);
double Wp=0, sum=0;
for (int x = -radius; x <= radius; x++)
for (int y = -radius; y <= radius; y++)
{
double Gs = exp(- (x*x+y*y)/gauss_space_coeff);
double Gc = exp(- pow(_src[i][j]-_src[i+x][j+y],2)/gauss_color_coeff)
double Wpq = Gc*Gs;
sum += Wpq * _src[i+x][j+y];
Wp += Wpq;
}
_dst[i][j] = sum / Wp;