// SISMatch.cpp: implementation of the CSISMatch class.
|
//
|
//////////////////////////////////////////////////////////////////////
|
|
#include "stdafx.h"
|
#include "SISMatch.h"
|
#include "MatchImpl.h"
|
|
#include "MatchBuffer.h"
|
|
#ifdef _DEBUG
|
#define new DEBUG_NEW
|
#undef THIS_FILE
|
static char THIS_FILE[] = __FILE__;
|
#endif
|
|
//#include "cv_src/cv.h"
|
|
#define SIS_MATCH_IMPL_SIMD
|
//////////////////////////////////////////////////////////////////////
|
// Construction/Destruction
|
//////////////////////////////////////////////////////////////////////
|
|
CSISMatch::CSISMatch()
|
/*: m_pBigImage(NULL), m_pSmallImage(NULL), m_pResultImage(NULL)
|
,m_pBigImage2(NULL), m_pSmallImage2(NULL), m_pResultImage2(NULL)*/
|
{
|
m_pMatchImpl= new CMatchImpl;
|
}
|
|
CSISMatch::~CSISMatch()
|
{
|
delete m_pMatchImpl;
|
/*
|
if(m_pBigImage)
|
cvReleaseImage(&m_pBigImage);
|
if(m_pSmallImage)
|
cvReleaseImage(&m_pSmallImage);
|
if(m_pResultImage)
|
cvReleaseImage(&m_pResultImage);
|
if(m_pBigImage2)
|
cvReleaseImage(&m_pBigImage2);
|
if(m_pSmallImage2)
|
cvReleaseImage(&m_pSmallImage2);
|
if(m_pResultImage2)
|
cvReleaseImage(&m_pResultImage2);
|
*/
|
}
|
|
void CSISMatch::NormalizeMatchRect(CRect &rect)
|
{
|
rect.NormalizeRect();
|
rect.right= rect.left+ rect.Width()/4*4;
|
rect.bottom= rect.top+ rect.Height()/4*4;
|
}
|
|
/*
|
BOOL CSISMatch::SetImage(_IplImage **pImage, CSISBuffer *pBuffer, CRect &rect)
|
{
|
int width= rect.Width();
|
int height= rect.Height();
|
|
if(pBuffer == NULL) return FALSE;
|
|
if(*pImage != NULL)
|
{
|
if(width != (*pImage)->width || height != (*pImage)->height)
|
{
|
cvReleaseImage(pImage);
|
*pImage= cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
|
}
|
}
|
else
|
{
|
*pImage= cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
|
}
|
|
|
_IplImage *pImageData= *pImage;
|
|
if(pImageData == NULL)
|
return FALSE;
|
|
int yy;
|
int left= rect.left;
|
int top= rect.top;
|
for(yy= 0; yy< height; yy++)
|
{
|
memcpy(pImageData->imageData+ yy*width, pBuffer->GetDataAddress(left, top+ yy), sizeof(BYTE)*width);
|
}
|
|
return TRUE;
|
}
|
BOOL CSISMatch::MakeImage(struct _IplImage **ppImage, int width, int height)
|
{
|
if(*ppImage == NULL)
|
{
|
*ppImage= cvCreateImage(cvSize(width, height), IPL_DEPTH_32F, 1);
|
}
|
else
|
{
|
if(width != (*ppImage)->width || height != (*ppImage)->height)
|
{
|
cvReleaseImage(ppImage);
|
*ppImage= cvCreateImage(cvSize(width, height), IPL_DEPTH_32F, 1);
|
}
|
}
|
return *ppImage != NULL;
|
}
|
|
BOOL CSISMatch::SetImage32f(_IplImage **ppImage, CSISBuffer *pBuffer, CRect &rect)
|
{
|
int width= rect.Width();
|
int height= rect.Height();
|
|
if(pBuffer == NULL) return FALSE;
|
|
// result image Data ¾Æ´Ò¶§´Â 4ºÐÀÇ 1·Î Ãà¼ÒÇØ¼ µ¥ÀÌÅ͸¦ ä¿ö ³Ö´Â´Ù..
|
width= width/4;
|
height= height/4;
|
|
/* if(width*4 > rect.Width() || (height)*4 > rect.Height())
|
AfxMessageBox("width*4 > rect.Width");
|
if(rect.left < 0 || rect.top < 0 || rect.bottom > 1024 || rect.right >= 8192)
|
{
|
char str[200];
|
_tprintf(str, "L:%d, R:%d, T:%d, B:%d", rect.left, rect.right, rect.top, rect.bottom);
|
AfxMessageBox(str);
|
}
|
*/
|
/*
|
if(*ppImage == NULL)
|
{
|
*ppImage= cvCreateImage(cvSize(width, height), IPL_DEPTH_32F, 1);
|
}
|
else
|
{
|
if(width != (*ppImage)->width || height != (*ppImage)->height)
|
{
|
cvReleaseImage(ppImage);
|
*ppImage= cvCreateImage(cvSize(width, height), IPL_DEPTH_32F, 1);
|
}
|
}
|
|
if(*ppImage == NULL)
|
return FALSE;
|
|
|
|
_IplImage *pImageData= *ppImage;
|
|
float *pData;
|
int x, y, xx, yy;
|
int left= rect.left;
|
int top= rect.top;
|
for(yy= 0; yy< height; yy++)
|
{
|
// pData2= (float*)pImageData->imageData+ yy*width;
|
y= top+ yy*4;
|
for(xx= 0; xx< width; xx++)
|
{
|
pData= (((float*)(pImageData->imageData))+ yy*width+ xx);//pData2+ xx;
|
x= left+ xx*4;
|
|
*pData= (float)(pBuffer->GetPixel(x, y)
|
+ pBuffer->GetPixel(x+ 1, y+ 1)
|
+ pBuffer->GetPixel(x+ 2, y+ 2)
|
+ pBuffer->GetPixel(x+ 3, y+ 3)
|
|
+ pBuffer->GetPixel(x, y+ 1)
|
+ pBuffer->GetPixel(x+ 1, y+ 2)
|
+ pBuffer->GetPixel(x+ 2, y+ 3)
|
+ pBuffer->GetPixel(x+ 3, y)
|
|
+ pBuffer->GetPixel(x, y+ 2)
|
+ pBuffer->GetPixel(x+ 1, y+ 3)
|
+ pBuffer->GetPixel(x+ 2, y)
|
+ pBuffer->GetPixel(x+ 3, y+ 1)
|
|
+ pBuffer->GetPixel(x, y+ 3)
|
+ pBuffer->GetPixel(x+ 1, y)
|
+ pBuffer->GetPixel(x+ 2, y+ 1)
|
+ pBuffer->GetPixel(x+ 3, y+ 2)
|
|
)/16;
|
|
}
|
}
|
|
return TRUE;
|
}
|
|
|
*/
|
BOOL CSISMatch::SetBigImage(CSISBuffer buffer, CRect &roi)
|
{
|
m_BigRect= roi;
|
m_BigBuffer= buffer;
|
NormalizeMatchRect(m_BigRect);
|
|
#if defined (SIS_MATCH_IMPL_SIMD)
|
if(m_pMatchImpl)
|
return m_pMatchImpl->SetBigImage(m_BigBuffer, m_BigRect);
|
return FALSE;
|
#endif
|
|
return TRUE;
|
}
|
BOOL CSISMatch::SetSmallImage(CSISBuffer buffer, CRect &roi)
|
{
|
m_SmallRect= roi;
|
m_SmallBuffer= buffer;
|
NormalizeMatchRect(m_SmallRect);
|
#if defined (SIS_MATCH_IMPL_SIMD)
|
if(m_pMatchImpl)
|
return m_pMatchImpl->SetSmallImage(m_SmallBuffer, m_SmallRect);
|
return FALSE;
|
#endif
|
|
return TRUE;
|
}
|
BOOL CSISMatch::SetBigImage2(CSISBuffer buffer, CRect &roi)
|
{
|
m_BigRect= roi;
|
m_BigBuffer= buffer;
|
NormalizeMatchRect(m_BigRect);
|
|
|
return TRUE;
|
}
|
BOOL CSISMatch::SetSmallImage2(CSISBuffer buffer, CRect &roi)
|
{
|
m_SmallRect= roi;
|
m_SmallBuffer= buffer;
|
NormalizeMatchRect(m_SmallRect);
|
|
|
return TRUE;
|
}
|
/*
|
BOOL ExtractMatchResult(IplImage *pResultImage, stSISMatchResult &result, BOOL bUseInterplate)
|
{
|
int width, height;
|
float best= 0.0;
|
float *pBest;
|
int i, j;
|
int xx, yy;
|
double xxx, yyy;
|
|
width= pResultImage->width;
|
height= pResultImage->height;
|
|
for(j= 0; j< height- 1; j++)
|
{
|
for(i= 0; i< width- 1; i++)
|
{
|
pBest= (float*)(pResultImage->imageData+ 4*(i+ j*width));
|
if(best < *pBest)
|
{
|
best= *pBest;
|
xx= i;
|
yy= j;
|
}
|
}
|
}
|
|
result.m_Score= best;
|
result.m_X= xx;
|
result.m_Y= yy;
|
if(!bUseInterplate)
|
{
|
return TRUE;
|
}
|
|
// if(xx > width- 2)
|
// return FALSE;
|
// if(xx < 1)
|
// return FALSE;
|
// if(yy > height- 2)
|
// return FALSE;
|
// if(xx < 1)
|
// return FALSE;
|
|
pBest= (((float*)pResultImage->imageData)+ (xx+ yy*width));
|
best= *pBest;
|
float best1, best3;
|
best1= *(pBest- 1);
|
best3= *(pBest+ 1);
|
if(best == best3)
|
{
|
xxx= xx+ 0.5;
|
}
|
else if(best == best1)
|
{
|
xxx= xx- 0.5;
|
}
|
else if(best1 < best3)
|
{
|
xxx= xx+ 0.5- 0.5*(best- best3)/(best- best1);
|
}
|
else// if(*(pBest-1) > best3)
|
{
|
xxx= xx- 0.5+ 0.5/(best- best3)*(best- best1);
|
}
|
// float besty;
|
float best11, best33;
|
best11= *(pBest- width);
|
best33= *(pBest+ width);
|
if(best == best33)
|
{
|
yyy= yy+ 0.5;
|
}
|
else if(best == best11)
|
{
|
yyy= yy- 0.5;
|
}
|
else if(best11 < best33)
|
{
|
yyy= yy+ 0.5- 0.5*(best- best33)/(best- best11);
|
}
|
else// if(*(pBest-1) > best3)
|
{
|
yyy= yy- 0.5+ 0.5*(best- best11)/(best- best33);
|
}
|
/*
|
if(xxx < xx- 0.5)
|
return FALSE;
|
if(xxx > xx+ 0.5)
|
return FALSE;
|
if(yyy < yy- 0.5)
|
return FALSE;
|
if(yyy > yy+ 0.5)
|
return FALSE;
|
*/
|
/*
|
result.m_X= xxx;
|
result.m_Y= yyy;
|
result.m_Score= best;
|
return TRUE;
|
}
|
*/
|
BOOL CSISMatch::DoTemplateMatch(stSISMatchResult &result, stSISMatchParam &matchParam)
|
{
|
m_MatchParam= matchParam;
|
#if defined (SIS_MATCH_IMPL_SIMD)
|
|
return m_pMatchImpl->DoTemplateMatch(result, m_MatchParam);
|
#else
|
// return TRUE;
|
|
// m_MatchParam.m_Method= CV_TM_SQDIFF_NORMED;
|
// m_MatchParam.m_Method= CV_TM_CCORR_NORMED;
|
// m_MatchParam.m_Method= CV_TM_CCOEFF_NORMED;
|
|
if(m_BigRect.Height() <= m_SmallRect.Height()+ 10)
|
return DoTemplateMatch2(result);
|
|
int width, height;
|
width= m_BigRect.Width()/4- m_SmallRect.Width()/4+ 1;
|
height= m_BigRect.Height()/4- m_SmallRect.Height()/4+ 1;
|
|
if(!SetImage32f(&m_pSmallImage, &m_SmallBuffer, m_SmallRect))
|
return FALSE;
|
if(!SetImage32f(&m_pBigImage, &m_BigBuffer, m_BigRect))
|
return FALSE;
|
if(!MakeImage(&m_pResultImage, width, height))
|
return FALSE;
|
|
cvMatchTemplate(m_pBigImage, m_pSmallImage, m_pResultImage, m_MatchParam.m_Method);
|
|
stSISMatchResult tempResult;
|
if(!ExtractMatchResult(m_pResultImage, tempResult, m_MatchParam.m_bUseInterpolate))
|
return FALSE;
|
|
/*
|
// Á¤¹Ð ¸ÅĪ ¾øÀÌ ¸®ÅÏ ÇÒ °æ¿ì.
|
result.m_X= tempResult.m_X*4;//+ m_BigRect.left;
|
result.m_Y= tempResult.m_Y*4;//+ m_BigRect.top;
|
result.m_Score= tempResult.m_Score;
|
return TRUE;
|
*/
|
// ÇǶó¹Ìµå ¸ÅĪ ÈÄ ÀÛÀº ¿µ¿ª¿¡¼ Á¤¹Ð ¸ÅĪ.
|
|
int x, y;
|
x= (int)(m_BigRect.left+ tempResult.m_X*4+ 0.5);
|
y= (int)(m_BigRect.top+ tempResult.m_Y*4+ 0.5);
|
|
|
CRect rect;
|
x= x- 4;
|
y= y-4;
|
|
if(x < 0)
|
x= 0;
|
if(y < 0)
|
y= 0;
|
|
rect.SetRect(x, y, x+ m_SmallRect.Width()+ 8, y+ m_SmallRect.Height()+ 8);
|
|
|
if(!SetImage(&m_pSmallImage2, &m_SmallBuffer, m_SmallRect))
|
return FALSE;
|
if(!SetImage(&m_pBigImage2, &m_BigBuffer, rect))
|
return FALSE;
|
if(!MakeImage(&m_pResultImage2, 8+ 1, 8+ 1))
|
return FALSE;
|
|
|
cvMatchTemplate(m_pBigImage2, m_pSmallImage2, m_pResultImage2, m_MatchParam.m_Method);
|
if(! ExtractMatchResult(m_pResultImage2, tempResult, m_MatchParam.m_bUseInterpolate))
|
return FALSE;
|
|
|
result.m_X= rect.left+ tempResult.m_X- m_BigRect.left;
|
result.m_Y= rect.top+ tempResult.m_Y- m_BigRect.top;
|
result.m_Score= tempResult.m_Score;
|
return result.m_Score >= m_MatchParam.m_Acceptance;
|
#endif
|
}
|
/*
|
BOOL CSISMatch::DoTemplateMatch2(stSISMatchResult &result)
|
{
|
int width= m_BigRect.Width()- m_SmallRect.Width()+ 1;
|
int height= m_BigRect.Height()- m_SmallRect.Height()+ 1;
|
stSISMatchResult tempResult;
|
if(! SetImage(&m_pSmallImage2, &m_SmallBuffer, m_SmallRect))
|
return FALSE;
|
if(! SetImage(&m_pBigImage2, &m_BigBuffer, m_BigRect))
|
return FALSE;
|
if(! MakeImage(&m_pResultImage2, width, height))
|
return FALSE;
|
|
cvMatchTemplate(m_pBigImage2, m_pSmallImage2, m_pResultImage2, m_MatchParam.m_Method);
|
BOOL bRet= ExtractMatchResult(m_pResultImage2, tempResult, m_MatchParam.m_bUseInterpolate);
|
|
|
result.m_X= tempResult.m_X;
|
result.m_Y= tempResult.m_Y;
|
result.m_Score= tempResult.m_Score;
|
if(bRet)
|
return (result.m_Score >= m_MatchParam.m_Acceptance);
|
return FALSE;
|
}
|
*/
|