//双边滤波
void CImgPrcView::BilateralFilter()
{
// TODO: 在此添加命令处理程序代码
if (!m_pBitmap) return;
FreeInterResultImage();
int r = 7;//滤波器边长
int w_filter = 2 * r + 1;
//修改该参数
double sigma_d = 5;
double sigma_r = 25;
int nx = m_dwWidth, ny = m_dwHeight;
double gaussian_d_coeff = -1 / (2 * sigma_d * sigma_d); //定义域核 sigma_d为标准差
double gaussian_r_coeff = -1 / (2 * sigma_r * sigma_r); //值域核 sigma_r为标准差
double *d_metrix = new double[w_filter * w_filter]; // spatial weight 空间距离系数
double *r_metrix = new double[w_filter * w_filter]; // r_metrix weight 空间距离系数
double *metrix = new double[w_filter * w_filter]; // metrix weight 空间距离系数
//double r_metrix[256]; // similarity weight 灰度差值系数
// copy the original image
BYTE *img_tmp = new BYTE[nx * ny];
BYTE *img = new BYTE[nx * ny];
for (int i = 0; i < ny; i++)
for (int j = 0; j < nx; j++)
{
img_tmp[i * nx + j] = m_pBitmap[i * nx + j];
img[i * nx + j] = 255;
}
// compute spatial weight
for (int i = -r; i <= r; i++)
for (int j = -r; j <= r; j++)
{
d_metrix[(i + r) * w_filter + (j + r)] = exp((i * i + j * j) * gaussian_d_coeff);
}
// bilateral filter
for (int i = 0; i < ny; i++)
{
for (int j = 0; j < nx; j++)
{
// compute similarity weight
double weight_temp = 0;
for (int k = -r; k <= r; k++)
{
for (int l = -r; l <= r; l++)
{
if (((i + k) < 0) || ((i + k) > ny) || ((j + l) < 0) || ((j + l) > nx))
{
weight_temp = abs(img_tmp[i * nx + j] - 0);
r_metrix[(k + r)*(2 * r + 1) + (l + r)] = exp(gaussian_r_coeff * pow(weight_temp, 2));
}
else
{
weight_temp = abs(img_tmp[i * nx + j] - img_tmp[(i + k) * nx + (j + l)]);
r_metrix[(k + r)*(2 * r + 1) + (l + r)] = exp(gaussian_r_coeff * pow(weight_temp , 2));
}
}
}
// compute weight
double weight_up = 0, weight_down = 0;
for (int k = -r; k <= r; k++)
{
for (int l = -r; l <= r; l++)
{
if (((i + k) < 0) || ((i + k) > ny) || ((j + l) < 0) || ((j + l) > nx))
{
metrix[(k + r) * (2 * r + 1) + (l + r)] = 0;
//计算当前灰度值
weight_down += metrix[(k + r) * (2 * r + 1) + (l + r)];
weight_up += metrix[(k + r) * (2 * r + 1) + (l + r)] * 0/* * img_tmp[(i) * nx + (j)]*/; //边界处理
}
else
{
metrix[(k + r) * (2 * r + 1) + (l + r)] = r_metrix[(k + r) * (2 * r + 1) + (l + r)] * d_metrix[(k + r) * (2 * r + 1) + (l + r)];
//计算当前灰度值
weight_down += metrix[(k + r) * (2 * r + 1) + (l + r)];
weight_up += metrix[(k + r) * (2 * r + 1) + (l + r)] * img_tmp[(i + k) * nx + (j + l)];
}
}
}
img[i * nx + j] = weight_up / weight_down;
}
}
AddInterResultImage(img, m_dwHeight, m_dwWidth, 8, "双边滤波");
Invalidate(FALSE);
UpdateWindow();
delete [] img;
delete [] img_tmp;
delete [] d_metrix;
delete [] r_metrix;
delete [] metrix;
}