www.pudn.com > wavelets-11.rar > Diproc.cpp


// Diproc.cpp: implementation of the CDiproc class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "wavelets.h" 
#include "Diproc.h" 
#include "WvltTrans.h" 
#include  
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CDiproc::CDiproc() 
{ 
} 
 
CDiproc::~CDiproc() 
{ 
 
} 
 
/******************************************************************************** 
*函数描述:	DIP_WvltRevers完成图像小波系数的复原,恢复出原始的图像数据			* 
*函数参数:	short **spData		:二维指针,指向原始的图像数据					* 
*			short **spTransData0:小波变换系数,存放一次水平变换后的小波系数	* 
*			short **spTransData1:小波变换系数,存放一次数值变换后的小波系数	* 
*			int   nHeight		:图像属性参数,数值为原始图像的高度值			* 
*			int	  nHeight_H		:图像属性参数,数值为原始图像高度值的一半		* 
*			int   nWidth		:图像属性参数,数值为原始图像的宽度值			* 
*			int	  nWidth_H		:图像属性参数,数值为原始图像宽度值的一半		* 
*			int   layer			:小波变换的层数,数值为3层						* 
*			float fRadius		:小波变换因子,在调用时候已指定数值为1.414		* 
********************************************************************************/ 
 
void CDiproc::DIP_WvltRevers(short **spData, short **spTransData0, short **spTransData1, int nHeight, int nHeight_H, int nWidth, int nWidth_H, int layer, float fRadius) 
{ 
	short **spOriginData, **spTransData, **spWvltData; 
	int iHeight = (int)nHeight /pow(2,layer-1), iWidth =(int)nWidth / pow(2,layer-1); 
	int iHeight_H =(int) nHeight_H / pow(2,layer-1), iWidth_H = (int)nWidth_H/ pow(2,layer-1); 
	//分配图像复原所需的内存空间 
	spOriginData = spData; 
	spTransData = spTransData0; 
	spWvltData = spTransData1; 
	//完成图像小波变换的逆变换 
	CWvltTrans *WTrans; 
	for(int i = layer; i >= 1; i--) 
	{ 
		WTrans->DWTi_Once(spOriginData, spTransData, spWvltData, iHeight, iHeight_H, iWidth, iWidth_H, i, 1.414); 
		iHeight <<= 1;		iWidth <<= 1; 
		iHeight_H <<= 1;	iWidth_H <<= 1; 
	} 
		 
} 
 
/******************************************************************************** 
*函数描述:	DIP_ConsEnhance完成图像对比度信息的增强,获取隐藏的图像信息			* 
*函数参数:	short **spData		:二维指针,指向原始的图像数据					* 
*			int   nHeight		:图像属性参数,数值为原始图像的高度值			* 
*			int   nWidth		:图像属性参数,数值为原始图像的宽度值			* 
*			float *NormWvltRng	:存放图像小波的正则化参数以及逆变换的正则化参数* 
********************************************************************************/ 
 
void CDiproc::DIP_ConsEnhance(short **spData, int nHeight, int nWidth, float *NormWvltRng) 
{ 
	short **spOriginData, **spTransData, **spWvltData; 
	float **fpNormGradient , filtCoeff[10],   *fWvltRng; 
	int iHeight = nHeight, iWidth = nWidth; 
	int iHeight_H = nHeight / 2, iWidth_H = nWidth / 2; 
	int x, y; 
	fWvltRng = NormWvltRng; 
	//为图像处理分配内存空间 
	spOriginData = spData; 
	spTransData = new short * [nHeight]; 
	spWvltData = new short * [nHeight]; 
	fpNormGradient = new float * [nHeight]; 
	for(int i = 0; i < nHeight; i ++) 
	{ 
		spTransData[i] = new short [nWidth]; 
		spWvltData[i] = new short [nWidth]; 
		fpNormGradient[i] = new float [nWidth]; 
	} 
	//完成一次图像小波变换 
	CWvltTrans *pTrans; 
	pTrans->DWT_TriLayers(spOriginData, spTransData, spWvltData, iHeight, iHeight_H, iWidth, iWidth_H, 3, 1.414); 
	//小波系数的正则化处理 
	//正则化处理后spData存放非正则化的小波系数,spWvltData存放正则化后的小波系数 
	Wvlt_Normalize(spWvltData, iHeight, iWidth, fWvltRng); 
	//计算小波系数的梯度信息,将其存放在spTransData中 
	//设定显示设备的颜色灰度范围是0~255 
	for(y = 0; y < nHeight; y ++) 
	{ 
		for(x = 0; x < nWidth; x ++) 
		{ 
			fpNormGradient[y][x] = (float) spWvltData[y][x] / 255; 
		} 
	} 
	//选择线性滤波器gj(x) = x, 且v =kj gj(u) 
	//统计出不同频带小波系数的极大值 
	for(y = 0; y < 3; y ++) 
	{ 
		if(y == 0) 
		{ 
			filtCoeff[4*y] = Search_BandMax(spWvltData, 0, 0, iHeight / 8, iWidth / 8); 
		} 
		filtCoeff[3*y + 1] = Search_BandMax(spWvltData, 0, (int)(pow(2,y) * iWidth / 8), (int)(pow(2,y)* iHeight / 8), (int)(pow(2,y)*iWidth / 4)); 
		filtCoeff[3*y + 2] = Search_BandMax(spWvltData, (int)(pow(2,y) * iHeight / 8), 0, (int)(pow(2,y)* iHeight / 4), (int)(pow(2,y)*iWidth / 8)); 
		filtCoeff[3*y + 3] = Search_BandMax(spWvltData, (int)(pow(2,y) * iHeight / 8), (int)(pow(2,y) * iWidth / 8), (int)(pow(2,y)* iHeight / 4), (int)(pow(2,y)*iWidth / 4)); 
	} 
	//计算得到各频带滤波器的滤波系数 
	for(y = 0; y < 10; y++) 
	{ 
		filtCoeff[y] = (float) 255.0 / filtCoeff[y]; 
		filtCoeff[0] += (float)sqrt(filtCoeff[y]); 
	} 
	filtCoeff[0] /= 10; 
	//正则化后小波信息的梯度信息滤波处理 
	for(y = 0; y < 3; y ++) 
	{ 
		if(y == 0) 
		{ 
			Band_Enhance(fpNormGradient, filtCoeff[3*y], 0, 0, iHeight / 8, iWidth / 8); 
		} 
		Band_Enhance(fpNormGradient, (float)sqrt(filtCoeff[3*y + 1]) /2, 0, (int)(pow(2,y) * iWidth / 8), (int)(pow(2,y)* iHeight / 8), (int)(pow(2,y)*iWidth / 4)); 
		Band_Enhance(fpNormGradient, (float)sqrt(filtCoeff[3*y + 2]) /2, (int)(pow(2,y) * iHeight / 8), 0, (int)(pow(2,y)* iHeight / 4), (int)(pow(2,y)*iWidth / 8)); 
		Band_Enhance(fpNormGradient, (float)sqrt(filtCoeff[3*y + 3]) /2, (int)(pow(2,y) * iHeight / 8), (int)(pow(2,y) * iWidth / 8), (int)(pow(2,y)* iHeight / 4), (int)(pow(2,y)*iWidth / 4)); 
	} 
	//还原出滤波增强后的小波系数 
	for(y = 0; y< iHeight; y ++) 
	{ 
		for(x = 0; x < iWidth; x++) 
		{ 
			fpNormGradient[y][x] *= (float) (fWvltRng[1] - fWvltRng[0]); 
			fpNormGradient[y][x] /= 255.0; 
			spWvltData[y][x] = (short) fpNormGradient[y][x] + fWvltRng[0]; 
		} 
	} 
 
	//复原增强后的小波系数 
	DIP_WvltRevers(spOriginData, spTransData, spWvltData, iHeight, iHeight_H, iWidth, iWidth_H, 3, 1.414); 
	//将复原的图像数据进行正则化 
	Wvlt_Normalize(spOriginData, iHeight, iWidth, fWvltRng); 
	//释放临时的数据空间 
	delete spTransData; 
	delete spWvltData; 
	delete fpNormGradient; 
} 
 
/******************************************************************************** 
*函数描述:	DIP_ImageFusion完成两幅图像的融合,恢复出原始的图像					* 
*函数参数:	short **spImgData0	:二维指针,存放其中一幅原始图像的数据			* 
*			short **spImgData1	:二维指针,存放其中另外一幅原始图像的数据		* 
*			int   nHeight		:图像属性参数,数值为原始图像的高度值			* 
*			int   nWidth		:图像属性参数,数值为原始图像的宽度值			* 
********************************************************************************/ 
void CDiproc::DIP_ImageFusion(short **spImgData0, short **spImgData1, int nHeight, int nWidth) 
{ 
	//获取图像的属性参数 
	int iHeight = nHeight, iWidth = nWidth; 
	//图像融合所用到的数据空间及数据指针 
	short **spOriginData, **spTransData, **spWvltData0, **spWvltData1; 
	//分配数据空间 
	spTransData = new short *[iHeight]; 
	spWvltData0 = new short *[iHeight]; 
	spWvltData1 = new short *[iHeight]; 
	for(int i = 0; i < iWidth; i ++) 
	{ 
		spTransData[i] = new short [iWidth]; 
		spWvltData0[i] = new short [iWidth]; 
		spWvltData1[i] = new short [iWidth]; 
	} 
	//创建小波变换类,完成图像的小波变换 
	CWvltTrans *pTrans; 
	//获得图像数据空间的指针,完成小波变换 
	spOriginData = spImgData0; 
	//三层小波变换 
	pTrans->DWT_TriLayers(spOriginData, spTransData, spWvltData0, iHeight, iHeight / 2, iWidth, iWidth / 2, 1, 1.414); 
	//获得图像数据空间的指针,完成另一幅图像的小波变换 
	spOriginData = spImgData1; 
	//三层小波变换 
	pTrans->DWT_TriLayers(spOriginData, spTransData, spWvltData1, iHeight,iHeight / 2, iWidth, iWidth / 2, 1, 1.414); 
	//小波系数的融合处理:频带有LL3,LH3,HL3,HH3,LH2,HL2,HH2,LH1,HL1,HH1 
	//融合处理将分频带进行,处理方法采用的是3*3的窗口 
	//LL3频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, 0, 0, iHeight / 8, iWidth / 8); 
	//HL3频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, 0, iWidth / 8, iHeight / 8, iWidth / 4); 
	//LH3频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 8, 0, iHeight / 4, iWidth / 8); 
	//HH3频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 8, iWidth / 8, iHeight / 4, iWidth / 4); 
	//HL2频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, 0, iWidth / 4, iHeight / 4, iWidth / 2); 
	//LH2频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 4, 0, iHeight / 2, iWidth / 4); 
	//HH2频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 4, iWidth / 4, iHeight / 2, iWidth / 2); 
	//HL1频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, 0, iWidth / 2, iHeight / 2, iWidth); 
	//LH1频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 2, 0, iHeight, iWidth / 2); 
	//HH1频带小波系数的融合 
	Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 2, iWidth / 2, iHeight, iWidth); 
	//将融合后的小波系数复原,完成图像的融合 
	DIP_WvltRevers(spOriginData, spTransData, spWvltData0, iHeight, iHeight / 2, iWidth, iWidth / 2, 1, 1.414); 
	//释放临时的数据空间 
	delete spTransData; 
	delete spWvltData0; 
	delete spWvltData1; 
} 
 
 
/******************************************************************************** 
*函数描述:	Wvlt_Normalize完成图像小波数据与逆变换数据的正则化处理				* 
*函数参数:	short **spWvltNormData:二维指针,存放正则化后的小波系数			* 
*			int   nHeight		:图像属性参数,数值为原始图像的高度值			* 
*			int	  nHeight_H		:图像属性参数,数值为原始图像高度值的一半		* 
*			int   nWidth		:图像属性参数,数值为原始图像的宽度值			* 
*			float *NormWvltRng	:存放图像小波的正则化参数以及逆变换的正则化参数* 
********************************************************************************/ 
 
