📄 dwt.cpp
字号:
{
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 + -