📄 dwt.cpp
字号:
/**************************************************************
* CDWT类:用于进行小波变换的类
*
* 构造函数
* // 初始化滤波器
* Wavelet (FilterSet *filterset)
* // 初始化滤波器
* Wavelet()
* 析构函数 Wavelet::~Wavelet ()
*
* // 进行小波变换滤波器的选择
* selectFilter(FilterSet *filterset)
* // 一维小波变换
* transform1d (Real *input, Real *output,
* int size, int nsteps, int sym_ext)
* // 一维小波反变换
* invert1d (Real *input, Real *output,
* int size, int nsteps, int sym_ext)
* // 二维小波变换
* transform2d (Real *input, Real *output,
* int hsize, int vsize,
* int nsteps, int sym_ext)
* // 二维小波反变换
* invert2d (Real *input, Real *output,
* int hsize, int vsize,
* int nsteps, int sym_ext)
* // 小波单步变换,
* transform_step (Real *input, Real *output,
* int size, int sym_ext)
* // 小波单步反变换,
* invert_step (Real *input, Real *output,
* int size, int sym_ext)
*
* 小波变换的两种扩展模式
* // 采用对称扩展
* symmetric_extension (Real *output, int size,
* int left_ext, int right_ext,
* int symmetry)
* // 采用周期扩展
* periodic_extension (Real *output, int size)
*
**************************************************************/
#include "stdafx.h"
#include <math.h>
#include <assert.h>
#include "global.h"
#include "ImageDWT.h"
#include "DWT.h"
#include "Filter.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*************************************************************
* 构造函数
**************************************************************/
CDWT::CDWT()
{
// 初始化滤波器
// 设置滤波器参数
Hi_D=Lo_D=Hi_R=Lo_R=NULL;
// 设置边界延拓模式, 默认为周期延拓
ExtendMode = 0;
npad = 0;
}
/*************************************************************
* 析构函数
**************************************************************/
CDWT::~CDWT()
{
delete[]Lo_D;
delete[]Hi_D;
delete[]Lo_R;
delete[]Hi_R;
}
/////////////////////////////////////////////////////////////////////////////
// CDWT message handlers
/**************************************************************
* 设置分解合成滤波器组,filtername是滤波器组的名称
**************************************************************/
void CDWT::SetFilters(LPCSTR filtername)
{
int i;
FilterName = filtername;
FilterName.MakeLower();
if(FilterName=="haar") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=2;
else if(FilterName=="db2") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=4;
else if(FilterName=="db3") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=6;
else if(FilterName=="db4") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=8;
else if(FilterName=="db5") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=10;
else if(FilterName=="db6") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=12;
else if(FilterName=="db7") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=14;
else if(FilterName=="db8") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=16;
else if(FilterName=="bior1.3") L_Lo_D=L_Hi_R=L_Lo_R=L_Hi_D=6;
else if(FilterName=="bior1.5") L_Lo_D=L_Hi_R=L_Lo_R=L_Hi_D=10;
else if(FilterName=="bior2.2") L_Lo_D=L_Hi_R=L_Lo_R=L_Hi_D=6;
else if(FilterName=="bior2.4") L_Lo_D=L_Hi_R=L_Lo_R=L_Hi_D=10;
else if(FilterName=="bior2.6") L_Lo_D=L_Hi_R=L_Lo_R=L_Hi_D=14;
else if(FilterName=="bior2.8") L_Lo_D=L_Hi_R=L_Lo_R=L_Hi_D=18;
else if(FilterName=="bior3.1") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=4;
else if(FilterName=="bior3.3") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=8;
else if(FilterName=="bior3.5") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=12;
else if(FilterName=="bior3.7") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=16;
else if(FilterName=="bior3.9") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=20;
else if(FilterName=="bior4.4") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=10;
else if(FilterName=="bior5.5") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=12;
else if(FilterName=="bior6.8") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=18;
else if(FilterName=="sym2") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=4;
else if(FilterName=="sym3") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=6;
else if(FilterName=="sym4") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=8;
else if(FilterName=="sym5") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=10;
else if(FilterName=="sym6") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=12;
else if(FilterName=="sym7") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=14;
else if(FilterName=="sym8") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=16;
else if(FilterName=="coif1") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=6;
else if(FilterName=="coif2") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=12;
else if(FilterName=="coif3") L_Lo_R=L_Lo_D=L_Hi_R=L_Hi_D=18;
FilterLong = L_Lo_R;
Lo_D=new double[L_Lo_D];
Hi_D=new double[L_Hi_D];
Lo_R=new double[L_Lo_R];
Hi_R=new double[L_Hi_R];
if(FilterName=="haar")
{
for(i=0;i<2;i++)
{
Lo_D[i]=haar_Lo[i];Hi_D[i]=haar_Hi[i];
}
}
else if(FilterName=="db2")
{
for(i=0;i<4;i++)
{
Lo_D[i]=db2_Lo[i];Hi_D[i]=db2_Hi[i];
}
}
else if(FilterName=="db3")
{
for(i=0;i<6;i++)
{
Lo_D[i]=db3_Lo[i];Hi_D[i]=db3_Hi[i];
}
}
else if(FilterName=="db4")
{
for(i=0;i<8;i++)
{
Lo_D[i]=db4_Lo[i];Hi_D[i]=db4_Hi[i];
}
}
else if(FilterName=="db5")
{
for(i=0;i<10;i++)
{
Lo_D[i]=db5_Lo[i];Hi_D[i]=db5_Hi[i];
}
}
else if(FilterName=="db6")
{
for(i=0;i<12;i++)
{
Lo_D[i]=db6_Lo[i];Hi_D[i]=db6_Hi[i];
}
}
else if(FilterName=="db7")
{
for(i=0;i<14;i++)
{
Lo_D[i]=db7_Lo[i];Hi_D[i]=db7_Hi[i];
}
}
else if(FilterName=="db8")
{
for(i=0;i<16;i++)
{
Lo_D[i]=db8_Lo[i];Hi_D[i]=db8_Hi[i];
}
}
else if(FilterName=="bior1.3")
{
for(i=0;i<6;i++)
{
Lo_D[i]=bior13_Lo[i];Hi_D[i]=bior13_Hi[i];
}
}
else if(FilterName=="bior1.5")
{
for(i=0;i<10;i++)
{
Lo_D[i]=bior15_Lo[i];Hi_D[i]=bior15_Hi[i];
}
}
else if(FilterName=="bior2.2")
{
for(i=0;i<6;i++)
{
Lo_D[i]=bior22_Lo[i];Hi_D[i]=bior22_Hi[i];
}
}
else if(FilterName=="bior2.4")
{
for(i=0;i<10;i++)
{
Lo_D[i]=bior24_Lo[i];Hi_D[i]=bior24_Hi[i];
}
}
else if(FilterName=="bior2.6")
{
for(i=0;i<14;i++)
{
Lo_D[i]=bior26_Lo[i];Hi_D[i]=bior26_Hi[i];
}
}
else if(FilterName=="bior2.8")
{
for(i=0;i<18;i++)
{
Lo_D[i]=bior28_Lo[i];Hi_D[i]=bior28_Hi[i];
}
}
else if(FilterName=="bior3.1")
{
for(i=0;i<4;i++)
{
Lo_D[i]=bior31_Lo[i];Hi_D[i]=bior31_Hi[i];
}
}
else if(FilterName=="bior3.3")
{
for(i=0;i<8;i++)
{
Lo_D[i]=bior33_Lo[i];Hi_D[i]=bior33_Hi[i];
}
}
else if(FilterName=="bior3.5")
{
for(i=0;i<12;i++)
{
Lo_D[i]=bior35_Lo[i];Hi_D[i]=bior35_Hi[i];
}
}
else if(FilterName=="bior3.7")
{
for(i=0;i<16;i++)
{
Lo_D[i]=bior37_Lo[i];Hi_D[i]=bior37_Hi[i];
}
}
else if(FilterName=="bior3.9")
{
for(i=0;i<20;i++)
{
Lo_D[i]=bior39_Lo[i];Hi_D[i]=bior39_Hi[i];
}
}
else if(FilterName=="bior4.4")
{
for(i=0;i<10;i++)
{
Lo_D[i]=bior44_Lo[i];Hi_D[i]=bior44_Hi[i];
}
}
else if(FilterName=="bior5.5")
{
for(i=0;i<12;i++)
{
Lo_D[i]=bior55_Lo[i];Hi_D[i]=bior55_Hi[i];
}
}
else if(FilterName=="bior6.8")
{
for(i=0;i<18;i++)
{
Lo_D[i]=bior68_Lo[i];Hi_D[i]=bior68_Hi[i];
}
}
else if(FilterName=="sym2")
{
for(i=0;i<4;i++)
{
Lo_D[i]=sym2_Lo[i];Hi_D[i]=sym2_Hi[i];
}
}
else if(FilterName=="sym3")
{
for(i=0;i<6;i++)
{
Lo_D[i]=sym3_Lo[i];Hi_D[i]=sym3_Hi[i];
}
}
else if(FilterName=="sym4")
{
for(i=0;i<8;i++)
{
Lo_D[i]=sym4_Lo[i];Hi_D[i]=sym4_Hi[i];
}
}
else if(FilterName=="sym5")
{
for(i=0;i<10;i++)
{
Lo_D[i]=sym5_Lo[i];Hi_D[i]=sym5_Hi[i];
}
}
else if(FilterName=="sym6")
{
for(i=0;i<12;i++)
{
Lo_D[i]=sym6_Lo[i];Hi_D[i]=sym6_Hi[i];
}
}
else if(FilterName=="sym7")
{
for(i=0;i<14;i++)
{
Lo_D[i]=sym7_Lo[i];Hi_D[i]=sym7_Hi[i];
}
}
else if(FilterName=="sym8")
{
for(i=0;i<16;i++)
{
Lo_D[i]=sym8_Lo[i];Hi_D[i]=sym8_Hi[i];
}
}
else if(FilterName=="coif1")
{
for(i=0;i<6;i++)
{
Lo_D[i]=coif1_Lo[i];Hi_D[i]=coif1_Hi[i];
}
}
else if(FilterName=="coif2")
{
for(i=0;i<12;i++)
{
Lo_D[i]=coif2_Lo[i];Hi_D[i]=coif2_Hi[i];
}
}
else if(FilterName=="coif3")
{
for(i=0;i<18;i++)
{
Lo_D[i]=coif3_Lo[i];Hi_D[i]=coif3_Hi[i];
}
}
for(i=0;i<L_Lo_R;i++)
{
if(i%2==0)
Lo_R[i] = Hi_D[i];
else
Lo_R[i] =-Hi_D[i];
}
for(i=0;i<L_Hi_R;i++)
{
if(i%2==0)
Hi_R[i] = Lo_D[i];
else
Hi_R[i] =-Lo_D[i];
}
// 对称扩展的填充空间大小
npad = max(L_Lo_D, L_Hi_D);
}
///////////////////////////////////////////////////////////////////////////
// 小波处理函数
/**************************************************************
* 小波单步变换,
* input and output are padded with npad values
* at the beginning and at the end
**************************************************************/
void CDWT::DWTStep_1D (double *input, double *output,
int dataLong, int extendmode)
{
int i, j;
int LowSize = (dataLong+1)/2;
if (extendmode)
// 对称扩展
symmetric_extension (input, dataLong);
else
// 周期扩展
periodic_extension (input, dataLong);
// 分解低频
for (i = 0; i < LowSize; i++)
{
output [npad+i] = 0.0;
for (j = 0; j < L_Lo_D; j++)
output [npad+i] +=
( input[npad + 2*i + j] * Lo_D[j] ) / Sqrt2;
}
// 分解高频
for (i = LowSize; i < dataLong; i++)
{
output [npad+i] = 0.0;
for (j = 0; j < L_Hi_D; j++)
output [npad+i] +=
( input[npad + 2*(i-LowSize) + j] * Hi_D[j] ) / Sqrt2;
}
}
/**************************************************************
* 一维小波变换
**************************************************************/
void CDWT::DWT_1D (double *input, double *output,
int dataLong, int nsteps, int extendmode)
{
int LowSize = dataLong, HighSize;
int currentIndex = 0;
double *data[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);
while (nsteps--)
{
if (LowSize <= 2 && ExtendMode == 1)
{
MessageBox(NULL,"请减少分解级数或增加信号长度! \n低通子带太小了!","error",MB_OKCANCEL|MB_ICONERROR);
return;
}
// 单步小波变换
DWTStep_1D (data[currentIndex], data[1-currentIndex],
LowSize, extendmode);
// 复制数据给输出信号
copy (data[1-currentIndex] + npad, output, LowSize);
// Now convolve low-pass portion again
HighSize = LowSize/2;
LowSize = (LowSize+1)/2;
currentIndex = 1 - currentIndex;
}
delete [] data[1];
delete [] data[0];
}
/**************************************************************
* 小波二维变换
**************************************************************/
void CDWT::DWT_2D (double *input, double *output,
int rowLong, int colLong,
int nsteps, int extendmode)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -