-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathWavelet.h
215 lines (179 loc) · 7.58 KB
/
Wavelet.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#pragma once
#include "assert.h"
#include "math.h"
#include <algorithm>
#include <vector>
#include "3Dmath.h"
#define OneBySqrt2 0.70710678118654752440084436210485f
#define AT(f,r,c) ((f)[(r)*n+(c)])
class CWavelet
{
public:
CWavelet(void);
~CWavelet(void);
////////////////////////////////////////////////////////////////////////// new Non-standard
void DecompositionStep(float* array, int len);//haar1D
void NonstandDecomposition(float* mat, int rowNum, int colNum);//haar2D
void DecompositionStep(Vec3* array, int len);//haar1D
void NonstandDecomposition(Vec3* mat, int rowNum, int colNum);//haar2D
//////////////////////////////////////////////////////////////////////////standard
void Haar1D(float* array, int len);
void ReverseHaar1D(float* array, int len); //Haar reverse
void Haar2D(float* mat, int rowNum, int colNum);//haar2D reverse
void ReverseHaar2D(float* mat, int rowNum, int colNum);//Haar2D reverse
//////////////////////////////////////////////////////////////////////////
void Haar1D(Vec3* array, int len);
void ReverseHaar1D(Vec3* array, int len); //Haar reverse
void Haar2D(Vec3* mat, int rowNum, int colNum);//haar2D reverse
void ReverseHaar2D(Vec3* mat, int rowNum, int colNum);//Haar2D reverse
inline void haar2d(Vec3 *fi, Vec3* fo, const int n)
{
int lv,sz,i,j;
Vec3 a,b,c,d;
for(lv=1,sz=n;lv<n;lv*=2)
{
sz/=2;
for(i=0;i<sz;i++)
for(j=0;j<sz;j++)
{
a=AT(fi,i*2,j*2);
b=AT(fi,i*2+1,j*2);
c=AT(fi,i*2,j*2+1);
d=AT(fi,i*2+1,j*2+1);
AT(fi,i,j)=(a+b+c+d)/2.0f;
AT(fo,i+sz,j)=(a-b+c-d)/2.0f;
AT(fo,i,j+sz)=(a+b-c-d)/2.0f;
AT(fo,i+sz,j+sz)=(a-b-c+d)/2.0f;
}
}
*fo=*fi;//1st item copy, not pointer copy!!!
}
protected:
Vec3* m_temp; //we can use this instead of "temp" above, in performance stage. but i misused it and get troubled.... ^%$#&^%&(*^&(&*^%%%R#$@!$#@!$E#@RAaaaaaaaaaaa~~~~~~~
Vec3* m_temp2;
Vec3* m_temp1k;
float* m_fTemp;
float* m_fTemp2;
float* m_fTemp1k;
};
inline bool _idxLess(std::pair<float, int> first, std::pair<float, int> second)
{
return first.second < second.second;
};
inline bool _coefFabsGreater(const std::pair<float, short int> &first, const std::pair<float, short int>& second)
{
return fabs(first.first) > fabs(second.first);
};
//keep only nth_element bigger former part of coefs, copy them into bigCoefs, track each's indices into coefIndices.
inline void KeepLoss(Vec3* array, int num, int keepNum, Vec3* bigElements, short int* elementIndices)
{
std::vector<std::pair<float, short int> > CoefAndIdx(num);
for(short int i = 0; i < (short int)num; ++i)
CoefAndIdx[i] = std::pair<float, short int>(0.299f * array[i].x + 0.587f * array[i].y + 0.114f * array[i].z , i);
//deb CoefAndIdx[i] = std::pair<float, unsigned int>(Norm(array[i]), i);
std::nth_element(CoefAndIdx.begin(), CoefAndIdx.begin() + keepNum, CoefAndIdx.end(), _coefFabsGreater);//cut off: first 128 is biggest
//when wavelet num can vary, add this line
std::sort(CoefAndIdx.begin(), CoefAndIdx.begin() + keepNum, _coefFabsGreater);//for real-time flexible choice of num of LIGHT coefs, sort these coefs decreasely
//bigCoefs and corresponding indices in the same position in coefIndices
for (int i = 0; i < keepNum; ++i)
{
bigElements[i] = array[CoefAndIdx[i].second];
elementIndices[i] = CoefAndIdx[i].second;
}
}
//keep only nth_element bigger former part of coefs, copy them into bigCoefs, track each's indices into coefIndices.
inline void KeepLoss(float* array, int num, int keepNum, float* bigElements, short int* elementIndices)
{
std::vector<std::pair<float, short int> > CoefAndIdx(num);
for(short int i = 0; i < (short int)num; ++i)
CoefAndIdx[i] = std::pair<float, short int>(array[i], i);
std::nth_element(CoefAndIdx.begin(), CoefAndIdx.begin() + keepNum, CoefAndIdx.end(), _coefFabsGreater);//cut off: first 128 is biggest
//when wavelet num can vary, add this line
std::sort(CoefAndIdx.begin(), CoefAndIdx.begin() + keepNum, _coefFabsGreater);//for real-time flexible choice of num of LIGHT coefs, sort these coefs decreasely
//bigCoefs and corresponding indices in the same position in coefIndices
for (int i = 0; i < keepNum; ++i)
{
bigElements[i] = CoefAndIdx[i].first;
elementIndices[i] = CoefAndIdx[i].second;
}
}
inline int log2(int x)
{
int i = 0;
while((x = x >> 1) > 0)
++i;
return i;
}
//keep only nth_element bigger former part of area-weighted cube coefs, copy orig coefs into bigCoefs, track each's indices into coefIndices.
inline void CubeKeepLoss(const float* array, const int cubeRes, const int keepNum, float* bigElements, short int* elementIndices, bool bAreaWeighting, bool bSortByCoef, bool bSortByIdx)
{
#define max(a,b) (((a) > (b)) ? (a) : (b))
int sideNum = cubeRes * cubeRes;
std::vector<std::pair<float, short int> > WCoefAndIdx(sideNum * 6);
for(short int i = 0; i < (short int)sideNum*6; ++i)
{
//effect too bad!! WCoefAndIdx[i] = std::pair<float, short int>(array[i], i);
if(bAreaWeighting)
WCoefAndIdx[i] = std::pair<float, short int>(array[i] /
(1 << log2(max((i % sideNum) % cubeRes, (i % sideNum) / cubeRes))), i);
else
WCoefAndIdx[i] = std::pair<float, short int>(array[i], i);
}
std::nth_element(WCoefAndIdx.begin(), WCoefAndIdx.begin() + keepNum, WCoefAndIdx.end(), _coefFabsGreater);//cut off: first 128 is biggest
//when wavelet num can vary, add this line
if(bSortByCoef)
std::sort(WCoefAndIdx.begin(), WCoefAndIdx.begin() + keepNum, _coefFabsGreater);//for real-time flexible choice of num of LIGHT coefs, sort these coefs decreasely
else if(bSortByIdx)
std::sort(WCoefAndIdx.begin(), WCoefAndIdx.begin() + keepNum, _idxLess);//for real-time 3p indexing, sort into s/l/i/j/m increasing order. Refer to Ng04
//bigCoefs and corresponding indices in the same position in coefIndices
for (int i = 0; i < keepNum; ++i)
{
bigElements[i] = array[WCoefAndIdx[i].second];
elementIndices[i] = WCoefAndIdx[i].second;
}
}
//keep only nth_element bigger former part of area-weighted cube coefs, copy orig coefs into bigCoefs, track each's indices into coefIndices.
inline void WeightedCubeKeepLossNoSort(Vec3* array, int cubeRes, int keepNum, Vec3* bigElements, short int* elementIndices)
{
#define max(a,b) (((a) > (b)) ? (a) : (b))
int sideNum = cubeRes * cubeRes;
std::vector<std::pair<float, short int> > WCoefAndIdx(sideNum * 6);
for(short int i = 0; i < (short int)sideNum*6; ++i)
{
//int test = (1 << log2(max((i % sideNum) % cubeRes, (i % sideNum) / cubeRes)));
WCoefAndIdx[i] = std::pair<float, short int>((0.299f * array[i].x + 0.587f * array[i].y + 0.114f * array[i].z ) /
(1 << log2(max((i % sideNum) % cubeRes, (i % sideNum) / cubeRes))), i);
}
std::nth_element(WCoefAndIdx.begin(), WCoefAndIdx.begin() + keepNum, WCoefAndIdx.end(), _coefFabsGreater);//cut off: first 128 is biggest
//when wavelet num can vary, add this line
//std::sort(AreaWeightedCoefAndIdx.begin(), AreaWeightedCoefAndIdx.begin() + keepNum, _coefFabsGreater);//for real-time flexible choice of num of LIGHT coefs, sort these coefs decreasely
//bigCoefs and corresponding indices in the same position in coefIndices
for (int i = 0; i < keepNum; ++i)
{
bigElements[i] = array[WCoefAndIdx[i].second];
elementIndices[i] = WCoefAndIdx[i].second;
}
}
inline void haar2d(float *fi,float *fo,const int n)
{
int lv,sz,i,j;
float a,b,c,d;
for(lv=1,sz=n;lv<n;lv*=2)
{
sz/=2;
for(i=0;i<sz;i++)
for(j=0;j<sz;j++)
{
a=AT(fi,i*2,j*2);
b=AT(fi,i*2+1,j*2);
c=AT(fi,i*2,j*2+1);
d=AT(fi,i*2+1,j*2+1);
AT(fi,i,j)=(a+b+c+d)/2.0f;
AT(fo,i+sz,j)=(a-b+c-d)/2.0f;
AT(fo,i,j+sz)=(a+b-c-d)/2.0f;
AT(fo,i+sz,j+sz)=(a-b-c+d)/2.0f;
}
}
*fo=*fi;
}
#undef AT