平滑

1。邻域平均法

    噪声点像素的灰度与其临近像素的灰度显著不同,根据噪声点这一特性,可以使用邻域平均法。

 

Bitmap desc  =   new  Bitmap(source.Width, source.Height);
BitmapData sourcedata 
=  source.LockBits( new  Rectangle( 0 0 , source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
=  desc.LockBits( new  Rectangle( 0 0 , desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte *  sourceptr  =  ( byte * )sourcedata.Scan0;  
      
byte *  descptr  =  ( byte * )descdata.Scan0;
      
int  step  =  source.Width  *   3 ;
      
for  ( int  x  =   0 ; x  <  source.Height; x ++ )
      {
           
for  ( int  y  =   0 ; y  <  source.Width; y ++ )
           {
                
* (descptr ++ =  ( byte )(( * (sourceptr  -  (step  +   3 ))  +   * (sourceptr  -  step)  +   * (sourceptr  -  (step  -   3 ))  +
                               
* (sourceptr  -   3 +   * (sourceptr)  +   * (sourceptr  +   3 +
                               
* (sourceptr  +  (step  -   3 ))  +   * (sourceptr  +  step)  +   * (sourceptr  +  (step  +   3 )))  /   9 );
                sourceptr
++ ;
            }
            sourceptr 
+=  sourcedata.Stride  -  source.Width  *   3 ;
            descptr 
+=  descdata.Stride  -  desc.Width  *   3 ;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

2。加权平均法

    邻域平均处理方法是以图像模糊为代价减小噪声。有时为了突出源图像中的点(i, j)本身的重要性,对于同一尺寸的模板,不同位置的系数采用不同的数值就可以采用加权平均法实现。

 

Bitmap desc  =   new  Bitmap(source.Width, source.Height);
BitmapData sourcedata 
=  source.LockBits( new  Rectangle( 0 0 , source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
=  desc.LockBits( new  Rectangle( 0 0 , desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte *  sourceptr  =  ( byte * )sourcedata.Scan0;  
      
byte *  descptr  =  ( byte * )descdata.Scan0;
      
int  step  =  source.Width  *   3 ;
      
for  ( int  x  =   0 ; x  <  source.Height; x ++ )
      {
           
for  ( int  y  =   0 ; y  <  source.Width; y ++ )
           {
                
* (descptr ++ =  ( byte )(( * (sourceptr  -  (step  +   3 ))  +   * (sourceptr  -  step)  *   2   +   * (sourceptr  -  (step  -   3 )) +
                               
* (sourceptr  -   3 *   2   +   * (sourceptr)  *   4   +   * (sourceptr  +   3 *   2   +
                               
* (sourceptr  +  (step  -   3 ))  +   * (sourceptr  +  step)  *   2   +   * (sourceptr  +  (step  +   3 )))  /   16 );
                sourceptr
++ ;
            }
            sourceptr 
+=  sourcedata.Stride  -  source.Width  *   3 ;
            descptr 
+=  descdata.Stride  -  desc.Width  *   3 ;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 3。选择式掩膜平滑

     邻域平均法和加权平均法在消除噪声的同时,都不可避免地带来平均化的缺憾,致使尖锐变化的边缘或线条变得模糊。考虑图像中目标物体和背景一般都具有不同的统计特性,即不同的均值和方差,为保留一定的边缘信息,可采用选择式掩膜平滑滤波,这样可以得到较好的图像细节。这种方法以尽量不模糊边缘轮廓为目的。

 

代码
Bitmap desc  =   new  Bitmap(source.Width, source.Height);
BitmapData sourcedata 
=  source.LockBits( new  Rectangle( 0 0 , source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
=  desc.LockBits( new  Rectangle( 0 0 , desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte *  sourceptr  =  ( byte * )sourcedata.Scan0;   // B,G,R
       byte *  descptr  =  ( byte * )descdata.Scan0;
      
int  step  =  source.Width  *   3 ;
      sourceptr 
+=  step  *   2 ;
      descptr 
+=  step  *   2 ;
      
byte [] pixel  =   new   byte [ 9 ];
      
float [,] mean  =   new   float [ 9 , 3 ];
      
float [,] var  =   new   float [ 9 , 3 ];
      
int  n, m;
      
float  min;
      
for  ( int  x  =   2 ; x  <  source.Height  -   2 ; x ++ )
      {
            sourceptr 
+=   6 ;
            descptr 
+=   6 ;
            
for  ( int  y  =   2 ; y  <  source.Width  -   2 ; y ++ )
            {
                  
for  ( int  color  =   0 ; color  <   3 ; color ++
                     {
                         pixel[
0 =   * (sourceptr  -  (step  +   3 ));
                         pixel[
1 =   * (sourceptr  -  step);
                         pixel[
2 =   * (sourceptr  -  (step  -   3 ));
                         pixel[
3 =   * (sourceptr  -   3 );
                         pixel[
4 =   * (sourceptr);
                         pixel[
5 =   * (sourceptr  +   3 );
                         pixel[
6 =   * (sourceptr  +  (step  -   3 ));
                         pixel[
7 =   * (sourceptr  +  step);
                         pixel[
8 =   * (sourceptr  +  (step  +   3 ));
                         mean[
0 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                        pixel[
5 +  pixel[ 6 +  pixel[ 7 +  pixel[ 8 ])  /   9 ;
                         var[
0 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   9 ; n ++ )
                              var[
0 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 0 , color]  *  mean[ 0 , color];

                         pixel[
0 =   * (sourceptr  -  (step  +   6 ));
                         pixel[
1 =   * (sourceptr  -  (step  +   3 ));
                         pixel[
2 =   * (sourceptr  -   6 );
                         pixel[
3 =   * (sourceptr  -   3 );
                         pixel[
4 =   * (sourceptr);
                         pixel[
5 =   * (sourceptr  +  (step  -   6 ));
                         pixel[
6 =   * (sourceptr  +  (step  -   3 ));
                         mean[
1 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                          pixel[
5 +  pixel[ 6 ])  /   7 ;
                         var[
1 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   7 ; n ++ )
                              var[
1 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 1 , color]  *  mean[ 1 , color];

                         pixel[
0 =   * (sourceptr  -  (step  +  step  +   3 ));
                         pixel[
1 =   * (sourceptr  -  (step  +  step));
                         pixel[
2 =   * (sourceptr  -  (step  +  step  -   3 ));
                         pixel[
3 =   * (sourceptr  -  (step  +   3 ));
                         pixel[
4 =   * (sourceptr  -  step);
                         pixel[
5 =   * (sourceptr  -  (step  -   3 ));
                         pixel[
6 =   * (sourceptr);
                         mean[
2 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                          pixel[
5 +  pixel[ 6 ])  /   7 ;
                         var[
2 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   7 ; n ++ )
                              var[
2 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 2 , color]  *  mean[ 2 , color];

                         pixel[
0 =   * (sourceptr  -  (step  -   3 ));
                         pixel[
1 =   * (sourceptr  -  (step  -   6 ));
                         pixel[
2 =   * (sourceptr);
                         pixel[
3 =   * (sourceptr  +   3 );
                         pixel[
4 =   * (sourceptr  +   6 );
                         pixel[
5 =   * (sourceptr  +  (step  +   3 ));
                         pixel[
6 =   * (sourceptr  +  (step  +   6 ));
                         mean[
3 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                          pixel[
5 +  pixel[ 6 ])  /   7 ;
                         var[
3 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   7 ; n ++ )
                              var[
3 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 3 , color]  *  mean[ 3 , color];

                         pixel[
0 =   * (sourceptr);
                         pixel[
1 =   * (sourceptr  +  (step  -   3 ));
                         pixel[
2 =   * (sourceptr  +  step);
                         pixel[
3 =   * (sourceptr  +  (step  +   3 ));
                         pixel[
4 =   * (sourceptr  +  (step  +  step  -   3 ));
                         pixel[
5 =   * (sourceptr  +  step  +  step);
                         pixel[
6 =   * (sourceptr  +  (step  +  step  +   3 ));
                         mean[
4 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                          pixel[
5 +  pixel[ 6 ])  /   7 ;
                         var[
4 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   7 ; n ++ )
                              var[
4 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 4 , color]  *  mean[ 4 , color];

                         pixel[
0 =   * (sourceptr  -  (step  +  step  +   6 ));
                         pixel[
1 =   * (sourceptr  -  (step  +  step  +   3 ));
                         pixel[
2 =   * (sourceptr  -  (step  +   6 ));
                         pixel[
3 =   * (sourceptr  -  (step  +   3 ));
                         pixel[
4 =   * (sourceptr  -  step);
                         pixel[
5 =   * (sourceptr  -   3 );
                         pixel[
6 =   * (sourceptr);
                         mean[
5 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                          pixel[
5 +  pixel[ 6 ])  /   7 ;
                         var[
5 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   7 ; n ++ )
                              var[
5 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 5 , color]  *  mean[ 5 , color];

                         pixel[
0 =   * (sourceptr  -  (step  +  step  -   3 ));
                         pixel[
1 =   * (sourceptr  -  (step  +  step  -   6 ));
                         pixel[
2 =   * (sourceptr  -  step);
                         pixel[
3 =   * (sourceptr  -  (step  -   3 ));
                         pixel[
4 =   * (sourceptr  -  (step  -   6 ));
                         pixel[
5 =   * (sourceptr);
                         pixel[
6 =   * (sourceptr  +   3 );
                         mean[
6 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                          pixel[
5 +  pixel[ 6 ])  /   7 ;
                         var[
6 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   7 ; n ++ )
                              var[
6 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 6 , color]  *  mean[ 6 , color];

                         pixel[
0 =   * (sourceptr);
                         pixel[
1 =   * (sourceptr  +   3 );
                         pixel[
2 =   * (sourceptr  +  step);
                         pixel[
3 =   * (sourceptr  +  (step  +   3 ));
                         pixel[
4 =   * (sourceptr  +  (step  +   6 ));
                         pixel[
5 =   * (sourceptr  +  (step  +  step  +   3 ));
                         pixel[
6 =   * (sourceptr  +  (step  +  step  +   6 ));
                         mean[
7 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                          pixel[
5 +  pixel[ 6 ])  /   7 ;
                         var[
7 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   7 ; n ++ )
                              var[
7 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 7 , color]  *  mean[ 7 , color];

                         pixel[
0 =   * (sourceptr  -   3 );
                         pixel[
1 =   * (sourceptr);
                         pixel[
2 =   * (sourceptr  +  (step  -   6 ));
                         pixel[
3 =   * (sourceptr  +  (step  -   3 ));
                         pixel[
4 =   * (sourceptr  +  step);
                         pixel[
5 =   * (sourceptr  +  (step  +  step  -   6 ));
                         pixel[
6 =   * (sourceptr  +  (step  +  step  -   3 ));
                         mean[
8 , color]  =  ( float )(pixel[ 0 +  pixel[ 1 +  pixel[ 2 +  pixel[ 3 +  pixel[ 4 +
                                          pixel[
5 +  pixel[ 6 ])  /   7 ;
                         var[
8 , color]  =   0 ;
                         
for  (n  =   0 ; n  <   7 ; n ++ )
                              var[
8 , color]  +=  pixel[n]  *  pixel[n]  -  mean[ 8 , color]  *  mean[ 8 , color];

                         descptr
++ ;
                         sourceptr
++ ;
                   }

                   min 
=  var[ 0 0 +  var[ 0 1 +  var[ 0 2 ];
                   m 
=   0 ;
                   
for  (n  =   1 ; n  <   9 ; n ++ )
                   {
                        
if  (min  >  var[n,  0 +  var[n,  1 +  var[n,  2 ])
                        {
                             min 
=  var[n,  0 +  var[n,  1 +  var[n,  2 ];
                             m 
=  n;
                        }
                   }

                   
* (descptr  -   3 =  ( byte )(mean[m,  0 ]);
                   
* (descptr  -   2 =  ( byte )(mean[m,  1 ]);
                   
* (descptr  -   1 =  ( byte )(mean[m,  2 ]);
             }
             sourceptr 
+=  sourcedata.Stride  -  source.Width  *   3   +   6 ;
             descptr 
+=  descdata.Stride  -  desc.Width  *   3   +   6 ;
      }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

4。中值滤波法

    中值滤波是一种非线性平滑滤波,在一定条件下可以克服线性滤波带来的图像细节模糊问题,而且对滤除噪声干扰及图像扫描噪声非常有效。中值滤波通常采用一个含有奇数个点的滑动窗口,用窗口中各点灰度值的中值来代替中心点的灰度值。对于奇数个元素,中值是指按大小排序后中间的数值;对偶数个元素,中值是指排序后中间两个元素灰度值的平均值。

 

 

Bitmap desc  =   new  Bitmap(source.Width, source.Height);
BitmapData sourcedata 
=  source.LockBits( new  Rectangle( 0 0 , source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
=  desc.LockBits( new  Rectangle( 0 0 , desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte *  sourceptr  =  ( byte * )sourcedata.Scan0;  
      
byte *  descptr  =  ( byte * )descdata.Scan0;
      
int  step  =  source.Width  *   3 ;
      
byte [] mean  =   new   byte [ 9 ];
      
for  ( int  x  =   0 ; x  <  source.Height; x ++ )
      {
           
for  ( int  y  =   0 ; y  <  source.Width; y ++ )
           {
                mean[
0 =   * (sourceptr  -  (step  +   3 ));
                mean[
1 =   * (sourceptr  -  step);
                mean[
2 =   * (sourceptr  -  (step  -   3 ));
                mean[
3 =   * (sourceptr  -   3 );
                mean[
4 =   * (sourceptr);
                mean[
5 =   * (sourceptr  +   3 );
                mean[
6 =   * (sourceptr  +  (step  -   3 ));
                mean[
7 =   * (sourceptr  +  step);
                mean[
8 =   * (sourceptr  +  (step  +   3 ));

                Array.Sort(mean);
                
* (descptr ++ =  mean[ 4 ];
                sourceptr
++ ;
            }
            sourceptr 
+=  sourcedata.Stride  -  source.Width  *   3 ;
            descptr 
+=  descdata.Stride  -  desc.Width  *   3 ;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

 

你可能感兴趣的:(平滑)