#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 *pmapProfile,std::multimap *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 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(ptSecond.x - ptFirst.x) / static_cast((ptSecond.y - ptFirst.y))); std::multimap::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(it->second); if(pointSet == NULL) continue; dResultX = (float)(static_cast(pointSet->x) * cos(m_dTheta) - static_cast(pointSet->y) * sin(m_dTheta)); dResultY = (float)(static_cast(pointSet->y) * cos(m_dTheta) + static_cast(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::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(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::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(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 0) { for(v=ptGlass.y+2;v= 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 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::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(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::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(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 > &vecProfile) { if((int)vecProfile.size() <= 0 || m_pmapAlignProfile == NULL) return FALSE; CPoint *pointSet; CPoint pointPre; vector< pair >::iterator itProfile; std::multimap::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(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;iLoopOffset(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::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::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(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(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; }