图像处理中的频域的图像增强——VC关键代码实现

                     理想,高斯,巴特沃思高通/低通滤波函数代码 


/*************************************************************************
* /函数名称:
 *   LowPassFilter()
* /输入参数:
 *   LPSTR lpDIBBits     - 指向需要滤波的图像像素指针
 *   int nWidth      - 数据宽度
 *   int nHeight      - 数据高度
 *   int nRadius      - 理想低通滤波的滤波半径
 * /返回值:
 *    BOOL        // 成功返回TRUE,否则返回FALSE。
 * /说明:
 *  lpDIBBits 是指向需要滤波的图像像素指针。
 *  经过低通滤波的数据仍然存储在lpDIBBits 当中。
**************************************************************************/
BOOL LowPassFilter(LPSTR lpDIBBits, LONG nWidth, LONG nHeight,int nRadius)
{
 unsigned char* lpSrc;       // 指向源图像的指针
 int y ;          // 循环控制变量
 int x ;          // 循环控制变量
 double dTmpOne ;        //存放临时变量
 double dTmpTwo ;        //存放临时变量
 int nTransWidth ;        // 傅立叶变换的宽度(2的整数次幂)
 int nTransHeight;        // 傅立叶变换的高度(2的整数次幂)
 double unchValue;        // 存贮图像各像素灰度的临时变量
 complex<double> * pCTData ;      // 指向时域数据的指针
 complex<double> * pCFData ;      // 指向频域数据的指针
 
 // 计算进行傅立叶变换的点数-横向 (2的整数次幂)
 dTmpOne = log(nWidth)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransWidth = (int) dTmpTwo; 
 // 计算进行傅立叶变换的点数-纵向 (2的整数次幂)
 dTmpOne = log(nHeight)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransHeight = (int) dTmpTwo;

 double dReal;         // 傅立叶变换的实部
 double dImag;         // 傅立叶变换的虚部
 // 低通滤波的半径不能超过频域的最大半径
 if(nRadius> (nTransWidth/2) || nRadius> (nTransHeight/2) )
 {
  return (false);        // 返回FALSE
 } 
 pCTData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 pCFData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 // 图像数据的宽和高不一定是2的整数次幂,所以pCTData有一部分数据需要补0
 for(y=0; y<nTransHeight; y++)
 {
  for(x=0; x<nTransWidth; x++)
  {
   pCTData[y*nTransWidth + x]=complex<double>(0,0);  // 补零
  }
 }
 //把图像数据传给pCTData
 for(y=0; y<nHeight; y++)
 {
  for(x=0; x<nWidth; x++)
  {
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   unchValue = *lpSrc;
   pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
  }
 }
 FFT_2D(pCTData, nWidth, nHeight, pCFData) ;    // 傅立叶正变换


   for(x=0;x<nTransWidth;x++)        //开始实施理想的低通滤波
 {
  for(y=nRadius;y<nTransHeight-nRadius;y++)
  {
   // 把纵向所有大于nRadius2的高频分量设置为0
   pCFData[x*nTransHeight + y]=complex<double>(0,0);
  }
 }
 for(x=nRadius;x<nTransWidth-nRadius;x++)
 {
  for(y=0;y<nTransHeight;y++)
  {
   // 把横向所有大于nRadius1的高频分量设置为0
   pCFData[x*nTransHeight + y]=complex<double>(0,0);
  }
 }

 IFFT_2D(pCFData, pCTData,nHeight, nWidth);     // 经过低通滤波的图象进行反变换

 
 for(y=0; y<nHeight; y++)        // 反变换的数据传给lpDIBBits
 {
  for(x=0; x<nWidth; x++)
  {
   //需要考虑信号的正负问题以及实际所用的图象数据是灰度值还是原始数据
   dReal = pCTData[y*nTransWidth + x].real() ;   // 实部
   dImag = pCTData[y*nTransWidth + x].imag() ;  // 虚部
   unchValue =dReal;
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   *lpSrc =unchValue ;
  }
 } 
 delete pCTData;          // 释放内存
 delete pCFData;          // 释放内存
 pCTData = NULL;
 pCFData = NULL; 
 return (true);          //返回结果
}


/*************************************************************************
* /函数名称:
 *   ButterWorthLowPass()
* /输入参数:
 *  LPSTR lpDIBBits     - 指向需要滤波的图像像素指针
 *   int nWidth      - 数据宽度
 *   int nHeight      - 数据高度
 *   int nRadius      - ButterWorth低通滤波的"半功率"点
* /返回值:
 *    BOOL        // 成功返回TRUE,否则返回FALSE。
* /说明:
 *  pDIBBits 是指向需要滤波的图像像素指针。
 *  经过ButterWorth低通滤波的数据仍然存储在lpDIBBits 当中。
 **************************************************************************/
BOOL ButterWorthLowPass(LPSTR lpDIBBits, LONG nWidth, LONG nHeight, int nRadius)
{
 unsigned char* lpSrc;       // 指向源图像的指针
 int y ;          // 循环控制变量
 int x ;          // 循环控制变量
 double dTmpOne ;        //存放临时变量
 double dTmpTwo ;        //存放临时变量
 double H ;          // ButterWorth 滤波系数
 int nTransWidth ;        // 傅立叶变换的宽度(2的整数次幂)
 int nTransHeight;        // 傅立叶变换的高度(2的整数次幂)
 double dReal ;         // 傅立叶变换的实部
 double dImag;         // 傅立叶变换的虚部
 double unchValue;        // 存贮图像各像素灰度的临时变量
 complex<double> * pCTData ;      // 指向时域数据的指针
 complex<double> * pCFData ;      // 指向频域数据的指针
 // 计算进行傅立叶变换的点数-横向 (2的整数次幂)
 dTmpOne = log(nWidth)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransWidth = (int) dTmpTwo; 
 // 计算进行傅立叶变换的点数-纵向 (2的整数次幂)
 dTmpOne = log(nHeight)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransHeight = (int) dTmpTwo;
 
 // 低通滤波的半径不能超过频域的最大半径
 if(nRadius> (nTransWidth/2) || nRadius> (nTransHeight/2) )
 {
  return (false);        // 返回FALSE
 } 

 pCTData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 pCFData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存

 // 图像数据的宽和高不一定是2的整数次幂,所以pCTData有一部分数据需要补0
 for(y=0; y<nTransHeight; y++)
 {
  for(x=0; x<nTransWidth; x++)
  {
   pCTData[y*nTransWidth + x]=complex<double>(0,0); // 补零
  }
 }
 for(y=0; y<nHeight; y++)       // 把图像数据传给pCTData
 {
  for(x=0; x<nWidth; x++)
  {
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   unchValue = *lpSrc;
   pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
  }
 } 
 FFT_2D(pCTData, nWidth, nHeight, pCFData) ;   // 傅立叶正变换
 for(y=0; y<nTransHeight; y++)      // 开始实施ButterWorth低通滤波
 {
  for(x=0; x<nTransWidth; x++)
  {
   H = (double)(y*y+x*x) ;
   H = H / (nRadius * nRadius);
   H = 1/(1+H)  ;       // 求H值
   pCFData[y*nTransWidth + x]=complex<double>(pCFData[y*nTransWidth + x].real()*H,
   pCFData[y*nTransWidth + x].imag()*H);
  }
 }
 // 经过ButterWorth低通滤波的图象进行反变换
 IFFT_2D(pCFData, pCTData, nWidth, nHeight);
 for(y=0; y<nHeight; y++)       // 反变换的数据传给lpDIBBits
 {
  for(x=0; x<nWidth; x++)
  {
   dReal = pCTData[y*nTransWidth + x].real() ;
   dImag = pCTData[y*nTransWidth + x].imag() ;
   unchValue = max(0,min(255,sqrt(dReal*dReal+dImag*dImag) ));
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   *lpSrc =unchValue ;
  }
 }
 delete pCTData;         // 释放内存
 delete pCFData;         // 释放内存
 pCTData = NULL;
 pCFData = NULL;
 return (true);         //返回结果 
}


/*************************************************************************
* /函数名称:
 *   GaussLowPass()
* /输入参数:
 *  LPSTR lpDIBBits     - 指向需要滤波的图像像素指针
 *   int nWidth      - 数据宽度
 *   int nHeight      - 数据高度
 *   int nRadius      - Gauss低通滤波的"半功率"点
* /返回值:
 *    BOOL        // 成功返回TRUE,否则返回FALSE。
* /说明:
 *  pDIBBits 是指向需要滤波的图像像素指针。
 *  经过Gauss低通滤波的数据仍然存储在lpDIBBits 当中。
 **************************************************************************/
BOOL GaussLowPass(LPSTR lpDIBBits, LONG nWidth, LONG nHeight, int nRadius)
{
 unsigned char* lpSrc;       // 指向源图像的指针
 int y ;          // 循环控制变量
 int x ;          // 循环控制变量
 double dTmpOne ;        //存放临时变量
 double dTmpTwo ;        //存放临时变量
 double H ;          // ButterWorth 滤波系数
 int nTransWidth ;        // 傅立叶变换的宽度(2的整数次幂)
 int nTransHeight;        // 傅立叶变换的高度(2的整数次幂)
 double dReal ;         // 傅立叶变换的实部
 double dImag;         // 傅立叶变换的虚部
 double unchValue;        // 存贮图像各像素灰度的临时变量
 complex<double> * pCTData ;      // 指向时域数据的指针
 complex<double> * pCFData ;      // 指向频域数据的指针
 // 计算进行傅立叶变换的点数-横向 (2的整数次幂)
 dTmpOne = log(nWidth)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransWidth = (int) dTmpTwo; 
 // 计算进行傅立叶变换的点数-纵向 (2的整数次幂)
 dTmpOne = log(nHeight)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransHeight = (int) dTmpTwo;
 
 // 低通滤波的半径不能超过频域的最大半径
 if(nRadius> (nTransWidth/2) || nRadius> (nTransHeight/2) )
 {
  return (false);        // 返回FALSE
 } 

 pCTData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 pCFData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存

 // 图像数据的宽和高不一定是2的整数次幂,所以pCTData有一部分数据需要补0
 for(y=0; y<nTransHeight; y++)
 {
  for(x=0; x<nTransWidth; x++)
  {
   pCTData[y*nTransWidth + x]=complex<double>(0,0); // 补零
  }
 }
 for(y=0; y<nHeight; y++)       // 把图像数据传给pCTData
 {
  for(x=0; x<nWidth; x++)
  {
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   unchValue = *lpSrc;
   pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
  }
 } 
 FFT_2D(pCTData, nWidth, nHeight, pCFData) ;   // 傅立叶正变换

 for(y=0; y<nTransHeight; y++)      // 开始实施Gauss低通滤波
 {
  for(x=0; x<nTransWidth; x++)
  {
   H = (double)(y*y+x*x) ;
   H = H / (2 * nRadius * nRadius);
   H = exp (-H)  ;       // 求H值
   pCFData[y*nTransWidth + x]=complex<double>(pCFData[y*nTransWidth + x].real()*H,
   pCFData[y*nTransWidth + x].imag()*H);
  }
 }
 // 经过Gauss低通滤波的图象进行反变换
 IFFT_2D(pCFData, pCTData, nWidth, nHeight);
 for(y=0; y<nHeight; y++)       // 反变换的数据传给lpDIBBits
 {
  for(x=0; x<nWidth; x++)
  {
   dReal = pCTData[y*nTransWidth + x].real() ;
   dImag = pCTData[y*nTransWidth + x].imag() ;
   unchValue = max(0,min(255,sqrt(dReal*dReal+dImag*dImag) ));
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   *lpSrc =unchValue ;
  }
 }
 delete pCTData;         // 释放内存
 delete pCFData;         // 释放内存
 pCTData = NULL;
 pCFData = NULL;
 return (true);         //返回结果 
}


/*************************************************************************
* /函数名称:
 *   HighPassFilter()
* /输入参数:
 *   LPSTR lpDIBBits     - 指向需要滤波的图像像素指针
 *   int nWidth      - 数据宽度
 *   int nHeight      - 数据高度
 *   int nRadius      - 理想高通滤波的滤波半径
 * /返回值:
 *    BOOL        // 成功返回TRUE,否则返回FALSE。
 * /说明:
 *  lpDIBBits 是指向需要滤波的图像像素指针。
 *  经过高通滤波的数据仍然存储在lpDIBBits 当中。
**************************************************************************/
BOOL HighPassFilter(LPSTR lpDIBBits, LONG nWidth, LONG nHeight,int nRadius)
{
 unsigned char* lpSrc;       // 指向源图像的指针
 int y ;          // 循环控制变量
 int x ;          // 循环控制变量
 double dTmpOne ;        //存放临时变量
 double dTmpTwo ;        //存放临时变量
 int nTransWidth ;        // 傅立叶变换的宽度(2的整数次幂)
 int nTransHeight;        // 傅立叶变换的高度(2的整数次幂)
 double unchValue;        // 存贮图像各像素灰度的临时变量
 complex<double> * pCTData ;      // 指向时域数据的指针
 complex<double> * pCFData ;      // 指向频域数据的指针

 // 计算进行傅立叶变换的点数-横向 (2的整数次幂)
 dTmpOne = log(nWidth)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransWidth = (int) dTmpTwo; 
 // 计算进行傅立叶变换的点数-纵向 (2的整数次幂)
 dTmpOne = log(nHeight)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransHeight = (int) dTmpTwo;

 double dReal;         // 傅立叶变换的实部
 double dImag;         // 傅立叶变换的虚部

 // 滤波的半径不能超过频域的最大半径
 if(nRadius>nTransWidth-1 || nRadius>nTransHeight-1)
 {
  return (false);        // 返回false
 }

 pCTData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 pCFData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 // 图像数据的宽和高不一定是2的整数次幂,所以pCTData有一部分数据需要补0
 for(y=0; y<nTransHeight; y++)
 {
  for(x=0; x<nTransWidth; x++)
  {
   pCTData[y*nTransWidth + x]=complex<double>(0,0); // 补零
  }
 }
 for(y=0; y<nHeight; y++)        // 把图像数据传给pCTData
 {
  for(x=0; x<nWidth; x++)
  {
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   unchValue = *lpSrc;
   pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
  }
 } 

 FFT_2D(pCTData, nWidth, nHeight, pCFData) ;    // 傅立叶正变换
 for(x=0;x<nTransWidth;x++)       // 开始实施理想的高通滤波
 {
  for(y=0;y<nRadius;y++)
  {
   //把纵向所有小于nRadius的低频分量设置为0
   pCFData[x*nTransHeight + y]=complex<double>(0,0);
  }
   
  for(y=nTransHeight-1-nRadius;y<nTransHeight;y++)
  {
   pCFData[x*nTransHeight + y]=complex<double>(0,0);
  }
 }

 for(x=0;x<nRadius;x++)
 {
  //把横向所有小于nRadius的低频分量设置为0
  for(y=0;y<nTransHeight;y++)
  {
   pCFData[x*nTransHeight + y]=complex<double>(0,0);
  }
 }

 for(x=nTransWidth-nRadius;x<nTransWidth;x++)
 {
  for(y=0;y<nTransHeight;y++)
  {
   pCFData[x*nTransHeight + y]=complex<double>(0,0);
  }
 }
 
 IFFT_2D(pCFData, pCTData,nHeight, nWidth);   // 经过高通滤波的图象进行反变换
 for(y=0; y<nHeight; y++)       // 反变换的数据传给lpDIBBits
 {
  for(x=0; x<nWidth; x++)
  {
   //需要考虑信号的正负问题以及实际所用的图象数据是灰度值还是原始数据
   dReal = pCTData[y*nTransWidth + x].real() ;
   dImag = pCTData[y*nTransWidth + x].imag() ;
   unchValue =dReal;
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   *lpSrc =unchValue ;
  }
 }
 delete pCTData;          // 释放内存
 delete pCFData;          // 释放内存
 pCTData = NULL;
 pCFData = NULL; 
 return (true);          // 返回结果
}

/*************************************************************************
 * /函数名称:
 *   ButterWorthHighPass()
 * /输入参数:
 *  LPSTR lpDIBBits     - 指向需要滤波的图像像素指针
 *   int nWidth       - 数据宽度
 *   int nHeight      - 数据高度
 *   int nRadius            - ButterWorth高通滤波的"半功率"点
* /返回值:
 *    BOOL        // 成功返回TRUE,否则返回FALSE。
* /说明:
 *  pDIBBits 是指向需要滤波的图像像素指针。
 *  经过ButterWorth低通滤波的数据仍然存储在lpDIBBits 当中。
 **************************************************************************/
BOOL ButterWorthHighPass(LPSTR lpDIBBits, LONG nWidth, LONG nHeight, int nRadius)
{
 unsigned char* lpSrc;       // 指向源图像的指针
 int y ;          // 循环控制变量
 int x ;          // 循环控制变量
 double dTmpOne ;        //存放临时变量
 double dTmpTwo ;        //存放临时变量
 double H ;          // ButterWorth 滤波系数
 int nTransWidth ;        // 傅立叶变换的宽度(2的整数次幂)
 int nTransHeight;        // 傅立叶变换的高度(2的整数次幂)
 double dReal ;         // 傅立叶变换的实部
 double dImag;         // 傅立叶变换的虚部
 double unchValue;        // 存贮图像各像素灰度的临时变量
 complex<double> * pCTData ;      // 指向时域数据的指针
 complex<double> * pCFData ;      // 指向频域数据的指针
 // 计算进行傅立叶变换的点数-横向(2的整数次幂)
 dTmpOne = log(nWidth)/log(2);
 dTmpTwo = ceil(dTmpOne);
 dTmpTwo = pow(2,dTmpTwo);
 nTransWidth = (int) dTmpTwo; 
 // 计算进行傅立叶变换的点数-纵向 (2的整数次幂)
 dTmpOne = log(nHeight)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransHeight = (int) dTmpTwo; 
 pCTData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 pCFData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 // 图像数据的宽和高不一定是2的整数次幂,所以pCTData有一部分数据需要补0
 for(y=0; y<nTransHeight; y++)
 {
  for(x=0; x<nTransWidth; x++)
  {
   pCTData[y*nTransWidth + x]=complex<double>(0,0); // 补零
  }
 }
 for(y=0; y<nHeight; y++)      // 把图像数据传给pCTData
 {
  for(x=0; x<nWidth; x++)
  {
  // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   unchValue = *lpSrc;
   pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
  }
 }
 FFT_2D(pCTData, nWidth, nHeight, pCFData) ;  // 傅立叶正变换
 for(y=0; y<nTransHeight; y++)     // 下面开始实施ButterWorth高通滤波
 {
  for(x=0; x<nTransWidth; x++)
  {
   H = (double)(y*y+x*x) ;
   H = (nRadius * nRadius) / H ;
   H = 1/(1+H);      // 求H值
   pCFData[y*nTransWidth + x]=complex<double>(H*(pCFData[y*nTransWidth + x].real()),
      H*(pCFData[y*nTransWidth + x].imag())  );
  }
 }
 // 经过ButterWorth高通滤波的图象进行反变换
 IFFT_2D(pCFData, pCTData, nWidth, nHeight);
 for(y=0; y<nHeight; y++)      // 反变换的数据传给lpDIBBits
 {
  for(x=0; x<nWidth; x++)
  {
   dReal = pCTData[y*nTransWidth + x].real() ;
   dImag = pCTData[y*nTransWidth + x].imag() ;
   unchValue = max(0,min(255,sqrt(dReal*dReal+dImag*dImag)+100 ));
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   *lpSrc =unchValue ;
  }
 } 
 delete pCTData;         // 释放内存
 delete pCFData;         // 释放内存
 pCTData = NULL;
 pCFData = NULL;
 return (true);         // 返回结果
}


