📄 wavelet1ddlg.cpp
字号:
return TRUE;
}
// 分配小波变换所需内存
BOOL CWavelet1DDlg::GetMemory()
{
BOOL flag=TRUE;
Data=new double *[m_nImageHeight];
for(int n=0;n<=m_nDecomposeStage;n++)
{
*(Data+n)=new double[sizeof(double)*m_nImageWidth];
if(*(Data+n)==NULL)
flag=FALSE;
}
DotData=new double[sizeof(double)*(m_nImageWidth+m_nImageHeight)];
if(DotData==NULL)
flag=FALSE;
return flag;
}
// 释放小波变换所用内存资源
void CWavelet1DDlg::ReleaseMemory()
{
for(int k=0;k<m_nDecomposeStage;k++)
if(*(Data+k))
delete *(Data+k);
if(Data)
{
delete []Data;
Data=NULL;
}
if(DotData)
{
delete DotData;
DotData=NULL;
}
if(DIB)
{
::GlobalFree((HGLOBAL) DIB);
DIB=NULL;
}
}
// 返回H算子周期化后得值
double CWavelet1DDlg::HH(int i,int m)
{
return h[i+m];
}
// 返回G算子周期化后的值
double CWavelet1DDlg::GG(int i, int m)
{
char flag;
if(i%2)
flag=-1;
else
flag=1;
return HH(-1*i+1,m)*flag;
}
// H算子周期化过程
BOOL CWavelet1DDlg::HHH(int level,int size)
{
int len,m,i;
double temp;
int sign;
len=size>>level;
m=m_nFilterLen/2;
if((ph=new double[sizeof(double)*len])==NULL)
{
AfxMessageBox("H算子内存分配失败!",MB_OK|MB_ICONINFORMATION);
return FALSE;
}
for(sign=0;sign<len;sign++)
{
temp=0;
for(i=(-1*m+1);i<=m;i++)
{
if(((sign-i)%len)==0)
temp+=HH(i-1,m);
}
ph[sign]=temp;
}
return TRUE;
}
// G算子周期化过程
BOOL CWavelet1DDlg::GGG(int level,int size)
{
int len,m,i;
double temp;
int sign;
len=size>>level;
m=m_nFilterLen/2;
if((pg=new double[sizeof(double)*len])==NULL)
{
AfxMessageBox("G算子内存分配失败!",MB_OK|MB_ICONINFORMATION);
return FALSE;
}
for(sign=0;sign<len;sign++)
{
temp=0;
for(i=(-1*m+3);i<=m+2;i++)
{
if(((sign-i)%len)==0)
temp+=GG(i-1,m);
}
pg[sign]=temp;
}
return TRUE;
}
// H算子作用于一维数据
void CWavelet1DDlg::HOperatorOn(int filterlen, int start, int len,int level)
{
int i,i2,m,k,len1;
double temp1;
m=m_nFilterLen/2;
len1=len>>1;
for(i=0;i<len1;i++)
{
i2=2*i;
Data[level][i+start]=0;
if(len>filterlen)
{
for(k=i2-len;k<=i2-len+m;k++)
{
if((k>=0)&&(k<len))
if((temp1=ph[(k-i2+len)%len])!=0)
Data[level][i+start]+=temp1*Data[level-1][k+start];
}
for(k=i2-m+1;k<=i2+m;k++)
{
if((k>=0)&&(k<len))
if((temp1=ph[(k-i2+len)%len])!=0)
Data[level][i+start]+=temp1*Data[level-1][k+start];
}
for(k=i2+len-m+1;k<=i2+len;k++)
{
if((k>=0)&&(k<len))
if((temp1=ph[(k-i2+len)%len])!=0)
Data[level][i+start]+=temp1*Data[level-1][k+start];
}
}
else
{
for(k=0;k<len;k++)
{
if((temp1=ph[(k-i2+len)%len])!=0)
Data[level][i+start]+=temp1*Data[level-1][k+start];
}
}
}
}
// G算子作用于一维数据
void CWavelet1DDlg::GOperatorOn(int filterlen, int start, int len,int level)
{
int i,i2,m,k,len1;
double temp1;
m=m_nFilterLen/2;
len1=len>>1;
for(i=0;i<len1;i++)
{
i2=2*i;
Data[level][i+start+len1]=0;
if(len>filterlen)
{
for(k=i2-len;k<=i2-len+m+2;k++)
{
if((k>=0)&&(k<len))
if((temp1=pg[(k-i2+len)%len])!=0)
Data[level][i+start+len1]+=temp1*Data[level-1][k+start];
}
for(k=i2-m+3;k<=i2+m+2;k++)
{
if((k>=0)&&(k<len))
if((temp1=pg[(k-i2+len)%len])!=0)
Data[level][i+start+len1]+=temp1*Data[level-1][k+start];
}
for(k=i2+len-m+3;k<=i2+len;k++)
{
if((k>=0)&&(k<len))
if((temp1=pg[(k-i2+len)%len])!=0)
Data[level][i+start+len1]+=temp1*Data[level-1][k+start];
}
}
else
{
for(k=0;k<len;k++)
{
if((temp1=pg[(k-i2+len)%len])!=0)
Data[level][i+start+len1]+=temp1*Data[level-1][k+start];
}
}
}
}
// 对一维数据进行level层小波变换
BOOL CWavelet1DDlg::DecompStage(int level, int filterlen)
{
int start,len;
len=(m_nImageWidth+m_nImageHeight)>>(level-1);
start=0;
if((!HHH(level-1,m_nImageWidth+m_nImageHeight))||(!GGG(level-1,m_nImageWidth+m_nImageHeight)))
return FALSE;
HOperatorOn(filterlen,start,len,level);
GOperatorOn(filterlen,start,len,level);
if(ph&&pg)
{
delete ph;
delete pg;
ph=NULL;
pg=NULL;
}
return TRUE;
}
// 绘制m_nDisplayStage指定层次的小波变换结果
void CWavelet1DDlg::DrawWavelet1D()
{
// 创建绘图所需资源
int Ox=0,Oy=0;
int Ox1=0,Oy1=0,Ox2=0,Oy2=0;
CString Text=_T("");
CPen *OldPen,PenWhite,PenGreen,PenBlue,Pen;
CPen* OldPen2;
PenWhite.CreatePen(PS_SOLID,1,0x00FFFFFF);
PenGreen.CreatePen(PS_SOLID,1,0x0000FF00);
PenBlue.CreatePen(PS_SOLID,1,0x00FF0000);
Pen.CreatePen(PS_SOLID,1,0x00FFFFFF);
CDC* pDC=GetDC();
CRect RectClient,Workarea;
GetClientRect(RectClient);
// 锁定DIB
lpDIB = (LPSTR)::GlobalLock((HGLOBAL) GetHDIB());
// 在对话框右上部分绘制原始数据图像及二值化后点阵投影图像
int temp;
int i,j;
// 创建绘制区
Workarea.left=RectClient.left+(RectClient.right-RectClient.left)/5*2;
Workarea.right=RectClient.right-10;
Workarea.top=RectClient.top+10;
Workarea.bottom=RectClient.top+(RectClient.bottom-RectClient.top-10)/2+40;
pDC->Rectangle(Workarea);
pDC->SetBkColor(0x00FFFFFF);
// 绘制坐标轴
Ox = Workarea.left+20; Oy = Workarea.bottom-20;
pDC->MoveTo(Ox,Oy);
pDC->LineTo(Ox,Workarea.top+10);
pDC->MoveTo(Ox,Oy);
pDC->LineTo(Workarea.right-10,Oy);
// 绘制二值化后数据图像
Ox1= Ox+m_nImageWidth; Oy1= Oy-m_nImageHeight;
pDC->MoveTo(Ox1,Oy1);
pDC->LineTo(Ox1,Oy1-m_nImageHeight);
pDC->LineTo(Ox1+m_nImageWidth,Oy1-m_nImageHeight);
pDC->LineTo(Ox1+m_nImageWidth,Oy1);
pDC->LineTo(Ox1,Oy1);
pDC->SetTextColor(0x000000FF);
pDC->TextOut(Ox,Workarea.top+3,"原始数据图像二值化及投影图");
OldPen=pDC->SelectObject(&PenBlue);
for(i=0;i<m_nImageHeight;i++)
for(j=0;j<m_nImageWidth;j++)
{
temp=*((unsigned char *)lpDIBBits+m_nImageWidth*i+j);
if(temp<=m_nBinGate)
{
*((unsigned char *)lpDIBBits+m_nImageWidth*i+j)=0;
pDC->MoveTo(Ox1+j,Oy1-i);
pDC->LineTo(Ox1+j,Oy1-i-2);
OldPen2=pDC->SelectObject(&PenWhite);
pDC->LineTo(Ox1+j,Oy1-i-1);
pDC->SelectObject(OldPen2);
}
else
{
*((unsigned char *)lpDIBBits+m_nImageWidth*i+j)=255;
}
}
// 绘制垂直和水平方向的投影
for(i=0;i<m_nImageHeight;i++)
{
temp=Data[0][i];
pDC->MoveTo(Ox,Oy1-i);
pDC->LineTo(Ox+temp,Oy1-i);
}
for(j=0;j<m_nImageWidth;j++)
{
temp=Data[0][m_nImageHeight+j];
pDC->MoveTo(Ox1+j,Oy);
pDC->LineTo(Ox1+j,Oy-temp);
}
pDC->SelectObject(OldPen);
// 在对话框右下部分绘制小波变换后第m_nDisplayStage层数据图像
int DataLen=0;
double XUnit=1,YUnit=1,tempX=0,tempY=0;
int temp1=0,temp2=0;
double max=0,min=0,scale=0;
// 创建绘制区
Workarea.left=RectClient.left+(RectClient.right-RectClient.left)/5*2;
Workarea.right=RectClient.right-10;
Workarea.top=RectClient.top+10+(RectClient.bottom-RectClient.top-10)/2+40;
Workarea.bottom=RectClient.bottom-10;
pDC->Rectangle(Workarea);
pDC->SetBkColor(0x00FFFFFF);
// 绘制坐标轴
Ox = Workarea.left+20; Oy = Workarea.bottom-20;
pDC->MoveTo(Ox,Oy);
pDC->LineTo(Ox,Workarea.top+10);
pDC->MoveTo(Ox,Oy);
pDC->LineTo(Workarea.right-10,Oy);
// 归一化小波变换后数据并绘制
max=Data[m_nDisplayStage][0];
min=Data[m_nDisplayStage][0];
for(j=0;j<m_nImageWidth+m_nImageHeight;j++)
{
if(max<Data[m_nDisplayStage][j])
max=Data[m_nDisplayStage][j];
if(min>Data[m_nDisplayStage][j])
min=Data[m_nDisplayStage][j];
}
scale=max-min;
XUnit=double(Workarea.right-Workarea.left-30)/double(m_nImageHeight+m_nImageWidth);
YUnit=double(Workarea.bottom-Workarea.top-30-10)/scale;
if(min>0)
scale=0;
else
scale=(0-min)*YUnit;
pDC->MoveTo(Ox,Oy-scale);
pDC->LineTo(Workarea.right-10,Oy-scale);
pDC->SetTextColor(0x000000FF);
pDC->TextOut(Ox-10,Oy-scale-6,"O");
Text.Format("Max:%f Min:%f",max,min);
pDC->TextOut(Ox+10,Workarea.top+5,Text);
pDC->SelectObject(&PenBlue);
for(j=0;j<m_nImageWidth+m_nImageHeight-1;j++)
{
tempX=j*XUnit;
tempY=(Data[m_nDisplayStage][j]-min)*YUnit;
pDC->MoveTo(tempX+Ox,Oy-tempY);
tempX=(j+1)*XUnit;
tempY=(Data[m_nDisplayStage][j+1]-min)*YUnit;
pDC->LineTo(tempX+Ox,Oy-tempY);
}
pDC->SelectObject(OldPen);
// 绘制说明文字如C0,D0等
DataLen=m_nImageWidth+m_nImageHeight;
for(j=0;j<=m_nDisplayStage;j++)
{
temp1=temp2;
temp2=DataLen>>(m_nDisplayStage-j);
tempX=(temp2-1)*XUnit;
tempY=(Data[m_nDisplayStage][temp2-1]-min)*YUnit;
pDC->MoveTo(tempX+Ox,Oy-tempY);
pDC->LineTo(tempX+Ox,Oy);
if(j==0)
Text.Format("C%d",m_nDisplayStage);
else
Text.Format("D%d",m_nDisplayStage+1-j);
tempX=((temp2-temp1-1)/2+temp1)*XUnit-5;
pDC->SetTextColor(0x000000FF);
pDC->TextOut(Ox+tempX,Oy+3,Text);
}
// 释放资源
PenWhite.DeleteObject();
PenGreen.DeleteObject();
PenBlue.DeleteObject();
Pen.DeleteObject();
// 解除锁定
::GlobalUnlock((HGLOBAL)GetHDIB());
}
// Hn系数文件产生函数,因为Hn文件只需产生一次,所以程序中并没有使用此函数。
// 若要重新产生Hn文件,读者可以调用此函数。
BOOL CWavelet1DDlg::GenerateHnFile()
{
double Hn[10][20] ={ {0,0},
{ 0.4829629131445341, 0.8365163037378077, 0.2241438680420134,
-0.1294095225512603 },
{ 0.3326705529500825, 0.8068915093110924, 0.4598775021184914,
-0.1350110200102546,-0.0854412738820267, 0.0352262918857095 },
{ 0.2303778133088964, 0.7148465705529154, 0.6308807679398587,
-0.0279837694168599,-0.1870348117190931, 0.0308413818355607,
0.0328830116668852,-0.0105974017850890 },
{ 0.1601023979741929, 0.6038292697971895, 0.7243085284377726,
0.1384281459013203,-0.2422948870663823,-0.0322448695846381,
0.0775714938400459,-0.0062414902127983,-0.0125807519990820,
0.0033357252854738 },
{ 0.1115407433501095, 0.4946238903984533, 0.7511339080210959,
0.3152503517091982,-0.2262646939654400,-0.1297668675672625,
0.0975016055873225, 0.0275228655303053,-0.0315820393174862,
0.0005538422011614, 0.0047772575109455, 0.0010773010853085 },
{ 0.0778520540850037, 0.3965393194818912, 0.7291320908461957,
0.4697822874051889,-0.1439060039285212,-0.2240361549938412,
0.0713092192668272, 0.0806123091510774,-0.0380299369350104,
-0.0165745416306655, 0.0125509985560986, 0.0004295779729214,
-0.0018016407040473, 0.0003537137999745 },
{ 0.0544158422431072, 0.3128715909143166, 0.6756307362973195,
0.5852546836542159,-0.0158291052563823,-0.2840155429615824,
0.0004724845739124, 0.1287474266204893,-0.0173693010018090,
-0.0440882539307971, 0.0139810279174001, 0.0087160940474065,
-0.0048703529934520,-0.0003917403733770, 0.0006754494064506,
-0.0001174767841248 },
{ 0.0380779473638778, 0.2438346746125858, 0.6048231236900955,
0.6572880780512736, 0.1331973858249883,-0.2932737832791663,
-0.0968407832229492, 0.1485407493381256, 0.0307256814793385,
-0.0676328290613279, 0.0002509471148340, 0.0223616621236798,
-0.0047232047577518,-0.0042815036824635, 0.0018476468830563,
0.0002303857645232,-0.0002519631889427, 0.0000393473203163 },
{ 0.0266700579005473, 0.1881768000776347, 0.5272011889315757,
0.6884590394534363, 0.2811723436605715,-0.2498464243271598,
-0.1959462743772862, 0.1273693403357541, 0.0930573646035547,
-0.0713941471663501,-0.0294575368218399, 0.0332126740593612,
0.0036065535669870,-0.0107331754833007, 0.0013953517470688,
0.0019924052951925,-0.0006858566949564,-0.001164668551285,
0.0000935886703202,-0.0000132642028945 },
};
BOOL flag=TRUE;
FILE *fp;
int i,j;
for(i=0;i<10;i++)
{
if((fp=fopen(m_strFilterFile[i],"wb+"))==NULL)
{
AfxMessageBox("Hn算子文件生成失败!",MB_OK|MB_ICONINFORMATION);
flag=FALSE;
break;
}
for(j=0;j<2*(i+1);j++)
fwrite(&Hn[i][j],sizeof(double),1,fp);
fclose(fp);
}
return flag;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -