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

1

1 [2]
<script type="math/tex; mode=display" id="MathJax-Element-1">图1\ 论文[2]中的双边滤波效果图</script>

双边滤波器中输出 (i,j) <script type="math/tex" id="MathJax-Element-2">(i,j)</script>位置的像素值 g <script type="math/tex" id="MathJax-Element-3">g</script>依赖于邻域内像素值f<script type="math/tex" id="MathJax-Element-4">f</script>的加权组合( k,l <script type="math/tex" id="MathJax-Element-5">k,l</script>表示邻域像素位置):

g(i,j)=k,lf(k,l)w(i,j,k,l)k,lw(i,j,k,l)
<script type="math/tex; mode=display" id="MathJax-Element-6">g(i,j)=\frac{\sum_{k,l}f(k,l)w(i,j,k,l)}{\sum_{k,l}w(i,j,k,l)}</script>
权重系数 w(i,j,k,l) <script type="math/tex" id="MathJax-Element-7">w(i,j,k,l)</script>取决于定义域核 d <script type="math/tex" id="MathJax-Element-8">d</script>与值域核r<script type="math/tex" id="MathJax-Element-9">r</script>的乘积:
d(i,j,k,l)=exp((ik)2+(jl)22σ2d),
<script type="math/tex; mode=display" id="MathJax-Element-10">d(i,j,k,l)=exp(-\frac{(i-k)^2+(j-l)^2}{2\sigma_d^2}),</script>
r(i,j,k,l)=exp(||f(i,j)f(k,l)||22σ2r),
<script type="math/tex; mode=display" id="MathJax-Element-11">r(i,j,k,l)=exp(-\frac{||f(i,j)-f(k,l)||^2}{2\sigma_r^2}),</script>
w(i,j,k,l)=exp((ik)2+(jl)22σ2d||f(i,j)f(k,l)||22σ2r)
<script type="math/tex; mode=display" id="MathJax-Element-12">w(i,j,k,l)=exp(-\frac{(i-k)^2+(j-l)^2}{2\sigma_d^2}-\frac{||f(i,j)-f(k,l)||^2}{2\sigma_r^2})</script>

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

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博客

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