双边滤波器 Bilater filter

来源:互联网 发布:贵阳房价上涨知乎 编辑:程序博客网 时间:2024/05/21 05:06

双边滤波器主要是针对高斯模糊滤波来说的,处理后的效果比单纯的用高斯模糊要好。

    在图像的低对比度区域,也就是图像平滑区域,像素间的相关性较强,在图像的高对比度区域,edge区域,像素间的相关性比较弱,双边滤波器同时考虑邻域像素与中心像素间的几何距离度量和像素间灰度相似度度量,这两个度量均用高斯核函数。对领域中距离近并且灰度相似的像素赋予较大的权值,否则,则赋予较小的权值。正是这种双重异性加权机制(距离各式异性与灰度各向异性)保证了双边滤波器的图像边缘保持平滑。

    数学原理如下图中所示:

    

    其中G为高斯函数.

    

    当前像素点在做平滑处理的时候,对周围像素点分配的权值跟距离和灰度相关,而传统的方法只跟距离有关,不难想象,传统的高斯平滑会破坏图像中的edge。而双边滤波器也考虑了像素间的灰度差,所以即可以达到平滑denoise的目的,同时也很好的保护edge不被破坏,以保持图像的清晰度。

    算法原理就这么简单。下面附加上一段code,从别人的code中修改而来。参考局部5x5的像素来做滤波处理。

 
/××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××\

// Bilateral_Filtering.cpp : Defines the entry point for the console application.
//

#include "StdAfx.h"
#include "highgui.h"
#include <stdio.h>
#include "cv.h"
#include "cxcore.h"
#include <math.h>
#pragma comment(lib,"cv.lib") 
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")

 

void main(int argc,char **argv)
{
 IplImage *m_image=cvLoadImage("Frame_20130123_090302114_eeh40.bmp");
 int w=m_image->width;
 int h=m_image->height;
 
 IplImage *m_ba=cvCreateImage(cvSize(w,h),IPL_DEPTH_8U,3);
 int k=0,q=0,y=0,x=0;
 for(int i=2;i<h-2;i++)
 {
  for(int j=2;j<w-2;j++)
  {
   
   CvScalar cs[25];
   CvScalar css;
   CvScalar cc=cvGet2D(m_image,i,j);
   int a=0;
   double sum=0;
   double c[25],s[25];
   
   
   for(int k=i-2;k<=i+2;k++)
   {
    for(int q=j-2;q<=j+2;q++)
    {
     cs[a]=cvGet2D(m_image,k,q);
     c[a]=exp(-((pow(k-i,2)+pow(q-j,2))/512));
     s[a]=exp(-( pow(((cs[a].val[0]-cc.val[0])),2)+
              pow(((cs[a].val[1]-cc.val[1])),2)+
        pow(((cs[a].val[2]-cc.val[2])),2)  )/256);   //此处可视情况而定
     
     a++;
     
                }
   }
   for( y=0;y<25;y++)
   {  
    sum += c[y]*s[y];
   }
   
   for( x=0;x<25;x++)
   {
    css.val[0]+=(c[x]*s[x]*(cs[x].val[0]));
    css.val[1]+=(c[x]*s[x]*(cs[x].val[1]));
    css.val[2]+=(c[x]*s[x]*(cs[x].val[2]));
    
   }
   
   css.val[0] /= sum;
   css.val[1] /= sum;
   css.val[2] /= sum;

   css.val[0] = css.val[0]<0?0:css.val[0];
   css.val[1] = css.val[1]<0?0:css.val[1];
   css.val[2] = css.val[2]<0?0:css.val[2];

   css.val[0] = css.val[0]>255?255:css.val[0];
   css.val[1] = css.val[1]>255?255:css.val[1];
   css.val[2] = css.val[2]>255?255:css.val[2];

    
   cvSet2D(m_ba,i,j,css);
   
   
  }
 }
 
 cvNamedWindow("source",1);
 cvShowImage("source",m_image);
 
 cvNamedWindow("bilateral filtering",1);
 cvShowImage("bilateral filtering",m_ba);
 cvSaveImage("res.bmp",m_ba);
 
 cvWaitKey(0);
 cvReleaseImage(&m_ba);
 cvReleaseImage(&m_image);
 
}

 上述code是算法的实现过程,opencv中的平滑函数也封装了该功能,cvSmooth(m_image,m_ba,CV_BILATERAL,16,16);最后两个参数是亮度方差和空间方差。对应的方差越大,denoise的能力也越强,同时图像的清晰度也会有所下降。

    详细的算法请参考文献 :bilateral filtering for gray and color images

                                              :Adaptive bilateral filter for sharpness enhancement and noise removal -- IEEE 2008

                                              :A Fast Approximatino of the Bilateral Filter using a signal processing Approach --ECCV 2006

  参考:http://www.opencv.org.cn/forum/viewtopic.php?t=7433

          :http://www.doc88.com/p-673855926301.html

0 0