www.pudn.com > ImgFFT.zip > Pro2View.cpp


// Pro2View.cpp : implementation of the CPro2View class
//

#include "stdafx.h"
#include "Pro2.h"

#include "Pro2Doc.h"
#include "Pro2View.h"
#include "CDib.h"
#include "DialogIm.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPro2View

IMPLEMENT_DYNCREATE(CPro2View, CView)

BEGIN_MESSAGE_MAP(CPro2View, CView)
//{{AFX_MSG_MAP(CPro2View)
ON_COMMAND(ID_LINEAR, OnLinear)
ON_COMMAND(ID_STATISTIC, OnStatistic)
ON_COMMAND(ID_BALANCE, OnBalance)
ON_COMMAND(ID_SMOOTH, OnSmooth)
ON_COMMAND(ID_MIXFILTER, OnMixfilter)
ON_COMMAND(ID_DEFINITION, OnDefinition)
ON_COMMAND(ID_PICFILE, OnPicfile)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPro2View construction/destruction

CPro2View::CPro2View()
{
// TODO: add construction code here
m_nSupp=3;
m_nDWTCurDepth=0;
m_pDbImage=NULL;
m_nInv=0;
m_bOne=TRUE;
m_nRGBBit=3;
m_sFile=_T("f:\\zhj\\picture\\za.bmp");

//the below is a strange phenomena that in CString, the character '\' is viewed as '\\',
//but in CString ,the successional character '\\' is viewed as '\'. It's so confusing.
// char u='\\';
// u=m_sFile[2];
// u=m_sFile[3];
//

}

CPro2View::~CPro2View()
{
}

BOOL CPro2View::PreCreateWindow(CREATESTRUCT&amt; cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs

return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CPro2View drawing

void CPro2View::OnDraw(CDC* pDC)
{
CPro2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CPoint orig;
CSize si;

orig.x=10;
orig.y=10;
si.cx=600;
si.cy=600;

Dib.Draw(pDC,orig,si);
}

/////////////////////////////////////////////////////////////////////////////
// CPro2View printing

BOOL CPro2View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}

void CPro2View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}

void CPro2View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CPro2View diagnostics

#ifdef _DEBUG
void CPro2View::AssertValid() const
{
CView::AssertValid();
}

void CPro2View::Dump(CDumpContext&amt; dc) const
{
CView::Dump(dc);
}

CPro2Doc* CPro2View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPro2Doc)));
return (CPro2Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CPro2View message handlers
//////////////////////////////////////////////////////////////////////////////
//calculate Log2

BYTE CPro2View::FloatToByte(double f)
{
if(f<=0) return (BYTE)0;
else if(f>=255) return (BYTE)255;
else return (BYTE)(f+0.5);
}

char CPro2View::FloatToChar(double f)
{
if(f>=0)
if(f>=127.0)
return (char)127;
else return (char)(f+0.5);
else
if(f<=-128)
return (char)-128;
else return -(char)(-f+0.5);
}

//************************************linear
void CPro2View::OnLinear()
{
// TODO: Add your command handler code here
pFile=new CFile(m_sFile,CFile::modeReadWrite|CFile::typeBinary);

Dib.Read(pFile);
Dib.MakePalette();

Linear(&amt;Dib,0,150,0,255);

if(m_bOne)
pFile->Close();

Invalidate();

}

BOOL CPro2View::Linear(CDib* pDib,int Upper1,int Lower1,int Upper2,int Lower2)
{
int i,j;
int nWidth=pDib->m_lpBMIH->biWidth;
int nHeight=pDib->m_lpBMIH->biHeight;

switch(pDib->m_lpBMIH->biBitCount)
{
case 24:
m_nRGBBit=3;
break;
case 32:
m_nRGBBit=4;
break;
default:
m_nRGBBit=3;
}

CSize sizeImageSave=pDib->GetDibSaveDim();

double *pDbTemp;
BYTE *pBits;
int nRGB=0;

if(!m_pDbImage) {
m_pDbImage=new double[nWidth*nHeight];
if(!m_pDbImage) return FALSE;

}

//get data of the source DIB
for(nRGB=0;nRGB<3;nRGB++)
{

for(j=0;j<nHeight;j++)
{
pDbTemp=m_pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
//yes, the below is to get one color value among B,G,R.
pDbTemp[i]=(double)(*(pBits+i*m_nRGBBit));
}
}

for(int m=0;m<nHeight;m++)
{
pDbTemp=m_pDbImage+m*nWidth;
for(int n=0;n<nWidth;n++)
{
pDbTemp[n]=(pDbTemp[n]-Lower1)*(Upper2-Lower2)/(Upper1-Lower1)+Lower2;//m_pDbImage[n+m*nWidth]=m_pDbImage[n+m*nWidth]+150;
}
}

for(j=0;j<nHeight;j++)
{
pDbTemp=m_pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
*(pBits+i*m_nRGBBit)=FloatToByte(pDbTemp[i]);
}
}

}

