三种平滑滤波器的比较(均值,中值和带方向特性的边沿保持)

类别:编程语言 点击:0 评论:0 推荐:

三种平滑滤波器的比较(均值,中值和带方向特性的边沿保持)

 

在获取的原始图像中一般带有一些噪声,为了消除这些噪声,可以对图像应用一些平滑滤波器,但平滑滤波器往往又容易造成图像模糊.下面比较了3种常用的平滑滤波器的平滑效果.

 

1.    均值滤波

原理是子图像在N*N子块中的,另检测点的灰度为块中灰度的平均值,这种方法通过把突变点的灰度分散在其相邻点中来达到平滑效果,操作起来也简单,但这样平滑往往造成图像的模糊,N选取得约大,模糊越严重.

 

 

2.    中值滤波

中值滤波平滑也在图像得N*N子块中操作,和均值平滑选择临近点得平均灰度值来作为检测点得灰度值不同,中值平滑使用临近点得中间灰度来作为检测点得灰度,即

 

 f(x,y)=mid{f(1,1),f(1,2)…f(n,n)}  n∈[1,N]

 

3.    带方向检测的边沿保持滤波

这种滤波的方法很多,其中一种是使用5个方向模板

x                       x          x         xxxxx

 x                     x           x         xxxxx

  x      x x x x x    x            x         xxxxx

   x                 x             x         xxxxx

    x               x              x         xxxxx

统计各个模板的方差D和均值E

定义

选择S最小的模板的D,再与正方形模板的方差D比较,选择比较小的一个模板作为象素使用的模板,另目标象素的灰度为所选用的模板灰度的均值.

这种带方向特性的模板能够保存图像的边沿,使图像线条边沿不至于因为平滑而变得模糊.但计算量比较大.

 

看看3种平滑的效果
  原始图像
------------------------------------------
 均值滤波器平滑(3*3子块)
---------------------------------------------
 中值滤波器平滑(3*3子块)
--------------------------------------------
 边沿保持滤波器平滑(3*3子块)
----------------------------------------------

可以看到3张图像都变得平滑了,但均值滤波模糊效果非常严重,中值滤波把比较细的线滤掉了,边沿保持滤波对边沿保持的效果比较好,根据需要选择.

下面是我的4种平滑的C代码

//----------------------在VC.NET 中编译通过.
/*
author:Lingch(Sboom)
date:2005-1-26
subject: Smooth Filter
*/
bool FilterAV(unsigned char *image,int height,int width) //均值滤波器
{
 int i,j;
 unsigned char *p=(unsigned char*)malloc(height*width);

 for(i=1;i<height-1;i++)
 {
  for(j=1;j<width-1;j++)
  {
   p[i*width+j]=(unsigned char)(((int)image[(i-1)*width+j-1]
      +(int)image[(i-1)*width+j]
      +(int)image[(i-1)*width+j+1]
      +(int)image[i*width+j-1]
      +(int)image[i*width+j]
      +(int)image[i*width+j+1]
      +(int)image[(i+1)*width+j-1]
      +(int)image[(i+1)*width+j]
      +(int)image[(i+1)*width+j+1])/9);
  }
 }

 for(i=1;i<height-1;i++)
 {
  for(j=1;j<width-1;j++)
  {
   image[i*width+j]=p[i*width+j];
  }
 }

 free(p);
 return true;
}
//----------------------------中值滤波器
bool FilterMid(unsigned char *image,int height,int width)
{
 int i,j,k,l;
 int pos;
 unsigned char temp;
 unsigned char psr[9];
 unsigned char *p=(unsigned char*)malloc(height*width);

  for(i=1;i<height-1;i++)
     {
  for(j=1;j<width-1;j++)
  {     //---3*3窗口矩阵
              psr[0]=image[(i-1)*width+j-1];
              psr[1]=image[(i-1)*width+j];
              psr[2]=image[(i-1)*width+j+1];
              psr[3]=image[i*width+j-1];
              psr[4]=image[i*width+j];
              psr[5]=image[i*width+j+1];
              psr[6]=image[(i+1)*width+j-1];
              psr[7]=image[(i+1)*width+j];
              psr[8]=image[(i+1)*width+j+1];

              //--------选择排序
              for(k=0;k<9;k++)
              {
                    pos=k;
                    for(l=k;l<9;l++)
                    {
                        if(psr[l]<psr[pos])
                                pos=l;
                    }
                    temp=psr[k];
                    psr[k]=psr[pos];
                    psr[pos]=temp;
              } 
              //------取中值
              p[i*width+j]=psr[4];
  }
 }

  for(i=1;i<height-1;i++)
     {
  for(j=1;j<width-1;j++)
  {
   image[i*width+j]=p[i*width+j];
  }
  }
  free(p);
  return true;
}
//-----------------边沿保持滤波器
bool Filter5(unsigned char *image ,int height,int width)
{
 int i,j,k,l;
 double av[5],av2[5];
 double s;
 double sd[4];

 unsigned char *p=(unsigned char*)malloc(height*width);

 for(i=2;i<height-2;i++)
 {
  for(j=2;j<width-2;j++)
  {
   av[0]=0.0;av[1]=0.0;av[2]=0.0;av[3]=0.0;av[4]=0.0;
   av2[0]=0.0;av2[1]=0.0;av2[2]=0.0;av2[3]=0.0;av2[4]=0.0;
  
   av[0]=(
     +image[i*width+j-1]
     +image[i*width+j]
     +image[i*width+j+1]
    )/3;
   av2[0]=(
     +image[i*width+j-1]*image[i*width+j-1]
     +image[i*width+j]*image[i*width+j]
     +image[i*width+j+1]*image[i*width+j+1]
     )/3-av[0]*av[0];

    av[1]=(
     +image[(i+1)*width+j-1]
     +image[i*width+j]
     +image[(i-1)*width+j+1]
     )/3;
    av2[1]=(
     +image[(i+1)*width+j-1]*image[(i+1)*width+j-1]
     +image[i*width+j]*image[i*width+j]
     +image[(i-1)*width+j+1]*image[(i-1)*width+j+1]
     )/3-av[1]*av[1];

    av[2]=(
     +image[(i-1)*width+j]
     +image[i*width+j]
     +image[(i+1)*width+j]
     )/3;
    av2[2]=(
     +image[(i-1)*width+j]*image[(i-1)*width+j]
     +image[i*width+j]*image[i*width+j]
     +image[(i+1)*width+j]*image[(i+1)*width+j]
     )/3-av[2]*av[2];

    av[3]=(
     +image[(i-1)*width+j-1]
     +image[i*width+j]
     +image[(i+1)*width+j+1]
     )/3;
    av2[3]=(
     +image[(i-1)*width+j-1]*image[(i-1)*width+j-1]
     +image[i*width+j]*image[i*width+j]
     +image[(i+1)*width+j+1]*image[(i+1)*width+j+1]
    )/3-av[3]*av[3];

   av[4]=0.0;av2[4]=0.0;
   for(k=i-1;k<=i+1;k++)
   {
    for(l=j-1;l<=j+1;l++)
    {
     av[4]+=image[k*width+l];
     av2[4]+=image[k*width+l]*image[k*width+l];
    }
   }
   av[4]=av[4]/9.0;
   av2[4]=av2[4]/9.0-av[4]*av[4];

   for(k=0;k<4;k++)
    sd[k]=av2[k]/av2[(k+2)%4];

   l=0;
   for(k=0;k<4;k++)
    if(sd[k]<sd[l])
     l=k;

   if(av2[l]<av[4])
    p[i*width+j]=av[l];
   else
    p[i*width+j]=av[4];
  }
 }

 for(i=0;i<height;i++)
  for(j=0;j<width;j++)
   image[i*width+j]=p[i*width+j];

 free(p);
 return true;
}

本文地址:http://com.8s8s.com/it/it23407.htm