visual c++数字图像处理典型算法及实现(包括算法和源程序)

源代码在线查看: dwt.cpp

软件大小: 6490 K
上传用户: laosoler
关键词: visual 算法 数字图像处理 典型
下载地址: 免注册下载 普通下载 VIP

相关代码

				// 文件DWT.cpp存放的是有关小波变换的函数
				
				#include "stdafx.h"
				#include "cdib.h"
				#include "math.h"
				#include "GlobalApi.h"
				
				
				/*************************************************************************
				 *
				 * \函数名称:
				 *   DWT_1D()
				 *
				 * \输入参数:
				 *   double * pDbSrc		- 指向源数据的指针
				 *   int nMaxLevel		- 最大可分解的层数
				 *   int nDWTSteps		- 需要分界的层数
				 *   int nInv			- 是否为DWT,1表示为IDWT,0表示DWT
				 *   int nStep			- 当前的计算层数
				 *   int nSupp			- 小波基的紧支集的长度
				 *
				 * \返回值:
				 *   BOOL			- 成功则返回TRUE,否则返回FALSE
				 *
				 * \说明:
				 *   该函数用对存放在pDBSrc中的数据进行一维DWT或者IDWT。其中,nInv为表示进行
				 *   DWT或者IDWT的标志。nStep为当前已经分界的层数。计算后数据仍存放在pDbSrc中
				 *
				 *************************************************************************
				 */
				BOOL DWT_1D(double* pDbSrc, int nMaxLevel,
							int nDWTSteps, int nInv, int nStep, int nSupp )
				{
					// 计算最小可分界的层数
					int MinLevel = nMaxLevel-nDWTSteps;
				
					// 判断是否为DWT
					if (!nInv)
					{	// DWT
						int n = nMaxLevel;
				
						while (n>MinLevel)
							// 调用DWTStep_1D进行第n层的DWT
							if (!DWTStep_1D(pDbSrc, n--, nInv, nStep, nSupp)) 
								return FALSE;
					}
				
					// nInv为1则进行IDWT
					else
					{	// IDWT
						int n = MinLevel;
				
						while (n							// 调用DWTStep_1D进行第n层的IDWT
							if (!DWTStep_1D(pDbSrc, n++, nInv, nStep, nSupp)) 
								return FALSE;
					}
					return TRUE;
				}
				
				/*************************************************************************
				 *
				 * \函数名称:
				 *   DWTStep_1D()
				 *
				 * \输入参数:
				 *   double * pDbSrc		- 指向源数据的指针
				 *   int nCurLevel		- 当前分界的层数
				 *   int nInv			- 是否为DWT,1表示为IDWT,0表示DWT
				 *   int nStep			- 当前的计算层数
				 *   int nSupp			- 小波基的紧支集的长度
				 *
				 * \返回值:
				 *   BOOL			- 成功则返回TRUE,否则返回FALSE
				 *
				 * \说明:
				 *   该函数用对存放在pDBSrc中的数据进行一层的一维DWT或者IDWT。其中,nInv为表示进行
				 *   DWT或者IDWT的标志。nCurLevel为当前需要进行分界的层数。nStep为已经分界的层数
				 *   计算后数据仍存放在pDbSrc中
				 *
				 *************************************************************************
				 */
				BOOL DWTStep_1D(double* pDbSrc, int nCurLevel,
							int nInv, int nStep,int nSupp)
				{
					double s = sqrt(2);
				
					// 获得小波基的指针
					double* h = (double*)hCoef[nSupp-1];
				
					// 确认当前层数有效
					ASSERT(nCurLevel>=0);
				
					// 计算当前层数的长度
					int CurN = 1					if (nInv) CurN 				
					// 确认所选择的小波基和当前层数的长度有效
					if (nSupp10 || CurN						return FALSE;
				
					// 分配临时内存用于存放结果
					double *ptemp = new double[CurN];
					if (!ptemp) return FALSE;
				
					double	s1, s2;
					int	Index1, Index2;
				
					// 判断是进行DWT还是IDWT
					if (!nInv)
					{	// DWT
						Index1=0;
						Index2=2*nSupp-1;
						
						// 进行卷积,其中s1为低频部分,s2为高频部分的结果
						for (int i=0; i						{	
							s1 = s2 = 0;
							double t = -1;
							for (int j=0; j							{
								s1 += h[j]*pDbSrc[(Index1 & CurN-1) * nStep];
								s2 += t*h[j]*pDbSrc[(Index2 & CurN-1) * nStep];
				
								Index1++;
								Index2--;
							}
				
							// 将结果存放在临时内存中
							ptemp[i] = s1/s;
							ptemp[i+CurN/2] = s2/s;
				
							Index1 -= 2*nSupp;
							Index2 += 2*nSupp;
							Index1 += 2;
							Index2 += 2;
						}
					}
				
					// 否则进行IDWT
					else
					{	// IDWT
						Index1 = CurN/2;
						Index2 = CurN/2-nSupp+1;
						
						// 进行卷积,其中其中s1为低频部分,s2为高频部分的结果
						for (int i=0; i						{
							s1 = s2 = 0;
							int Index3 = 0;
							for (int j=0; j							{
									s1 += h[Index3]*pDbSrc[(Index1 & CurN/2-1) * nStep]
										 +h[Index3+1]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];
									s2 += h[Index3+1]*pDbSrc[(Index1 & CurN/2-1) * nStep]
										 -h[Index3]*pDbSrc[((Index2 & CurN/2-1) + CurN/2) * nStep];
									
									Index3+=2;
									Index1--,		Index2++;
							}
				
							// 将结果存入临时内存
							ptemp[2*i] = s1*s;
							ptemp[2*i+1] = s2*s;
				
							Index1 += nSupp;
							Index2 -= nSupp;
							Index1++;
							Index2++;
						}
					}
					
					// 将结果存入源图象中
					for (int i=0; i						pDbSrc[i*nStep] = ptemp[i];
				
					// 释放临时内存,并返回
					delete[] ptemp;
					return TRUE;
				}
				
				/*************************************************************************
				 *
				 * \函数名称:
				 *   DWT_2D()
				 *
				 * \输入参数:
				 *   double * pDbSrc		- 指向源数据的指针
				 *   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。其中,nDWTSteps表示
				 *   需要分解的层数,nInv为表示进行DWT或者IDWT的标志。nStep为当前已经分界的层数
				 *   计算后数据仍存放在pDbSrc中
				 *
				 *************************************************************************
				 */
				BOOL DWT_2D(double* pDbSrc, int nMaxWLevel, int nMaxHLevel,
							int nDWTSteps, int nInv, int nStep, int nSupp)
				{
					// 计算X,Y方向上最小的分界层数
					int MinWLevel = nMaxWLevel - nDWTSteps;
					int MinHLevel = nMaxHLevel - nDWTSteps;
				
					// 判断是进行DWT,还是IDWT
					if (!nInv)
					{	// DWT
						int n = nMaxWLevel, m = nMaxHLevel;
				
						// 调用DWTStep_2D进行分解,分解的层数为nDWTSteps		
						while (n>MinWLevel)
							if (!DWTStep_2D(pDbSrc, n--, m--, nMaxWLevel, nMaxHLevel, nInv, nStep, nSupp)) 
								return FALSE;
					}
				
					// 否则进行IDWT
					else
					{	// IDWT
						int n = MinWLevel, m = MinHLevel;
				
						// 调用DWTStep_2D进行IDWT,进行恢复的层数为nDWTSteps	
						while (n							if (!DWTStep_2D(pDbSrc, n++, m++, nMaxWLevel, nMaxHLevel, nInv, nStep, nSupp)) 
								return FALSE;
					}
				
					// 返回
					return TRUE;
				}
				
				/*************************************************************************
				 *
				 * \函数名称:
				 *   DWTStep_2D()
				 *
				 * \输入参数:
				 *   double * pDbSrc		- 指向源数据的指针
				 *   int nCurWLevel		- X方向上当前分解的层数
				 *   int nCurHLevel		- Y方向上当前分解的层数
				 *   int nMaxWLevel		- X方向上最大可分解的层数
				 *   int nMaxHLevel		- Y方向上最大可分解的层数
				 *   int nInv			- 是否为DWT,1表示为IDWT,0表示DWT
				 *   int nStep			- 当前的计算层数
				 *   int nSupp			- 小波基的紧支集的长度
				 *
				 * \返回值:
				 *   BOOL			- 成功则返回TRUE,否则返回FALSE
				 *
				 * \说明:
				 *   该函数用对存放在pDBSrc中的数据进行一层的二维DWT或者IDWT。
				 *   计算后数据仍存放在pDbSrc中
				 *
				 *************************************************************************
				 */
				BOOL DWTStep_2D(double* pDbSrc, int nCurWLevel, int nCurHLevel,
						int nMaxWLevel, int nMaxHLevel, int nInv, int nStep, int nSupp)
				{
					// 计算图象的长度和宽度(2次幂对齐)
					int W = 1				
					// 计算当前分解的图象的长度和宽度
					int CurW = 1				
					// 判断是进行DWT还是IDWT
					if (!nInv)
					{	// 对行进行一维DWT
						for (int i=0; i							if (!DWTStep_1D(pDbSrc+(int)i*W*nStep, nCurWLevel, nInv, nStep, nSupp)) return FALSE;
						// 对列进行一维DWT
						for (i=0; i							if (!DWTStep_1D(pDbSrc+i*nStep, nCurHLevel, nInv, W*nStep, nSupp)) return FALSE;
					}
				
					// 否则进行IDWT
					else
					{
						// 计算当前变换的图象的长度和宽度
						CurW 						CurH 				
						// 对列进行IDWT
						for (int i=0; i							if (!DWTStep_1D(pDbSrc+i*nStep, nCurHLevel, nInv, W*nStep, nSupp)) return FALSE;
						// 对行进行IDWT
						for (i=0; i							if (!DWTStep_1D(pDbSrc+(int)i*W*nStep, nCurWLevel, nInv, nStep, nSupp)) return FALSE;
					}
				
					// 返回
					return TRUE;
				}
				
				
				/*************************************************************************
				 *
				 * \函数名称:
				 *   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 ImageDWT(LPBYTE lpImage, int nMaxWLevel, int nMaxHLevel,
							int nDWTSteps, int nInv, int nStep, int nSupp)
				{
					// 判断变换的层数以及当前层数是否有效
					if (nDWTSteps>nMaxWLevel || nDWTSteps>nMaxHLevel || nStep						return FALSE;
				
					// 获得X,Y方向上的最大象素数(2次幂对齐)
					int W = 1				
					// 获得X,Y方向上变换时最小的象素数
					int minW = W>>nDWTSteps, minH = H>>nDWTSteps;
				
					int i, j, index;
					
					// 分配临时内存存放结果
					double*	pDbTemp = new double[W*H];
					if (!pDbTemp) return FALSE;
				
					// 判断是进行DWT还是IDWT,然后将数据存放到临时内存中,需要注意的是,需要进行采样
					if (!nInv)	// DWT
						for (index=0; index					else		// IDWT
					{
						index = 0;
						for (i=0; i						{
							for (j=0; j								pDbTemp[index] = lpImage[index*nStep];
							for (; j								pDbTemp[index] = (char)lpImage[index*nStep];
						}
						for (; index							pDbTemp[index] = (char)lpImage[index*nStep];
					}
				
					// 调用DWT_2D进行小波变换
					if(!DWT_2D(pDbTemp, nMaxWLevel, nMaxHLevel, nDWTSteps, nInv, nStep, nSupp))
					{
						delete []pDbTemp;
						return FALSE;
					}
				
					// 将数据存入原始的内存中,需要注意的是,存储时需要进行类型转换
					if (!nInv)	// DWT
					{
						index = 0;
						for (i=0; i						{
							for (j=0; j								lpImage[index*nStep] = FloatToByte(pDbTemp[index]);
							for (; j								lpImage[index*nStep] = (BYTE)FloatToChar(pDbTemp[index]);
							//	lpImage[index*nStep] = (BYTE)FloatToByte(pDbTemp[index]);
						}
						for (; index							lpImage[index*nStep] = (BYTE)FloatToChar(pDbTemp[index]);
							//lpImage[index*nStep] = (BYTE)FloatToByte(pDbTemp[index]);
					}
					else		// IDWT
						for (index=0; index							lpImage[index*nStep] = FloatToByte(pDbTemp[index]);
				
					// 释放内存
					delete []pDbTemp;
				
					// 返回
					return TRUE;
				}
				
				/*************************************************************************
				 *
				 * \函数名称:
				 *   FloatToByte()
				 *
				 * \输入参数:
				 *   double  f			- 输入双精度变量
				 *
				 * \返回值:
				 *   BYTE			- 返回比特型变量
				 *
				 * \说明:
				 *   该函数将输入的双精度变量转换为BYTE型的变量
				 *
				 *************************************************************************
				 */
				BYTE FloatToByte(double f)
				{
					if (f					else if (f>=255) return (BYTE)255;
					else return (BYTE)(f+0.5);
				}
				
				/*************************************************************************
				 *
				 * \函数名称:
				 *   FloatToChar()
				 *
				 * \输入参数:
				 *   double  f			- 输入双精度变量
				 *
				 * \返回值:
				 *   Char			- 返回字符变量
				 *
				 * \说明:
				 *   该函数将输入的双精度变量转换为Char型的变量
				 *
				 *************************************************************************
				 */
				char FloatToChar(double f)
				{
					if (f>=0)
						if (f>=127.0)
							return (char)127;
						else return (char)(f+0.5);
					else
						if (f							return (char)-128;
						else return -(char)(-f+0.5);
				}
				
				/*************************************************************************
				 *
				 * \函数名称:
				 *   Log2()
				 *
				 * \输入参数:
				 *   int  n			- 输入整型变量
				 *
				 * \返回值:
				 *   int			- 返回输入参数的对数
				 *
				 * \说明:
				 *   该函数求取输入参数的以2为底的对数,并转换为整型输出。
				 *
				 *************************************************************************
				 */
				int Log2(int n)
				{
					int rsl = 0;
					while (n >>= 1) rsl++;
					return rsl;
				}			

相关资源