return TRUE;
}

//************************************Statistic
BOOL CPro2View::StatChart(CDib* pDib)
{
int i,j;
int nWidth=pDib->m_lpBMIH->biWidth;
int nHeight=pDib->m_lpBMIH->biHeight;

switch(pDib->m_lpBMIH->biBitCount)
{
case 24:
m_nRGBBit=3;
break;
case 32:
m_nRGBBit=4;
break;
default:
m_nRGBBit=3;
}

CSize sizeImageSave=pDib->GetDibSaveDim();

unsigned char* pDbTemp;
unsigned char* pDbImage;
BYTE *pBits;
int nRGB=0;

pDbImage=new unsigned char[nWidth*nHeight];

if(!pDbImage) return FALSE;

//get data of the source DIB
for(nRGB=0;nRGB<1;nRGB++)
{

for(j=0;j<nHeight;j++)
{
pDbTemp=pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
//yes, the below is to get one color value among B,G,R.
pDbTemp[i]=(unsigned char)(*(pBits+i*m_nRGBBit));
}
}

unsigned char* lpSrc;

for(int m=0;m<nHeight;m++)
{
pDbTemp=pDbImage+m*nWidth;
for(int n=0;n<nWidth;n++)
{
lpSrc=(unsigned char*)pDbImage+m*nWidth+n;
m_Chart.m_nStat[*(lpSrc)]=m_Chart.m_nStat[*(lpSrc)]+1;
}
}

/* for(j=0;j<nHeight;j++)
{
pDbTemp=m_pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
*(pBits+i*m_nRGBBit)=FloatToByte(pDbTemp[i]);
}
}
*/
}

delete pDbImage;

return TRUE;
}


void CPro2View::OnStatistic()
{
// TODO: Add your command handler code here

pFile=new CFile(m_sFile,CFile::modeReadWrite|CFile::typeBinary);

Dib.Read(pFile);
Dib.MakePalette();

StatChart(&amt;Dib);

m_Chart.DoModal();

pFile->Close();

Invalidate();
}

//************************************Balance
void CPro2View::OnBalance()
{
// TODO: Add your command handler code here

pFile=new CFile(m_sFile,CFile::modeReadWrite|CFile::typeBinary);

Dib.Read(pFile);
Dib.MakePalette();

Balance(&amt;Dib);

m_Chart.DoModal();

pFile->Close();
Invalidate();
}

BOOL CPro2View::Balance(CDib* pDib)
{
int i,j;
int m,n;
int nWidth=pDib->m_lpBMIH->biWidth;
int nHeight=pDib->m_lpBMIH->biHeight;

switch(pDib->m_lpBMIH->biBitCount)
{
case 24:
m_nRGBBit=3;
break;
case 32:
m_nRGBBit=4;
break;
default:
m_nRGBBit=3;
}

CSize sizeImageSave=pDib->GetDibSaveDim();

unsigned char* pDbTemp;
unsigned char* pDbImage;
BYTE *pBits;
int nRGB=0;

pDbImage=new unsigned char[nWidth*nHeight];

if(!pDbImage) return FALSE;

//get data of the source DIB
for(nRGB=0;nRGB<1;nRGB++)
{

for(j=0;j<nHeight;j++)
{
pDbTemp=pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
//yes, the below is to get one color value among B,G,R.
pDbTemp[i]=(unsigned char)(*(pBits+i*m_nRGBBit));
}
}

unsigned char* lpSrc;

for(i=0;i<256;i++)
{
m_Chart.m_nStat[i]=0;
}

for(m=0;m<nHeight;m++)
{
for(n=0;n<nWidth;n++)
{
lpSrc=(unsigned char*)pDbImage+m*nWidth+n;
m_Chart.m_nStat[*(lpSrc)]=m_Chart.m_nStat[*(lpSrc)]+1;
}
}

int nTemp;

for(i=0;i<256;i++)
{
nTemp=0;
for(j=0;j<i;j++)
{
nTemp+=m_Chart.m_nStat[j];
}
m_bal[i]=(BYTE)(nTemp*255/(nWidth*nHeight));
}

for(j=0;j<nHeight;j++)
{
for(i=0;i<nWidth;i++)
{
lpSrc=(unsigned char*)pDbImage+j*nWidth+i;
*lpSrc=m_bal[*lpSrc];
}
}

for(j=0;j<nHeight;j++)
{
pDbTemp=pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
*(pBits+i*m_nRGBBit)=pDbTemp[i];
}
}

for(i=0;i<256;i++)
{
m_Chart.m_nStat[i]=0;
}

for(m=0;m<nHeight;m++)
{
for(n=0;n<nWidth;n++)
{
lpSrc=(unsigned char*)pDbImage+m*nWidth+n;
m_Chart.m_nStat[*(lpSrc)]=m_Chart.m_nStat[*(lpSrc)]+1;
}
}

}

delete pDbImage;

return TRUE;
}

//************************************Smooth
void CPro2View::OnSmooth()
{
// TODO: Add your command handler code here

pFile=new CFile(m_sFile,CFile::modeReadWrite|CFile::typeBinary);

Dib.Read(pFile);
Dib.MakePalette();

double model[9]={1.0,2.0,1.0,2.0,4.0,2.0,1.0,2.0,1.0};
double coef;
coef=1.0/16.0;

GeneralTemplate(&amt;Dib,3,3,1,1,model,coef);

// m_Chart.DoModal();

pFile->Close();
Invalidate();

}

BOOL CPro2View::GeneralTemplate(CDib* pDib,int nTempWidth,int nTempHeight,int nTempCenX,int nTempCenY,double* pdbTemp,double dbCoef)
{
int i,j;
int nWidth=pDib->m_lpBMIH->biWidth;
int nHeight=pDib->m_lpBMIH->biHeight;

switch(pDib->m_lpBMIH->biBitCount)
{
case 24:
m_nRGBBit=3;
break;
case 32:
m_nRGBBit=4;
break;
default:
m_nRGBBit=3;
}

CSize sizeImageSave=pDib->GetDibSaveDim();

unsigned char* pDbTemp;
unsigned char* pDbImage;
BYTE *pBits;
int nRGB=0;

pDbImage=new unsigned char[nWidth*nHeight];

if(!pDbImage) return FALSE;

//get data of the source DIB
for(nRGB=0;nRGB<3;nRGB++)
{

for(j=0;j<nHeight;j++)
{
pDbTemp=pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
//yes, the below is to get one color value among B,G,R.
pDbTemp[i]=(unsigned char)(*(pBits+i*m_nRGBBit));
}
}

unsigned char* lpSrc;
unsigned char* lpDst;
double dbResult;

for(i=nTempCenY;i<nHeight-nTempHeight+nTempCenY+1;i++)
{
for(j=nTempCenX;j<nWidth-nTempWidth+nTempCenX+1;j++)
{
lpDst=(unsigned char*)pDbImage+i*nWidth+j;

dbResult=0;

for(int k=0;k<nTempHeight;k++)
{
for(int l=0;l<nTempWidth;l++)
{
lpSrc=(unsigned char*)pDbImage+(i-nTempCenY+k)*nWidth+(j-nTempCenX+l);
dbResult+=(*lpSrc)*pdbTemp[k*nTempWidth+l];
}
}

dbResult*=dbCoef;

dbResult=(double)fabs(dbResult);

if(dbResult>255)
*lpDst=255;
else
*lpDst=(unsigned char)(dbResult+0.5);
}
}


for(j=0;j<nHeight;j++)
{
pDbTemp=pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
*(pBits+i*m_nRGBBit)=pDbTemp[i];
}
}

}

