#include "StdAfx.h"
|
#include "ProfileCADProc.h"
|
#include "FreeImage.h"
|
#include "EdgeProc.h"
|
|
#define JPEG_RATE JPEG_QUALITYNORMAL|JPEG_OPTIMIZE
|
#define M_PI acos(-1.0)
|
#define M_RADIAN(x) (((M_PI)*(x))/180.0)
|
#define M_DEGREE(x) (((180.0)*(x))/M_PI)
|
|
CProfileCADProc::CProfileCADProc(void)
|
{
|
m_pmapProfile = NULL;
|
m_pmapAlignProfile = NULL;
|
m_pointMasterMax = CPoint(0,0);
|
m_pointMasterMin = CPoint(INT_MAX,INT_MAX);
|
Reset();
|
}
|
|
|
CProfileCADProc::~CProfileCADProc(void)
|
{
|
}
|
|
void CProfileCADProc::SetProfileOrigin(CPoint ptOrigin)
|
{
|
m_pointMasterMin = ptOrigin;
|
}
|
|
void CProfileCADProc::SetProfileData(std::multimap<int, CPoint*> *pmapProfile,std::multimap<int, CPoint*> *pmapAlignProfile)
|
{
|
Reset();
|
m_pmapProfile = pmapProfile;
|
m_pmapAlignProfile = pmapAlignProfile;
|
m_bLoadMaster = TRUE;
|
}
|
|
void CProfileCADProc::Reset()
|
{
|
m_ptOrigin = m_ptOffset = m_ptAlign = CPoint(0,0);
|
m_dTheta = 0.;
|
m_bLoadMaster = FALSE;
|
}
|
|
int CProfileCADProc::MakeProfileCAD(int iSide,CString strFile)
|
{
|
int nLineCnt = 0;
|
|
Reset();
|
|
if(strFile.IsEmpty() == TRUE)
|
return nLineCnt;
|
|
CSISImageBuffer imgBuffer;
|
|
if(imgBuffer.ReadFromFile(strFile) == FALSE)
|
return nLineCnt;
|
|
//imgBuffer.FlipUpDown();
|
|
nLineCnt = FindProfileLine(imgBuffer);
|
|
return nLineCnt;
|
}
|
|
int CProfileCADProc::FindProfileLine(CSISBuffer &BufCad)
|
{
|
if(m_pmapProfile == NULL)
|
return 0;
|
|
int nLineCnt = 0;
|
int x,y;
|
LPBYTE lpBuf;
|
const int nOffsetImg = 5;
|
|
for(y=nOffsetImg;y<BufCad.GetHeight()-nOffsetImg;y++)
|
{
|
lpBuf = BufCad.GetDataAddress(nOffsetImg,y);
|
|
for(x=nOffsetImg;x<BufCad.GetWidth()-nOffsetImg;x++,lpBuf++)
|
{
|
if(*lpBuf > 0)
|
{
|
CPoint *pPoint = new CPoint(x,y);
|
m_pmapProfile->insert(std::make_pair(pPoint->y, pPoint));
|
}
|
}
|
}
|
|
return (int)m_pmapProfile->size();
|
}
|
|
BOOL CProfileCADProc::RotateProfileData(CvPoint2D32f ptFirst,CvPoint2D32f ptSecond,CvPoint2D32f ptOffset)
|
{
|
if(m_pmapProfile == NULL || m_pmapAlignProfile == NULL)
|
return FALSE;
|
|
CPoint *pointSet;
|
CvPoint2D32f pointPre;
|
|
m_dTheta = -1*atan(static_cast<double>(ptSecond.x - ptFirst.x) / static_cast<double>((ptSecond.y - ptFirst.y)));
|
|
std::multimap<int, CPoint*>::iterator it;
|
float dResultX,dResultY;
|
|
m_pointMasterMin = CPoint(INT_MAX,INT_MAX);
|
m_pointMasterMax = CPoint(0,0);
|
|
for(it=m_pmapProfile->begin();it!=m_pmapProfile->end();it++)
|
{
|
pointSet = static_cast<CPoint*>(it->second);
|
if(pointSet == NULL)
|
continue;
|
|
dResultX = (float)(static_cast<float>(pointSet->x) * cos(m_dTheta) - static_cast<float>(pointSet->y) * sin(m_dTheta));
|
dResultY = (float)(static_cast<float>(pointSet->y) * cos(m_dTheta) + static_cast<float>(pointSet->x) * sin(m_dTheta));
|
|
pointPre.x = dResultX+ptFirst.x;
|
pointPre.y = dResultY+ptFirst.y;
|
|
pointPre.x += ptOffset.x;
|
pointPre.y += ptOffset.y;
|
|
CPoint *pPoint = new CPoint();
|
pPoint->x = (int)ROUND(pointPre.x);
|
pPoint->y = (int)ROUND(pointPre.y);
|
|
m_pmapAlignProfile->insert(std::make_pair(pPoint->y, pPoint));
|
|
if(pPoint->x < m_pointMasterMin.x) m_pointMasterMin.x = pPoint->x;
|
if(pPoint->y < m_pointMasterMin.y) m_pointMasterMin.y = pPoint->y;
|
if(pPoint->x > m_pointMasterMax.x) m_pointMasterMax.x = pPoint->x;
|
if(pPoint->y > m_pointMasterMax.y) m_pointMasterMax.y = pPoint->y;
|
}
|
|
return TRUE;
|
}
|
|
CPoint CProfileCADProc::FindCADPointY(int nX,BOOL bStart)
|
{
|
if(m_pmapAlignProfile == NULL)
|
return CPoint(0,0);
|
|
CPoint ptPoint(0,0);
|
|
std::multimap<int, CPoint*>::iterator it,itLast;
|
|
int nFirstY;
|
int nEndY;
|
|
if(bStart == TRUE)
|
{
|
nFirstY = m_pointMasterMin.y;
|
nEndY = nFirstY + 50;
|
}
|
else
|
{
|
nFirstY = m_pointMasterMax.y - 50;
|
nEndY = m_pointMasterMax.y;
|
}
|
|
it = m_pmapAlignProfile->lower_bound(nFirstY);
|
itLast = m_pmapAlignProfile->upper_bound(nEndY);
|
|
if (it == m_pmapAlignProfile->end())
|
return CPoint(0,0);
|
|
CPoint *pPt;
|
double dDist,dMinDist = INT_MAX;
|
while (it != itLast)
|
{
|
if (it == m_pmapAlignProfile->end())
|
break;
|
if( it == itLast)
|
break;
|
|
pPt = static_cast<CPoint*>(it->second);
|
if(pPt == NULL)
|
{
|
it++;
|
continue;
|
}
|
|
dDist = abs(nX-pPt->x);
|
if(dDist < dMinDist)
|
{
|
ptPoint = *pPt;
|
dMinDist = dDist;
|
}
|
it++;
|
}
|
|
return ptPoint;
|
}
|
|
CPoint CProfileCADProc::FindCADPointY(int nX,BOOL bStart,LPBYTE lpImg,int nWidth,int nHeight,CPoint &ptGlass,CPoint &ptChamfer,int nGlassthres,int nChamferThres)
|
{
|
if(m_pmapAlignProfile == NULL)
|
return CPoint(0,0);
|
|
CPoint ptPoint(0,0);
|
|
std::multimap<int, CPoint*>::iterator it,itLast;
|
|
int nFirstY;
|
int nEndY;
|
|
if(bStart == TRUE)
|
{
|
nFirstY = m_pointMasterMin.y;
|
nEndY = nFirstY + 50;
|
}
|
else
|
{
|
nFirstY = m_pointMasterMax.y - 50;
|
nEndY = m_pointMasterMax.y;
|
}
|
|
it = m_pmapAlignProfile->lower_bound(nFirstY);
|
itLast = m_pmapAlignProfile->upper_bound(nEndY);
|
|
if (it == m_pmapAlignProfile->end())
|
return CPoint(0,0);
|
|
CPoint *pPt;
|
double dDist,dMinDist = INT_MAX;
|
while (it != itLast)
|
{
|
if (it == m_pmapAlignProfile->end())
|
break;
|
if( it == itLast)
|
break;
|
|
pPt = static_cast<CPoint*>(it->second);
|
if(pPt == NULL)
|
{
|
it++;
|
continue;
|
}
|
|
dDist = abs(nX-pPt->x);
|
if(dDist < dMinDist)
|
{
|
ptPoint = *pPt;
|
dMinDist = dDist;
|
}
|
it++;
|
}
|
|
if(lpImg == NULL || nWidth <= 0 || nHeight <= 0)
|
return ptPoint;
|
|
int nfindRange = 20;
|
int nBright,v;
|
|
if(bStart == TRUE)
|
{
|
ptGlass = ptChamfer = CPoint(0,0);
|
for(v=ptPoint.y-nfindRange;v<ptPoint.y+nfindRange;v++)
|
{
|
nBright = *(lpImg + v*nWidth + ptPoint.x);
|
if(nBright <= nGlassthres)
|
{
|
ptGlass.x = ptPoint.x;
|
ptGlass.y = v;
|
break;
|
}
|
}
|
|
if(ptGlass.y > 0)
|
{
|
for(v=ptGlass.y+2;v<ptGlass.y+nfindRange*2;v++)
|
{
|
nBright = *(lpImg + v*nWidth + ptPoint.x);
|
if(nBright >= nGlassthres)
|
{
|
ptChamfer.x = ptGlass.x;
|
ptChamfer.y = v-1;
|
break;
|
}
|
}
|
|
if(ptChamfer.y <= 0)
|
ptChamfer = ptGlass;
|
}
|
else
|
{
|
ptGlass = ptPoint;
|
ptChamfer = ptPoint;
|
}
|
}
|
else
|
{
|
ptGlass = ptChamfer = CPoint(0,0);
|
for(v=ptPoint.y+nfindRange-1;v>=ptPoint.y-nfindRange;v--)
|
{
|
nBright = *(lpImg + v*nWidth + ptPoint.x);
|
if(nBright <= nGlassthres)
|
{
|
ptGlass.x = ptPoint.x;
|
ptGlass.y = v;
|
break;
|
}
|
}
|
|
if(ptGlass.y > 0)
|
{
|
for(v=ptGlass.y-2;v>=ptGlass.y-nfindRange*2;v--)
|
{
|
nBright = *(lpImg + v*nWidth + ptPoint.x);
|
if(nBright >= nGlassthres)
|
{
|
ptChamfer.x = ptGlass.x;
|
ptChamfer.y = v+1;
|
break;
|
}
|
}
|
|
if(ptChamfer.y <= 0)
|
ptChamfer = ptGlass;
|
}
|
else
|
{
|
ptGlass = ptPoint;
|
ptChamfer = ptPoint;
|
}
|
}
|
return ptPoint;
|
}
|
|
BOOL CProfileCADProc::FindGlassLine(CPoint ptOrigin,int nRange,double dTheta,LPBYTE lpImg,int nWidth,int nHeight,int nGlassThres,int nChamferThres,CPoint &ptGlass,CPoint &ptChamfer)
|
{
|
CEdgeProc EdgeProc;
|
double dOutX,dOutY;
|
CPoint pointOrg = CPoint((int)ptOrigin.x-nRange,(int)ptOrigin.y);
|
CPoint pointSet = CPoint((int)ptOrigin.x,(int)ptOrigin.y);
|
|
int nFindRange = 50;
|
int x;
|
BOOL bFindGlass = FALSE, bFindChamfer= FALSE;
|
|
for(x=ptOrigin.x-nRange-nFindRange;x<ptOrigin.x-nRange+nFindRange;x++)
|
{
|
pointOrg.x = x;
|
pointOrg.y = ptOrigin.y;
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dTheta)), cos(M_RADIAN(dTheta)));
|
|
if(dOutX <= 0 || dOutY <=0)
|
continue;
|
|
int nFindX = (int)ROUND(dOutX);
|
int nFindY = (int)ROUND(dOutY);
|
|
if(bFindGlass == TRUE && bFindChamfer == FALSE)// && x > ptGlass.x+2)
|
{
|
if(*(lpImg + nFindY*nWidth + nFindX) >= nChamferThres)
|
{
|
ptChamfer.x = nFindX;
|
ptChamfer.y = nFindY;
|
bFindChamfer = TRUE;
|
}
|
}
|
|
if(bFindGlass == FALSE)
|
{
|
if(*(lpImg + nFindY*nWidth + nFindX) <= nGlassThres)
|
{
|
ptGlass.x = nFindX;
|
ptGlass.y = nFindY;
|
bFindGlass = TRUE;
|
}
|
}
|
|
if(bFindGlass == TRUE && bFindChamfer == TRUE)
|
break;
|
}
|
|
return TRUE;
|
|
}
|
|
CPoint CProfileCADProc::FindCADPoint(CvPoint2D32f ptCenter,double dTheta,int nRange)
|
{
|
if(m_pmapAlignProfile == NULL)
|
return CPoint(0,0);
|
|
CPoint ptPoint(0,0);
|
|
CEdgeProc EdgeProc;
|
double dOutX,dOutY;
|
CPoint pointOrg = CPoint((int)ptCenter.x-nRange,(int)ptCenter.y);
|
CPoint pointSet = CPoint((int)ptCenter.x,(int)ptCenter.y);
|
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dTheta)), cos(M_RADIAN(dTheta)));
|
|
if(dOutX <= 0 || dOutY <=0)
|
return ptPoint;
|
|
int nFindRange = 1;
|
|
int nFirstY = (int)dOutY;
|
int nEndY = (int)dOutY + nFindRange;
|
std::multimap<int, CPoint*>::iterator it,itLast;
|
|
it = m_pmapAlignProfile->lower_bound(nFirstY);
|
itLast = m_pmapAlignProfile->upper_bound(nEndY);
|
|
if (it == m_pmapAlignProfile->end())
|
return FALSE;
|
|
CPoint *pPt;
|
double dDist,dMinDist = INT_MAX;
|
while (it != itLast)
|
{
|
if (it == m_pmapAlignProfile->end())
|
break;
|
if( it == itLast)
|
break;
|
|
pPt = static_cast<CPoint*>(it->second);
|
if(pPt == NULL)
|
{
|
it++;
|
continue;
|
}
|
|
dDist = sqrt(pow(((double)pPt->x-dOutX),2)+pow(((double)pPt->y-dOutY),2));
|
if(dDist < dMinDist)
|
{
|
ptPoint = *pPt;
|
dMinDist = dDist;
|
}
|
it++;
|
}
|
|
return ptPoint;
|
}
|
|
CPoint CProfileCADProc::FindCADPoint(CvPoint2D32f ptCenter,double dTheta,int nRange,LPBYTE lpImg,int nWidth,int nHeight,CPoint &ptGlass,CPoint &ptChamfer,int nGlassthres,int nChamferThres)
|
{
|
if(m_pmapAlignProfile == NULL)
|
return CPoint(0,0);
|
|
CPoint ptPoint(0,0);
|
|
CEdgeProc EdgeProc;
|
double dOutX,dOutY;
|
CPoint pointOrg = CPoint((int)ptCenter.x-nRange,(int)ptCenter.y);
|
CPoint pointSet = CPoint((int)ptCenter.x,(int)ptCenter.y);
|
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dTheta)), cos(M_RADIAN(dTheta)));
|
|
if(dOutX <= 0 || dOutY <=0)
|
return ptPoint;
|
|
int nFindRange = 1;
|
|
int nFirstY = (int)dOutY;
|
int nEndY = (int)dOutY + nFindRange;
|
std::multimap<int, CPoint*>::iterator it,itLast;
|
|
it = m_pmapAlignProfile->lower_bound(nFirstY);
|
itLast = m_pmapAlignProfile->upper_bound(nEndY);
|
|
if (it == m_pmapAlignProfile->end())
|
return FALSE;
|
|
CPoint *pPt;
|
double dDist,dMinDist = INT_MAX;
|
while (it != itLast)
|
{
|
if (it == m_pmapAlignProfile->end())
|
break;
|
if( it == itLast)
|
break;
|
|
pPt = static_cast<CPoint*>(it->second);
|
if(pPt == NULL)
|
{
|
it++;
|
continue;
|
}
|
|
dDist = sqrt(pow(((double)pPt->x-dOutX),2)+pow(((double)pPt->y-dOutY),2));
|
if(dDist < dMinDist)
|
{
|
ptPoint = *pPt;
|
dMinDist = dDist;
|
}
|
it++;
|
}
|
|
FindGlassLine(pointSet,nRange,dTheta,lpImg,nWidth,nHeight,nGlassthres,nChamferThres,ptGlass,ptChamfer);
|
|
|
return ptPoint;
|
}
|
|
BOOL CProfileCADProc::GetProfilePosition(std::vector< pair<int,STU_PROFILE_POSITION*> > &vecProfile)
|
{
|
if((int)vecProfile.size() <= 0 || m_pmapAlignProfile == NULL)
|
return FALSE;
|
|
CPoint *pointSet;
|
CPoint pointPre;
|
|
vector< pair<int,STU_PROFILE_POSITION*> >::iterator itProfile;
|
std::multimap<int, CPoint*>::iterator it,itEnd;
|
STU_PROFILE_POSITION *pProfile;
|
|
itProfile = vecProfile.begin();
|
|
int nMinY = (itProfile->second)->nMin;
|
BOOL bContinue = FALSE;
|
|
it = m_pmapAlignProfile->lower_bound(nMinY);
|
itEnd = m_pmapAlignProfile->end();
|
|
if (it == m_pmapAlignProfile->end())
|
return FALSE;
|
|
while (it != itEnd)
|
{
|
if (it == m_pmapAlignProfile->end())
|
break;
|
|
pointSet = static_cast<CPoint*>(it->second);
|
pointPre = *pointSet;
|
|
if(bContinue == TRUE)
|
break;
|
|
bContinue = TRUE;
|
for(itProfile=vecProfile.begin();itProfile!=vecProfile.end();itProfile++)
|
{
|
pProfile = itProfile->second;
|
|
if(pProfile->bFindPos == TRUE)
|
continue;
|
|
bContinue = FALSE;
|
if(pProfile->nMin <= pointPre.y && pProfile->nMax >= pointPre.y)
|
{
|
pProfile->point = pointPre;
|
pProfile->bFindPos = TRUE;
|
break;
|
}
|
}
|
|
it++;
|
}
|
|
return TRUE;
|
}
|
|
BOOL CProfileCADProc::ReadProfileData(CString strFile)
|
{
|
if(m_pmapProfile == NULL)
|
return FALSE;
|
|
Reset();
|
|
const int MASTER_OFFSET = 0; // Rotation ¿µ¿ª È®º¸¸¦ À§Çؼ.
|
|
if(strFile.IsEmpty() == TRUE)
|
return FALSE;
|
|
CFileFind filefind;
|
if(filefind.FindFile(strFile) == FALSE)
|
return FALSE;
|
|
CFile file;
|
|
if(FALSE == file.Open(strFile, CFile::modeRead))
|
return FALSE;
|
|
int nCnt,iLoop;
|
CPoint point;
|
|
m_pointMasterMax = CPoint(0,0);
|
m_pointMasterMin = CPoint(INT_MAX,INT_MAX);
|
|
file.Read(&nCnt,sizeof(int));
|
for(iLoop=0;iLoop<nCnt;iLoop++)
|
{
|
file.Read(&point,sizeof(CPoint));
|
|
CPoint *pPoint = new CPoint(point.x,point.y);
|
|
pPoint->Offset(MASTER_OFFSET,MASTER_OFFSET);
|
m_pmapProfile->insert(std::make_pair(pPoint->y, pPoint));
|
|
|
if(point.x < m_pointMasterMin.x) m_pointMasterMin.x = point.x;
|
if(point.y < m_pointMasterMin.y) m_pointMasterMin.y = point.y;
|
}
|
|
file.Close();
|
|
std::multimap<int, CPoint *>::iterator it;
|
CPoint *pPoint;
|
|
for(it=m_pmapProfile->begin();it!=m_pmapProfile->end();it++)
|
{
|
pPoint = it->second;
|
if(pPoint == NULL)
|
continue;
|
|
pPoint->Offset(-m_pointMasterMin.x,-m_pointMasterMin.y);
|
|
if(pPoint->x > m_pointMasterMax.x) m_pointMasterMax.x = pPoint->x;
|
if(pPoint->y > m_pointMasterMax.y) m_pointMasterMax.y = pPoint->y;
|
}
|
|
m_bLoadMaster = TRUE;
|
|
return TRUE;
|
}
|
|
BOOL CProfileCADProc::WriteProfileData(CString strFile,CString strImg)
|
{
|
if(strFile.IsEmpty() == TRUE)
|
return FALSE;
|
|
DeleteFile(strFile);
|
|
CFileFind finder;
|
DWORD nTick = GetTickCount();
|
do
|
{
|
if (finder.FindFile(strFile) == FALSE)
|
break;
|
|
if(GetTickCount()-nTick >= 2000)
|
break;
|
|
} while (TRUE);
|
|
CFile file;
|
|
if(FALSE == file.Open(strFile, CFile::modeCreate | CFile::modeWrite))
|
return FALSE;
|
|
int nCnt = (int)m_pmapProfile->size();
|
file.Write(&nCnt,sizeof(int));
|
|
std::multimap<int, CPoint*>::iterator it;
|
CPoint *pPoint;
|
CPoint pointMax(0,0);
|
CPoint pointMin(INT_MAX,INT_MAX);
|
|
for(it=m_pmapProfile->begin();it!=m_pmapProfile->end();it++)
|
{
|
pPoint = static_cast<CPoint*>(it->second);
|
if(pPoint == NULL)
|
continue;
|
|
file.Write(pPoint,sizeof(CPoint));
|
|
if(pointMax.x < pPoint->x) pointMax.x = pPoint->x;
|
if(pointMax.y < pPoint->y) pointMax.y = pPoint->y;
|
if(pointMin.x > pPoint->x) pointMin.x = pPoint->x;
|
if(pointMin.y > pPoint->y) pointMin.y = pPoint->y;
|
}
|
|
file.Close();
|
|
#define SAVE_DEBUG_IMAGE
|
#ifdef SAVE_DEBUG_IMAGE
|
if(strImg.IsEmpty() == TRUE)
|
return TRUE;
|
|
DeleteFile(strImg);
|
|
COwnerBuffer ownerBuf(pointMax.x+10,pointMax.y+10);
|
ZeroMemory(ownerBuf.GetDataAddress(),ownerBuf.GetDataSize());
|
|
for(it=m_pmapProfile->begin();it!=m_pmapProfile->end();it++)
|
{
|
pPoint = static_cast<CPoint*>(it->second);
|
|
if(pPoint->x < 0 || pPoint->y < 0
|
|| pPoint->x >= ownerBuf.GetWidth() || pPoint->y >= ownerBuf.GetHeight())
|
continue;
|
|
ownerBuf.SetPixel(pPoint->x,pPoint->y,255);
|
}
|
|
SaveImageJPG(strImg,ownerBuf);
|
#endif
|
|
return TRUE;
|
}
|
|
BOOL CProfileCADProc::SaveImageJPG(CString strFile,CSISBuffer &buffer)
|
{
|
FIBITMAP *bitmap = NULL;
|
BYTE *pBitBuffer;
|
|
bitmap = FreeImage_Allocate(buffer.GetWidth(),buffer.GetHeight(),8);
|
|
pBitBuffer = FreeImage_GetBits(bitmap);
|
if(pBitBuffer == NULL)
|
{
|
FreeImage_Unload(bitmap);
|
return FALSE;
|
}
|
|
CopyMemory(pBitBuffer,buffer.GetDataAddress(),buffer.GetDataSize());
|
|
FIBITMAP *pBit24 = FreeImage_ConvertTo24Bits(bitmap);
|
if(pBit24 == NULL)
|
return FALSE;
|
|
char cFilePath[255];
|
|
#ifdef _UNICODE
|
int nSize = WideCharToMultiByte(CP_ACP, 0, strFile.GetBuffer(), -1, NULL, 0, NULL,NULL);
|
WideCharToMultiByte(CP_ACP, 0, strFile.GetBuffer(), -1, cFilePath, nSize, NULL, NULL);
|
#else
|
sprintf_s(cFilePath,sizeof(char)*255,_T("%s"),(LPSTR)(LPCTSTR)strFile);
|
#endif
|
|
FreeImage_Save(FIF_JPEG, pBit24, cFilePath,JPEG_RATE);
|
|
FreeImage_Unload(bitmap);
|
FreeImage_Unload(pBit24);
|
|
return TRUE;
|
}
|