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

📄 dwt.cpp

📁 基于DCT的小波变换EZW压缩算法以及毕业设计论文
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{  
	int i;
	int rLowSize = rowLong, rHighSize;
	int cLowSize = colLong, cHighSize;

	double *temp_in	= new double [2*npad + rowLong*colLong];
	double *temp_out= new double [2*npad + rowLong*colLong];

	copy(input, temp_in+npad, rowLong * colLong);

   	while (nsteps--)  
	{
		if ((rLowSize <= 2 || cLowSize <= 2) && extendmode == 1) 
		{
			MessageBox(NULL,"请减少分解级数或增加信号长度! \n低通子带太小了!","error",MB_OKCANCEL|MB_ICONERROR);
			return;
		}
		
		 // 行 分解 
		for (i = 0; i < cLowSize; i++) 
		{			
			// 调用一维小波分解 
			DWT_1D (temp_in+i*rowLong, temp_out+i*rowLong, rLowSize,1, extendmode);
		}
	   //提取列元素
		for (i = 0; i < rLowSize; i++) 
		   copy(temp_out+i, rowLong, temp_in+i*colLong,cLowSize);
		
	   // 列分解
		for (i = 0; i < rLowSize; i++)  
		{ 				
			// 调用一维小波分解 
			DWT_1D (temp_in+i*colLong, temp_out+i*colLong, cLowSize,1, extendmode);
       	}
       for (i = 0; i < rLowSize; i++) 
		   copy(temp_out+i, rowLong, temp_in+i*colLong,cLowSize);
		copy(temp_in+npad,output,rowLong*colLong);
	   // Now convolve low-pass portion again
		rHighSize =  rLowSize/2;
		rLowSize  = (rLowSize+1)/2;		
		cHighSize =  cLowSize/2;	
		cLowSize  = (cLowSize+1)/2;		
	}

	delete [] temp_out;
	delete [] temp_in;
}


/**************************************************************
* 小波单步反变换,
* input and output are padded with npad values 
* at the beginning and at the end
**************************************************************/

void CDWT::IDWTStep_1D (double *input, double *output, 
		                int dataLong, int extendmode)

{
	int i, j;
	int LowSize = (dataLong+1)/2, HighSize = dataLong/2;
	double templow, temphigh;
	double *temp_in  = new double [2*npad + dataLong];

	/*--------- 低频合成 ---------*/
	
    for (i=0; i< LowSize; i++)
	{
		temp_in[npad+2*i] = input[npad+i];
		temp_in[npad+2*i+1] = 0.0;
	}
	
	// 边界延拓
    if (extendmode)
		// 对称扩展
		symmetric_extension (temp_in, dataLong);
	else
		// 周期扩展
		periodic_extension (temp_in, dataLong);

	for (i = 0; i < dataLong; i++)  
    {
		templow = 0;
		for (j = 0; j < L_Lo_R ; j++) 
			templow +=	temp_in[npad+i-(L_Lo_R-1)+j] * Lo_R[L_Lo_R-1-j];
    
		output[npad + i] = templow * Sqrt2;
	}

	/*--------- 高频合成 ---------*/
   
	for (i=0; i< HighSize; i++)
	{
		temp_in[npad+2*i] = input[npad+LowSize+i];
		temp_in[npad+2*i+1] = 0.0;
	}

	// 边界延拓
	if (extendmode)
		// 对称扩展
		symmetric_extension (temp_in, dataLong);
	else
		// 周期扩展
		periodic_extension (temp_in, dataLong);
	
	for (i = 0; i < dataLong; i++)  
    {
		temphigh = 0;
		for (j = 0; j < L_Hi_R; j++) 	
			temphigh +=	temp_in[npad+i-(L_Hi_R-1)+j] * Hi_R[L_Hi_R-1-j];
      	
		output[npad + i] = output[npad + i] + temphigh * Sqrt2;
	}

   delete [] temp_in;   
}


/**************************************************************
* 一维小波反变换
**************************************************************/

