WaveTranform.cpp
上传用户:aqingfeng
上传日期:2014-03-25
资源大小:1839k
文件大小:18k
- // WaveTranform.cpp: implementation of the CWaveTranform class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "小波变换.h"
- #include "WaveTranform.h"
- #include "DIBAPI.h"
- #include "Diproc.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;// 返回
- }
- /*************************************************************************
- *
- * 函数名称:
- * DIBDisWavelet()
- *
- * 参数:
- * LPSTR lpDIB - 指向DIB图像指针
- * LPSTR lpDIBBits - 指向源DIB象素指针
- * double *LF - 使用的小波尺度函数,是常量
- * double *HF - 使用的小波母函数,是常量
- * int FWidth - 小波窗的宽度
- * int nLevel - 小波分解的层数
- *
- * 返回值:
- * BOOL - 成功返回TRUE,否则返回FALSE。
- *
- * 说明:
- * 该函数用来对图像进行小波变换重建。于上面不同的是,此处是将二维
- * 矩阵转换成一个列向量,然后对该列向量进行一次一维小波变换。
- *
- ************************************************************************/
- BOOL CWaveTranform::DIBDisWavelet(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);// 给时域赋值
- //将规划处理后的值变回原样
- f[i*lWidth+j]=(m_GrayMax-m_GrayMin)/255*f[i*lWidth+j]+m_GrayMin;
- }
- }
- int n;//层数循环变量
- //小波变换重建过程循环
- for(n=nLevel-1;n>=0;n--)
- {
- LONG Height,Width;
- Height=long(lHeight/pow(2,n));
- Width=long(lWidth/pow(2,n));
- double *H00=new double[Height]; //按列存放低低元素
- double *H01=new double[Height]; //按列存放低高元素
- double *H10=new double[Height]; //按列存放高低元素
- double *H11=new double[Height]; //按列存放高高元素
- for(i = 0; i < Width/2; i++)
- {
- for(j=0;j<Height/2;j++)
- {
- H00[2*j]=f[i+j*lWidth];
- H00[2*j+1]=0;
- }
- for(j=Height/2;j<Height;j++)
- {
- H01[2*j-Height]=f[i+j*lWidth];
- H01[2*j-Height+1]=0;
- }
- DisConvolution( LF,HF, FWidth,H00,H01 ,Height);// 对y方向进行解内积运算
- for(j=0;j<Height;j++)
- {
- f[i+j*lWidth]=H00[j];
- }
- }
- for(i =Width/2 ; i < Width; i++)
- {
- for(j=0;j<Height/2;j++)
- {
- H10[2*j]=f[i+j*lWidth];
- H10[2*j+1]=0;
- }
- for(j=Height/2;j<Height;j++)
- {
- H11[2*j-Height]=f[i+j*lWidth];
- H11[2*j-Height+1]=0;
- }
- DisConvolution( LF,HF, FWidth,H10,H11, Height); // 对y方向进行解内积运算
- for(j=0;j<Height;j++)
- {
- f[i+j*lWidth]=H10[j];
- }
- }
- delete H00,H01,H10,H11;//释放内存
- double *H0=new double[Width]; //按行存放低元素
- double *H1=new double[Width]; //按行存放高元素
- for(i = 0; i < Height; i++)
- {
- for(j=0;j<Width/2;j++)
- {
- H0[2*j]=f[i*lWidth+j];
- H0[2*j+1]=0;
- }
- for(j=Width/2;j<Width;j++)
- {
- H1[2*j-Width]=f[i*lWidth+j];
- H1[2*j-Width+1]=0;
- }
- DisConvolution( LF,HF, FWidth,H0,H1, Width);// 对x方向进行解卷积运算
- for(j=0;j<Width;j++)
- {
- f[i*lWidth+j]=H0[j];
- }
- }
- delete H0,H1;
- }
- // 更新源图像
- for(i = 0; i < lHeight; i++)// 每列
- {
- for(j = 0; j < lWidth; j++)// 每行
- {
- dTemp = f[i * lWidth + j]; // 计算频谱
- if (dTemp > 255)
- dTemp = 255;
- if(dTemp < 0)
- dTemp=0;
- 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);// 给时域赋值
- //将规划处理后的值变回原样
- f[i*lWidth+j]=(m_ColorMax[ncolor]-m_ColorMin[ncolor])/255*f[i*lWidth+j]+m_ColorMin[ncolor];
- }
- }
- int n;//层数循环变量
- //小波变换重建过程循环
- for(n=nLevel-1;n>=0;n--)
- {
- LONG Height,Width;
- Height=long(lHeight/pow(2,n));
- Width=long(lWidth/pow(2,n));
- double *H00=new double[Height]; //按列存放低低元素
- double *H01=new double[Height]; //按列存放低高元素
- double *H10=new double[Height]; //按列存放高低元素
- double *H11=new double[Height]; //按列存放高高元素
- for(i = 0; i < Width/2; i++)
- {
- for(j=0;j<Height/2;j++)
- {
- H00[2*j]=f[i+j*lWidth];
- H00[2*j+1]=0;
- }
- for(j=Height/2;j<Height;j++)
- {
- H01[2*j-Height]=f[i+j*lWidth];
- H01[2*j-Height+1]=0;
- }
- DisConvolution( LF,HF, FWidth,H00,H01 ,Height);// 对y方向进行解内积运算
- for(j=0;j<Height;j++)
- {
- f[i+j*lWidth]=H00[j];
- }
- }
- for(i =Width/2 ; i < Width; i++)
- {
- for(j=0;j<Height/2;j++)
- {
- H10[2*j]=f[i+j*lWidth];
- H10[2*j+1]=0;
- }
- for(j=Height/2;j<Height;j++)
- {
- H11[2*j-Height]=f[i+j*lWidth];
- H11[2*j-Height+1]=0;
- }
- DisConvolution( LF,HF, FWidth,H10,H11, Height); // 对y方向进行解内积运算
- for(j=0;j<Height;j++)
- {
- f[i+j*lWidth]=H10[j];
- }
- }
- delete H00,H01,H10,H11;//释放内存
- double *H0=new double[Width]; //按行存放低元素
- double *H1=new double[Width]; //按行存放高元素
- for(i = 0; i < Height; i++)
- {
- for(j=0;j<Width/2;j++)
- {
- H0[2*j]=f[i*lWidth+j];
- H0[2*j+1]=0;
- }
- for(j=Width/2;j<Width;j++)
- {
- H1[2*j-Width]=f[i*lWidth+j];
- H1[2*j-Width+1]=0;
- }
- DisConvolution( LF,HF, FWidth,H0,H1, Width);// 对x方向进行解卷积运算
- for(j=0;j<Width;j++)
- {
- f[i*lWidth+j]=H0[j];
- }
- }
- delete H0,H1;
- }
- // 更新源图像
- for(i = 0; i < lHeight; i++)// 每列
- {
- for(j = 0; j < lWidth; j++)// 每行
- {
- dTemp = f[i * lWidth + j]; // 计算频谱
- if (dTemp > 255)
- dTemp = 255;
- if(dTemp < 0)
- dTemp=0;
- lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + 3*j+ncolor;// 指向DIB第i行,第j个象素的指针
- * (lpSrc) = (BYTE)(dTemp);// 更新源图像
- }
- }
- }
- }
- delete f;//释放内存
- return TRUE;// 返回
- }
- void CWaveTranform::DIP_ImageFusion2(LPSTR lpDIB1,LPSTR lpDIBBits1,LPSTR lpDIB2,LPSTR lpDIBBits2,int nlever)
- {
- unsigned char* lpSrc;// 指向源图像的指针
- double dTemp;// 中间变量
- LONG lLineBytes; // 图像每行的字节数
- LONG lWidth,lHeight;
- lWidth=::DIBWidth(lpDIB1);
- lHeight=::DIBHeight(lpDIB1);
- LONG i,j;//循环变量
- double *f1 = new double[lWidth*lHeight];// 分配内存
- double *f2 = new double[lWidth*lHeight];
- int N=lWidth*lHeight;
- int x,y;
- int dd=(int)pow(2,nlever);
- int nw=lWidth/dd;
- int nh=lHeight/dd;
- int p1,p2;
- if((::DIBNumColors(lpDIB1)==256)&&(::DIBNumColors(lpDIB2)==256))
- {
- lLineBytes = WIDTHBYTES(lWidth * 8);// 计算图像每行的字节数
- // 从源图像1中读取数据。
- for(i = 0; i < lHeight; i++)// 每列
- {
- for(j = 0; j < lWidth; j++)// 每行
- {
- lpSrc = (unsigned char*)lpDIBBits1 + lLineBytes * (lHeight - 1 - i) +j; // 指向DIB第i行,第j个象素的指针
- f1[i*lWidth+j] = *(lpSrc);// 给时域赋值
- //将规划处理后的值变回原样
- f1[i*lWidth+j]=(m_GrayMax-m_GrayMin)/255*f1[i*lWidth+j]+m_GrayMin;
- }
- }
- // 从源图像1中读取数据。
- for(i = 0; i < lHeight; i++)// 每列
- {
- for(j = 0; j < lWidth; j++)// 每行
- {
- lpSrc = (unsigned char*)lpDIBBits2 + lLineBytes * (lHeight - 1 - i) +j; // 指向DIB第i行,第j个象素的指针
- f2[i*lWidth+j] = *(lpSrc);// 给时域赋值
- //将规划处理后的值变回原样
- f2[i*lWidth+j]=(m_GrayMax-m_GrayMin)/255*f2[i*lWidth+j]+m_GrayMin;
- }
- }
- for(i=0;i<N;i++)
- {
- p1=f1[i];
- p2=f2[i];
- x=i%lWidth;
- y=i/lWidth;
- if((x<nw)&&(y<nh))
- {
- f1[i]=(p1+p2)/2;
- }
- else
- {
- f1[i]=(abs(p1)>abs(p2))?p1:p2;
- }
- }
- //更新图像源
- for(i = 0; i < lHeight; i++)// 每列
- {
- for(j = 0; j < lWidth; j++)// 每行
- {
- dTemp = f1[i * lWidth + j]; // 计算频谱
- dTemp=255/(m_GrayMax-m_GrayMin)*(dTemp-m_GrayMin);
- lpSrc = (unsigned char*)lpDIBBits1 + 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*)lpDIBBits1 + lLineBytes * (lHeight - 1 - i) +3*j+ncolor; // 指向DIB第i行,第j个象素的指针
- f1[i*lWidth+j] = *(lpSrc);// 给时域赋值
- //将规划处理后的值变回原样
- f1[i*lWidth+j]=(m_ColorMax[ncolor]-m_ColorMin[ncolor])/255*f1[i*lWidth+j]+m_ColorMin[ncolor];
- }
- }
- // 从源图像中读取数据。
- for(i = 0; i < lHeight; i++)// 每列
- {
- for(j = 0; j < lWidth; j++)// 每行
- {
- lpSrc = (unsigned char*)lpDIBBits2 + lLineBytes * (lHeight - 1 - i) +3*j+ncolor; // 指向DIB第i行,第j个象素的指针
- f2[i*lWidth+j] = *(lpSrc);// 给时域赋值
- //将规划处理后的值变回原样
- f2[i*lWidth+j]=(m_ColorMax[ncolor]-m_ColorMin[ncolor])/255*f2[i*lWidth+j]+m_ColorMin[ncolor];
- }
- }
- for(i=0;i<N;i++)
- {
- p1=f1[i];
- p2=f2[i];
- x=i%lWidth;
- y=i/lWidth;
- if((x<nw)&&(y<nh))
- {
- f1[i]=(p1+p2)/2;
- }
- else
- {
- f1[i]=(abs(p1)>abs(p2))?p1:p2;
- }
- }
- for(i = 0; i < lHeight; i++)// 每列
- {
- for(j = 0; j < lWidth; j++)// 每行
- {
- dTemp = f1[i * lWidth + j]; // 计算频谱
- dTemp=255/(m_ColorMax[ncolor]-m_ColorMin[ncolor])*(dTemp-m_ColorMin[ncolor]);
- lpSrc = (unsigned char*)lpDIBBits1 + lLineBytes * (lHeight - 1 - i) + 3*j+ncolor;// 指向DIB第i行,第j个象素的指针
- * (lpSrc) = (BYTE)(dTemp);// 更新源图像
- }
- }
- }
- delete f1;//释放内存
- delete f2;//释放内存
- }
- }