⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enhance.cpp

📁 提供了图像识别
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			 }
			 
			 // 梯度值写入内存
			 *(pdGrad+y*nWidth+x)=dGrad;
	 }
	for(y=0; y<nHeight ; y++ )
	{
		for(x=0 ; x<nWidth ; x++ )
		{
			lpImage[y*nWidth+x] = (unsigned char)max(0,min(255,(lpImage[y*nWidth+x] + (int)pdGrad[y*nWidth+x]) ));
		}
	}
  delete []pdGrad ;
	pdGrad = NULL   ;
}


/*************************************************************************
 *
 * 函数名称:
 *   ReplaceDIBColorTable()
 *
 * 参数:
 *   CDib * pDib		- 指向CDib类的指针,含有原始图象信息
 *   LPBYTE pColorsTable	- 伪彩色编码表
 *
 * 返回值:
 *   BOOL			- 成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   该函数用指定的伪彩色编码表来替换指定的DIB图像的颜色表,参数pColorsTable
 *   指向要替换的伪彩色编码表。
 *
 ************************************************************************/
BOOL  ReplaceDIBColorTable(CDib* pDib, LPBYTE  pColorsTable)
{
	
	// 循环变量
	int i;

	// 颜色表的表项数
	int nColorEntries;

	// 临时变量
	LPRGBQUAD pDibQuad;

	// 指向DIB的颜色表
	pDibQuad = (LPRGBQUAD) pDib->m_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<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 ;
	}
	
	// 分配内存
	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++)
		{
			unchValue = lpImage[y*nWidth +x];
			pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
		}
	}
	
	// 傅立叶正变换
	DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;

	// 下面开始实施低通滤波,把所有大于nRadius的高频分量设置为0
	//  注意这里高频分量采用的范数不是欧式距离,而是无穷大范数
	//  || (u,v)-(0,0) || = max(|u|,|v|) 
	for(y=nRadius; y<nTransHeight; y++)
	{
		for(x=nRadius; x<nTransWidth; x++)
		{
			pCFData[y*nTransWidth + x]=complex<double>(0,0);
		}
	}
	
	// 经过低通滤波的图象进行反变换
	IFFT_2D(pCFData, pCTData, nWidth, nHeight);

	// 反变换的数据传给lpImage
	for(y=0; y<nHeight; y++)
	{
		for(x=0; x<nWidth; x++)
		{
			dReal = pCTData[y*nTransWidth + x].real() ;
			dImag = pCTData[y*nTransWidth + x].imag() ;
			unchValue = (unsigned char)max(0,min(255,sqrt(dReal*dReal+dImag*dImag) ));
			lpImage[y*nWidth + x] = unchValue ;
		}
	}

	
	// 释放内存
	delete pCTData;
	delete pCFData;
	pCTData = NULL;
	pCFData = NULL;
	
}

/*************************************************************************
 *
 * \函数名称:
 *   HighPassFilterEnhance()
 *
 * \输入参数:
 *   LPBYTE lpImage					- 指向需要增强得图象数据
 *   int nWidth							- 数据宽度
 *   int nHeight						- 数据高度
 *   int nRadius            - 高通滤波的滤波半径
 *
 * \返回值:
 *   无
 *
 * \说明:
 *   lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是CDib指向的数据区
 *	 因为CDib指向的数据区的每一行是DWORD对齐的。
 *   经过高通滤波的数据存储在lpImage当中。
 *
 *************************************************************************
 */
void HighPassFilterEnhance(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<double> * pCTData ;
	// 指向频域数据的指针
	complex<double> * 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<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++)
		{
			unchValue = lpImage[y*nWidth +x];
			pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
		}
	}
	
	// 傅立叶正变换
	DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;

	// 下面开始滤波,把所有小于nRadius的低频分量设置为0
	// 采用的范数不是欧式距离,而是无穷大范数
	//  || (u,v)-(0,0) || = max(|u|,|v|) 
	for(y=0; y<nRadius; y++)
	{
		for(x=0; x<nRadius; x++)
		{
			pCFData[y*nTransWidth + x]=complex<double>(0,0);
		}
	}
	// 经过滤波的图象进行反变换
	IFFT_2D(pCFData, pCTData, nWidth, nHeight);

	// 反变换的数据传给lpImage
	for(y=0; y<nHeight; y++)
	{
		for(x=0; x<nWidth; x++)
		{
		  // 因为高通滤波器会把低频成分去掉,所以图象看起来会比较暗,为了解决这个问题
			// 在经过增强后的图象加上一个常数,使图象变得亮起来。严格来讲这种处理相当于
			// 增加了一些低频分量(在频率(0,0))。不过如果不加一个常数,高通效果在观看
			// 上就不是很方便。
			dReal = pCTData[y*nTransWidth + x].real() ;
			dImag = pCTData[y*nTransWidth + x].imag() ;
			unchValue = (unsigned char)max(0,min(255,(sqrt(dReal*dReal+dImag*dImag)+100 )));
			lpImage[y*nWidth + x] = unchValue ;
		}
	}

	
	// 释放内存
	delete pCTData;
	delete pCFData;
	pCTData = NULL;
	pCFData = NULL;
	
}