delete pDbImage;

return TRUE;

}


//************************************Mixfilter
void CPro2View::OnMixfilter()
{
// TODO: Add your command handler code here

pFile=new CFile(m_sFile,CFile::modeReadWrite|CFile::typeBinary);

Dib.Read(pFile);
Dib.MakePalette();

Filter(&amt;Dib);

pFile->Close();
Invalidate();
}

BOOL CPro2View::Filter(CDib* pDib)
{
CPro2Doc* pDoc=GetDocument();

int i,j;
int m,n;

double nRadius=100.0;
int nGet=0;
double H=0.0;

int nWidth=pDib->m_lpBMIH->biWidth;
int nHeight=pDib->m_lpBMIH->biHeight;

switch(pDib->m_lpBMIH->biBitCount)
{
case 24:
m_nRGBBit=3;
break;
case 32:
m_nRGBBit=4;
break;
default:
m_nRGBBit=3;
}

CSize sizeImageSave=pDib->GetDibSaveDim();

double *pDbTemp;
BYTE *pBits;
int nRGB=0;

if(!m_pDbImage) {
m_pDbImage=new double[nWidth*nHeight];
if(!m_pDbImage) return FALSE;

}

//get data of the source DIB
for(nRGB=0;nRGB<3;nRGB++)
{

for(j=0;j<nHeight;j++)
{
pDbTemp=m_pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
//yes, the below is to get one color value among B,G,R.
pDbTemp[i]=(double)(*(pBits+i*m_nRGBBit));
}
}

//*****************************
//
for(m=0;m<nHeight;m++)
{
pDbTemp=m_pDbImage+m*nWidth;
for(n=0;n<nWidth;n++)
{
if(pDbTemp[n]==0)
continue;

pDbTemp[n]=log(pDbTemp[n]);
}
}

//FFT
double dTmpOne;
double dTmpTwo;

int nTransWidth;
int nTransHeight;

dTmpOne=log(nWidth)/log(2);
dTmpTwo=ceil(dTmpOne);
dTmpTwo=pow(2,dTmpTwo);
nTransWidth=(int)dTmpTwo;

dTmpOne=log(nHeight)/log(2);
dTmpTwo=ceil(dTmpOne);
dTmpTwo=pow(2,dTmpTwo);
nTransHeight=(int)dTmpTwo;

complex<double>* pCTData;
complex<double>* pCFData;

pCTData=new complex<double>[nTransWidth*nTransHeight];
pCFData=new complex<double>[nTransWidth*nTransHeight];

for(m=0;m<nTransHeight;m++)
{
for(n=0;n<nTransWidth;n++)
{
pCTData[m*nTransWidth+n]=complex<double>(0,0);
}
}

for(m=0;m<nHeight;m++)
{
pDbTemp=m_pDbImage+m*nWidth;
for(n=0;n<nWidth;n++)
{
pCTData[m*nTransWidth+n]=complex<double>(pDbTemp[n],0);
}
}

//FFT
pDoc->FFT_2D(pCTData,nWidth,nHeight,pCFData);

//apply the Butterworth filter.
for(m=0;m<nTransHeight;m++)
{
for(n=0;n<nTransWidth;n++)
{
nGet=m*m+n*n;
H=(double)nGet/(nGet+nRadius*nRadius);
pCFData[m*nTransWidth+n]=
complex<double>(H*pCFData[m*nTransWidth+n].real(),H*pCFData[m*nTransWidth+n].imag());
}
}

//IFFT
pDoc->IFFT_2D(pCFData,nWidth,nHeight,pCTData);

double dTemp;

for(m=0;m<nHeight;m++)
{
pDbTemp=m_pDbImage+m*nWidth;
for(n=0;n<nWidth;n++)
{
dTemp=pCTData[m*nTransWidth+n].real()*pCTData[m*nTransWidth+n].real()
+pCTData[m*nTransWidth+n].imag()*pCTData[m*nTransWidth+n].imag();

dTemp=exp(dTemp);

dTemp=sqrt(dTemp)/600;

dTemp=min(dTemp,255);

pDbTemp[n]=dTemp;
}
}

for(j=0;j<nHeight;j++)
{
pDbTemp=m_pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx+nRGB;
for(i=0;i<nWidth;i++)
{
*(pBits+i*m_nRGBBit)=FloatToByte(pDbTemp[i]);
}
}

}

