双边滤波器原理及实现

双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波器的好处是可以做边缘保存(edge preserving),一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显地模糊边缘,对于高频细节的保护效果并不明显[1]。

双边滤波器原理及实现_第1张图片

1 [2]

双边滤波器中输出 (i,j) 位置的像素值 g 依赖于邻域内像素值 f 的加权组合( k,l 表示邻域像素位置):

g(i,j)=k,lf(k,l)w(i,j,k,l)k,lw(i,j,k,l)

权重系数 w(i,j,k,l) 取决于定义域核 d 与值域核 r 的乘积:
d(i,j,k,l)=exp((ik)2+(jl)22σ2d),

r(i,j,k,l)=exp(||f(i,j)f(k,l)||22σ2r),

w(i,j,k,l)=exp((ik)2+(jl)22σ2d||f(i,j)f(k,l)||22σ2r)

同时考虑了空间域与值域的差别。一般过去用的维纳滤波或者高斯滤波去降噪,只考虑了空间域差别,都会较明显地模糊边缘,对于高频细节的保护效果并不明显;α-截尾均值滤波器,去掉百分率为α的最小值和最大之后剩下像素的均值作为滤波器,只考虑了值域差别。

OpenCV demo

#include "stdafx.h"

#include "stdio.h"
#include "cv.h"
#include "highgui.h"
#include "Math.h"
#include "time.h"

using namespace cv;

int main()
{
    clock_t start,finish;

    Mat img = imread("lena.jpg",1);
    Mat dst = Mat::zeros(img.rows,img.cols,CV_8UC3);

    start = clock();
    //src为输入原图像,dst为双边滤波后的图像,d为滤波内核的大小,即邻域的大小  
    // sigmaColor为灰度值权值公式中的方差,即公式2中的σr  
    // sigmaSpace为距离权值公式中的方差,即公式1中的σd  
    // borderType表示用什么方式来处理加宽后的图像四周边界 
    bilateralFilter(img, dst, 10,  
                      25, 25);
    finish = clock();
    printf("time is:%fs\n",(double)(finish - start) / CLOCKS_PER_SEC);

    imshow("img", img);
    imshow("dst", dst);

    cvWaitKey(-1);

    return 0;
}

结果图如下,皮肤明显变光滑了,主要的边缘都保留了下来:
双边滤波器原理及实现_第2张图片
计算速度较慢,将近100ms。

参考资料
[1]双边滤波-百度百科
[2]Tomasi C, Manduchi R. Bilateral filtering for gray and color images[C]//Computer Vision, 1998. Sixth International Conference on. IEEE, 1998: 839-846. 引用次数:5896
[3]双边滤波matlab实现-CSDN博客

你可能感兴趣的:(图像处理,OpenCV)