void CDWT::IDWT_1D (double *input, double *output, 
					int dataLong, int nsteps,  int extendmode)
{
	int i;	  
	int currentIndex = 0;
	double *data[2];

	int *LowSize  = new int [nsteps];
	int *HighSize = new int [nsteps]; 
	
	LowSize[0]  = (dataLong+1)/2;
	HighSize[0] = dataLong/2;

	for (i = 1; i < nsteps; i++)
	{
		LowSize[i]  = (LowSize[i-1]+1)/2;
		HighSize[i] = LowSize[i-1]/2;
	}
    // data[0]用于存放填充边界后的输入数据
    // data[1]用于存放填充边界后的输出数据
    data[0] = new double [2*npad + dataLong];
    data[1] = new double [2*npad + dataLong];
	
	// 获得最低层低频数据部分
	copy(input, data[currentIndex]+npad, dataLong);
	copy(input, data[1-currentIndex]+npad, dataLong);
	
	while (nsteps--)  
	{	
	 	// 单步小波反变换
		IDWTStep_1D(data[currentIndex], data[1-currentIndex], 
			        LowSize[nsteps]+HighSize[nsteps], extendmode);
    
		// Now pass low-pass data (first 1/2 of signal) back to
		// transform routine
		currentIndex = 1 - currentIndex;
	}

	// 复制数据给输出信号
	copy (data[currentIndex]+npad, output, dataLong);

   delete [] HighSize;
   delete [] LowSize;

   delete [] data [1];
   delete [] data [0];
}


/**************************************************************
* 小波二维反变换
**************************************************************/

void CDWT::IDWT_2D (double *input, double *output,
				    int rowLong, int colLong,
		            int nsteps,  int extendmode)
{
    int i; 
	
	double *temp_in  = new double [2*npad + rowLong*colLong];
    double *temp_out = new double [2*npad + rowLong*colLong];

	int *rLowSize  = new int [nsteps];
    int *rHighSize = new int [nsteps];
    int *cLowSize  = new int [nsteps];
    int *cHighSize = new int [nsteps];

	rLowSize[0]  = (rowLong+1)/2;
	rHighSize[0] = rowLong/2;
	cLowSize[0]  = (colLong+1)/2;
	cHighSize[0] = colLong/2;

	for (i = 1; i < nsteps; i++)
	{
		rLowSize[i]  = (rLowSize[i-1]+1)/2;
		rHighSize[i] = rLowSize[i-1]/2;
		cLowSize[i]  = (cLowSize[i-1]+1)/2;
		cHighSize[i] = cLowSize[i-1]/2;
	}

    
  	copy( input,temp_in+npad,rowLong*colLong);
	while (nsteps--)  
	{ 
		for (i = 0; i < rLowSize[nsteps]+rHighSize[nsteps]; i++) 
		   copy(temp_in+i, rowLong, temp_out+i*colLong,cLowSize[nsteps]+cHighSize[nsteps]); 
		// 列 合成 
		for (i = 0; i < cLowSize[nsteps] + cHighSize[nsteps]; i++) 
		{			
			// 调用一维小波合成 
			IDWT_1D (temp_out+i*rowLong, temp_in+i*rowLong, rLowSize[nsteps] + rHighSize[nsteps],1, extendmode);
		}
		for (i = 0; i < cLowSize[nsteps]+cHighSize[nsteps]; i++) 
		   copy(temp_in+i+npad, rowLong, temp_out+i*colLong,rLowSize[nsteps]+rHighSize[nsteps]); 
		   
		//  行 合成
		for (i = 0; i < rLowSize[nsteps]+rHighSize[nsteps] ; i++) 
		{
			// 调用一维小波合成
			IDWT_1D (temp_out+i*colLong, temp_in+i*colLong, cLowSize[nsteps]+cHighSize[nsteps],1, extendmode);
	
   		}	
        copy(temp_in+npad,output,rowLong*colLong);
	}

   	delete [] rLowSize;
	delete [] rHighSize;
	delete [] cLowSize;
	delete [] cHighSize;
	
	delete [] temp_out;
	delete [] temp_in;
}





