📄 freqcalculate.cpp
字号:
// 抽取数据
for (j = 0; j < h; j++)
TempIn[j] = f[j * w * 3 + i];
// 一维快速离散余弦变换
WALSH(TempIn, TempOut, hp);
// 保存变换结果
for (j = 0; j < h; j++)
f[j * w * 3 + i] = TempOut[j];
}
// 释放内存
delete TempIn;
delete TempOut;
// 分配内存
TempIn = new double[w];
TempOut = new double[w];
// 对x方向进行快速离散余弦变换
for (i = 0; i < h; i++)
{
for (k = 0; k < 3; k++)
{
// 抽取数据
for (j = 0; j < w; j++)
TempIn[j] = f[i * w * 3 + j * 3 + k];
// 一维快速离散余弦变换
WALSH(TempIn, TempOut, wp);
// 保存变换结果
for (j = 0; j < w; j++)
F[i * w * 3 + j * 3 + k] = TempOut[j];
}
}
// 释放内存
delete TempIn;
delete TempOut;
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* IFreqWALSH()
*
* 参数:
* double* f - 输入的时域序列
* double* F - 输出的频域序列
* LONG lWidth - 图象宽度
* LONG lHeight - 图象高度
*
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数进行二维快速沃尔什——哈达玛逆变换。
*
************************************************************************/
BOOL CFreqCalculate::IFreqWALSH(double *f, double *F, LONG lWidth, LONG lHeight)
{
// 循环变量
LONG i;
LONG j;
LONG k;
// 更改光标形状
BeginWaitCursor();
// 赋初值
LONG w = 1;
LONG h = 1;
int wp = 0;
int hp = 0;
// 计算进行付立叶变换的宽度和高度(2的整数次方)
while (w < lWidth)
{
w *= 2;
wp++;
}
while (h < lHeight)
{
h *= 2;
hp++;
}
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 分配内存
double* TempIn = new double[w];
double* TempOut = new double[w];
// 对x方向进行快速付立叶变换
for (i = 0; i < h; i++)
{
for (k = 0; k < 3; k++)
{
// 抽取数据
for (j = 0; j < w; j++)
TempIn[j] = F[i * w * 3 + j * 3 + k];
// 一维快速傅立叶变换
IWALSH(TempIn, TempOut, wp);
// 保存变换结果
for (j = 0; j < w; j++)
F[i * w * 3 + j * 3 + k] = TempOut[j];
}
}
// 释放内存
delete TempIn;
delete TempOut;
TempIn = new double[h];
TempOut = new double[h];
// 对y方向进行快速付立叶变换
for (i = 0; i < w * 3; i++)
{
// 抽取数据
for (j = 0; j < h; j++)
TempIn[j] = F[j * w * 3 + i];
// 一维快速傅立叶变换
IWALSH(TempIn, TempOut, hp);
// 保存变换结果
for (j = 0; j < h; j++)
F[j * w * 3 + i] = TempOut[j];
}
// 释放内存
delete TempIn;
delete TempOut;
for (i = 0; i < h; i++)
{
for (j = 0; j < w * 3; j++)
{
if (i < lHeight && j < lLineBytes)
*(f + i * lLineBytes + j) = F[i * w * 3 + j];
}
}
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* DIBWalsh()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数对图象进行二维快速沃尔什——哈达马变换。
*
************************************************************************/
BOOL CFreqCalculate::DIBWalsh(HDIB hDIB)
{
// 循环变量
LONG i;
LONG j;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return FALSE;
}
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 进行沃尔什——哈达玛变换的宽度和高度(2的整数次方)
LONG w = 1;
LONG h = 1;
int wp = 0;
int hp = 0;
// 计算进行离散余弦变换的宽度和高度(2的整数次方)
while (w < lWidth)
{
w *= 2;
wp++;
}
while (h < lHeight)
{
h *= 2;
hp++;
}
// 分配内存
double *f = new double[w * h * 3];
double *F = new double[w * h * 3];
// 向时域赋值并补零
for (i = 0; i < h; i++)
{
for (j = 0; j < w * 3; j++)
{
if (i < lHeight && j < lLineBytes)
f[i * w * 3 + j] = *(unsigned char*)(lpDIBBits + lLineBytes * i + j);
else
f[w * i * 3 + j] = 0.0f;
}
}
// 进行频谱分析
if (FreqWALSH(f, F,lWidth, lHeight) == FALSE)
return FALSE;
// 更新所有象素
for (i = 0; i < lHeight; i++)
{
for (j = 0; j < lLineBytes; j++)
{
// 判断是否超过255
if (fabs(F[i * w * 3 + j] * 1000) > 255)
{
// 对于超过的,直接设置为255
*(unsigned char*)(lpDIBBits + lLineBytes * (lHeight - 1 - i) + j) = 255;
}
else
{
// 如果没有超过,则按实际计算结果赋值
*(unsigned char*)(lpDIBBits + lLineBytes * (lHeight - 1 - i) + j) = fabs(F[i * w * 3 + j] * 1000);
}
}
}
// 解除锁定
::GlobalUnlock(hDIB);
//释放内存
delete[] f;
delete[] F;
// 返回
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
// //
// 小波变换 //
// //
///////////////////////////////////////////////////////////////////////////
#define DD 13
float h[DD] = { -0.00332761f,0.00569794f, 0.0196637f, -0.0482603f, -0.0485391f,
0.292562f, 0.564406f, 0.292562f, -0.0485391f, -0.0482602f,
-0.0196637f, 0.00569794f, -0.0033276f};
float g[DD] = {0.00332761f, 0.00569794f, -0.0196637f, -0.0482603f, 0.0485391f,
0.292562f, -0.564406f, 0.292562f, 0.0485391f, -0.0482602f,
0.0196637f, 0.00569794f, 0.0033276f};
float hi[DD];
float gi[DD];
int CFreqCalculate::a(int nX, int nXSize)
{
if (nX < 0)
nX = -nX;
if (nX >= nXSize)
nX = nXSize * 2 - nX - 2;
return nX;
}
/*************************************************************************
*
* 函数名称:
* DWT()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对二维点阵进行离散小波变换。
*
************************************************************************/
void CFreqCalculate::DWT(LPBYTE lpData, int nX, int nY, int nXSize, int nYSize)
{
// 循环变量
int i, j, k, n;
// 中间变量
float temp1, temp2;
float* BufferX;
float* BufferY;
BufferX = new float[nXSize];
BufferY = new float[nYSize];
// 水平方向
for (n = 0; n < nY; n++)
{
for (i = 0; i < nX; i += 2)
{
temp1 = temp2 = 0;
for (j = -(DD - 1) / 2; j <= (DD - 1) / 2; j++)
temp1 = temp1 + *(lpData + n * nX + a(i + j, nX)) * h[j + (DD - 1) / 2];
for (j = -(DD - 1) / 2 + 1; j <= (DD - 1) / 2 + 1; j++)
temp2 = temp2 + *(lpData + n * nX + a(i + j, nX)) * g[j + (DD - 1) / 2 - 1];
BufferX[i / 2] = temp1;
BufferX[i / 2 + nX / 2] = temp2;
}
// 回存数据
for (k = 0; k < nX; k++)
*(lpData + n * nX + k) = BufferX[k];
}
// 垂直方向
for (n = 0; n < nX; n++)
{
for (i = 0; i < nY; i += 2)
{
temp1 = temp2 = 0;
for (j = -(DD - 1) / 2; j <= (DD - 1) / 2; j++)
temp1 = temp1 + *(lpData + a(i + j, nY) * nX + n) * h[j + (DD - 1) / 2];
for (j = -(DD - 1) / 2 + 1; j <= (DD - 1) / 2 + 1; j++)
temp2 = temp2 + *(lpData + a(i + j, nY) * nX + n) * g[j + (DD - 1) / 2 - 1];
BufferY[i / 2] = temp2;
BufferY[i / 2 + nY / 2] = temp1;
}
// 回存数据
for (k = 0; k < nY; k++)
*(lpData + k * nX + n) = BufferY[k];
}
delete[] BufferX;
delete[] BufferY;
}
/*************************************************************************
*
* 函数名称:
* IDWT()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对二维点阵进行小波重构。
*
************************************************************************/
void CFreqCalculate::IDWT(LPBYTE lpData, int nX, int nY, int nXSize, int nYSize)
{
// 循环变量
int i, j, k, n;
// 中间变量
float temp1, temp2;
float* Buffer1;
float* Buffer2;
Buffer1 = new float[nXSize];
Buffer2 = new float[nYSize];
for (i = 0; i < DD; i++)
{
hi[i] = h[DD - 1 - i];
gi[i] = g[DD - 1 - i];
}
// 垂直方向
for (n = 0; n < nX; n++)
{
for (k = 0; k < nY / 2; k++)
{
Buffer1[k * 2] = *(lpData + k * nX + n);
Buffer1[k * 2 + 1] = 0;
}
for (i = 0; i < nY; i++)
{
temp1 = 0;
for (j = -(DD - 1) / 2; j <= (DD - 1) / 2; j++)
{
temp1 = temp1 + Buffer1[a(i + j, nY)] * hi[j + (DD - 1) / 2];
Buffer2[i] = temp1;
}
}
for (k = 0; k < nY / 2; k++)
{
Buffer1[k * 2] = *(lpData + (k + nY / 2) * nX + n);
Buffer1[k * 2 + 1] = 0;
}
for (i = 0; i < nY; i++)
{
temp1 = 0;
for (j = -(DD - 1) / 2 - 1; j <= (DD - 1) / 2 - 1; j++)
temp1 = temp1 + Buffer1[a(i + j, nY)] * gi[j + (DD - 1) / 2 + 1];
temp2 = temp1 + Buffer2[i];
Buffer2[i] = temp2;
}
// 回存数据
for (k = 0; k < nY; k++)
*(lpData + k * nX + n) = Buffer2[k];
}
// 水平方向
for (n = 0; n < nY; n++)
{
for (k = 0; k < nX / 2; k++)
{
Buffer1[k * 2] = *(lpData + n * nX + k);
Buffer1[k * 2 + 1] = 0;
}
for (i = 0; i < nX; i++)
{
temp1 = 0;
for (j = -(DD - 1) / 2; j <= (DD - 1) / 2; j++)
temp1 = temp1 + Buffer1[a(i + j, nX)] * hi[j + (DD - 1) / 2];
Buffer2[i] = temp1;
}
for (k = 0; k < nX / 2; k++)
{
Buffer1[k * 2] = *(lpData + n * nX + k + nX / 2);
Buffer1[k * 2 + 1] = 0;
}
for (i = 0; i < nX; i++)
{
temp1 = 0;
for (j = -(DD - 1) / 2 - 1; j <= (DD - 1) / 2 - 1; j++)
temp1 = temp1 + gi[j + (DD - 1) / 2 + 1] * Buffer1[a(i + j, nX)];
temp2 = temp1 + Buffer2[i];
Buffer2[i] = temp2;
}
// 回存数据
for (k = 0; k < nX; k++)
*(lpData + n * nX + k) = Buffer2[k] * 4;
}
delete[] Buffer1;
delete[] Buffer2;
}
/*************************************************************************
*
* 函数名称:
* DIBDWT()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对图象进行二维离散小波变换。
*
************************************************************************/
void CFreqCalculate::DIBDWT(HDIB hDIB)
{
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 8)
{
// 提示用户
MessageBox("请先将其转换为8位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 进行小波分解
DWT(lpDIBBits, lWidth, lHeight, lWidth, lHeight);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* DIBIDWT()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对图象进行二维小波重构。
*
************************************************************************/
void CFreqCalculate::DIBIDWT(HDIB hDIB)
{
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 8)
{
// 提示用户
MessageBox("请先将其转换为8位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 进行小波重构
IDWT(lpDIBBits, lWidth, lHeight, lWidth, lHeight);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 恢复光标
EndWaitCursor();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -