均值滤波快速算法

来源:互联网 发布:销售数据表格 编辑:程序博客网 时间:2024/06/04 17:44

1.概述

 在图像处理中,在进行如边缘检测这样的进一步处理之前,通常需要首先进行一定程度的降噪。中值滤波是一种非线性数字滤波器技术,经常用于去除图像或者其它信号中的噪声。这个设计思想就是检查输入信号中的采样并判断它是否代表了信号,使用奇数个采样组成的观察窗实现这项功能。观察窗口中的数值进行排序,位于观察窗中间的中值作为输出。然后,丢弃最早的值,取得新的采样,重复上面的计算过程。中值滤波是图像处理中的一个常用步骤,它对于斑点噪声和椒盐噪声来说尤其有用。保存边缘的特性使它在不希望出现边缘模糊的场合也很有用。

 1.1中值滤波快速算法 

很多人提出了各种中值滤波的快速算法,其共同特点是只考虑滑动窗口中移入和移出的数据,避免了传统算法中因排序所需的大量数据比较,从而较大地提高了速度。本文从另一个角度提出了一种快速算法,考虑的对象是单个滑
动窗内的像素。具体步骤如下:


(1)   X
考虑待处理的窗口内像素为i={X1,Xc,Xn},加权窗为Wi={W1W2  Wn} X。对中心像素c进行比较,将窗口内的像素分为小于、等于和大于Xc3[3],并加上相应权值来统计每一类的个数分别记为LeftCenterRight。把小于和大于Xc的像素分别放入数组LEFT[]RIGHT[]。例如X3Left=Left+W3,并加入W3X3到数组LEFT[m]LEFT[m+1]、直到LEFT[m+W3-1],m=Left,取下一个像素重复以
上步骤,取完为止。

(2)  比较LeftRightX,如两者相等则中值为中心像素c
(3)  |Left-Right|rX,则中值为中心像素c
(4)  |Left-Right|>Cente
r,则分为Left>RightRight>Left两种情况。Left>Right为例,X说明中值在小于c的这一类中 LEFT[Left] =Left-Right-Center。表示中值就是数组LEFT[Left]中最大的△个数的中值。计算index=(+1)/2.表示中值就是LEFT[Left]中第index
大这个数(Right>Left)情况下分析类似
(5)   
最后对LEFT[Left]RIGHT[Right]进行局部排序,排序到第index个大小时结束。

流程图如下:

均值滤波快速算法

 

2 调试

2. 1 中值滤波快速算法

测试结果:

根据测试,处理同样一副椒盐噪声图像,与一般的中值滤波方法相比,采用3*3的滤波窗口,本文的中值滤波的快速算法在时间上大约可以缩短一半,而对于更大的滤波窗口来说,窗口越大采用本文的方法实验结果越明显。由此可见,本中值滤波在实际应用中可以更为快速的解决问题。

椒盐噪声图像滤波:

均值滤波快速算法

高斯图像滤波:

均值滤波快速算法

CCS代码:

 

#include

#include

#include"IMG_thr_le2min.h"

 

#define IMAGEWIDTH  256

#define IMAGEHEIGHT 256

#define Uint8      unsigned char

 

unsigned chargrey[IMAGEHEIGHT][IMAGEWIDTH];

 

void ReadImage(char *cFileName);

void bmpDataPart(FILE* fpbmp);

void fastmiddle();

Uint8 GetMedianLocalSort(Uint8 *array,Uint8length,Uint8 index,int type);

 

 

void main()

{

 

  ReadImage("D:\\Administrator\\MyPictures\\Lena1.bmp");

 

  fastmiddle();

 

  while (1);                                               

}                                         

 

 

void ReadImage(char *cFileName)

{

 

       FILE*fp;

       if ( fp=fopen(cFileName,"rb" ) )

       {

          

             bmpDataPart(fp);

             fclose(fp);

       }

}

 

void bmpDataPart(FILE* fpbmp)

{

  int i,j=0;

  unsigned char*pix=NULL;

  fseek(fpbmp, 55L,SEEK_SET);

 

  pix=(unsignedchar*)malloc(256);

 

 for(j=0;j

  {

    

              fread(pix,1, 256, fpbmp);

    for(i=0;i

       {

          

                

           grey[IMAGEHEIGHT-1-j][i]  =pix[i];

 

       }

 

   }

 

}

 

 

void fastmiddle()

{

 

 inti=0,j=0;

 intwheight=1,wwidth=1;                  //窗口大小(2*wheight+1)* (2*wwidth+1)

 intk=0,l=0;

 Uint8left[9],right[9],X;

 Uint8leftnum=0,rightnum=0,centernum=0,index=0;

 

 for(i=0;i

  {

 

    for(j=0;j

       {

          

           if((i>wheight-1) && (iwwidth-1) &&(j

                      

                     {

              

              X=grey[i][j];

              leftnum=0;

              rightnum=0;

              centernum=0;

              index=0;

 

                      for(k=i-wheight;k<=i+wheight;k++)

                       for(l=j-wwidth;l<=j+wwidth;l++)

                        {

                  if(grey[k][l]>X )

                                   {

                                   

                                   left[leftnum] = grey[k][l];

                                   leftnum++;

                                   }

 

                   else if(grey[k][l]

                                   {

                                   

                                   right[rightnum] =grey[k][l];

                                   rightnum++;

                                   }

 

                                   else

                                    centernum++;

 

                 }

 

               if(leftnum == rightnum)

                             continue;//grey[i][j]=X;

                           else

                            if(abs(leftnum-rightnum)< centernum)

                             continue;//grey[i][j]=X;

                           else

                            if(leftnum>rightnum)

                            {

                             index=(leftnum-rightnum-centernum+1)/2;

                  grey[i][j]=GetMedianLocalSort(left,leftnum,index,1);

                            }

                           else   

                 {

                             index=(rightnum-leftnum-centernum+1)/2;

                  grey[i][j]=GetMedianLocalSort(right,rightnum,index,2);

                            }

            

                     }

 

 

       }

 

   }

 

 

}

 

 

Uint8 GetMedianLocalSort(Uint8 *array,Uint8length,Uint8 index,int type)

{

 intMedian=0,i=0,j=0;

 if(type==1)

 {

  for(i=0;i

  {

   for(j=i+1;j

   {

    if(array[i]>array[j])

 

    {

     Median=array[i];

     array[i]=array[j];

     array[j]=Median;

    }

   }

  }

 returnarray[index-1];

 

 }

 

if(type==2)

 {

  for(i=0;i

  {

    for(j=i+1;j

    {

      if(array[i]

        {

          Median=array[i];

          array[i]=array[j];

          array[j]=Median;

        }

    }

  }

 returnarray[index-1];

 }

 return-1;

}

0 0