#include "StdAfx.h"
#include "DWT.h"
//多用8个的
const double h[4] = {0.482962913145,0.836516303738,0.224143868042,-0.129409522551};
const double g[4] = {-0.129409522551,-0.224143868042,0.836516303738,-0.482962913145};
void DWT_1D(double *T,int N,double *W)
{
//采用对称延拓
//采用0延拓
//采用周期延拓好
/*
周期延拓效果最好,重建结果无失真,对称延拓重建psnr达到60以上,0延拓达到50以上,都还不错。
*/
ASSERT(T != NULL);
ASSERT(W != NULL);
//
int K = N/2;
deque<double> tempc,tempd;
//double vernier[4];
//
//计算
for(int i = 0;i < 2*K;i++)
{
tempc.push_back(T[i]);
}
tempd = tempc;
//
for(int i = 0;i < 3;i++)
{
//tempc.push_back(T[2*K-1-i]);
tempc.push_back(T[i]);//周期
//tempc.push_back(0);
}
for(int i = 0;i < 2;i++)
{
//tempd.push_front(T[i]);
tempd.push_front(T[2*K-1-i]);
//tempd.push_front(0);
}
//tempd.push_back(T[2*K-1]);
tempd.push_back(T[0]);
//tempd.push_back(0);
/////////
for(int i = 0;i < K;i++)
{
double sumc,sumd;
sumc = sumd = 0;
for(int k = 0;k < 4;k++)
{
sumc += tempc[2*i+k]*h[k];
sumd += tempd[2*i+k]*g[k];
}
W[i] = sumc;
W[i+K] = sumd;
}
if(N%2!=0)
{
W[N-1] = T[N-1];
}
tempc.clear();
tempd.clear();
}
void DWT_2D(double *Img,int nW,int nH,double *W)
{
//一层小波变换
ASSERT(Img != NULL);
ASSERT(W != NULL);
//
double *T,*W0;
//行变换
T = new double[nW];
W0 = new double[nW];
for(int i = 0;i < nH;i++)
{
for(int j = 0;j < nW;j++)
{
T[j] = Img[i*nW+j];
}
DWT_1D(T,nW,W0);
for(int j = 0;j < nW;j++)
{
W[i*nW+j] = W0[j];
}
}
delete []T;
delete []W0;
//列变换
T = new double[nH];
W0 = new double[nH];
for(int i = 0;i < nW;i++)
{
for(int j = 0;j < nH;j++)
{
T[j] = (double)W[j*nW+i];
}
DWT_1D(T,nH,W0);
for(int j = 0;j < nH;j++)
{
W[j*nW+i] = W0[j];
}
}
delete []T;
delete []W0;
}
void DWT_2D(double *Img,int nW,int nH,double *W,int n)
{
ASSERT(Img != NULL);
ASSERT(W != NULL);
////////////////////
int r,r1,r2;
r1 = (int)(log((double)nW)/log(2.0));
r2 = (int)(log((double)nH)/log(2.0));
r = min(r1,r2);
ASSERT(n <= r);
////////////////////////////////////////////////////
for(int i = 0;i < nH;i++)
{
for(int j = 0;j < nW;j++)
{
W[i*nW+j] = Img[i*nW+j];
}
}
//////
double *T,*DWT;
for(int i = 0;i < n;i++)
{
int h,w;
h = (int)((double)nH/pow(2.0,(double)i));
w = (int)((double)nW/pow(2.0,(double)i));
///////////////////////////////////////
T = new double[h*w];
DWT = new double[h*w];
for(int j = 0;j < h;j++)
{
for(int k = 0;k < w;k++)
{
T[j*w+k] = W[j*nW+k];
}
}
DWT_2D(T,w,h,DWT);
for(int j = 0;j < h;j++)
{
for(int k = 0;k < w;k++)
{
W[j*nW+k] = DWT[j*w+k];
}
}
delete []T;
delete []DWT;
///////////////////////////////////////
}
}
void IDWT_1D(double *T,int N,double *W)
{
//反变换,从W到T
ASSERT(T != NULL);
ASSERT(W != NULL);
//
int K = N/2;
deque<double> tempc,tempd;
for(int i = 0;i < K*2;i++)
{
if(i%2==0)
{
tempc.push_back(W[i/2]);
tempd.push_back(W[i/2+K]);
//tempd.push_back(0);
}
else
{
tempc.push_back(0);
tempd.push_back(0);
//tempd.push_back(W[i/2+K]);
}
}
/////
// tempc.push_front(0);
// tempc.push_front(0);
// tempc.push_front(0);
//
// tempd.push_front(0);
// tempd.push_back(0);
// tempd.push_back(0);
// tempc.push_front(0);
// tempc.push_front(W[0]);
// tempc.push_front(0);
//
// tempd.push_front(0);
// tempd.push_back(W[2*K-1]);
// tempd.push_back(0);
//周期
tempc.push_front(0);
tempc.push_front(W[K-1]);
tempc.push_front(0);
tempd.push_front(0);
tempd.push_back(W[K]);
tempd.push_back(0);
//延拓仍然有点问题
////
for(int i = 0;i < K*2;i++)
{
double sumc,sumd;
sumc = sumd = 0;
for(int k = 0;k < 4;k++)
{
sumc += tempc[i+k]*h[3-k];
sumd += tempd[i+k]*g[3-k];
}
T[i] = sumc+sumd;
}
if(N%2!=0)
{
T[N-1] = W[N-1];
}
tempc.clear();
tempd.clear();
}
void IDWT_2D(double *Img,int nW,int nH,double *W)
{
//一层小波反变换
ASSERT(Img != NULL);
ASSERT(W != NULL);
//
double *T,*W0;
//列反变换
T = new double[nH];
W0 = new double[nH];
for(int i = 0;i < nW;i++)
{
for(int j = 0;j < nH;j++)
{
W0[j] = (double)W[j*nW+i];
}
IDWT_1D(T,nH,W0);
for(int j = 0;j < nH;j++)
{
Img[j*nW+i] = T[j];
}
}
delete []T;
delete []W0;
//行反变换
T = new double[nW];
W0 = new double[nW];
for(int i = 0;i < nH;i++)
{
for(int j = 0;j < nW;j++)
{
W0[j] = Img[i*nW+j];
}
IDWT_1D(T,nW,W0);
for(int j = 0;j < nW;j++)
{
Img[i*nW+j] = T[j];
}
}
delete []T;
delete []W0;
}
void IDWT_2D(double *Img,int nW,int nH,double *W,int n)
{
int r,r1,r2;
r1 = (int)(log((double)nW)/log(2.0));
r2 = (int)(log((double)nH)/log(2.0));
r = min(r1,r2);
ASSERT(n <= r);
ASSERT(Img != NULL);
ASSERT(W != NULL);
////////////////////////////////////////////////////
for(int i = 0;i < nH;i++)
{
for(int j = 0;j < nW;j++)
{
Img[i*nW+j] = W[i*nW+j];
}
}
//////
double *T,*DWT;
for(int i = n-1;i >= 0;i--)
{
int h,w;
h = (int)((double)nH/pow(2.0,(double)i));
w = (int)((double)nW/pow(2.0,(double)i));
///////////////////////////////////////
T = new double[h*w];
DWT = new double[h*w];
for(int j = 0;j < h;j++)
{
for(int k = 0;k < w;k++)
{
DWT[j*w+k] = Img[j*nW+k];
}
}
IDWT_2D(T,w,h,DWT);
for(int j = 0;j < h;j++)
{
for(int k = 0;k < w;k++)
{
Img[j*nW+k] = T[j*w+k];
}
}
delete []T;
delete []DWT;
///////////////////////////////////////
}
}