/*************************************************************************
* /函数名称:
 *   GaussHighPass()
* /输入参数:
 *  LPSTR lpDIBBits     - 指向需要滤波的图像像素指针
 *   int nWidth          - 数据宽度
 *   int nHeight      - 数据高度
 *   int nRadius      - Gauss高通滤波的"半功率"点
* /返回值:
 *    BOOL        // 成功返回TRUE,否则返回FALSE。
* /说明:
 *  pDIBBits 是指向需要滤波的图像像素指针。
 *  经过Gauss高通滤波的数据仍然存储在lpDIBBits 当中。
 **************************************************************************/
BOOL GaussHighPass(LPSTR lpDIBBits, LONG nWidth, LONG nHeight, int nRadius)
{
 unsigned char* lpSrc;       // 指向源图像的指针
 int y ;          // 循环控制变量
 int x ;          // 循环控制变量
 double dTmpOne ;        //存放临时变量
 double dTmpTwo ;        //存放临时变量
 double H ;          // ButterWorth 滤波系数
 int nTransWidth ;        // 傅立叶变换的宽度(2的整数次幂)
 int nTransHeight;        // 傅立叶变换的高度(2的整数次幂)
 double dReal ;         // 傅立叶变换的实部
 double dImag;         // 傅立叶变换的虚部
 double unchValue;        // 存贮图像各像素灰度的临时变量
 complex<double> * pCTData ;      // 指向时域数据的指针
 complex<double> * pCFData ;      // 指向频域数据的指针
 // 计算进行傅立叶变换的点数-横向 (2的整数次幂)
 dTmpOne = log(nWidth)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransWidth = (int) dTmpTwo; 
 // 计算进行傅立叶变换的点数-纵向 (2的整数次幂)
 dTmpOne = log(nHeight)/log(2);
 dTmpTwo = ceil(dTmpOne) ;
 dTmpTwo = pow(2,dTmpTwo);
 nTransHeight = (int) dTmpTwo;
 
 // 高通滤波的半径不能超过频域的最大半径
 if(nRadius> (nTransWidth/2) || nRadius> (nTransHeight/2) )
 {
  return (false);        // 返回FALSE
 } 

 pCTData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存
 pCFData=new complex<double>[nTransWidth * nTransHeight]; // 分配内存

 // 图像数据的宽和高不一定是2的整数次幂,所以pCTData有一部分数据需要补0
 for(y=0; y<nTransHeight; y++)
 {
  for(x=0; x<nTransWidth; x++)
  {
   pCTData[y*nTransWidth + x]=complex<double>(0,0); // 补零
  }
 }
 for(y=0; y<nHeight; y++)       // 把图像数据传给pCTData
 {
  for(x=0; x<nWidth; x++)
  {
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   unchValue = *lpSrc;
   pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
  }
 } 
 FFT_2D(pCTData, nWidth, nHeight, pCFData) ;   // 傅立叶正变换

 for(y=0; y<nTransHeight; y++)      // 开始实施Gauss高通滤波
 {
  for(x=0; x<nTransWidth; x++)
  {
   H = (double)(y*y+x*x) ;
   H = H / (2 * nRadius * nRadius);
   H = 1 - exp (-H)  ;       // 求H值
   pCFData[y*nTransWidth + x]=complex<double>(pCFData[y*nTransWidth + x].real()*H,
   pCFData[y*nTransWidth + x].imag()*H);
  }
 }
 // 经过Gauss高通滤波的图象进行反变换
 IFFT_2D(pCFData, pCTData, nWidth, nHeight);
 for(y=0; y<nHeight; y++)       // 反变换的数据传给lpDIBBits
 {
  for(x=0; x<nWidth; x++)
  {
   dReal = pCTData[y*nTransWidth + x].real() ;
   dImag = pCTData[y*nTransWidth + x].imag() ;
   unchValue = max(0,min(255,sqrt(dReal*dReal+dImag*dImag) ));
   // 指向DIB第y行,第x个象素的指针
   lpSrc = (unsigned char*)lpDIBBits + nWidth * (nHeight - 1 - y) + x;
   *lpSrc =unchValue ;
  }
 }
 delete pCTData;         // 释放内存
 delete pCFData;         // 释放内存
 pCTData = NULL;
 pCFData = NULL;
 return (true);         //返回结果 
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值