return TRUE;
}

//************************************Definition
void CPro2View::OnDefinition()
{
// TODO: Add your command handler code here

pFile=new CFile(m_sFile,CFile::modeReadWrite|CFile::typeBinary);

Dib.Read(pFile);
Dib.MakePalette();

DefinFun1(&amt;Dib);

m_Defin.DoModal();

pFile->Close();
Invalidate();

}

BOOL CPro2View::DefinFun1(CDib* pDib)
{
int i,j;
int nWidth=pDib->m_lpBMIH->biWidth;
int nHeight=pDib->m_lpBMIH->biHeight;

switch(pDib->m_lpBMIH->biBitCount)
{
case 24:
m_nRGBBit=3;
break;
case 32:
m_nRGBBit=4;
break;
default:
m_nRGBBit=3;
}

CSize sizeImageSave=pDib->GetDibSaveDim();

double* pDbTemp;
double* pDbImage;
BYTE *pBits;
int nRGB=0;

pDbImage=new double[nWidth*nHeight];

if(!pDbImage) return FALSE;

//get data of the source DIB

for(j=0;j<nHeight;j++)
{
pDbTemp=pDbImage+j*nWidth;
pBits=pDib->m_lpImage+(nHeight-j-1)*sizeImageSave.cx;
for(i=0;i<nWidth;i++)
{
nRGB=0;

for(nRGB=0;nRGB<3;nRGB++)
{
if(nRGB==0)//blue
pDbTemp[i]=(double)0.11*(*(pBits+i*m_nRGBBit+nRGB));

if(nRGB==1)//green
pDbTemp[i]+=(double)0.59*(*(pBits+i*m_nRGBBit+nRGB));

if(nRGB==2)//red
pDbTemp[i]+=(double)0.30*(*(pBits+i*m_nRGBBit+nRGB));
}
}
}

double* lpSrc;
double* lpDst;
double dbResult=0;
double dTemp;
double dCen;

//calculate the definition value.
for(i=1;i<nHeight-1;i++)
{
for(j=1;j<nWidth-1;j++)
{
lpDst=(double*)pDbImage+i*nWidth+j;

dCen=*lpDst;

lpSrc=(double*)pDbImage+(i-1)*nWidth+(j);
dTemp=(double)fabs(dCen-(*lpSrc));
dbResult+=dTemp;

lpSrc=(double*)pDbImage+(i)*nWidth+(j-1);
dTemp=(double)fabs(dCen-(*lpSrc));
dbResult+=dTemp;

lpSrc=(double*)pDbImage+(i+1)*nWidth+(j);
dTemp=(double)fabs(dCen-(*lpSrc));
dbResult+=dTemp;

lpSrc=(double*)pDbImage+(i)*nWidth+(j+1);
dTemp=(double)fabs(dCen-(*lpSrc));
dbResult+=dTemp;

}
}

m_Defin.m_Value=dbResult/100;

delete pDbImage;

return TRUE;
}


void CPro2View::OnPicfile()
{
// TODO: Add your command handler code here
CDialogIm dialog;
dialog.DoModal();
m_sFile=dialog.m_sFileName;

m_bOne=TRUE;
}