// 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; } */