www.pudn.com > ImageProcessing.rar > Enhance.cpp


 
#include "stdafx.h" 
#include "cdib.h" 
#include "math.h" 
#include  
#include  
using namespace std; 
#include "GlobalApi.h" 
 
/************************************************************************* 
 * 
 * \函数名称: 
 *   HistogramEqualize() 
 * 
 * \输入参数: 
 *   CDib * pDib		- 指向CDib类的指针,含有原始图象信息 
 * 
 * \返回值: 
 *   BOOL			- 成功则返回TRUE,否则返回FALSE 
 * 
 * \说明: 
 *   该函数对指定的图象进行直方图均衡化处理 
 * 
 ************************************************************************* 
 */ 
 BOOL HistogramEqualize(CDib* pDib) 
 { 
	 // 指向源图像的指针 
	unsigned char*	lpSrc; 
	 
	// 临时变量 
	int	nTemp; 
	 
	// 循环变量 
	int i,j; 
	 
	// 累积直方图,即灰度映射表 
	BYTE	byMap[256]; 
	 
	// 直方图 
	int	nCount[256]; 
	 
	// 图象的高度和宽度 
	CSize sizeImage; 
	sizeImage = pDib->GetDimensions(); 
 
 
	// 获得图象数据存储的高度和宽度 
	CSize SizeSaveImage; 
	SizeSaveImage = pDib->GetDibSaveDim(); 
 
 
 
	// 重置计数为0 
	for (i = 0; i < 256; i ++) 
	{ 
		// 清零 
		nCount[i] = 0; 
	} 
	 
	// 计算各个灰度值的计数,即得到直方图 
	for (i = 0; i < sizeImage.cy; i ++) 
	{ 
		for (j = 0; j < sizeImage.cx; j ++) 
		{ 
			lpSrc = (unsigned char *)pDib->m_lpImage + SizeSaveImage.cx * i + j; 
			 
			// 计数加1 
			nCount[*(lpSrc)]++; 
		} 
	} 
	 
	// 计算累积直方图 
	for (i = 0; i < 256; i++) 
	{ 
		// 初始为0 
		nTemp = 0; 
		 
		for (j = 0; j <= i ; j++) 
		{ 
			nTemp += nCount[j]; 
		} 
		 
		// 计算对应的新灰度值 
		byMap[i] = (BYTE) (nTemp * 255 / sizeImage.cy / sizeImage.cx); 
	} 
	 
	// 每行 
	for(i = 0; i < sizeImage.cy; i++) 
	{ 
		// 每列 
		for(j = 0; j < sizeImage.cx; j++) 
		{ 
			// 指向DIB第i行,第j个象素的指针 
			lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i,j); 
			 
			// 计算新的灰度值 
			*lpSrc = byMap[*lpSrc]; 
		} 
	} 
	 
	// 返回 
	return TRUE; 
 } 
 
/************************************************************************* 
 * 
 * \函数名称: 
 *   GraySegLinTrans() 
 * 
 * \输入参数: 
 *   CDib* pDib			- 指向CDib类的指针,含有原始图象信息 
 *   int   nX1			- 分段线性灰度变换第一个拐点的X坐标 
 *   int   nY1			- 分段线性灰度变换第一个拐点的Y坐标 
 *   int   nX2			- 分段线性灰度变换第二个拐点的X坐标 
 *   int   nY2			- 分段线性灰度变换第二个拐点的Y坐标 
 * 
 * \返回值: 
 *   BOOL               - 成功返回TRUE,否则返回FALSE。 
 * 
 * \说明: 
 *   该函数用来对图像进行分段线性灰度变换,输入参数中包含了两个拐点的坐标 
 * 
 ************************************************************************* 
 */ 