/*************************************************************************
 *
 * \函数名称:
 *   ImageDWT()
 *
 * \输入参数:
 *   CDib* pDibSrc		- 指向源数据的指针
 *   int nMaxWLevel		- X方向上最大可分解的层数
 *   int nMaxHLevel		- Y方向上最大可分解的层数
 *   int nDWTSteps		- 需要进行变换的层数
 *   int nInv			- 是否为DWT,1表示为IDWT,0表示DWT
 *   int nStep			- 当前的计算层数
 *   int nSupp			- 小波基的紧支集的长度
 *
 * \返回值:
 *   BOOL			- 成功则返回TRUE,否则返回FALSE
 *
 * \说明:
 *   该函数用对存放在pDBSrc中的数据进行一层的二维DWT或者IDWT。
 *   计算后数据仍存放在pDbSrc中
 *
 *************************************************************************
 */
BOOL CDWT::ImageDWT(LPBYTE lpImage, double *outdata, 
					int ImageWidth, int ImageHeight, 
					int nCurStep, int nSteps,
					int extendmode)
  
{
	int i, j;

    // 获得X,Y方向上的需要进行小波分解/合成的图象长宽(2次幂对齐)
	int DwtWidth  = ImageWidth  >> nCurStep;
	int	DwtHeight = ImageHeight >> nCurStep;
	
	// 获得X,Y方向上分解后的低频象素数
	int minWidth  = ImageWidth  >> (nCurStep + nSteps);
	int	minHeight = ImageHeight >> (nCurStep + nSteps);

	// 分配临时内存,并将图象数据存放到临时内存中
	double* pTempinput = new double[DwtWidth*DwtHeight];
  	if (!pTempinput) return FALSE;
	double* pTempoutput = new double[DwtWidth*DwtHeight];
  	if (!pTempoutput) return FALSE;

	for (i=0; i<DwtHeight; i++) 
		for (j=0; j<DwtWidth; j++) 		
			pTempinput[i*DwtWidth+j] = lpImage[(ImageHeight-1-i)*ImageWidth+j];
		
	// 调用DWT_2D进行小波变换
	DWT_2D (pTempinput, pTempoutput, DwtWidth, DwtHeight, nSteps, extendmode);
	
	for (j=0; j<DwtHeight; j++)
		copy (pTempoutput+j*DwtWidth, outdata+j*ImageWidth, DwtWidth);


	// 将数据存入原始的内存中,需要注意的是,存储时需要进行类型转换
	for (i=0; i<minHeight; i++)
	{	
		for (j=0; j<minWidth; j++)
			lpImage[(ImageHeight-1-i)*ImageWidth + j] = DoubleToByte(pTempoutput[i*DwtWidth + j]);
		for (j=minWidth; j<DwtWidth; j++)
			lpImage[(ImageHeight-1-i)*ImageWidth + j] = BYTE (DoubleToChar(pTempoutput[i*DwtWidth + j]) + 128);
  	}
	
	for (i=minHeight; i<DwtHeight; i++)
		for (j=0; j<DwtWidth; j++)
			lpImage[(ImageHeight-1-i)*ImageWidth + j] = BYTE(DoubleToChar(pTempoutput[i*DwtWidth + j]) +128);
				
	// 释放内存
	delete []pTempinput;
    delete []pTempoutput;

	// 返回
	return TRUE;
} 



BOOL CDWT::ImageIDWT(double *indata, LPBYTE lpImage,
					int ImageWidth, int ImageHeight, 
					int nCurStep, int nSteps,
					int extendmode)
  