/*************************************************************************
 *
 * \函数名称:
 *   ButterWorthLowPass()
 *
 * \输入参数:
 *   LPBYTE lpImage					- 指向需要增强得图象数据
 *   int nWidth							- 数据宽度
 *   int nHeight						- 数据高度
 *   int nRadius            - ButterWorth低通滤波的“半功率”点
 *
 * \返回值:
 *   无
 *
 * \说明:
 *   lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是CDib指向的数据区
 *	 因为CDib指向的数据区的每一行是DWORD对齐的。
 *   经过ButterWorth低通滤波的数据存储在lpImage当中。
 *
 *************************************************************************
 */
void ButterWorthLowPass(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
	// 循环控制变量
	int y ;
	int x ;

	double dTmpOne ;
	double dTmpTwo ;

	// ButterWorth 滤波系数
	double H       ;

	// 傅立叶变换的宽度和高度(2的整数次幂)
	int nTransWidth ;
	int nTransHeight;

	double dReal    ;
	double dImag    ;
	// 图象象素值
	unsigned char 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);
		}
	}

	// 把图像数据传给pCTData
	for(y=0; y<nHeight; y++)
	{
		for(x=0; x<nWidth; x++)
		{
			unchValue = lpImage[y*nWidth +x];
			pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
		}
	}
	
	// 傅立叶正变换
	DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;

	// 下面开始实施ButterWorth低通滤波
	for(y=0; y<nTransHeight; y++)
	{
		for(x=0; x<nTransWidth; x++)
		{
			H = (double)(y*y+x*x) ; 
			H = H / (nRadius * nRadius); 
			H = 1/(1+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);

	// 反变换的数据传给lpImage
	for(y=0; y<nHeight; y++)
	{
		for(x=0; x<nWidth; x++)
		{
			dReal = pCTData[y*nTransWidth + x].real() ;
			dImag = pCTData[y*nTransWidth + x].imag() ;
			unchValue = (unsigned char)max(0,min(255,sqrt(dReal*dReal+dImag*dImag) ));
			lpImage[y*nWidth + x] = unchValue ;
		}
	}

	
	// 释放内存
	delete pCTData;
	delete pCFData;
	pCTData = NULL;
	pCFData = NULL;
	
}
/*************************************************************************
 *
 * \函数名称:
 *   ButterWorthHighPass()
 *
 * \输入参数:
 *   LPBYTE lpImage					- 指向需要增强得图象数据
 *   int nWidth							- 数据宽度
 *   int nHeight						- 数据高度
 *   int nRadius            - ButterWorth高通滤波的“半功率”点
 *
 * \返回值:
 *   无
 *
 * \说明:
 *   lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是
 *	 CDib指向的数据区, 因为CDib指向的数据区的每一行是DWORD对齐的。
 *   经过ButterWorth高通滤波的数据存储在lpImage当中。
 *
 *************************************************************************
 */
void ButterWorthHighPass(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
	// 循环控制变量
	int y ;
	int x ;

	double dTmpOne ;
	double dTmpTwo ;

	// ButterWorth 滤波系数
	double H       ;

	// 傅立叶变换的宽度和高度(2的整数次幂)
	int nTransWidth ;
	int nTransHeight;

	double dReal    ;
	double dImag    ;
	// 图象象素值
	unsigned char 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);
		}
	}

	// 把图像数据传给pCTData
	for(y=0; y<nHeight; y++)
	{
		for(x=0; x<nWidth; x++)
		{
			unchValue = lpImage[y*nWidth +x];
			pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
		}
	}
	
	// 傅立叶正变换
	DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;

	// 下面开始实施ButterWorth高通滤波
	for(y=0; y<nTransHeight; y++)
	{
		for(x=0; x<nTransWidth; x++)
		{
			
			H = (double)(y*y+x*x) ; 
			H = (nRadius * nRadius) / H ; 
			H = 1/(1+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);

	// 反变换的数据传给lpImage
	for(y=0; y<nHeight; y++)
	{
		for(x=0; x<nWidth; x++)
		{
			dReal = pCTData[y*nTransWidth + x].real() ;
			dImag = pCTData[y*nTransWidth + x].imag() ;
			unchValue = (unsigned char)max(0,min(255,sqrt(dReal*dReal+dImag*dImag)+100 ));
			lpImage[y*nWidth + x] = unchValue ;
		}
	}

	
	// 释放内存
	delete pCTData;
	delete pCFData;
	pCTData = NULL;
	pCFData = NULL;
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -