snifer

(原创)维纳斯滤波

0
阅读(3170)

最近在研究滤波器,读了很多相关资料,有软件滤波方法,硬件滤波的方法,硬件滤波可以使用ADI 的ADV7840: 12位、170 MHz视频和图形数字化仪,集成3D梳状滤波解码器和四通道HDMI 1.3接收器 12位等,今天上午完成了一个维纳斯滤波的程序,把程序贴出来,供大家参考,如果觉得可以进一步改进的,可以留言,谢谢!!!!从连续的(或离散的)输入数据中滤除噪声和干扰以提取有用信息的过程称为滤波,而相应的装置称为滤波器。根据滤波器的输出是否为输入的线性函数,可将它分为线性滤波器和非线性滤波器两种。

 

这个滤波器我采用c++实现:

//参数说明:
//LPSTR lpDIBBits:指向源DIB图像指针
//LONG  lWidth:源图像宽度(象素数)
//LONG  lHeight:源图像高度(象素数)
//函数说明:
//该函数用来对DIB图像进行维纳滤波复原操作。
BOOL WINAPI WienerDIB (LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
 // 指向源图像的指针
 LPSTR lpSrc;
 //循环变量
 long i;
 long j;
 //像素值
 unsigned char pixel;
 // 图像每行的字节数
 LONG lLineBytes;
 //用于做FFT的数组
 double *fftSrc,*fftKernel,*fftNoise;
 double a,b,c,d,e,f,multi;
 //二维FFT的长度和宽度
 unsigned long nn[3];
 //图像归一化因子
 double MaxNum;
 
 // 计算图像每行的字节数
 lLineBytes = WIDTHBYTES(lWidth * 8);
 
 double dPower = log((double)lLineBytes)/log(2.0);
 if(dPower != (int) dPower)
 {
  return false;
 }
 dPower = log((double)lHeight)/log(2.0);
 if(dPower != (int) dPower)
 {
  return false;
 }
 
 fftSrc = new double [lHeight*lLineBytes*2+1];
 fftKernel = new double [lHeight*lLineBytes*2+1];
 fftNoise = new double [lHeight*lLineBytes*2+1];
 
 nn[1] = lHeight;
 nn[2] = lLineBytes;
 for (j = 0;j < lHeight ;j++)
 {
  for(i = 0;i < lLineBytes ;i++)
  {
   // 指向源图像倒数第j行,第i个象素的指针   
   lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
   
   pixel = (unsigned char)*lpSrc;
   
   fftSrc[(2*lLineBytes)*j + 2*i + 1] = (double)pixel;
   fftSrc[(2*lLineBytes)*j + 2*i + 2] = 0.0;
   
   if(i < 5 && j == 0)
   {
    fftKernel[(2*lLineBytes)*j + 2*i + 1] = 1/5.0;
   }
   else
   {
    fftKernel[(2*lLineBytes)*j + 2*i + 1] = 0.0;
   }
   fftKernel[(2*lLineBytes)*j + 2*i + 2] = 0.0;
   if ( i + j == ((int)((i+j)/8))*8)
   {
    fftNoise [(2*lLineBytes)*j + 2*i + 1]= -16.0;
   }
   else
   {
    fftNoise [(2*lLineBytes)*j + 2*i + 1]= 0.0;
   }
   fftNoise[(2*lLineBytes)*j + 2*i + 2] = 0.0;
  }
 }
 
 srand((unsigned)time(NULL));
 //对源图像进行FFT
 fourn(fftSrc,nn,2,1);
 //对卷积核图像进行FFT
 fourn(fftKernel,nn,2,1);
 //对噪声图像进行FFT
 fourn(fftNoise,nn,2,1);
 
 for (i = 1;i <lHeight*lLineBytes*2;i+=2)
 {
  a = fftSrc[i];
  b = fftSrc[i+1];
  c = fftKernel[i];
  d = fftKernel[i+1];
  e = fftNoise[i];
  f = fftNoise[i+1];
  multi = (a*a + b*b)/(a*a + b*b - e*e - f*f);
  if (c*c + d*d > 1e-3)
  {
   fftSrc[i] = ( a*c + b*d ) / ( c*c + d*d ) / multi;
   fftSrc[i+1] = ( b*c - a*d ) / ( c*c + d*d )/multi;
  }
 }
 
 //对结果图像进行反FFT
 fourn(fftSrc,nn,2,-1);
 
 //确定归一化因子
 MaxNum = 0.0;
 for (j = 0;j < lHeight ;j++)
 {
  for(i = 0;i < lLineBytes ;i++)
  {
   fftSrc[(2*lLineBytes)*j + 2*i + 1] =
    sqrt(fftSrc[(2*lLineBytes)*j + 2*i + 1] * fftSrc[(2*lLineBytes)*j + 2*i + 1]\
    +fftSrc[(2*lLineBytes)*j + 2*i + 2] * fftSrc[(2*lLineBytes)*j + 2*i + 2]);
   if( MaxNum < fftSrc[(2*lLineBytes)*j + 2*i + 1])
    MaxNum = fftSrc[(2*lLineBytes)*j + 2*i + 1];
  }
 }
 
 //转换为图像
 for (j = 0;j < lHeight ;j++)
 {
  for(i = 0;i < lLineBytes ;i++)
  {
   // 指向源图像倒数第j行,第i个象素的指针   
   lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
   
   *lpSrc = (unsigned char) (fftSrc[(2*lLineBytes)*j + 2*i + 1]*255.0/MaxNum );
  }
 }
 
 delete fftSrc;
 delete fftKernel;
 delete fftNoise;
 // 返回
 return true;
}
我都加了注释,可以供编程爱好者研究,呵呵