{	
	int i, j;

    // 获得X,Y方向上的需要进行小波分解/合成的图象长宽(2次幂对齐)
	int DwtWidth  = ImageWidth  >> nCurStep;
	int	DwtHeight = ImageHeight >> nCurStep;
	
	// 获得X,Y方向上合成后的低频象素数
	int maxWidth  = ImageWidth  >> (nCurStep - nSteps);
	int	maxHeight = ImageHeight >> (nCurStep - nSteps);

	// 分配临时内存,并将图象数据存放到临时内存中
	double* pTempinput = new double[maxWidth*maxHeight];
  	if (!pTempinput) return FALSE;
	double* pTempoutput = new double[maxWidth*maxHeight];
  	if (!pTempoutput) return FALSE;
    
	for (i=0; i<maxHeight; i++)
		for (j=0; j<maxWidth; j++)
			pTempinput[i*maxWidth + j] = indata[i*ImageWidth+j];
			
	// 调用DWT_2D进行小波变换
	IDWT_2D (pTempinput, pTempoutput, maxWidth, maxHeight, nSteps, extendmode);
	
	for (j=0; j<maxHeight; j++)
		copy (pTempoutput+j*maxWidth, indata+j*ImageWidth, maxWidth);
	
	// 将数据存入原始的内存中,需要注意的是,存储时需要进行类型转换
	for (i=0; i<maxHeight; i++) 
		for (j=0; j<maxWidth; j++) 	
			lpImage[(ImageHeight-1-i)*ImageWidth+j] = DoubleToByte(pTempoutput[i*maxWidth+j]);
	
	// 释放内存
	delete []pTempinput;
    delete []pTempoutput;

	// 返回
	return TRUE;
} 

//  小波处理函数结束
///////////////////////////////////////////////////////////////////////////


/**************************************************************
* 小波变换的延拓模式,采用周期延拓
*  
* Do periodic extension of data using prescribed symmetries
*   Original values are in output[npad] through output[npad+size-1]
*   New values will be placed in output[0] through output[npad] 
*   and in output[npad+size] through output[2*npad+size-1] 
*   (note: end values may not be filled in)
*   extension bdry is 
*   1 2 3 ... dataLong-2 dataLong-1 | 0 1 2 3 ...dataLong-2 dataLong-1
**************************************************************/

void CDWT::periodic_extension (double *output, int dataLong)
{
	int first = npad, last = npad + dataLong-1;

	// 左延拓 extend left periodically
	while (first > 0)
	{
		first--;
		output[first] = output[first+dataLong];
	}

	// 右延拓 extend right periodically
	while (last < 2*npad+dataLong-1) 
	{
		last++;
		output[last] = output[last-dataLong];
	}
}


/**************************************************************
* 小波变换的延拓模式,采用对称延拓
*  
* Do symmetric extension of data using prescribed symmetries
*   Original values are in output[npad] through output[npad+size-1]
*   New values will be placed in output[0] through output[npad] 
*   and in output[npad+size] through output[2*npad+size-1] 
*   (note: end values may not be filled in)
*    extension bdry is   ... 3 2 1 | 0 1 2 3 ...
***************************************************************/

void CDWT::symmetric_extension (double *output, int dataLong)
{
	int i;
	int first = npad, last = npad + dataLong-1;

	for(i=0; i<first; i++)
	{
		// 左延拓
		output[i] = output[2*first-i];
		// 右延拓
        output[last+1+i] = output[last-1-i];
	}
}


/*************************************************************************
 *
 * \函数名称:
 *   FloatToByte()
 *
 * \输入参数:
 *   double  f			- 输入双精度变量
 *
 * \返回值:
 *   BYTE			- 返回比特型变量
 *
 * \说明:
 *   该函数将输入的双精度变量转换为BYTE型的变量
 *
 *************************************************************************
 */
BYTE CDWT::DoubleToByte(double f)
{
	if (f<=0) return (BYTE)0;
	else if (f>=255) return (BYTE)255;
	else return (BYTE)(f+0.5);
}

/*************************************************************************
 *
 * \函数名称:
 *   FloatToChar()
 *
 * \输入参数:
 *   double  f			- 输入双精度变量
 *
 * \返回值:
 *   Char			- 返回字符变量
 *
 * \说明:
 *   该函数将输入的双精度变量转换为Char型的变量
 *
 *************************************************************************
 */
char CDWT::DoubleToChar(double f)
{
	if (f>=0)
		if (f>=127.0)
			return (char)127;
		else return (char)(f+0.5);
	else
		if (f<=-128)
			return (char)-128;
		else return -(char)(-f+0.5);
}




⌨️ 快捷键说明

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