图像处理-双边滤波原理
来源:互联网 发布:linux 安装 jdk 编辑:程序博客网 时间:2024/06/05 11:19
双边滤波(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 * 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学习资料
阅读全文
0 0
- 图像处理-双边滤波原理
- 图像平滑处理(归一化块滤波、高斯滤波、中值滤波、双边滤波)
- 图像平滑处理(归一化块滤波、高斯滤波、中值滤波、双边滤波)
- 图像处理理论(三)——双边滤波, Steerable滤波, Gabor滤波, Schmid滤波
- 图像平滑处理(归一化块滤波、高斯滤波、中值滤波、双边滤波)
- 【OpenCV3图像处理】非线性滤波:中值滤波、双边滤波、引导滤波
- 双边滤波算法原理
- 双边滤波原理
- 双边滤波算法原理
- 双边滤波原理理解
- 双边滤波算法原理
- 图像处理(六)递归双边滤波磨皮
- 图像处理(六)递归双边滤波磨皮
- 图像处理(六)递归双边滤波磨皮
- 灰度图像双边滤波代码
- 用双边滤波图像平滑
- 图像处理平滑处理--高斯滤波,简单模糊,中值模糊,双边滤波,简单无放缩变换
- 双边滤波(BilateralFilter)原理
- IOS编码GB2312与UTF-8互转
- No implementation found for int com.baidu.platform.comjni.engine.JNIEngine.initClass
- 浏览器缓存总结
- TensorLow: FailedPreconditionError:Attempting to use uninitialized value Variable
- 斐波那契+数颜色
- 图像处理-双边滤波原理
- android 链式调用
- KMP
- iOS开发-RunLoop的退出方式
- cvpr 2017 re-id papers
- 11.7 T3.B
- struct和typedef struct
- tensorflow(2)---linux,anaconda2,pycharm中调用tensorflow
- VB.net 图片加载内存问题