BOOL GraySegLinTrans(CDib* pDib, int nX1, int nY1, int nX2, int nY2) 
{ 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	 
	// 循环变量 
	int i,j; 
	 
	// 灰度映射表 
	BYTE	byMap[256]; 
	 
	// 图像每行的字节数 
	//LONG	lLineBytes; 
 
	// 图象的高度和宽度 
	CSize sizeImage; 
	sizeImage = pDib->GetDimensions(); 
 
 
	// 获得图象数据存储的高度和宽度 
	CSize SizeSaveImage; 
	SizeSaveImage = pDib->GetDibSaveDim(); 
 
	// 计算图像每行的字节数 
	//lLineBytes = WIDTHBYTES(sizeImage.cx * 8); 
	 
	// 计算灰度映射表 
	for (i = 0; i <= nX1; i++) 
	{ 
		// 判断nX1是否大于0(防止分母为0) 
		if (nX1 > 0) 
		{ 
			// 线性变换 
			byMap[i] = (BYTE) nY1 * i / nX1; 
		} 
		else 
		{ 
			// 直接赋值为0 
			byMap[i] = 0; 
		} 
	} 
	for (; i <= nX2; i++) 
	{ 
		// 判断nX1是否等于nX2(防止分母为0) 
		if (nX2 != nX1) 
		{ 
			// 线性变换 
			byMap[i] = nY1 + (BYTE) ((nY2 - nY1) * (i - nX1) / (nX2 - nX1)); 
		} 
		else 
		{ 
			// 直接赋值为nY1 
			byMap[i] = nY1; 
		} 
	} 
	for (; i < 256; i++) 
	{ 
		// 判断nX2是否等于255(防止分母为0) 
		if (nX2 != 255) 
		{ 
			// 线性变换 
			byMap[i] = nY2 + (BYTE) ((255 - nY2) * (i - nX2) / (255 - nX2)); 
		} 
		else 
		{ 
			// 直接赋值为255 
			byMap[i] = 255; 
		} 
	} 
	 
	// 对图象的象素值进行变换 
	// 每行 
	for(i = 0; i < sizeImage.cy; i++) 
	{ 
		// 每列 
		for(j = 0; j < sizeImage.cx; j++) 
		{ 
			// 指向DIB第i行,第j个象素的指针 
			lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i,j); 
			 
			// 计算新的灰度值 
			*lpSrc = byMap[*lpSrc]; 
		} 
	} 
	 
	// 返回 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * \函数名称: 
 *   GeneralTemplate() 
 * 
 * \输入参数: 
 *   CDib * pDib		- 指向CDib类的指针,含有原始图象信息 
 *   int nTempWidth		- 模板的宽度 
 *   int nTempHeight		- 模板的高度 
 *   int nTempCenX		- 模板中心的X坐标(相对于模板) 
 *   int nTempCenY		- 模板中心的Y坐标(相对于模板) 
 *   double* pdbTemp		- 模板数组的指针 
 *   double* dbCoef		- 模板的系数 
 * 
 * \返回值: 
 *   BOOL			- 成功则返回TRUE,否则返回FALSE 
 * 
 * \说明: 
 *   该函数用指定的模板对pDib指向的图象进行模板操作。模板的定义了宽度,高度, 
 *    中心坐标和系数,模板的数据存放在pdbTemp中。对图象进行模板操作后,仍 
 *    然存放在pDib指向的CDib对象中。需要注意的是,该函数只能处理8位的图象, 
 *   否则,指向的数据将出错。 
 * 
 ************************************************************************* 
 */ 
BOOL  GeneralTemplate(CDib* pDib,  int nTempWidth, int nTempHeight,  
					 int nTempCenX, int nTempCenY, 
					 double* pdbTemp, double dbCoef) 
{ 
	// 临时存放图像数据的指针 
	LPBYTE lpImage; 
	 
	// 循环变量 
	int i,j,k,l; 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	 
	// 指向要复制区域的指针 
	unsigned char*	lpDst; 
 
	// 计算结果 
	double	dbResult; 
 
	// 图象的高度和宽度 
	CSize sizeImage; 
	sizeImage = pDib->GetDimensions(); 
 
 
	// 获得图象数据存储的尺寸 
	int nSizeImage; 
	nSizeImage = pDib->GetSizeImage(); 
 
	// 给临时存放数据分配内存 
	lpImage = (LPBYTE) new char[nSizeImage]; 
 
	// 判断是否内存分配失败 
	if (lpImage == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 将原始图像的数据拷贝到临时存放内存中 
	memcpy(lpImage, pDib->m_lpImage, nSizeImage); 
 
	 
	 
	// 进行模板操作 
	// 行(除去边缘几行) 
	for(i = nTempCenY ; i < sizeImage.cy - nTempHeight + nTempCenY + 1; i++) 
	{ 
		// 列(除去边缘几列) 
		for(j = nTempCenX; j < sizeImage.cx - nTempWidth + nTempCenX + 1; j++) 
		{ 
			// 指向新DIB第i行,第j个象素的指针 
			lpDst = (unsigned char*)lpImage + pDib->GetPixelOffset(i,j); 
			 
			dbResult = 0; 
			 
			// 计算 
			for (k = 0; k < nTempHeight; k++) 
			{ 
				for (l = 0; l < nTempWidth; l++) 
				{ 
					// 指向DIB第i - nTempCenY + k行,第j - nTempCenX + l个象素的指针 
					lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i-nTempCenY+k, j-nTempCenX+l); 
					 
					// 保存象素值 
					dbResult += (* lpSrc) * pdbTemp[k * nTempWidth + l]; 
				} 
			} 
			 
			// 乘上系数 
			dbResult *= dbCoef; 
			 
			// 取绝对值 
			dbResult = (double ) fabs(dbResult); 
			 
			// 判断是否超过255 
			if(dbResult > 255) 
			{ 
				// 直接赋值为255 
				* lpDst = 255; 
			} 
			else 
			{ 
				// 赋值 
				* lpDst = (unsigned char) (dbResult + 0.5); 
			} 
			 
		} 
	} 
	 
	// 复制变换后的图像 
	memcpy(pDib->m_lpImage, lpImage, nSizeImage); 
	 
	// 释放内存 
	delete[]lpImage; 
	 
	// 返回 
	return TRUE; 
 
} 
 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   MedianFilter() 
 * 
 * \输入参数: 
 *   CDib * pDib		- 指向CDib类的指针,含有原始图象信息 
 *   int nTempWidth		- 模板的宽度 
 *   int nTempHeight		- 模板的高度 
 *   int nTempCenX		- 模板中心的X坐标(相对于模板) 
 *   int nTempCenY		- 模板中心的Y坐标(相对于模板) 
 * 
 * \返回值: 
 *   BOOL			- 成功则返回TRUE,否则返回FALSE 
 * 
 * 说明: 
 *   该函数对指定的DIB图像进行中值滤波。 
 * 
 ************************************************************************/ 
 
BOOL MedianFilter(CDib* pDib,  int nTempWidth, int nTempHeight,  
					 int nTempCenX, int nTempCenY) 
{	 
	// 临时存放图像数据的指针 
	LPBYTE lpImage; 
	 
	// 循环变量 
	int i,j,k,l; 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	 
	// 指向要复制区域的指针 
	unsigned char*	lpDst; 
 
	// 图象的高度和宽度 
	CSize sizeImage; 
	sizeImage = pDib->GetDimensions(); 
 
	// 获得图象数据存储的尺寸 
	int nSizeImage; 
	nSizeImage = pDib->GetSizeImage(); 
 
	// 指向滤波器数组的指针 
	unsigned char* pUnchFltValue; 
 
	// 给临时存放数据分配内存 
	lpImage = (LPBYTE) new char[nSizeImage]; 
	// 判断是否内存分配失败 
	if (lpImage == NULL) 
	{ 
		// 返回 
		return FALSE; 
	} 
	 
	// 将原始图像的数据拷贝到临时存放内存中 
	memcpy(lpImage, pDib->m_lpImage, nSizeImage); 
	 
	// 暂时分配内存,以保存滤波器数组 
	pUnchFltValue = new unsigned char[nTempHeight * nTempWidth]; 
	 
	// 判断是否内存分配失败 
	if (pUnchFltValue == NULL) 
	{ 
		// 释放已分配内存 
		delete[]lpImage; 
		 
		// 返回 
		return FALSE; 
	} 
	 
	// 开始中值滤波 
	// 行(除去边缘几行) 
	for(i = nTempCenY; i < sizeImage.cy - nTempHeight + nTempCenY + 1; i++) 
	{ 
		// 列(除去边缘几列) 
		for(j = nTempCenX; j < sizeImage.cx - nTempWidth + nTempCenX + 1; j++) 
		{ 
			// 指向新DIB第i行,第j个象素的指针 
			lpDst = (unsigned char*)lpImage + pDib->GetPixelOffset(i,j); 
			//lpDst = (unsigned char*)lpImage + sizeImage.cx * (sizeImage.cy - 1 - i) + j; 
			 
			// 读取滤波器数组 
			for (k = 0; k < nTempHeight; k++) 
			{ 
				for (l = 0; l < nTempWidth; l++) 
				{ 
					// 指向DIB第i - nTempCenY + k行,第j - nTempCenX + l个象素的指针 
					lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i-nTempCenY+k, j-nTempCenX+l); 
					//lpSrc = (unsigned char*)pDib->m_lpImage + sizeImage.cx * (sizeImage.cy - 1 - i + nTempCenY - k) + j - nTempCenX + l; 
					 
					// 保存象素值 
					pUnchFltValue[k * nTempWidth + l] = *lpSrc; 
				} 
			} 
			 
			// 获取中值 
			//* lpDst = GetMedianValue(pUnchFltValue, nTempHeight * nTempWidth); 
		} 
	} 
	 
	// 复制变换后的图像 
	memcpy(pDib->m_lpImage, lpImage, nSizeImage); 
	 
	// 释放内存 
	delete[]lpImage; 
	delete[]pUnchFltValue; 
 
	// 返回 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   GetMedianValue() 
 * 
 * 参数: 
 *   unsigned char * pUnchFltValue	- 指向要获取中值的数组指针 
 *   int   iFilterLen			- 数组长度 
 * 
 * 返回值: 
 *   unsigned char			- 返回指定数组的中值。 
 * 
 * 说明: 
 *   该函数用冒泡法对一维数组进行排序,并返回数组元素的中值。 
 * 
 ************************************************************************/ 
 
unsigned char  GetMedianValue(unsigned char * pUnchFltValue, int iFilterLen) 
{ 
	// 循环变量 
	int		i; 
	int		j; 
	 
	// 中间变量 
	unsigned char bTemp; 
	 
	// 用冒泡法对数组进行排序 
	for (j = 0; j < iFilterLen - 1; j ++) 
	{ 
		for (i = 0; i < iFilterLen - j - 1; i ++) 
		{ 
			if (pUnchFltValue[i] > pUnchFltValue[i + 1]) 
			{ 
				// 互换 
				bTemp = pUnchFltValue[i]; 
				pUnchFltValue[i] = pUnchFltValue[i + 1]; 
				pUnchFltValue[i + 1] = bTemp; 
			} 
		} 
	} 
	 
	// 计算中值 
	if ((iFilterLen & 1) > 0) 
	{ 
		// 数组有奇数个元素,返回中间一个元素 
		bTemp = pUnchFltValue[(iFilterLen + 1) / 2]; 
	} 
	else 
	{ 
		// 数组有偶数个元素,返回中间两个元素平均值 
		bTemp = (pUnchFltValue[iFilterLen / 2] + pUnchFltValue[iFilterLen / 2 + 1]) / 2; 
	} 
	 
	// 返回中值 
	return bTemp; 
} 
 
/************************************************************************* 
 * 
 * \函数名称: 
 *   LinearSharpen() 
 * 
 * \输入参数: 
 *   LPBYTE lpImage		- 指向图象数据得指针 
 *   int nWidth			- 图象数据宽度 
 *   int nHeight		- 图象数据高度 
 * 
 * \返回值: 
 *   无 
 * 
 * \说明: 
 *   线性锐化图象增强 
 *   本函数采用拉普拉斯算子对图象进行线性锐化 
 *   在原来图象上加上拉普拉斯算子锐化的信息 
 * 
 ************************************************************************* 
 */ 
void LinearSharpen (LPBYTE lpImage, int nWidth, int nHeight) 
{ 
	// 遍历图象的纵坐标 
	int y; 
 
	// 遍历图象的横坐标 
	int x; 
 
	double * pdGrad ; 
	pdGrad = new double[nWidth*nHeight]; 
 
	// 初始化为0 
	memset(pdGrad, 0, nWidth*nHeight*sizeof(double)) ; 
 
	// 设置模板系数 
	static int nWeight[3][3] ; 
	nWeight[0][0] = -1 ;    
	nWeight[0][1] = -1 ;    
	nWeight[0][2] = -1 ;    
	nWeight[1][0] = -1 ;    
	nWeight[1][1] =  8 ;    
	nWeight[1][2] = -1 ;    
	nWeight[2][0] = -1 ;    
	nWeight[2][1] = -1 ;    
	nWeight[2][2] = -1 ;    
 
	//这个变量用来表示Laplacian算子象素值 
	int nTmp[3][3]; 
 
	// 临时变量 
	double dGrad; 
 
	// 模板循环控制变量 
	int yy ; 
	int xx ; 
	for(y=1; ym_lpvColorTable; 
 
	// 获取DIB中颜色表中的表项数 
	nColorEntries = pDib->m_nColorTableEntries; 
	 
	// 判断颜色数目是否是256色 
	if (nColorEntries == 256) 
	{			 
		// 读取伪彩色编码,更新DIB颜色表 
		for (i = 0; i < nColorEntries; i++) 
		{		 
			// 更新DIB调色板红色分量 
			pDibQuad->rgbRed = pColorsTable[i * 4]; 
				 
			// 更新DIB调色板绿色分量 
			pDibQuad->rgbGreen = pColorsTable[i * 4 + 1]; 
				 
			// 更新DIB调色板蓝色分量 
			pDibQuad->rgbBlue = pColorsTable[i * 4 + 2]; 
				 
			// 更新DIB调色板保留位 
			pDibQuad->rgbReserved = 0; 
 
			pDibQuad++; 
		 
		} 
	} 
 
	// 如果不是256色的DIB,则不进行处理 
	else 
		return FALSE; 
	 
	// 返回 
	return TRUE; 
 
} 
 
 
/************************************************************************* 
 * 
 * \函数名称: 
 *   LowPassFilterEnhance() 
 * 
 * \输入参数: 
 *   LPBYTE lpImage					- 指向需要增强得图象数据 
 *   int nWidth							- 数据宽度 
 *   int nHeight						- 数据高度 
 *   int nRadius            - 低通滤波的滤波半径 
 * 
 * \返回值: 
 *   无 
 * 
 * \说明: 
 *   lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是CDib指向的数据区 
 *	 因为CDib指向的数据区的每一行是DWORD对齐的。 
 *   经过低通滤波的数据存储在lpImage当中。 
 * 
 ************************************************************************* 
 */ 
void LowPassFilterEnhance(LPBYTE lpImage, int nWidth, int nHeight, int nRadius) 
{ 
	// 循环控制变量 
	int y ; 
	int x ; 
 
	double dTmpOne ; 
	double dTmpTwo ; 
 
	// 傅立叶变换的宽度和高度(2的整数次幂) 
	int nTransWidth ; 
	int nTransHeight; 
 
	// 图象象素值 
	unsigned char unchValue; 
 
	// 指向时域数据的指针 
	complex * pCTData ; 
	// 指向频域数据的指针 
	complex * 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 ; 
	} 
	 
	// 分配内存 
	pCTData=new complex[nTransWidth * nTransHeight]; 
	pCFData=new complex[nTransWidth * nTransHeight]; 
 
	// 初始化 
	// 图像数据的宽和高不一定是2的整数次幂,所以pCTData 
	// 有一部分数据需要补0 
	for(y=0; y(0,0); 
		} 
	} 
 
	// 把图像数据传给pCTData 
	for(y=0; y(unchValue,0); 
		} 
	} 
	 
	// 傅立叶正变换 
	DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ; 
 
	// 下面开始实施低通滤波,把所有大于nRadius的高频分量设置为0 
	//  注意这里高频分量采用的范数不是欧式距离,而是无穷大范数 
	//  || (u,v)-(0,0) || = max(|u|,|v|)  
	for(y=nRadius; y(0,0); 
		} 
	} 
	 
	// 经过低通滤波的图象进行反变换 
	IFFT_2D(pCFData, pCTData, nWidth, nHeight); 
 
	// 反变换的数据传给lpImage 
	for(y=0; y * pCTData ; 
	// 指向频域数据的指针 
	complex * pCFData ; 
 
	double dReal; 
	double dImag; 
	 
	// 计算进行傅立叶变换的点数	(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-1 || nRadius>nTransHeight-1) 
	{ 
		return ; 
	} 
	 
	// 分配内存 
	pCTData=new complex[nTransWidth * nTransHeight]; 
	pCFData=new complex[nTransWidth * nTransHeight]; 
 
	// 初始化 
	// 图像数据的宽和高不一定是2的整数次幂,所以pCTData 
	// 有一部分数据需要补0 
	for(y=0; y(0,0); 
		} 
	} 
 
	// 把图像数据传给pCTData 
	for(y=0; y(unchValue,0); 
		} 
	} 
	 
	// 傅立叶正变换 
	DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ; 
 
	// 下面开始滤波,把所有小于nRadius的低频分量设置为0 
	// 采用的范数不是欧式距离,而是无穷大范数 
	//  || (u,v)-(0,0) || = max(|u|,|v|)  
	for(y=0; y(0,0); 
		} 
	} 
	// 经过滤波的图象进行反变换 
	IFFT_2D(pCFData, pCTData, nWidth, nHeight); 
 
	// 反变换的数据传给lpImage 
	for(y=0; y * pCTData ; 
	// 指向频域数据的指针 
	complex * 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[nTransWidth * nTransHeight]; 
	pCFData=new complex[nTransWidth * nTransHeight]; 
 
	// 初始化 
	// 图像数据的宽和高不一定是2的整数次幂,所以pCTData 
	// 有一部分数据需要补0 
	for(y=0; y(0,0); 
		} 
	} 
 
	// 把图像数据传给pCTData 
	for(y=0; y(unchValue,0); 
		} 
	} 
	 
	// 傅立叶正变换 
	DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ; 
 
	// 下面开始实施ButterWorth低通滤波 
	for(y=0; y(pCFData[y*nTransWidth + x].real()*H, 
																								 pCFData[y*nTransWidth + x].imag()*H); 
		} 
	} 
	 
	// 经过ButterWorth低通滤波的图象进行反变换 
	IFFT_2D(pCFData, pCTData, nWidth, nHeight); 
 
	// 反变换的数据传给lpImage 
	for(y=0; y * pCTData ; 
	// 指向频域数据的指针 
	complex * 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[nTransWidth * nTransHeight]; 
	pCFData=new complex[nTransWidth * nTransHeight]; 
 
	// 初始化 
	// 图像数据的宽和高不一定是2的整数次幂,所以pCTData 
	// 有一部分数据需要补0 
	for(y=0; y(0,0); 
		} 
	} 
 
	// 把图像数据传给pCTData 
	for(y=0; y(unchValue,0); 
		} 
	} 
	 
	// 傅立叶正变换 
	DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ; 
 
	// 下面开始实施ButterWorth高通滤波 
	for(y=0; y(H*(pCFData[y*nTransWidth + x].real()), 
																								 H*(pCFData[y*nTransWidth + x].imag())  ); 
		} 
	} 
	 
	// 经过ButterWorth高通滤波的图象进行反变换 
	IFFT_2D(pCFData, pCTData, nWidth, nHeight); 
 
	// 反变换的数据传给lpImage 
	for(y=0; y