先放下代码 回头补一下解释
头文件
const double haar_h[2] = {sqrt(2)/2 , sqrt(2)/2 };
const double haar_g[2] = { -sqrt(2) / 2 , sqrt(2) / 2 };
const double db5_h[10] = { 0.1601023980, 0.6038292698, 0.7243085284, 0.1384281459, \
-0.2422948871, -0.0322448696, 0.0775714938, -0.0062414902, -0.0125807520, 0.0033357253 };
const double db5_g[10] = { 0.0033357253, 0.0125807520, -0.0062414902, -0.0775714938,\
-0.0322448696, 0.2422948871, 0.1384281459, -0.7243085284, 0.6038292698, -0.1601023980 };
enum wavelets { haar, db5 }; //小波类型
cpp文件
void CDib::transpose()
{
unsigned char* temp = new BYTE[m_nHeight*m_nWidthBytes];
for (int lineX = 0; lineX < m_nHeight; lineX++)
{
for (int lineY = 0; lineY < m_nWidth; lineY++)
{
temp[lineY * m_nHeight + lineX] = m_pDibBits[lineX * m_nWidth + lineY];
}
}
memcpy(m_pDibBits, temp, m_nHeight*m_nWidthBytes);
delete temp;
}
void CDib::waveletTransform1D(wavelets selectedWavelet, int level, bool first_trans)
{
//按行进行小波变换
int hLen = 0;
const double* h = NULL;
const double* g = NULL;
double *result = new double[m_nHeight / level * m_nWidthBytes / level];
switch (selectedWavelet)
{
case haar:
hLen = 2;
h = haar_h;
g = haar_g;
break;
case db5:
hLen = 10;
h = db5_h;
g = db5_g;
break;
}
unsigned char* temp = new unsigned char[m_nWidthBytes + hLen];
for (int i = 0; i < m_nHeight / level; i++)
{
for (int j = 0; j < m_nWidthBytes / level; j++)
temp[j] = m_pDibBits[i * m_nWidthBytes + j];
// 末尾补最后一个
memset(temp + m_nWidthBytes/level, m_pDibBits[i * m_nWidthBytes + m_nWidthBytes / level - 1], hLen);
//memset(temp + m_nWidthBytes, 0, hLen);
for (int j = 0; j < m_nWidthBytes / level; j += 2)
{
double c = 0;
double d = 0;
for (int t = 0; t < hLen; t++)
{
c += temp[j + t] * h[t];
d += temp[j + t] * g[t];
}
result[i * m_nWidthBytes / level + j / 2] = c;
result[i * m_nWidthBytes / level + j / 2 + m_nWidthBytes / 2 / level] = d;
}
}
if (first_trans)
{
double max = 0;
double min = 0;
int beginXs[2] = { 0, m_nWidthBytes / level / 2 };
int beginX;
// find the max
for (int i = 0; i < 4; i++)
{
beginX = beginXs[i % 2];
for (int x = beginX; x < beginX + m_nWidthBytes / level / 2; x++)
{
for (int y = 0; y < m_nHeight / level; y++)
{
if (result[y * m_nWidthBytes / level + x] > max) max = result[y * m_nWidthBytes / level + x];
if (result[y * m_nWidthBytes / level + x] < min) min = result[y * m_nWidthBytes / level + x];
}
}
for (int x = beginX; x < beginX + m_nWidthBytes / level / 2; x++)
{
for (int y = 0; y < m_nHeight / level; y++)
{
m_pDibBits[y * m_nWidthBytes + x] = (result[y * m_nWidthBytes / level + x] - min) / (max - min) * 255;
}
}
}
}
else
{
double max = 0;
double min = 0;
int beginXs[2] = { 0, m_nWidthBytes / level / 2 };
int beginYs[2] = { 0 , m_nHeight / level / 2 };
int beginX, beginY;
// find the max
for (int i = 0; i < 4; i++)
{
beginX = beginXs[i % 2];
beginY = beginYs[i / 2];
for (int x = beginX; x < beginX + m_nWidthBytes / level / 2; x++)
{
for (int y = beginY; y < beginY + m_nHeight / level / 2; y++)
{
if (result[y * m_nWidthBytes / level + x] > max) max = result[y * m_nWidthBytes / level + x];
if (result[y * m_nWidthBytes / level + x] < min) min = result[y * m_nWidthBytes / level + x];
}
}
for (int x = beginX; x < beginX + m_nWidthBytes / level / 2; x++)
{
for (int y = beginY; y < beginY + m_nHeight / level / 2; y++)
{
m_pDibBits[y * m_nWidthBytes + x] = (result[y * m_nWidthBytes / level + x] - min) / (max - min) * 255;
}
}
}
}
delete[]result;
delete[]temp;
}
void CDib::waveletTransform2D(wavelets selectedWavelet, int level)
{
if (level == 2)
waveletTransform2D(selectedWavelet, 1);
waveletTransform1D(selectedWavelet, level , true);
transpose();
waveletTransform1D(selectedWavelet, level , false);
transpose();
double max = 0;
double min = 0;
int beginXs[2] = { 0, m_nWidthBytes / level / 2 };
int beginYs[2] = { 0 , m_nHeight / level / 2 };
int beginX, beginY;
// 调亮点
for (int i = 0; i < 4; i++)
{
beginX = beginXs[i % 2];
beginY = beginYs[i / 2];
for (int x = beginX; x < beginX + m_nWidthBytes / level / 2; x++)
{
for (int y = beginY; y < beginY + m_nHeight / level / 2; y++)
{
switch (selectedWavelet)
{
case haar:
switch (i)
{
case 0: break;
case 1: m_pDibBits[y * m_nWidthBytes + x] = pow(m_pDibBits[y * m_nWidthBytes + x], 1.1); break;
case 2: m_pDibBits[y * m_nWidthBytes + x] = pow(m_pDibBits[y * m_nWidthBytes + x], 1.2); break;
case 3: m_pDibBits[y * m_nWidthBytes + x] = pow(m_pDibBits[y * m_nWidthBytes + x], 1.35); break;
};
break;
case db5:
switch (i)
{
case 0: break;
case 1: m_pDibBits[y * m_nWidthBytes + x] = pow(m_pDibBits[y * m_nWidthBytes + x], 1.25); break;
case 2: m_pDibBits[y * m_nWidthBytes + x] = pow(m_pDibBits[y * m_nWidthBytes + x], 1.45); break;
case 3: m_pDibBits[y * m_nWidthBytes + x] = pow(m_pDibBits[y * m_nWidthBytes + x], 1.45); break;
};
break;
}
}
}
}
}