图像处理-双边滤波原理
2017-11-07 17:05
337 查看
双边滤波(Bilateral filter)是一种可以去噪保边的滤波器。之所以可以达到此效果,是因为滤波器是由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个由像素差值决定滤波器系数。
原理示意图如下:
双边滤波器中,输出像素的值依赖于邻域像素的值的加权组合,
权重系数w(i,j,k,l)取决于定义域核
和值域核
的乘积
二、C++实现
2.1 OpenCV调用方法:
cvSmooth(m_iplImg, dstImg, CV_BILATERAL, 2 * r + 1, 0, sigma_r, sigma_d);
2.3 C++代码
//双边滤波
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 *
cd4d
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;
}
性能方面,跟OpenCV处理速度有差距,有兴趣的,可以自己研究OpenCV版本的源代码
三、效果图
四、参考资料
资料[4]是MIT的学习资料,最全面,包括课件、论文、代码等,涵盖原理、改进、应用、与PDE的联系等等,最值得一看。
[1] 双边滤波器的原理及实现[Rachel-Zhang]
[2]【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
[3] Bilateral
Filtering(双边滤波) for SSAO
[4]MIT学习资料
原理示意图如下:
双边滤波器中,输出像素的值依赖于邻域像素的值的加权组合,
权重系数w(i,j,k,l)取决于定义域核
和值域核
的乘积
二、C++实现
2.1 OpenCV调用方法:
cvSmooth(m_iplImg, dstImg, CV_BILATERAL, 2 * r + 1, 0, sigma_r, sigma_d);
2.3 C++代码
//双边滤波
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 *
cd4d
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;
}
性能方面,跟OpenCV处理速度有差距,有兴趣的,可以自己研究OpenCV版本的源代码
三、效果图
四、参考资料
资料[4]是MIT的学习资料,最全面,包括课件、论文、代码等,涵盖原理、改进、应用、与PDE的联系等等,最值得一看。
[1] 双边滤波器的原理及实现[Rachel-Zhang]
[2]【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
[3] Bilateral
Filtering(双边滤波) for SSAO
[4]MIT学习资料
相关文章推荐
- 图像处理(六)递归双边滤波磨皮
- 数字图像处理(三):高斯滤波和双边滤波
- 【图像处理】图像滤波5种:方框、均值、高斯、中值、双边
- 图像处理平滑处理--高斯滤波,简单模糊,中值模糊,双边滤波,简单无放缩变换
- Atitit 图像处理 平滑 也称 模糊, 归一化块滤波、高斯滤波、中值滤波、双边滤波)
- 【OpenCV3图像处理】非线性滤波:中值滤波、双边滤波、引导滤波
- Atitit 图像处理 平滑 也称 模糊, 归一化块滤波、高斯滤波、中值滤波、双边滤波)
- 图像处理之双边滤波效果(Bilateral Filtering for Gray and Color Image)
- 图像平滑技术之核算子、均值滤波、中值滤波、高斯滤波、双边滤滤、导向滤波的原理概要及OpenCV代码实现
- 【计算机视觉】【图像处理】图像平滑-双边滤波+联合双边滤波+导向滤波
- 图像处理之双边滤波效果(Bilateral Filtering for Gray and Color Image)
- 图像处理之双边滤波效果(Bilateral Filtering for Gray and Color Image)
- 第6章 图像处理_6.2非线性滤波:中值滤波、双边滤波
- 图像平滑处理(归一化块滤波、高斯滤波、中值滤波、双边滤波)
- 图像处理(六)递归双边滤波磨皮
- 图像处理之双边滤波效果(Bilateral Filtering for Gray and Color Image)
- 图像处理之双边滤波介绍与源码实现
- 图像平滑处理(归一化块滤波、高斯滤波、中值滤波、双边滤波)
- 图像处理之双边滤波效果(Bilateral Filtering for Gray and Color Image)
- 图像处理之积分图应用二(快速边缘保留滤波算法)