void CDiproc::Wvlt_Normalize(short **spWvltNormData, int nHeight, int nWidth, float *nWvltRng) 
{ 
	int MaxPixVal, MinPixVal, Diff; 
	int x, y; 
	float NormCoeff; 
 
	MaxPixVal=spWvltNormData[0][0]; 
	MinPixVal=spWvltNormData[0][0]; 
	for( y=0; y < nHeight; y++) 
	{ 
		for( x=0; x < nWidth; x++) 
		{ 
			if(MaxPixValspWvltNormData[y][x]) 
				MinPixVal=spWvltNormData[y][x]; 
			//spWvltData[y][x] = spWvltNormData[y][x]; 
		} 
	} 
	Diff=MaxPixVal-MinPixVal; 
	nWvltRng[1] = MaxPixVal; 
	nWvltRng[0] = MinPixVal; 
	for(y=0; y < nHeight; y++) 
	{ 
		for(x=0; x < nWidth; x++) 
		{ 
		//因为小波变换后的小波系数有可能超过255甚至更多,那么就将 
		//小波系数的范围映射到0~255区间内,以后出现类似的处理,目的都是一样的 
			NormCoeff = spWvltNormData[y][x]; 
			NormCoeff -= MinPixVal; 
			NormCoeff *= 255; 
			NormCoeff /= (float) Diff; 
			spWvltNormData[y][x] = NormCoeff; 
 
		} 
	} 
} 
 
/********************************************************************************* 
*函数描述:	Window_WvltFusion完成图像小波系数的融合操作,得到各频带的小波融合数据* 
*函数参数:	short **spWvltData0 :二维指针,存放其中一幅图像的原始小波系数		 * 
*			short **spWvltData1 :二维指针,存放其中另外一幅图像的原始小波系数	 * 
*			int   Scan_y		:扫描线起始横坐标								 * 
*			int   Scan_x		:扫描线起始纵坐标								 * 
*			int   End_y			:扫描线终止横坐标								 * 
*			int   End_x			:扫描线终止纵坐标								 * 
*********************************************************************************/ 
 
void CDiproc::Window_WvltFusion(short **spWvltData0, short **spWvltData1, int Scan_y, int Scan_x, int End_y, int End_x) 
{ 
	int y,x; 
	short WndSum0, WndSum1; 
	for(y = Scan_y; y < End_y; y ++) 
	{ 
		for(x = Scan_x; x < End_x; x ++) 
		{ 
			//初始化窗口中小波系数的和 
			WndSum0 = 0;	WndSum1 = 0; 
			//计算窗口中小波系数的和 
			for(int i = -1; i <= 1; i++) 
			{ 
				for(int j = -1; j <= 1; j++) 
				{ 
					if( (y+i) < Scan_y || (x+j) < Scan_x || (y+i) >= End_y || (x+j) >= End_x) 
					{ 
						WndSum0 += 0; 
						WndSum1 += 0; 
					} 
					else 
					{ 
						WndSum0 += abs((int)spWvltData0[y + i][x + j]); 
						WndSum1 += abs((int)spWvltData1[y + i][x + j]); 
					} 
				} 
			} 
			if(WndSum0 < WndSum1) 
				spWvltData0[y][x] = spWvltData1[y][x]; 
		} 
	} 
} 
 
float CDiproc::Search_BandMax(short **spWvltData, int Scan_y, int Scan_x, int End_y, int End_x) 
{ 
	int x, y; 
	float Band_max; 
	Band_max = 0; 
	for(y = Scan_y; y < End_y; y ++) 
	{ 
		for(x = Scan_x; x < End_x; x ++) 
		{ 
			if(Band_max < spWvltData[y][x]) 
				Band_max = spWvltData[y][x]; 
		} 
	} 
	return Band_max; 
} 
 
void CDiproc::Band_Enhance(float **fpNormGradient, float FilterCoeff, int Scan_y, int Scan_x, int End_y, int End_x) 
{ 
	for(int y = Scan_y; y < End_y; y ++) 
		for(int x = Scan_x; x < End_x; x ++) 
			fpNormGradient[y][x] *= (float)(255.0 * FilterCoeff);	 
}