📄 wavetranform.cpp
字号:
// WaveTranform.cpp: implementation of the CWaveTranform class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "小波变换.h"
#include "WaveTranform.h"
#include "DIBAPI.h"
#include <math.h>
#include <direct.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWaveTranform::CWaveTranform()
{
m_GrayMax=255;
m_GrayMin=0;
for(int i=0;i<3;i++)
{
m_ColorMax[i]=255;//0蓝1绿2红
m_ColorMin[i]=0;
}
m_preoffset=0;
m_aftoffset=0;
}
CWaveTranform::~CWaveTranform()
{
}
/*************************************************************************
*
* 函数名称:
* Convolution()
*
* 参数:
* double * LF HF - 指向小波的指针,是常量
* FR - 小波窗的宽度
* double * f - 指向时域值的指针和返回的小波变换频域的指针
* fr -原图象每一行的像素个数
*
* 返回值:
* 无。
*
* 说明:
* 该函数用来实现卷积运算。
*
************************************************************************/
void CWaveTranform::Convolution(double *LF,double *HF,int FR, double *f, int fr)
{
int i,j,m;// 循环变量
double *X;
X = new double[fr]; // 分配运算所需的数组
// 卷积运算
for(i=0;i<fr/2;i++)
{
X[i]=0;
X[i+fr/2]=0;
for(j=0;j<FR;j++)
{
m=(2*i+j+fr-m_preoffset)%fr;
X[i]+=f[m]*LF[j];
X[i+fr/2]+=f[m]*HF[j];
}
}
//运算结果反传给f。
for(i= 0; i <fr; i++)
{
f[i]=X[i];
}
delete X;// 释放内存
}
/*************************************************************************
*
* 函数名称:
* DisConvolution()
*
* 参数:
* double * F - 指向小波的指针,是常量
* FR - 小波窗的宽度
* double * f - 指向时域值的指针和返回的小波变换频域的指针
* fr -原图象每一行的像素个数
*
* 返回值:
* 无。
*
* 说明:
* 该函数用来实现解卷积运算。
*
************************************************************************/
void CWaveTranform::DisConvolution(double *LF,double *HF,int FR, double *f0,double *f1, int fr)
{
int i,j;// 循环变量
double *X,*Y;
// 分配运算所需的数组
X = new double[fr];
Y = new double[fr];
// 解卷积运算
for(i=0;i<fr;i++)
{
X[i]=0;
Y[i]=0;
for(j=0;j<FR;j++)
{
X[i]+=f0[(i+j)%fr]*LF[j];
Y[i]+=f1[(i+j)%fr]*HF[j];
}
}
//运算结果反传给f0。
for(i= 0; i <fr; i++)
{
j=(i+fr-m_aftoffset)%fr;//循环移位
f0[i]=X[j]+Y[j];
}
delete X,Y; // 释放内存
}
/*************************************************************************
*
* 函数名称:
* DIBWavelet()
*
* 参数:
* LPSTR lpDIB - 指向DIB图像指针
* LPSTR lpDIBBits - 指向源DIB象素指针
* double *LF - 使用的小波尺度函数,是常量
* double *HF - 使用的小波母函数,是常量
* int FWidth - 小波窗的宽度
* int nLevel - 小波分解的层数
*
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用来对图像进行小波变换分解。于上面不同的是,此处是将二维
* 矩阵转换成一个列向量,然后对该列向量进行一次一维小波变换。
*
************************************************************************/
BOOL CWaveTranform::DIBWavelet(LPSTR lpDIB,LPSTR lpDIBBits,double* LF,double* HF,int FWidth,int nLevel)
{
unsigned char* lpSrc;// 指向源图像的指针
double dTemp;// 中间变量
LONG lLineBytes; // 图像每行的字节数
LONG lWidth, lHeight;
lWidth=::DIBWidth(lpDIB);
lHeight=::DIBHeight(lpDIB);
LONG i,j;//循环变量
double *f = new double[lWidth*lHeight];// 分配内存
if(::DIBNumColors(lpDIB)==256)
{
lLineBytes = WIDTHBYTES(lWidth * 8);// 计算图像每行的字节数
// 从源图像中读取数据。
for(i = 0; i < lHeight; i++)//每列
{
for(j = 0; j < lWidth; j++)// 每行
{
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) +j; // 指向DIB第i行,第j个象素的指针
f[i*lWidth+j] = *(lpSrc);// 给时域赋值
}
}
int n;//层数循环变量
//小波变换分解过程循环
for(n=0;n<nLevel;n++)
{
LONG Height,Width;//第n层图象的高度和宽度
Height=long(lHeight/pow(2,n));
Width=long(lWidth/pow(2,n));
double *LH=new double[Width]; //存放每一行元素
for(i = 0; i < Height; i++)
{
for(j=0;j<Width;j++)
{
LH[j]=f[i*lWidth+j];
}
Convolution( LF,HF, FWidth,LH, Width);// 对x方向进行卷积运算
for(j=0;j<Width;j++)
{
f[i*lWidth+j]=LH[j];
}
}
delete LH;
LH=new double[Height]; //存放每一列元素
for(i = 0; i < Width; i++)
{
for(j=0;j<Height;j++)
{
LH[j]=f[i+j*lWidth];
}
Convolution( LF,HF, FWidth,LH, Height);// 对y方向进行卷积运算
for(j=0;j<Height;j++)
{
f[i+j*lWidth]=LH[j];
}
}
delete LH;//释放内存
}
//将分解后的值规划处理
m_GrayMax=0;
m_GrayMin=255;
for(i=0;i<lHeight;i++)
{
for(j=0;j<lWidth;j++)
{
m_GrayMax=m_GrayMax>f[i * lWidth + j]?m_GrayMax:f[i * lWidth + j];
m_GrayMin=m_GrayMin<f[i * lWidth + j]?m_GrayMin:f[i * lWidth + j];
}
}
// 更新源图像
for(i = 0; i < lHeight; i++)// 每列
{
for(j = 0; j < lWidth; j++)// 每行
{
dTemp = f[i * lWidth + j]; // 计算频谱
dTemp=255/(m_GrayMax-m_GrayMin)*(dTemp-m_GrayMin);
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;// 指向DIB第i行,第j个象素的指针
* (lpSrc) = (BYTE)(dTemp);// 更新源图像
}
}
}
//处理真彩色
else
{
int ncolor;//颜色值循环
for(ncolor=0;ncolor<3;ncolor++)
{
lLineBytes = WIDTHBYTES(lWidth * 24);// 计算图像每行的字节数
// 从源图像中读取数据。
for(i = 0; i < lHeight; i++)//每列
{
for(j = 0; j < lWidth; j++)// 每行
{
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) +3*j+ncolor; // 指向DIB第i行,第j个象素的指针
f[i*lWidth+j] = *(lpSrc);// 给时域赋值
}
}
int n;//层数循环变量
//小波变换分解过程循环
for(n=0;n<nLevel;n++)
{
LONG Height,Width;//第n层图象的高度和宽度
Height=long(lHeight/pow(2,n));
Width=long(lWidth/pow(2,n));
double *LH=new double[Width]; //存放每一行元素
for(i = 0; i < Height; i++)
{
for(j=0;j<Width;j++)
{
LH[j]=f[i*lWidth+j];
}
Convolution( LF,HF, FWidth,LH, Width);// 对x方向进行卷积运算
for(j=0;j<Width;j++)
{
f[i*lWidth+j]=LH[j];
}
}
delete LH;
LH=new double[Height]; //存放每一列元素
for(i = 0; i < Width; i++)
{
for(j=0;j<Height;j++)
{
LH[j]=f[i+j*lWidth];
}
Convolution( LF,HF, FWidth,LH, Height);// 对y方向进行卷积运算
for(j=0;j<Height;j++)
{
f[i+j*lWidth]=LH[j];
}
}
delete LH;//释放内存
}
//将分解后的值规划处理
m_ColorMax[ncolor]=0;
m_ColorMin[ncolor]=255;
for(i=0;i<lHeight;i++)
{
for(j=0;j<lWidth;j++)
{
m_ColorMax[ncolor]=m_ColorMax[ncolor]>f[i * lWidth + j]?m_ColorMax[ncolor]:f[i * lWidth + j];
m_ColorMin[ncolor]=m_ColorMin[ncolor]<f[i * lWidth + j]?m_ColorMin[ncolor]:f[i * lWidth + j];
}
}
// 更新源图像
for(i = 0; i < lHeight; i++)// 每列
{
for(j = 0; j < lWidth; j++)// 每行
{
dTemp = f[i * lWidth + j]; // 计算频谱
dTemp=255/(m_ColorMax[ncolor]-m_ColorMin[ncolor])*(dTemp-m_ColorMin[ncolor]);
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + 3*j+ncolor;// 指向DIB第i行,第j个象素的指针
* (lpSrc) = (BYTE)(dTemp);// 更新源图像
}
}
}
}
delete f;//释放内存
return TRUE;// 返回
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -