📄 arisimageroutines1.cpp
字号:
// ArisImageRoutines1.cpp: implementation of the ArisImageRoutines class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ArisImageRoutines.h"
#include "ArisImageRoutines1.h"
#include "Complex.h"
#include "FFT2D.h"
#include "FFT1D.h"
#include "DCT2D.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define Sqrt2 1.4142136
#define log2(x) (3.321928*log10(x))
#define SWAP(a,b) tempr=(a); (a)=(b); (b)=tempr
#define Pi 3.1415926536
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//this acts like CEvent class
BOOL ThreadFinished[3] = {FALSE};
static int id = 0;
ArisImageRoutines::ArisImageRoutines()
{
for(int x=0;x<3;x++)
ThreadFinished[3] = FALSE;
}
ArisImageRoutines::~ArisImageRoutines()
{
}
bool ArisImageRoutines::IsPowerOfTwo (unsigned int x)
{
if ( x < 2 )
return false;
if ( x & (x-1) ) // Thanks to 'byang' for this cute trick!
return false;
return true;
}
BOOL ArisImageRoutines::FFT
(
//input
CMatrix *ReInput,
CMatrix *ImInput /*=NULL*/,
//output
CMatrix *ReOutput /*=NULL*/,
CMatrix *ImOutput /*=NULL*/,
//direction
int dir /*=1*/
)
{
if(ReInput == NULL && ImInput == NULL)
{
TRACE("Both input can't be NULL");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Both input can't be NULL");
#endif
return FALSE;
}
unsigned int w = ReInput->GetNumColumns();
unsigned int h = ReInput->GetNumRows();
unsigned int y,x;
if(dir != -1 && dir != 1)
{
//TRACE("Invalid Direction!");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Invalid Direction!");
#endif
return FALSE;
}
if(!IsPowerOfTwo(w) || !IsPowerOfTwo(h))
{
//TRACE("Cannot perform other than 2^n dimension");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Cannot perform other than 2^n dimension");
#endif
return FALSE;
}
// ok, now we're ready to start
CFFT2D fft(w, h);
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
if(ImInput)
{
if(!fft.SetInputAt(x,y,(double)ReInput->GetElement(x,y),(double)ImInput->GetElement(x,y)))
{
//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Cannot set input Value");
#endif
return FALSE;
}
}
else if(!fft.SetInputAt(x,y,(double)ReInput->GetElement(x,y),0.0))
{
//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Cannot set input Value");
#endif
return FALSE;
}
}
//do the core !!!
if(dir == 1)
{
fft.ForwardTransform();
}
else if(dir == -1)
{
fft.ReverseTransform();
}
if(ImOutput == NULL || ReOutput == NULL)
//if Output is NULL, then we do an in-place transform
{
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
CComplex complex_result;
complex_result = fft.GetInputAt(x,y);
//if ImInput is NULL, than the result in ReInput is the magnitude
if(ImInput == NULL)
ReInput->SetElement(x,y,complex_result.GetAbs());
else
{
ReInput->SetElement(x,y,complex_result.GetReal());
ImInput->SetElement(x,y,complex_result.GetImag());
}
}
}
else
//if Output is not NULL, then we do an out-place transform
{
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
CComplex complex_result;
complex_result = fft.GetInputAt(x,y);
ReOutput->SetElement(x,y,complex_result.GetReal());
ImOutput->SetElement(x,y,complex_result.GetImag());
}
}
return TRUE;
}
// I forgot the original author
// but this one is not my work
// I just modified it so that it's more C++
BOOL ArisImageRoutines::DCT
(
CMatrix *Source,
CMatrix *Destination /*=NULL*/,
int dir /*=1*/
)
{
if(Source == NULL)
{
//TRACE("Input can't be NULL");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Both input can't be NULL");
#endif
return FALSE;
}
int w = Source->GetNumColumns();
int h = Source->GetNumRows();
if(w <2 || h <2)
{
//TRACE("Matrix too small");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Matrix too small");
#endif
return FALSE;
}
if(dir != -1 && dir != 1)
{
//TRACE("Invalid Direction!");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Invalid Direction!");
#endif
return FALSE;
}
CDCT2D dct(w, h);
int x,y;
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
if(!dct.SetInputAt(x,y,(double)Source->GetElement(x,y)))
{
//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Cannot set input Value");
#endif
return FALSE;
}
}
//do the core !!!
if(dir == 1)
{
dct.ForwardTransform();
}
else if(dir == -1)
{
dct.ReverseTransform();
}
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
if(Destination)
{
Destination->SetElement(x,y,dct.GetInputAt(x,y));
}
else
{
Source->SetElement(x,y,dct.GetInputAt(x,y));
}
}
return TRUE;
}
//threads
UINT fft_thread(void* param)
{
CFFT2D *fft = (CFFT2D*) param;
fft->ForwardTransform();
ThreadFinished[id++] = TRUE;
return 0;
}
UINT ifft_thread(void* param)
{
CFFT2D *fft = (CFFT2D*) param;
fft->ReverseTransform();
ThreadFinished[id++] = TRUE;
return 0;
}
BOOL ArisImageRoutines::TRUEFFT
(
CMatrix *ReInput[3],
CMatrix *ImInput[3] /*= NULL*/,
CMatrix *ReOutput[3]/* = NULL*/,
CMatrix *ImOutput[3]/*= NULL*/,
int dir /*= 1*/
)
{
//check inputs
if
(
ReInput[0] == NULL &&
ImInput[0] == NULL &&
ReInput[0] == NULL &&
ImInput[0] == NULL &&
ReInput[0] == NULL &&
ImInput[0] == NULL
)
{
//TRACE("Both input can't be NULL");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Both input can't be NULL");
#endif
return FALSE;
}
unsigned int w = ReInput[0]->GetNumColumns();
unsigned int h = ReInput[0]->GetNumRows();
unsigned int y,x,z;
//check direction
if(dir != -1 && dir != 1)
{
TRACE("Invalid Direction!");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Invalid Direction!");
#endif
return FALSE;
}
//chek dimension
if(!IsPowerOfTwo(w) || !IsPowerOfTwo(h))
{
//TRACE("Cannot perform other than 2^n dimension");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Cannot perform other than 2^n dimension");
#endif
return FALSE;
}
CFFT2D *fft[3];
fft[0] = new CFFT2D(w,h);//R
fft[1] = new CFFT2D(w,h);//G
fft[2] = new CFFT2D(w,h);//B
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
for(z = 0;z<3;z++)
if(ImInput[0] && ImInput[1] && ImInput[2])
{
if(!fft[z]->SetInputAt(x,y,(double)ReInput[z]->GetElement(x,y),(double)ImInput[z]->GetElement(x,y)))
{
//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Cannot set input Value");
#endif
return FALSE;
}
}
else if(!fft[z]->SetInputAt(x,y,(double)ReInput[z]->GetElement(x,y),0.0))
{
//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Cannot set input Value");
#endif
return FALSE;
}
}
//do the core !!!
if(dir == 1)
{
::AfxBeginThread(fft_thread,fft[0],THREAD_PRIORITY_NORMAL);
::AfxBeginThread(fft_thread,fft[1],THREAD_PRIORITY_NORMAL);
::AfxBeginThread(fft_thread,fft[2],THREAD_PRIORITY_NORMAL);
}
else if(dir == -1)
{
::AfxBeginThread(ifft_thread,fft[0],THREAD_PRIORITY_NORMAL);
::AfxBeginThread(ifft_thread,fft[1],THREAD_PRIORITY_NORMAL);
::AfxBeginThread(ifft_thread,fft[2],THREAD_PRIORITY_NORMAL);
}
while(!(ThreadFinished[0] || ThreadFinished[1] || ThreadFinished [2]))
Sleep(500);
if(ImOutput == NULL || ReOutput == NULL)
//if Output is NULL, then we do an in-place transform
{
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
for(z = 0;z<3;z++)
{
CComplex complex_result;
complex_result = fft[z]->GetInputAt(x,y);
//if ImInput is NULL, than the result in ReInput is the magnitude
if(ImInput[z] == NULL)
ReInput[z]->SetElement(x,y,complex_result.GetAbs());
else
{
ReInput[z]->SetElement(x,y,complex_result.GetReal());
ImInput[z]->SetElement(x,y,complex_result.GetImag());
}
}
}
}
else
//if Output is not NULL, then we do an out-place transform
{
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
for(z = 0;z<3;z++)
{
CComplex complex_result;
complex_result = fft[z]->GetInputAt(x,y);
ReOutput[z]->SetElement(x,y,complex_result.GetReal());
ImOutput[z]->SetElement(x,y,complex_result.GetImag());
}
}
}
//cleanup
for(z=0;z<3;z++)
{
if(fft[z])
{
delete fft[z];
fft[z] = NULL;
}
}
return TRUE;
}
//threads
static UINT dct_thread(void* param)
{
CDCT2D *dct = (CDCT2D*) param;
dct->ForwardTransform();
ThreadFinished[id++] = TRUE;
return 0;
}
static UINT idct_thread(void* param)
{
CDCT2D *dct = (CDCT2D*) param;
dct->ReverseTransform();
ThreadFinished[id++] = TRUE;
return 0;
}
BOOL ArisImageRoutines::TRUEDCT
(
CMatrix *Source[3],
CMatrix *Destination[3] /*= NULL*/,
int dir /*= 1*/
)
{
if(Source[0] == NULL || Source[1] == NULL || Source[2] == NULL)
{
//TRACE("Input can't be NULL");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Both input can't be NULL");
#endif
return FALSE;
}
int w = Source[0]->GetNumColumns();
int h = Source[0]->GetNumRows();
if(w <2 || h <2)
{
//TRACE("Matrix too small");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Matrix too small");
#endif
return FALSE;
}
if(dir != -1 && dir != 1)
{
//TRACE("Invalid Direction!");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Invalid Direction!");
#endif
return FALSE;
}
CDCT2D* dct[3];
dct[0] = new CDCT2D(w,h);
dct[1] = new CDCT2D(w,h);
dct[2] = new CDCT2D(w,h);
int x,y,z;
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
for(z = 0;z<3;z++)
{
if(!dct[z]->SetInputAt(x,y,(double)Source[z]->GetElement(x,y)))
{
//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE
AfxMessageBox("Cannot set input Value");
#endif
return FALSE;
}
}
}
//do the core !!!
if(dir == 1)
{
::AfxBeginThread(dct_thread,dct[0],THREAD_PRIORITY_NORMAL);
::AfxBeginThread(dct_thread,dct[1],THREAD_PRIORITY_NORMAL);
::AfxBeginThread(dct_thread,dct[2],THREAD_PRIORITY_NORMAL);
}
else if(dir == -1)
{
::AfxBeginThread(idct_thread,dct[0],THREAD_PRIORITY_NORMAL);
::AfxBeginThread(idct_thread,dct[1],THREAD_PRIORITY_NORMAL);
::AfxBeginThread(idct_thread,dct[2],THREAD_PRIORITY_NORMAL);
}
while(!(ThreadFinished[0] || ThreadFinished[1] || ThreadFinished [2]))
Sleep(500);
for(x = 0; x<w ; x++)
for(y = 0; y<h; y++)
{
for(z = 0;z<3;z++)
{
if(Destination[z])
{
Destination[z]->SetElement(x,y,dct[z]->GetInputAt(x,y));
}
else
{
Source[z]->SetElement(x,y,dct[z]->GetInputAt(x,y));
}
}
}
for(z=0;z<3;z++)
{
if(dct[z])
{
delete dct[z];
dct[z] = NULL;
}
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -