#include "StdAfx.h" #include "SplineInspect.h" #include #include #include "ChamferInspect.h" #include "Edge_Log.h" const int g_SearchDirection[8][2] = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}}; CSplineModel::CSplineModel(void) { ClearModelData(); } CSplineModel::~CSplineModel(void) { ClearModelData(); } void CSplineModel::ClearModelData() { m_pointMasterMax = m_pointMasterMin = CPoint(0,0); m_bLoadMasterImg = FALSE; m_strLoadModel = ""; m_mapMasterPos.clear(); } BOOL CSplineModel::CopyModelData(CSplineModel *pSpline) { m_bLoadMasterImg = FALSE; m_mapMasterPos.clear(); m_pointMasterMax = CPoint(0,0); m_pointMasterMin = CPoint(INT_MAX,INT_MAX); if(pSpline == NULL) return FALSE; m_strLoadModel = pSpline->m_strLoadModel; m_bLoadMasterImg = pSpline->m_bLoadMasterImg; m_pointMasterMax = pSpline->m_pointMasterMax; m_pointMasterMin = pSpline->m_pointMasterMin; CPoint pointOrg; std::multimap::iterator it; for(it=pSpline->m_mapMasterPos.begin();it!=pSpline->m_mapMasterPos.end();it++) { pointOrg = static_cast(it->second); m_mapMasterPos.insert(std::make_pair(pointOrg.x, pointOrg)); } return TRUE; } BOOL CSplineModel::ReadModelData(CString strFile,CString strRecipe) { m_bLoadMasterImg = FALSE; m_mapMasterPos.clear(); m_pointMasterMax = CPoint(0,0); m_pointMasterMin = CPoint(INT_MAX,INT_MAX); const int MASTER_OFFSET = 100; // 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; file.Read(&nCnt,sizeof(int)); for(iLoop=0;iLoop m_pointMasterMax.x) m_pointMasterMax.x = point.x; if(point.y > m_pointMasterMax.y) m_pointMasterMax.y = point.y; if(point.x < m_pointMasterMin.x) m_pointMasterMin.x = point.x; if(point.y < m_pointMasterMin.y) m_pointMasterMin.y = point.y; } file.Close(); int *nPosCnt_X = new int[m_pointMasterMax.x+1]; int *nPosCnt_Y = new int[m_pointMasterMax.y+1]; ZeroMemory(nPosCnt_X,sizeof(int)*(m_pointMasterMax.x+1)); ZeroMemory(nPosCnt_Y,sizeof(int)*(m_pointMasterMax.y+1)); CPoint pointData; std::multimap::iterator it; for(it=m_mapMasterPos.begin();it!=m_mapMasterPos.end();it++) { pointData = static_cast(it->second); if(RANGEIN(pointData.x,0,m_pointMasterMax.x) == TRUE) nPosCnt_X[pointData.x]++; if(RANGEIN(pointData.y,0,m_pointMasterMax.y) == TRUE) nPosCnt_Y[pointData.y]++; } int nMaxCnt = 0; for(iLoop=0;iLoop<=m_pointMasterMax.x;iLoop++) { if(nPosCnt_X[iLoop] > nMaxCnt) { nMaxCnt = nPosCnt_X[iLoop]; m_pointMasterMin.x = iLoop; } } nMaxCnt = 0; for(iLoop=0;iLoop<=m_pointMasterMax.y;iLoop++) { if(nPosCnt_Y[iLoop] > nMaxCnt) { nMaxCnt = nPosCnt_Y[iLoop]; m_pointMasterMin.y = iLoop; } } delete[] nPosCnt_X,nPosCnt_X=NULL; delete[] nPosCnt_Y,nPosCnt_Y=NULL; m_bLoadMasterImg = TRUE; m_strLoadModel = strRecipe; return TRUE; } BOOL CSplineModel::WriteCSVData(CString strFile,CPoint *pPoint,int nCnt,CPoint pointOffset) { CStdioFile studioF; CFileException ex; int iLoop; CPoint point; CString strContents,str; DeleteFile(strFile); for(iLoop=0;iLoop 0) studioF.WriteString(strContents); studioF.Close(); return TRUE; } BOOL CSplineModel::WriteModelData(CString strFile,CString strRecipe,CString strCut,std::multimap *pPoint,CPoint pointOffset) { if(pPoint == NULL || (int)pPoint->size() <= 0) return FALSE; if(strFile.IsEmpty() == TRUE) return FALSE; DeleteFile(strFile); CFile file; if(FALSE == file.Open(strFile, CFile::modeCreate | CFile::modeWrite)) return FALSE; AdjustTilt(pPoint); int nCnt = (int)pPoint->size(); file.Write(&nCnt,sizeof(int)); CPoint pointMax(0,0); std::multimap::iterator itData,itLoop; CSplinePoint *splinePos; for(itData=pPoint->begin();itData!=pPoint->end();itData++) { splinePos = static_cast(&itData->second); if(splinePos == NULL) continue; file.Write(&splinePos->rotate,sizeof(CPoint)); if(pointMax.x < splinePos->rotate.x) pointMax.x = splinePos->rotate.x; if(pointMax.y < splinePos->rotate.y) pointMax.y = splinePos->rotate.y; } file.Close(); COwnerBuffer ownerBuf(pointMax.x+10,pointMax.y+10); for(itData=pPoint->begin();itData!=pPoint->end();itData++) { splinePos = static_cast(&itData->second); if(splinePos == NULL) continue; if(splinePos->rotate.x < 0 || splinePos->rotate.y < 0 || splinePos->rotate.x >= ownerBuf.GetWidth() || splinePos->rotate.y >= ownerBuf.GetHeight()) continue; ownerBuf.SetPixel(splinePos->rotate.x,splinePos->rotate.y,255); } CString strimg; strimg.Format(_T("C:\\EdgeInspector_App\\Spline\\%s_%s_org.bmp"),strRecipe,strCut); CBufferAttach attach(strimg); attach.AttachToFile(ownerBuf); return TRUE; } BOOL CSplineModel::AdjustTilt(std::multimap *pPos) { double dAngle,dAdjustAngle; double dCenX,dCenY; CEdgeProc EdgeProc; dAngle = GetTilt(pPos,dCenX,dCenY); dAdjustAngle = -90-dAngle; /*if(dAdjustAngle == 0) return TRUE;*/ CPoint pointOut; CPoint pointMin(INT_MAX,INT_MAX); std::multimap::iterator itData,itLoop; CSplinePoint *splinePos; for(itData=pPos->begin();itData!=pPos->end();itData++) { splinePos = static_cast(&itData->second); if(splinePos == NULL) continue; EdgeProc.RotatePoint(splinePos->origin,&pointOut,CPoint((int)dCenX,(int)dCenY),sin(M_RADIAN(dAdjustAngle)), cos(M_RADIAN(dAdjustAngle))); splinePos->rotate = pointOut; if(splinePos->rotate.x < pointMin.x) pointMin.x = splinePos->rotate.x; if(splinePos->rotate.y < pointMin.y) pointMin.y = splinePos->rotate.y; } return TRUE; } double CSplineModel::GetTilt(std::multimap *pPos,double &dCenX,double &dCenY) { int nRange = 10; int nDiffDist = 200; CPoint pointSum[2]; if((int)pPos->size() < nRange*2+nDiffDist) return 0.; std::multimap::iterator it; vector> vec; for(it = pPos->begin(); it != pPos->end(); ++it) { vec.push_back(make_pair(it->second.origin.y,it->second)); } std::sort(vec.begin(),vec.end(),SortOrginYPos()); ZeroMemory(pointSum,sizeof(CPoint)*2); int iPos; iPos = 0; CSplinePoint splinePos; for(iPos = 0; iPos < nRange; iPos++) { splinePos = vec[iPos].second; pointSum[0].x += splinePos.origin.x; pointSum[0].y += splinePos.origin.y; } iPos = 0; for(iPos = nRange+nDiffDist; iPos < nRange+nDiffDist+nRange; iPos++) { splinePos = vec[iPos].second; pointSum[1].x += splinePos.origin.x; pointSum[1].y += splinePos.origin.y; } double dXPos[2],dYPos[2]; dXPos[0] = (double)pointSum[0].x/(double)nRange; dYPos[0] = (double)pointSum[0].y/(double)nRange; dXPos[1] = (double)pointSum[1].x/(double)nRange; dYPos[1] = (double)pointSum[1].y/(double)nRange; dCenX = dXPos[0]; dCenY = dYPos[0]; return M_DEGREE( atan2(dYPos[1] - dYPos[0], dXPos[1] - dXPos[0]) ); } ////////////////////////////////////////////////////////////////////////// CSplineInspect::CSplineInspect(void) { m_pLabelMap = NULL; m_lpBuffer = NULL; m_pContourMap = NULL; m_pContourCnt = NULL; m_pSpModel = NULL; m_nCCCount = 0; m_szImageOrg = CSize(0,0); m_nDefectCount = 0; } CSplineInspect::CSplineInspect(CSISBuffer *lpBuffer) { m_pLabelMap = NULL; m_lpBuffer = NULL; m_pContourMap = NULL; m_pContourCnt = NULL; m_pSpModel = NULL; m_nCCCount = 0; m_szImageOrg = CSize(0,0); SetImage(lpBuffer); } CSplineInspect::~CSplineInspect(void) { ReleaseBuffer(); ResetValue(); } void CSplineInspect::ReleaseBuffer() { int i; if(m_pLabelMap != NULL) { for(i = 0; i < m_szImageOrg.cy; i++) { if(m_pLabelMap[i] != NULL) { delete[] m_pLabelMap[i]; m_pLabelMap[i] = NULL; } } delete[] m_pLabelMap; m_pLabelMap=NULL; } if(m_pContourMap != NULL) { for(i = 0; i < m_szImageOrg.cy; i++) { if(m_pContourMap[i] != NULL) { delete[] m_pContourMap[i]; m_pContourMap[i] = NULL; } } delete[] m_pContourMap; m_pContourMap=NULL; } m_nCCCount = 0; if(m_pContourCnt != NULL) delete[] m_pContourCnt, m_pContourCnt=NULL; m_nSplineOffsetX = m_nSplineOffsetY = 0; } void CSplineInspect::ResetValue() { m_dImageTheta = 0.; m_pointPosLeft = m_pointDiffImg = CPoint(0,0); m_mapSplinePos.clear(); ZeroMemory(m_dResultData,sizeof(double)*SPLINE_RESULT_DATA_CNT); m_insSplineOrg.ReleaseSpace(); m_insSplineRes.ReleaseSpace(); ReleaseBlob(); } void CSplineInspect::ReleaseBlob() { m_nDefectCount = 0; } BOOL CSplineInspect::FindForeLine(CSISBuffer &pBuffer,int *nForeLine,double &dTheta) { CRect rectLine; int nSize = 50,nSkipSize=200; int nVertSkipSize = 50; int u,v; int nLineCnt; CPoint nLinePos[2]; int nDetLine = (int)((double)nSize*0.3); BOOL bRet; nForeLine[0] = nForeLine[1] = -1; nLinePos[0] = nLinePos[1] = -1; rectLine = CRect(pBuffer.GetWidth()-nSize-nVertSkipSize,0,pBuffer.GetWidth()-1-nVertSkipSize,pBuffer.GetHeight()-1); bRet = FALSE; for(v=rectLine.top;v 0 && nLinePos[1].y > 0) { bRet = TRUE; break; } nLineCnt = 0; for(u=rectLine.left;u= nDetLine) { nLinePos[0].y = v; nLinePos[0].x = rectLine.right; } nLineCnt = 0; for(u=rectLine.left-nSkipSize;u= nDetLine) { nLinePos[1].y = v; nLinePos[1].x = rectLine.left-nSkipSize; } } if(bRet == TRUE) { nForeLine[1] = (nLinePos[0].y+nLinePos[1].y)/2; } bRet = FALSE; nLinePos[0] = nLinePos[1] = -1; rectLine = CRect(0,pBuffer.GetHeight()-nSize,pBuffer.GetWidth(),pBuffer.GetHeight()-1); for(u=rectLine.left;u 0 && nLinePos[1].x > 0) { bRet = TRUE; break; } nLineCnt = 0; for(v=rectLine.top;v= nDetLine) { nLinePos[0].x = u; nLinePos[0].y = rectLine.top; } nLineCnt = 0; for(v=rectLine.top-nSkipSize;v= nDetLine) { nLinePos[1].x = u; nLinePos[1].y = rectLine.top-nSkipSize; } } if(bRet == TRUE) { double dXPos[2],dYPos[2]; nForeLine[0] = (nLinePos[0].x+nLinePos[1].x)/2; dXPos[0] = (double)nLinePos[0].x; dYPos[0] = (double)nLinePos[0].y; dXPos[1] = (double)nLinePos[1].x; dYPos[1] = (double)nLinePos[1].y; dTheta = -90-M_DEGREE(atan2(dYPos[1] - dYPos[0], dXPos[1] - dXPos[0])); } if(dTheta <= 2) dTheta = 0.; return TRUE; } BOOL CSplineInspect::ShiftNRotateImage(CSISBuffer pOrg,CSISBuffer pBin,COwnerBuffer &pProcess,COwnerBuffer &pProcImg,int *nForeLine,double dTheta,CPoint &pPosImg) { if(pOrg.IsValidBuffer() == FALSE || pBin.IsValidBuffer() == FALSE) return FALSE; if(m_pSpModel == NULL) return FALSE; CPoint pointOut; int v,nSize; CPoint pointOrg,pointTgt; CPoint ptMasterMin = m_pSpModel->GetptMasterMin(); CPoint ptMasterMax = m_pSpModel->GetptMasterMax(); pointOrg = pointTgt = CPoint(0,0); if(nForeLine[0] > ptMasterMin.x) pointOrg.x = nForeLine[0]-ptMasterMin.x; else pointTgt.x = ptMasterMin.x-nForeLine[0]; if(nForeLine[1] > ptMasterMin.y) pointOrg.y = nForeLine[1]-ptMasterMin.y; else pointTgt.y = ptMasterMin.y-nForeLine[1]; int nImgWidth = pBin.GetWidth(); nSize = align_4byte(pBin.GetWidth()-(pointOrg.x+pointTgt.x)); pProcess.SetSize(nImgWidth,(int)((double)ptMasterMax.y+1)); pProcImg.SetSize(nImgWidth,(int)((double)ptMasterMax.y+1)); if(pProcess.IsValidBuffer() == FALSE || pProcImg.IsValidBuffer() == FALSE) return FALSE; ZeroMemory(pProcess.GetDataAddress(0,0),pProcess.GetDataSize()); ZeroMemory(pProcImg.GetDataAddress(0,0),pProcImg.GetDataSize()); //if(dTheta <= 0) // Shift¸¸ { for(v=pointOrg.y;v= pProcess.GetHeight()) break; CopyMemory(pProcess.GetDataAddress(pointTgt.x,pointTgt.y),pBin.GetDataAddress(pointOrg.x,v),sizeof(BYTE)*nSize); CopyMemory(pProcImg.GetDataAddress(pointTgt.x,pointTgt.y),pOrg.GetDataAddress(pointOrg.x,v),sizeof(BYTE)*nSize); } } /*else { int u; CPoint pointOrg,pointBase; pointBase = CPoint(nForeLine[0],pOrg.GetHeight()-1); for(v=pointOrg.y;v= pTgt.GetWidth() || pointOut.y < 0 || pointOut.y >= pTgt.GetHeight()) continue; pTgt.SetPixel(pointOut.x,pointOut.y,*pOrg.GetDataAddress(u,v)); } } }*/ /* if(pProcess.IsValidBuffer() == TRUE) { CString str; str.Format(_T("D:\\Image\\Spline\\RotateProc.bmp")); CBufferAttach attach(str); attach.AttachToFile(pProcess); str.Format(_T("D:\\Image\\Spline\\RotateProcImg.bmp")); CBufferAttach attach2(str); attach2.AttachToFile(pProcImg); } */ return TRUE; } int CSplineInspect::GetSplineValue(CEdgeProc &EdgeProc,CSISBuffer pOrg,double dXPos,double dYPos) { if((int)dXPos >= pOrg.GetWidth()-3 || (int)dYPos >= pOrg.GetHeight()-3 || (int)dXPos < 1 || (int)dYPos < 1 || pOrg.IsValidBuffer() == FALSE) return 0; float dMod,dXValue,dYValue; int nIntPosX,nIntPosY; nIntPosX = (int)dXPos; nIntPosY = (int)dYPos; LPBYTE pImg = pOrg.GetDataAddress(nIntPosX-1,nIntPosY); dMod = (float)dXPos-(float)nIntPosX; dXValue = EdgeProc.catmullRomSpline(dMod,*pImg,*(pImg+1),*(pImg+2),*(pImg+3)); dMod = (float)dYPos-(float)nIntPosY; pImg = pOrg.GetDataAddress(nIntPosX,nIntPosY-1); dYValue = EdgeProc.catmullRomSpline(dMod,*pImg,*(pImg+pOrg.GetDataWidth()),*(pImg+pOrg.GetDataWidth()*2),*(pImg+pOrg.GetDataWidth()*3)); return (int)((dXValue+dYValue)/2.); } BOOL CSplineInspect::DistInspection(CEdgeProc &EdgeProc,CSISBuffer &pTgt,double *dResult,double *dRangeRes) { if(m_pSpModel == NULL) return FALSE; std::multimap::iterator it; CPoint pointOrg,pointSet; int nCount=0,nLineSampleDet = 10; sPoint *pLinedata = NULL; double dAdjustTheta; const int nDetOffset = 50; const int nDEF_LINE_COUNT = nLineSampleDet/3; int iCnt,nValue,nDetPointCnt,iHorCnt; CDetectPoint *pDetPoint; int *pSampleHorCnt; CSplinePoint pSpPoint; double dSumDist,dSumCnt,dMaxAvg; double dAvg=0.,dSum=0.,dDist=0.; int nDetRange = 5,nMargin=200; double dOutX,dOutY; std::vector vecDist; TRACE("=====================================================================\r\n"); TRACE("Inspect Start\r\n"); //m_Log.DisplayEdgeLog("====================================================================="); //m_Log.DisplayEdgeLog("Inspect Start"); dSumDist = dSumCnt = dMaxAvg = 0; pDetPoint = new CDetectPoint[nDetOffset*2]; pSampleHorCnt = new int[nDetOffset*2]; std::multimap *pMasterData = m_pSpModel->GetMasterData(); CPoint ptMasterMin = m_pSpModel->GetptMasterMin(); pLinedata = new sPoint[nLineSampleDet]; for(it=pMasterData->begin();it!=pMasterData->end();it++) { pointOrg = static_cast(it->second); pLinedata[nCount].x = pointOrg.x; pLinedata[nCount].y = pointOrg.y; nCount++; if(nCount >= nLineSampleDet) { dAdjustTheta = EdgeProc.GetTheta(pLinedata,nLineSampleDet,5); ZeroMemory(pDetPoint,sizeof(CDetectPoint)*(nDetOffset*2)); nDetPointCnt = nCount = 0; ZeroMemory(pSampleHorCnt,sizeof(int)*(nDetOffset*2)); for(iCnt=0;iCnt 0) { pDetPoint[iHorCnt].orgX = pointSet.x; pDetPoint[iHorCnt].orgY = pointSet.y; pDetPoint[iHorCnt].imgX = dOutX; pDetPoint[iHorCnt].imgY = dOutY; pDetPoint[iHorCnt].dTheta = dAdjustTheta; pSampleHorCnt[iHorCnt]++; } } } int nDetIdx = -1; for(iHorCnt=0;iHorCnt= nDEF_LINE_COUNT) { nDetIdx = iHorCnt; break; } } if(nDetIdx < 0) { // ã±â ½ÇÆÐ ÇßÀ»°æ¿ì, Max °ªÀ» ³Ö´Â´Ù. dAvg = nDetOffset; vecDist.push_back(dAvg); continue; } if(pDetPoint[nDetIdx].imgX > 0 && pDetPoint[nDetIdx].imgY > 0) { dDist = sqrt(pow((pDetPoint[nDetIdx].orgX-pDetPoint[nDetIdx].imgX),2)+pow((pDetPoint[nDetIdx].orgY-pDetPoint[nDetIdx].imgY),2)); dAvg = dDist; if(abs(ptMasterMin.x-(int)pDetPoint[nDetIdx].imgX) <= nDetRange) { if(m_pointPosLeft.y > (int)pDetPoint[nDetIdx].imgY) { m_pointPosLeft.x = (int)pDetPoint[nDetIdx].imgX; m_pointPosLeft.y = (int)pDetPoint[nDetIdx].imgY; } } } if(dAvg > 1) { if(dMaxAvg < dAvg) dMaxAvg = dAvg; dSumDist += dAvg; dSumCnt++; vecDist.push_back(dAvg); } } } if(m_pointPosLeft.x != INT_MAX && m_pointPosLeft.y != INT_MAX) { m_pointPosLeft.y += nMargin; m_pointPosLeft.Offset(m_pointDiffImg.x,m_pointDiffImg.y); } else m_pointPosLeft = CPoint(0,0); delete[] pLinedata, pLinedata=NULL; delete[] pDetPoint, pDetPoint=NULL; delete[] pSampleHorCnt, pSampleHorCnt = NULL; TRACE("=====================================================================\r\n"); //m_Log.DisplayEdgeLog("====================================================================="); dResult[0] = dMaxAvg; if(dSumCnt > 0) dResult[1] = dSumDist/dSumCnt; //m_Log.DisplayEdgeLog("dResult = %f, dSumCnt = %f",dResult[1]*10.0816502900-10,dSumCnt); int nMaxCount=0; int nCurIndex=1; if((int)vecDist.size() > 5) { int nJumpVal = (int)dSumCnt/5; int nIndex = 0; if(nJumpVal <= 0) return TRUE; double dAverage = 0; double dCount = 0; for(std::vector::iterator it=vecDist.begin();it!=vecDist.end();it++,nCurIndex++) { double dtemp = *it; if(dtemp != nDetOffset) { dAverage += dtemp; dCount++; } if(nIndex == 4) { nMaxCount=nJumpVal+(int)dSumCnt%5; } else { nMaxCount=nJumpVal; } if(nCurIndex >= nMaxCount) { if(nIndex >= 5) break; if(dSumCnt != 0) dRangeRes[nIndex] = dAverage/dCount; else dRangeRes[nIndex] = 1; dAverage = 0; dCount = 0; nIndex++; nCurIndex=0; } } } return TRUE; } double CSplineInspect::GetTilt(std::multimap *pPos,double &dCenX,double &dCenY) { int nRange = 10; int nDiffDist = 200; CPoint pointSum[2]; if((int)pPos->size() < nRange*2+nDiffDist) return 0.; std::multimap::iterator it; vector> vec; for(it = pPos->begin(); it != pPos->end(); ++it) { vec.push_back(make_pair(it->second.origin.y,it->second)); } std::sort(vec.begin(),vec.end(),SortOrginYPos()); ZeroMemory(pointSum,sizeof(CPoint)*2); int iPos; iPos = 0; CSplinePoint splinePos; for(iPos = 0; iPos < nRange; iPos++) { splinePos = vec[iPos].second; pointSum[0].x += splinePos.origin.x; pointSum[0].y += splinePos.origin.y; } iPos = 0; for(iPos = nRange+nDiffDist; iPos < nRange+nDiffDist+nRange; iPos++) { splinePos = vec[iPos].second; pointSum[1].x += splinePos.origin.x; pointSum[1].y += splinePos.origin.y; } double dXPos[2],dYPos[2]; dXPos[0] = (double)pointSum[0].x/(double)nRange; dYPos[0] = (double)pointSum[0].y/(double)nRange; dXPos[1] = (double)pointSum[1].x/(double)nRange; dYPos[1] = (double)pointSum[1].y/(double)nRange; dCenX = dXPos[0]; dCenY = dYPos[0]; return M_DEGREE( atan2(dYPos[1] - dYPos[0], dXPos[1] - dXPos[0]) ); } BOOL CSplineInspect::AdjustTilt(std::multimap *pPos) { double dAngle,dAdjustAngle; double dCenX,dCenY; CEdgeProc EdgeProc; dAngle = GetTilt(pPos,dCenX,dCenY); dAdjustAngle = -90-dAngle; /*if(dAdjustAngle == 0) return TRUE;*/ CPoint pointOut; CPoint pointMin(INT_MAX,INT_MAX); std::multimap::iterator itData,itLoop; CSplinePoint *splinePos; for(itData=pPos->begin();itData!=pPos->end();itData++) { splinePos = static_cast(&itData->second); if(splinePos == NULL) continue; EdgeProc.RotatePoint(splinePos->origin,&pointOut,CPoint((int)dCenX,(int)dCenY),sin(M_RADIAN(dAdjustAngle)), cos(M_RADIAN(dAdjustAngle))); splinePos->rotate = pointOut; if(splinePos->rotate.x < pointMin.x) pointMin.x = splinePos->rotate.x; if(splinePos->rotate.y < pointMin.y) pointMin.y = splinePos->rotate.y; } for(itData=m_mapSplinePos.begin();itData!=m_mapSplinePos.end();itData++) { splinePos = static_cast(&itData->second); if(splinePos == NULL) continue; splinePos->rotate.Offset(-pointMin.x,-pointMin.y); } return TRUE; } void CSplineInspect::MakeSplineResultImage(COwnerBuffer &pRes,CSISBuffer &pProcess) { if(pProcess.IsValidBuffer() == FALSE) return; if(m_pSpModel == NULL) return; std::multimap::iterator it; CPoint pointData; int nWidth = align_4byte(pProcess.GetWidth()); pRes.SetSize(nWidth,pProcess.GetHeight()); CopyMemory(pRes.GetDataAddress(0,0),pProcess.GetDataAddress(0,0),pProcess.GetDataSize()); std::multimap *pMasterData = m_pSpModel->GetMasterData(); for(it=pMasterData->begin();it!=pMasterData->end();it++) { pointData = static_cast(it->second); if(pointData.x >= pRes.GetWidth() || pointData.y >= pRes.GetHeight() || pointData.x < 0 || pointData.y < 0) continue; pRes.SetPixel(pointData.x,pointData.y,100); } } SPLINE_ERR_MSG CSplineInspect::InspectSpline(CSISBuffer &pImg,CRect &rectCrop,int nDetDist,int nThres,BOOL bFlip,BOOL bSaveImg,BOOL bSaveDebug) { ResetValue(); if(pImg.IsValidBuffer() == FALSE) return ERR_SPLINE_IMAGE_NULL; bSaveDebug =FALSE; if(bSaveDebug == TRUE) { CString strImg = _T("D:\\Image\\Spline\\CropImg_2.bmp"); CBufferAttach attachDefect(strImg); attachDefect.AttachToFile(pImg); } m_insSplineOrg.SetSize(rectCrop.Width(),rectCrop.Height()); CopyRectImg(pImg.GetDataAddress(),m_insSplineOrg.GetDataAddress(),CSize(pImg.GetDataWidth(),pImg.GetHeight()),rectCrop); if(bFlip == TRUE) m_insSplineOrg.FlipUpDown(); return SPLINE_INS_SUCESS; if(bSaveDebug == TRUE) { CString strImg = _T("D:\\Image\\Spline\\CropImg_3.bmp"); CBufferAttach attachDefect(strImg); attachDefect.AttachToFile(m_insSplineOrg); } CEdgeProc EdgeProc; CRect rect(0,0,m_insSplineOrg.GetWidth(),m_insSplineOrg.GetHeight()); COwnerBuffer BufferCanny(m_insSplineOrg.GetWidth(),m_insSplineOrg.GetHeight()); if(BufferCanny.IsValidBuffer() == FALSE) return ERR_SPLINE_IMAGE_NULL_02; ZeroMemory(BufferCanny.GetDataAddress(),BufferCanny.GetDataSize()); EdgeProc.CannyEdgeProcessing(m_insSplineOrg.GetDataAddress(0,0),rect,GM_Sobel,nThres,BufferCanny); if(bSaveDebug == TRUE) { CString strImg = _T("D:\\Image\\Spline\\Canny.bmp"); CBufferAttach attachDefect(strImg); attachDefect.AttachToFile(BufferCanny); } int nForeLine[2]; FindForeLine(BufferCanny,nForeLine,m_dImageTheta); if(nForeLine[0] <= 0 || nForeLine[1] <= 0) return ERR_SPLINE_INDEXFIND; COwnerBuffer pProcess,pProcImg; if(ShiftNRotateImage(m_insSplineOrg,BufferCanny,pProcess,pProcImg,nForeLine,m_dImageTheta,m_pointDiffImg) == FALSE) { return ERR_SPLINE_INDEXFIND; } if(pProcess.IsValidBuffer() == FALSE || pProcImg.IsValidBuffer() == FALSE) return ERR_SPLINE_IMAGE_NULL_03; DistInspection(EdgeProc,pProcess,m_dResultData,m_dRangeResult); if(bSaveDebug == TRUE) { CString strImg = _T("D:\\Image\\Spline\\Process.bmp"); CBufferAttach attachDefect(strImg); attachDefect.AttachToFile(pProcess); } if(bSaveImg == TRUE) MakeSplineResultImage(m_insSplineRes,pProcess); if(bSaveDebug == TRUE) { CString strImg = _T("D:\\Image\\Spline\\Res.bmp"); CBufferAttach attachDefect(strImg); attachDefect.AttachToFile(m_insSplineRes); } return SPLINE_INS_SUCESS; } BOOL CSplineInspect::CopyRectImg(LPBYTE pOrg,LPBYTE pTgt,CSize szImg,CRect &rectIns) { if(pOrg == NULL || pTgt == NULL) return FALSE; int v; int dv = 0; for(v=rectIns.top;v &mapData,CPoint &pointMin,CPoint &pointMax,SPLINECHIP_INS_METHOD enOpt) { if(m_pSpModel == NULL) return FALSE; std::multimap *pMasterData = m_pSpModel->GetMasterData(); CPoint ptMasterMin = m_pSpModel->GetptMasterMin(); if((int)pMasterData->size() <= 0) return FALSE; int nStartX,nEndX; CPoint pointData; std::multimap::iterator it; std::multimap::iterator lowerIter; std::multimap::iterator upperIter; nStartX = insRegion.nStartX+ptMasterMin.x; nEndX = insRegion.nEndX+ptMasterMin.x; lowerIter = pMasterData->lower_bound(nStartX); upperIter = pMasterData->upper_bound(nEndX); switch(enOpt) { case METHOD_INS_LINE: for(it = lowerIter; it != upperIter; it++) { pointData = static_cast(it->second); if(pointData.x >= nStartX && pointData.x <= nEndX) { pointData.x -= nStartX; if(pointMin.y > pointData.y) pointMin = pointData; if(pointMax.y < pointData.y) pointMax = pointData; mapData.insert(std::make_pair(pointData.y, pointData)); } } break; case METHOD_INT_ROUND: for(it = lowerIter; it != upperIter; it++) { pointData = static_cast(it->second); if(pointData.x >= nStartX && pointData.x <= nEndX) { pointData.x -= nStartX; if(pointMin.x > pointData.x) pointMin = pointData; if(pointMax.x < pointData.x) pointMax = pointData; mapData.insert(std::make_pair(pointData.x, pointData)); } } break; } return TRUE; } double CSplineInspect::GetCAD2ImgOffset(std::multimap &mapData,CSISBuffer pBin,CPoint pointMin,CPoint pointMax,int nGap) { double dYPos = INT_MAX; int u,v; int *pImgPos = NULL; int *pCADPos = NULL; int nSampling = 4; int nWidth = pBin.GetWidth()/nSampling; if(pointMin.x > pointMax.x) return dYPos; pImgPos = new int[nWidth]; pCADPos = new int[nWidth]; for(u=0;u=nWidth/2;u--) { // if(bFirstFind == TRUE) // { // nFindStartY = nPreFind - 8; // nFindEndY = nPreFind + 8; // // nFindStartY = (nFindStartY < 0) ? 0 : nFindStartY; // nFindEndY = (pBin.GetHeight() <= nFindEndY) ? pBin.GetHeight()-1 : nFindEndY; // } for(v=nFindStartY;v::iterator it; CPoint pointData,pointDataMin; int iLoop; int nStart = pointMin.x/nSampling; int nEnd = pointMax.x/nSampling; for(u=nStart,iLoop=0;u<=nEnd;u++,iLoop++) { int nX = u * nSampling; if(iLoop >= nWidth) break; pointDataMin = CPoint(INT_MAX,INT_MAX); for(it=mapData.begin();it!=mapData.end();it++) { pointData = static_cast(it->second); if(pointData.x == nX && pointData.y < pointDataMin.y) { pointDataMin = pointData; } } if(iLoop < nWidth && pointDataMin.y != INT_MAX) pCADPos[iLoop] = pointDataMin.y; if(pCADPos[iLoop] == 0) pCADPos[iLoop] = -1; } int nOffsety,nOffsetCnt; nOffsety = nOffsetCnt = 0; for(u=0;u 0) dYPos = (double)nOffsety/(double)nOffsetCnt; delete[] pImgPos, pImgPos=NULL; delete[] pCADPos, pCADPos=NULL; return dYPos; } void CSplineInspect::MakeInspectResultImage(CSISBuffer &pRes,std::multimap &mapIns) { std::multimap::iterator itData; CSplinePoint splinePos; for(itData=mapIns.begin();itData!=mapIns.end();itData++) { splinePos = static_cast(itData->second); if(splinePos.origin.x >= pRes.GetWidth() || splinePos.origin.y >= pRes.GetHeight() || splinePos.origin.x < 0 || splinePos.origin.y < 0) continue; pRes.SetPixel(splinePos.origin.x,splinePos.origin.y,255); } int nPair = m_ChamferIns.GetPairDefectCount(); CChipPair *pPair; for(int i = 0; i < nPair; i++) { pPair = m_ChamferIns.GetPairDefect(i); if(pPair == NULL) continue; pRes.SetPixel(pPair->s_nDefectX,pPair->s_nDefectY,255); } } void CSplineInspect::MakeInspectResultImage(CSISBuffer &pRes,std::multimap &mapIns) { std::multimap::iterator itData; CPoint splinePos; for(itData=mapIns.begin();itData!=mapIns.end();itData++) { splinePos = static_cast(itData->second); if(splinePos.x >= pRes.GetWidth() || splinePos.y >= pRes.GetHeight() || splinePos.y < 0 || splinePos.y < 0) continue; pRes.SetPixel(splinePos.x,splinePos.y,255); } } void CSplineInspect::MakeSplineDebugImg(COwnerBuffer &pRes,std::multimap *pMaster,std::multimap *pData) { std::multimap::iterator it; CPoint pointData; int nOffset = 20; pRes.SetSize(m_szImageOrg.cx+nOffset,m_szImageOrg.cy+nOffset); if(pMaster != NULL) { for(it=pMaster->begin();it!=pMaster->end();it++) { pointData = static_cast(it->second); pointData.Offset(nOffset,nOffset); if(pointData.x >= pRes.GetWidth() || pointData.y >= pRes.GetHeight() || pointData.x < 0 || pointData.y < 0) continue; pRes.SetPixel(pointData.x,pointData.y,200); } } if(pData != NULL) { std::multimap::iterator itData; CSplinePoint splinePos; for(itData=pData->begin();itData!=pData->end();itData++) { splinePos = static_cast(itData->second); splinePos.rotate.Offset(nOffset,nOffset); if(splinePos.rotate.x >= pRes.GetWidth() || splinePos.rotate.y >= pRes.GetHeight() || splinePos.rotate.x < 0 || splinePos.rotate.y < 0) continue; pRes.SetPixel(splinePos.rotate.x,splinePos.rotate.y,100); } } } BOOL CSplineInspect::MakeInspectLine(std::multimap &mapData,std::multimap &mapIns,double dYPos,SPLINECHIP_INS_METHOD enOpt) { if((int)mapData.size() <= 0) return FALSE; int nOffsety = (int)dYPos; std::multimap::iterator it; CPoint pointData; CSplinePoint splinePos; switch(enOpt) { case METHOD_INS_LINE: break; case METHOD_INT_ROUND: for(it=mapData.begin();it!=mapData.end();it++) { pointData = static_cast(it->second); splinePos.Reset(); splinePos.origin = splinePos.rotate = pointData; splinePos.origin.Offset(0,nOffsety); splinePos.rotate.Offset(0,nOffsety); mapIns.insert(std::make_pair(pointData.x, splinePos)); } break; } return TRUE; } #define DEF_THICK_COUNT 3 double CSplineInspect::FindThick(CEdgeProc &EdgeProc,CSISBuffer pOrg,CRect &insRect,CPoint pointSet,CPoint &pointRotate,double dTheta,int nDetThres) { double dThick = 0.; double dOutX,dOutY; int iU,nValue; CPoint pointOrg = pointSet; const int nDetOffset = 100; int nContiCnt; nContiCnt = 0; for(iU=0;iU= nDetThres) nContiCnt++; else nContiCnt = 0; if(nContiCnt >= DEF_THICK_COUNT) { dThick = sqrt(pow(((double)pointSet.x-dOutX),2)+pow(((double)pointSet.y-dOutY),2))+1; pointRotate = CPoint((int)dOutX,(int)dOutY); break; } } return dThick; } int CSplineInspect::FilteringDefect(CHIP_INS_REGION &insRegion,std::multimap &mapIns,double dRes,int nJudge,CRect &insRect,BOOL bFlip) { if(m_nDefectCount <= 0) return m_nDefectCount; int i; std::multimap::iterator it; CSplinePoint *splinePos; std::vector vecBlob; int nSize,nDist; int nRange = 2; CPoint ptIns; CRect rect; for(i=0;is_DefectRect.Width()*dRes); break; case SPLINE_INS_DIRECTION_Y: nSize = (int)(pChipBlob->s_DefectRect.Height()*dRes); break; } if(nSize < nJudge) continue; for(it=mapIns.begin();it!=mapIns.end();it++) { splinePos = static_cast(&it->second); if(splinePos == NULL) continue; switch(insRegion.emDir) { case SPLINE_INS_DIRECTION_X: ptIns = splinePos->origin; ptIns.Offset(insRegion.nSkipDist,0); if(pChipBlob->s_DefectRect.top > ptIns.y || pChipBlob->s_DefectRect.bottom < ptIns.y) continue; if(pChipBlob->s_DefectRect.PtInRect(ptIns) == TRUE) nDist = 0; else nDist = abs(ptIns.x-pChipBlob->s_DefectRect.left); break; case SPLINE_INS_DIRECTION_Y: ptIns = splinePos->origin; ptIns.Offset(0,insRegion.nSkipDist); if(pChipBlob->s_DefectRect.left > ptIns.x || pChipBlob->s_DefectRect.right < ptIns.x) continue; if(pChipBlob->s_DefectRect.PtInRect(ptIns) == TRUE) nDist = 0; else nDist = abs(ptIns.y-pChipBlob->s_DefectRect.top); break; } if(nDist < nRange) { vecBlob.push_back(*pChipBlob); break; } } } m_nDefectCount = 0; std::vector::iterator itBlob; for(itBlob=vecBlob.begin();itBlob!=vecBlob.end();itBlob++) { if(m_nDefectCount >= MAX_SPLINE_DEFECT_COUNT) return m_nDefectCount; CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount]; *pChipBlob = *itBlob; pChipBlob->s_DefectRect.OffsetRect(insRect.left,insRect.top); pChipBlob->s_nDefectX += insRect.left; pChipBlob->s_nDefectY += insRect.top; pChipBlob->s_nDefectRScale = (int)pChipBlob->s_dThick; if(bFlip == TRUE) { pChipBlob->s_DefectRect.top = insRect.Height()-pChipBlob->s_DefectRect.top; pChipBlob->s_DefectRect.bottom = insRect.Height()-pChipBlob->s_DefectRect.bottom; std::swap(pChipBlob->s_DefectRect.top,pChipBlob->s_DefectRect.bottom); pChipBlob->s_nDefectY = insRect.Height()-pChipBlob->s_nDefectY; } m_nDefectCount++; } return m_nDefectCount; } int CSplineInspect::InspectChipBin(CEdgeProc &EdgeProc,CSISBuffer pOrg,CRect &insRect,CHIP_INS_REGION &insRegion,std::multimap &mapIns) { std::multimap::iterator it; CSplinePoint *splinePos; CPoint ptIns,ptEnd; int nValue,x,y; m_ChamferIns.ResetPairDefect(); if(insRegion.emDir == SPLINE_INS_DIRECTION_X) { for(it=mapIns.begin();it!=mapIns.end();it++) { splinePos = static_cast(&it->second); if(splinePos == NULL) continue; ptIns = splinePos->origin; ptIns.Offset(insRegion.nSkipDist+insRect.left,insRect.top); ptEnd = ptIns; ptEnd.Offset(insRegion.nInsRange,0); if(ptIns.x < 0 || ptIns.y < 0 || ptIns.x >= pOrg.GetWidth() || ptIns.y >= pOrg.GetHeight()) continue; if(ptEnd.x < 0 || ptEnd.y < 0 || ptEnd.x >= pOrg.GetWidth() || ptEnd.y >= pOrg.GetHeight()) continue; if(ptIns.x >= ptEnd.x) continue; for(x=ptIns.x ; x(&it->second); if(splinePos == NULL) continue; ptIns = splinePos->origin; ptIns.Offset(insRect.left,insRegion.nSkipDist+insRect.top); ptEnd = ptIns; ptEnd.Offset(0,insRegion.nInsRange); if(ptIns.x < 0 || ptIns.y < 0 || ptIns.x >= pOrg.GetWidth() || ptIns.y >= pOrg.GetHeight()) continue; if(ptEnd.x < 0 || ptEnd.y < 0 || ptEnd.x >= pOrg.GetWidth() || ptEnd.y >= pOrg.GetHeight()) continue; if(ptIns.y >= ptEnd.y) continue; for(y=ptIns.y ; y 0) { std::vector vecBlob; m_ChamferIns.BlobDefect_Pixel(vecBlob,0,4); if((int)vecBlob.size() > 0) { std::vector::iterator itBlob; for(itBlob=vecBlob.begin();itBlob!=vecBlob.end();itBlob++) { if(m_nDefectCount >= MAX_SPLINE_DEFECT_COUNT) return m_nDefectCount; CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount]; *pChipBlob = *itBlob; pChipBlob->s_nDefectRScale = (int)pChipBlob->s_dThick; m_nDefectCount++; } } } return m_nDefectCount; } int CSplineInspect::InspectChipBin_Diagonal(CEdgeProc &EdgeProc,CSISBuffer pOrg,CRect &insRect,CHIP_INS_REGION &insRegion,std::multimap &mapIns) { std::multimap::iterator it; CSplinePoint *splinePos; CPoint ptIns,ptEnd; int nValue,x,y; m_ChamferIns.ResetPairDefect(); for(it=mapIns.begin();it!=mapIns.end();it++) { splinePos = static_cast(&it->second); if(splinePos == NULL) continue; ptIns = splinePos->origin; ptIns.Offset(insRegion.nSkipDist+insRect.left, insRegion.nSkipDist+insRect.top); ptEnd = ptIns; ptEnd.Offset(insRegion.nInsRange, insRegion.nInsRange); if(ptIns.x < 0 || ptIns.y < 0 || ptIns.x >= pOrg.GetWidth() || ptIns.y >= pOrg.GetHeight()) continue; if(ptEnd.x < 0 || ptEnd.y < 0 || ptEnd.x >= pOrg.GetWidth() || ptEnd.y >= pOrg.GetHeight()) continue; if(ptIns.x >= ptEnd.x) continue; for(x=ptIns.x, y=ptIns.y; x 0) { std::vector vecBlob; m_ChamferIns.BlobDefect_Pixel(vecBlob,0,2); if((int)vecBlob.size() > 0) { std::vector::iterator itBlob; for(itBlob=vecBlob.begin();itBlob!=vecBlob.end();itBlob++) { if(m_nDefectCount >= MAX_SPLINE_DEFECT_COUNT) return m_nDefectCount; CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount]; *pChipBlob = *itBlob; pChipBlob->s_nDefectRScale = (int)pChipBlob->s_dThick; m_nDefectCount++; } } } return m_nDefectCount; } double CSplineInspect::InspectChip(CEdgeProc &EdgeProc,CSISBuffer pOrg,CRect &insRect,CHIP_INS_REGION &insRegion,std::multimap &mapIns) { sPoint *pLinedata = NULL; int nLineCnt = 0; double dAdjustTheta; std::multimap::iterator it; CSplinePoint *splinePos; double dSumThick,dSumCnt; dSumThick = dSumCnt = 0.; if(insRegion.emMethod == MAKE_METHOD_LINEAR) { pLinedata = new sPoint[(int)mapIns.size()+1]; for(it=mapIns.begin();it!=mapIns.end();it++) { splinePos = static_cast(&it->second); if(splinePos == NULL) continue; pLinedata[nLineCnt].x = splinePos->origin.x; pLinedata[nLineCnt].y = splinePos->origin.y; nLineCnt++; } if(nLineCnt <= 0) { if(pLinedata != NULL) delete[] pLinedata, pLinedata=NULL; return TRUE; } dAdjustTheta = EdgeProc.GetTheta(pLinedata,nLineCnt,3); for(it=mapIns.begin();it!=mapIns.end();it++) { splinePos = static_cast(&it->second); if(splinePos == NULL) continue; splinePos->dTheta = dAdjustTheta; splinePos->dThick = FindThick(EdgeProc,pOrg,insRect,splinePos->origin,splinePos->rotate,dAdjustTheta,insRegion.nFindThres); TRACE("Thick Pos : org[%d,%d],roate[%d,%d],Thick[%.2f]\r\n",splinePos->origin.x,splinePos->origin.y,splinePos->rotate.x,splinePos->rotate.y,splinePos->dThick); if(splinePos->dThick > 0) { dSumThick += splinePos->dThick; dSumCnt++; } } } else { int nCount=0,nLineSampleDet = 10; CPoint pointOrg,pointSet; std::vector pvecSpPoint; std::vector::iterator itData; pLinedata = new sPoint[nLineSampleDet]; for(it=mapIns.begin();it!=mapIns.end();it++) { splinePos = static_cast(&it->second); if(splinePos == NULL) continue; pvecSpPoint.push_back(splinePos); pLinedata[nCount].x = splinePos->origin.x; pLinedata[nCount].y = splinePos->origin.y; nCount++; if(nCount >= nLineSampleDet) { dAdjustTheta = EdgeProc.GetTheta(pLinedata,nLineSampleDet,3); for(itData=pvecSpPoint.begin();itData!=pvecSpPoint.end();itData++) { splinePos = *itData; if(splinePos == NULL) continue; splinePos->dTheta = dAdjustTheta; splinePos->dThick = FindThick(EdgeProc,pOrg,insRect,splinePos->origin,splinePos->rotate,dAdjustTheta,insRegion.nFindThres); TRACE("Thick Pos : org[%d,%d],roate[%d,%d],Thick[%.2f]\r\n",splinePos->origin.x,splinePos->origin.y,splinePos->rotate.x,splinePos->rotate.y,splinePos->dThick); if(splinePos->dThick > 0) { dSumThick += splinePos->dThick; dSumCnt++; } } nCount = 0; pvecSpPoint.clear(); } } } delete[] pLinedata, pLinedata=NULL; return dSumCnt>0?dSumThick/dSumCnt:-1; } #define SP_CHIP_CONTI_COUNT 3 int CSplineInspect::AnalysisThick(CEdgeProc &EdgeProc,CRect rectImg,double dRes,int nJudgeThick,double dAvgThick,BOOL bFlip,std::multimap &mapIns) { std::multimap::iterator it; CSplinePoint *splinePos; CResultDefect resDefect; double dOutX,dOutY,dThick; CPoint pointSet; std::vector vecPair; vector::iterator itData; int nDetCnt = 0; m_ChamferIns.ResetPairDefect(); for(it=mapIns.begin();it!=mapIns.end();it++) { splinePos = static_cast(&it->second); if(splinePos == NULL)// || splinePos->dThick <= 0) continue; dThick = fabs((splinePos->dThick*dRes)-dAvgThick); if(dThick > nJudgeThick) { nDetCnt++; if(nDetCnt >= SP_CHIP_CONTI_COUNT) { pointSet = splinePos->origin; pointSet.x += (int)(((dThick/dRes)/2)+(dAvgThick/dRes)); EdgeProc.RotatePoint(pointSet,dOutX,dOutY,splinePos->origin,sin(M_RADIAN(splinePos->dTheta)), cos(M_RADIAN(splinePos->dTheta))); if(dOutX < 0 || dOutY < 0) continue; m_ChamferIns.InsertPairing((int)dOutX,(int)dOutY,1,0,0,0,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,FALSE,dThick); nDetCnt = 0; } } else nDetCnt=0; } if(m_ChamferIns.GetPairDefectCount() > 0) { std::vector vecBlob; m_ChamferIns.BlobDefect_Pixel(vecBlob,0,4); if((int)vecBlob.size() > 0) { std::vector::iterator itBlob; for(itBlob=vecBlob.begin();itBlob!=vecBlob.end();itBlob++) { if(m_nDefectCount >= MAX_SPLINE_DEFECT_COUNT) return m_nDefectCount; CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount]; *pChipBlob = *itBlob; pChipBlob->s_DefectRect.OffsetRect(rectImg.left,rectImg.top); pChipBlob->s_nDefectX += rectImg.left; pChipBlob->s_nDefectY += rectImg.top; pChipBlob->s_nDefectRScale = (int)pChipBlob->s_dThick; if(bFlip == TRUE) { pChipBlob->s_DefectRect.top = rectImg.Height()-pChipBlob->s_DefectRect.top; pChipBlob->s_DefectRect.bottom = rectImg.Height()-pChipBlob->s_DefectRect.bottom; std::swap(pChipBlob->s_DefectRect.top,pChipBlob->s_DefectRect.bottom); pChipBlob->s_nDefectY = rectImg.Height()-pChipBlob->s_nDefectY; } m_nDefectCount++; } } } return m_nDefectCount; } //#define SAVE_SPLINE_CHIP double CSplineInspect::InspectSplineChip(CSISBuffer pImg,int nPosLeft,CHIP_INS_REGION &insRegion,double dRes,int nJudgeThick,COwnerBuffer &pRes,BOOL bFlip ,int iReg,BOOL bSaveDebug,SPLINECHIP_INS_METHOD enOpt) { double dAvgThick = 0; ReleaseBlob(); if(insRegion.bUse == FALSE || pImg.IsValidBuffer() == FALSE || nPosLeft <= 0) { return dAvgThick; } CRect insRect; insRect = CRect(nPosLeft+insRegion.nStartX,0,nPosLeft+insRegion.nEndX,pImg.GetHeight()); insRect.right= insRect.left + align_4byte(insRect.Width()); if(insRect.Width() <= 0 || insRect.Height() <= 0 || insRect.left < 0 || insRect.left >= pImg.GetWidth() || insRect.right <= 0 || insRect.right >= pImg.GetWidth()) return dAvgThick; pRes.SetSize(insRect.Width(),insRect.Height()); ZeroMemory(pRes.GetDataAddress(0,0),pRes.GetDataSize()); CEdgeProc EdgeProc; CRect rectBin(0,0,insRect.Width(),insRect.Height()); int nAdpSize = 15; COwnerBuffer ProcBuf(insRect.Width(),insRect.Height()); if(CopyRectImg(pImg.GetDataAddress(0,0),ProcBuf.GetDataAddress(0,0),CSize(pImg.GetDataWidth(),pImg.GetHeight()),insRect) == FALSE) return dAvgThick; if(bSaveDebug == TRUE) { if(ProcBuf.IsValidBuffer() == TRUE) { CString str; str.Format(_T("D:\\Image\\Spline\\[%d,%d]OrgImg.bmp"),bFlip,iReg); CBufferAttach attach(str); attach.AttachToFile(ProcBuf); } } int nLineThres = insRegion.nThres;//(int)((double)insRegion.nFindThres - (double)insRegion.nFindThres*0.1); EdgeProc.ThresholdProcessing(ProcBuf.GetDataAddress(0,0),CSize(ProcBuf.GetDataWidth(),ProcBuf.GetHeight()),nLineThres,0); //EdgeProc.Adaptive_Binarization(ProcBuf.GetDataAddress(0,0),ProcBuf.GetWidth(),ProcBuf.GetHeight(),ProcBuf.GetDataWidth(),nAdpSize,0.2,ProcBuf.GetDataAddress(0,0),rectBin); if(bSaveDebug == TRUE) { if(ProcBuf.IsValidBuffer() == TRUE) { CString str; str.Format(_T("D:\\Image\\Spline\\[%d,%d]Line_BinImg.bmp"),bFlip,iReg); CBufferAttach attach(str); attach.AttachToFile(ProcBuf); COwnerBuffer pInsBin(insRect.Width(),insRect.Height()); if(CopyRectImg(pImg.GetDataAddress(0,0),pInsBin.GetDataAddress(0,0),CSize(pImg.GetDataWidth(),pImg.GetHeight()),insRect) == FALSE) return dAvgThick; EdgeProc.ThresholdProcessing(pInsBin.GetDataAddress(0,0),CSize(pInsBin.GetDataWidth(),pInsBin.GetHeight()),insRegion.nFindThres,0); str.Format(_T("D:\\Image\\Spline\\[%d,%d]Defect_BinImg.bmp"),bFlip,iReg); CBufferAttach attach2(str); attach2.AttachToFile(pInsBin); } } std::multimap mapData; CPoint pointMin = CPoint(INT_MAX,INT_MAX); CPoint pointMax = CPoint(0,0); if(MakeCADLine(insRegion,mapData,pointMin,pointMax,enOpt) == FALSE) { return dAvgThick; } if(bSaveDebug == TRUE) { COwnerBuffer pCAD(insRect.Width(),insRect.Height()); ZeroMemory(pCAD.GetDataAddress(0,0),pCAD.GetDataSize()); MakeInspectResultImage(pCAD,mapData); CString strContour; strContour.Format(_T("D:\\Image\\Spline\\[%d,%d]CADMap.bmp"),bFlip,iReg); CBufferAttach attach(strContour); attach.AttachToFile(pCAD); } double dYPos = GetCAD2ImgOffset(mapData,ProcBuf,pointMin,pointMax); if(dYPos == INT_MAX) return dAvgThick; std::multimap mapIns; if(MakeInspectLine(mapData,mapIns,dYPos,enOpt) == FALSE) { return dAvgThick; } if((int)mapIns.size() <= 0) return dAvgThick; int nDefect = InspectChipBin(EdgeProc,pImg,insRect,insRegion,mapIns); nDefect = FilteringDefect(insRegion,mapIns,dRes,nJudgeThick,insRect,bFlip); /* dAvgThick = InspectChip(EdgeProc,pImg,insRect,insRegion,mapIns); dAvgThick *= dRes; if(dAvgThick > 0) { AnalysisThick(EdgeProc,insRect,dRes,nJudgeThick,dAvgThick,bFlip,mapIns); } */ if(bSaveDebug == TRUE) { if(pRes.IsValidBuffer() == TRUE) { if(CopyRectImg(pImg.GetDataAddress(0,0),pRes.GetDataAddress(0,0),CSize(pImg.GetDataWidth(),pImg.GetHeight()),insRect) == FALSE) return dAvgThick; MakeInspectResultImage(pRes,mapIns); CString strContour; strContour.Format(_T("D:\\Image\\Spline\\[%d,%d]ResultMap.bmp"),bFlip,iReg); CBufferAttach attach(strContour); attach.AttachToFile(pRes); } } return nDefect; } double CSplineInspect::InspectSplineChip_New(CSISBuffer pImg,int nPosLeft,CHIP_INS_REGION &insRegion,double dRes,int nJudgeThick,BOOL bFlip,int iReg,BOOL bSaveDebug,SPLINECHIP_INS_METHOD enOpt/*=METHOD_INT_ROUND*/) { double dAvgThick = 0; ReleaseBlob(); if(insRegion.bUse == FALSE || pImg.IsValidBuffer() == FALSE || nPosLeft <= 0) { return dAvgThick; } CRect insRect; insRect = CRect(nPosLeft+insRegion.nStartX,0,nPosLeft+insRegion.nEndX,pImg.GetHeight()); insRect.right= insRect.left + align_4byte(insRect.Width()); if(insRect.Width() <= 0 || insRect.Height() <= 0 || insRect.left < 0 || insRect.left >= pImg.GetWidth() || insRect.right <= 0 || insRect.right >= pImg.GetWidth()) return dAvgThick; CEdgeProc EdgeProc; CRect rectBin(0,0,insRect.Width(),insRect.Height()); COwnerBuffer ProcBuf(insRect.Width(),insRect.Height()); if(CopyRectImg(pImg.GetDataAddress(0,0),ProcBuf.GetDataAddress(0,0),CSize(pImg.GetDataWidth(),pImg.GetHeight()),insRect) == FALSE) return dAvgThick; if(bSaveDebug == TRUE) { if(ProcBuf.IsValidBuffer() == TRUE) { CString str; str.Format(_T("D:\\Image\\Spline\\[%d]OrgImg.bmp"),iReg); CBufferAttach attach(str); attach.AttachToFile(ProcBuf); } } int nLineThres = insRegion.nThres;//(int)((double)insRegion.nFindThres - (double)insRegion.nFindThres*0.1); EdgeProc.ThresholdProcessing(ProcBuf.GetDataAddress(0,0),CSize(ProcBuf.GetDataWidth(),ProcBuf.GetHeight()),nLineThres,0); if(bSaveDebug == TRUE) { if(ProcBuf.IsValidBuffer() == TRUE) { CString str; str.Format(_T("D:\\Image\\Spline\\[%d]BinImg.bmp"),iReg); CBufferAttach attach(str); attach.AttachToFile(ProcBuf); } } std::multimap mapData; CPoint pointMin = CPoint(INT_MAX,INT_MAX); CPoint pointMax = CPoint(0,0); if(MakeCADLine(insRegion,mapData,pointMin,pointMax,enOpt) == FALSE) { return dAvgThick; } if(bSaveDebug == TRUE) { COwnerBuffer pCAD(insRect.Width(),insRect.Height()); ZeroMemory(pCAD.GetDataAddress(0,0),pCAD.GetDataSize()); MakeInspectResultImage(pCAD,mapData); CString strContour; strContour.Format(_T("D:\\Image\\Spline\\[%d]CADMap.bmp"),iReg); CBufferAttach attach(strContour); attach.AttachToFile(pCAD); } double dYPos = GetCAD2ImgOffset(mapData,ProcBuf,pointMin,pointMax); if(dYPos == INT_MAX) return dAvgThick; std::multimap mapIns; if(MakeInspectLine(mapData,mapIns,dYPos,enOpt) == FALSE) { return dAvgThick; } if((int)mapIns.size() <= 0) return dAvgThick; int nDefect = InspectChipBin_New(EdgeProc,pImg,insRect,insRegion,mapIns); nDefect = FilteringDefect_New(insRegion,mapIns,dRes,nJudgeThick,insRect,bFlip); return nDefect; } int CSplineInspect::InspectChipBin_New(CEdgeProc &EdgeProc,CSISBuffer pOrg,CRect &insRect,CHIP_INS_REGION &insRegion,std::multimap &mapIns) { std::multimap::iterator it; CSplinePoint *splinePos; CPoint ptIns,ptEnd; int nValue,x,y; m_ChamferIns.ResetPairDefect(); COwnerBuffer pBinBuffer(insRect.Width(), insRect.Height()); pBinBuffer.MemSet(0); for(it=mapIns.begin();it!=mapIns.end();it++) { splinePos = static_cast(&it->second); if(splinePos == NULL) continue; ptIns = splinePos->origin; ptIns.Offset(insRegion.nSkipDist+insRect.left, insRegion.nSkipDist+insRect.top); ptEnd = ptIns; ptEnd.Offset(insRegion.nInsRange, insRegion.nInsRange); if(ptIns.x < 0 || ptIns.y < 0 || ptIns.x >= pOrg.GetWidth() || ptIns.y >= pOrg.GetHeight()) continue; if(ptEnd.x < 0 || ptEnd.y < 0 || ptEnd.x >= pOrg.GetWidth() || ptEnd.y >= pOrg.GetHeight()) continue; if(ptIns.x >= ptEnd.x) continue; for(y=ptIns.y ; y blobData; Blob_OpenCV(&pOrg, &pBinBuffer, insRect, &blobData, CHIPREGTYPE_RIGHT, INS_DEFECT_CHIP, 50, -1, FALSE); if((int) blobData.size() > 0) { std::vector::iterator itBlob; for(itBlob=blobData.begin();itBlob!=blobData.end();itBlob++) { if(m_nDefectCount >= MAX_SPLINE_DEFECT_COUNT) return m_nDefectCount; CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount]; *pChipBlob = *itBlob; m_nDefectCount++; } } return m_nDefectCount; } BOOL CSplineInspect::Blob_OpenCV(CSISBuffer* pOriginImg, COwnerBuffer* pBinImage, CRect rtInsRect, std::vector* vecBlobList, ChipResionType s_RegionType,DefectPosType s_DefectPos, int nMinSize, int nSideFilter, BOOL bROIOffset) { if (pOriginImg == NULL || pBinImage == NULL || vecBlobList == NULL) return FALSE; if (pOriginImg->GetWidth() == 0 || pOriginImg->GetHeight() == 0) return FALSE; if (rtInsRect.Width() != pBinImage->GetWidth() || rtInsRect.Height() != pBinImage->GetHeight()) return FALSE; cv::Mat pBinMat = cv::Mat::zeros(pBinImage->GetHeight(), pBinImage->GetWidth(), CV_8UC1); CopyMemory(pBinMat.data, pBinImage->GetDataAddress(), pBinImage->GetSize()); cv::Mat matLabel, matStats, matCentrois; int numOfLables = connectedComponentsWithStats(pBinMat, matLabel, matStats, matCentrois, 8); std::vector vecMin, vecMax, vecSum, vecPixelCount; vecMin.resize(numOfLables, 9999); vecMax.resize(numOfLables, -9999); vecSum.resize(numOfLables, 0); vecPixelCount.resize(numOfLables, 0); int nBackGroundIdx = 0; for (int i = 0; i < matLabel.rows; i++) { int* label = matLabel.ptr(i); for (int j = 0; j < matLabel.cols; j++) { int nLabelIdx = (int)label[j]; int nPxlValue = (int)pOriginImg->GetPixel(rtInsRect.left + j, rtInsRect.top + i); if (pBinImage->GetPixel(j, i) == 0) nBackGroundIdx = nLabelIdx; if (nPxlValue < vecMin[nLabelIdx]) vecMin[nLabelIdx] = nPxlValue; if (nPxlValue > vecMax[nLabelIdx]) vecMax[nLabelIdx] = nPxlValue; vecSum[nLabelIdx] = vecSum[nLabelIdx] + nPxlValue; vecPixelCount[nLabelIdx] = vecPixelCount[nLabelIdx] + 1; } } for (int nIdx = 0; nIdx < numOfLables; nIdx++) { int area = matStats.at(nIdx, cv::CC_STAT_AREA); int left = matStats.at(nIdx, cv::CC_STAT_LEFT); int top = matStats.at(nIdx, cv::CC_STAT_TOP); int width = matStats.at(nIdx, cv::CC_STAT_WIDTH); int height = matStats.at(nIdx, cv::CC_STAT_HEIGHT); int x = (int)matCentrois.at(nIdx, 0); int y = (int)matCentrois.at(nIdx, 1); if (nBackGroundIdx == nIdx) continue; if (vecPixelCount[nIdx] < nMinSize) continue; CRect rtDefectArea; rtDefectArea.left = left; rtDefectArea.top = top; rtDefectArea.right = left + width; rtDefectArea.bottom = top + height; if(0 < nSideFilter && s_RegionType == CHIPREGTYPE_RIGHT && nSideFilter <= rtDefectArea.left) continue; if(0 < nSideFilter && s_RegionType == CHIPREGTYPE_LEFT && rtDefectArea.right <= rtInsRect.Width() - nSideFilter) continue; if(bROIOffset == TRUE) rtDefectArea.OffsetRect(rtInsRect.left, rtInsRect.top); CChipBlob chipBlob; chipBlob.Reset(); // CheckDefectRect(chipBlob, pPair->s_nDefectX, pPair->s_nDefectY); // chipBlob.SetDefectPair(pPair->s_DefectPair); chipBlob.s_DefectRect = rtDefectArea; chipBlob.s_nDefectRScale = rtDefectArea.Width()*rtDefectArea.Height(); chipBlob.s_nIndex = (short) vecBlobList->size(); chipBlob.s_nDefectArea = vecPixelCount[nIdx]; if(bROIOffset == TRUE) { chipBlob.s_nDefectX = x + rtInsRect.left; chipBlob.s_nDefectY = y + rtInsRect.top; } else { chipBlob.s_nDefectX = x; chipBlob.s_nDefectY = y; } chipBlob.s_DefectType = CHIPDEFTYPE_MIXED; //pPair->s_DefectType; //½ÇÁ¦ ¹é°áÇÔÀº 1,Èæ°áÇÔÀº 0 chipBlob.s_sThreshold = 0; chipBlob.s_RegionType = s_RegionType; chipBlob.s_dThick = 0.0; chipBlob.s_bCornerChip = FALSE; chipBlob.s_DefectJudgeType = s_DefectPos; chipBlob.s_sLevelSrcMax = (short) vecMax[nIdx]; chipBlob.s_xLevelSrcMax = (short) chipBlob.s_nDefectX; chipBlob.s_yLevelSrcMax = (short) chipBlob.s_nDefectY; chipBlob.s_sLevelSrcMin = (short) vecMin[nIdx]; chipBlob.s_nLevelSrcSum = vecSum[nIdx]; vecBlobList->push_back(chipBlob); } return TRUE; } int CSplineInspect::FilteringDefect_New(CHIP_INS_REGION &insRegion,std::multimap &mapIns,double dRes,int nJudge,CRect &insRect,BOOL bFlip) { if(m_nDefectCount <= 0) return m_nDefectCount; int i; CSplinePoint *splinePos; std::vector vecBlob; int nSizeX, nSizeY; int nRange = 2; CPoint ptIns; CRect rect; std::multimap::iterator it; std::multimap::iterator lowerIter; std::multimap::iterator upperIter; for(i=0;is_DefectRect.Width()*dRes); nSizeY = (int)(pChipBlob->s_DefectRect.Height()*dRes); if(nSizeX < nJudge && nSizeY < nJudge) continue; lowerIter = mapIns.lower_bound(pChipBlob->s_DefectRect.left - insRegion.nSkipDist - nRange); upperIter = mapIns.upper_bound(pChipBlob->s_DefectRect.right - insRegion.nSkipDist - nRange); for(it = lowerIter; it != upperIter; it++) { splinePos = static_cast(&it->second); if(splinePos == NULL) continue; ptIns = splinePos->origin; ptIns.Offset(insRegion.nSkipDist+nRange,insRegion.nSkipDist+nRange); if(pChipBlob->s_DefectRect.PtInRect(ptIns) == TRUE) { vecBlob.push_back(*pChipBlob); break; } } } m_nDefectCount = 0; std::vector::iterator itBlob; for(itBlob=vecBlob.begin();itBlob!=vecBlob.end();itBlob++) { if(m_nDefectCount >= MAX_SPLINE_DEFECT_COUNT) return m_nDefectCount; CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount]; *pChipBlob = *itBlob; pChipBlob->s_DefectRect.OffsetRect(insRect.left,insRect.top); pChipBlob->s_nDefectX += insRect.left; pChipBlob->s_nDefectY += insRect.top; pChipBlob->s_nDefectRScale = (int)pChipBlob->s_dThick; if(bFlip == TRUE) { pChipBlob->s_DefectRect.top = insRect.Height()-pChipBlob->s_DefectRect.top; pChipBlob->s_DefectRect.bottom = insRect.Height()-pChipBlob->s_DefectRect.bottom; std::swap(pChipBlob->s_DefectRect.top,pChipBlob->s_DefectRect.bottom); pChipBlob->s_nDefectY = insRect.Height()-pChipBlob->s_nDefectY; } m_nDefectCount++; } return m_nDefectCount; } BOOL CSplineInspect::FindCADLine() { if(m_lpBuffer == NULL || m_lpBuffer->GetHeight() <= 0 || m_lpBuffer->GetWidth() <= 0) return FALSE; int ix,iy,iLoop; int nImgOffset = 5; m_mapSplinePos.clear(); CSplinePoint splinePos; m_nSplineOffsetX = m_nSplineOffsetY = INT_MAX; iLoop = 0; for(iy=m_lpBuffer->GetHeight()-nImgOffset;iy>=nImgOffset;iy--) { for(ix=nImgOffset;ixGetWidth()-nImgOffset;ix++) { if(m_lpBuffer->GetPixel(ix,iy) == 255) { splinePos.Reset(); if(m_nSplineOffsetX > ix) m_nSplineOffsetX = ix; if(m_nSplineOffsetY > iy) m_nSplineOffsetY = iy; splinePos.origin = splinePos.rotate = CPoint(ix,iy); m_mapSplinePos.insert(std::make_pair(ix, splinePos)); } } } return TRUE; } BOOL CSplineInspect::LabelingProcess() { if(CheckBuffer() == FALSE) return FALSE; int cx,cy; int nLabelingIdx,nTracedir; DWORD dwStarttime = GetTickCount(); const int MAX_DELAY_TIME = 1000; BOOL bBreak = FALSE; // CString str = _T("D:\\Image\\Spline\\Recipe_org.bmp"); // CBufferAttach attach(str); // attach.AttachToFile(*m_lpBuffer); nLabelingIdx = m_nCCCount = 0; for(cy = 2; cy < m_lpBuffer->GetHeight() - 2; cy++) { for(cx = 2, nLabelingIdx = 0; cx < m_lpBuffer->GetWidth() - 2; cx++) { if((GetTickCount()-dwStarttime) >= MAX_DELAY_TIME) { bBreak = TRUE; break; } if(CheckRange(cx,cy,m_lpBuffer) == FALSE) break; if(*m_lpBuffer->GetDataAddress(cx,cy) == 255)// black pixel { if(nLabelingIdx != 0)// use pre-pixel label { m_pLabelMap[cy][cx] = nLabelingIdx; } else { nLabelingIdx = m_pLabelMap[cy][cx]; if(nLabelingIdx == 0) { nLabelingIdx = ++m_nCCCount; nTracedir = 0; ContourTracing(cy, cx, nLabelingIdx, nTracedir);// external contour m_pLabelMap[cy][cx] = nLabelingIdx; } } } else if(nLabelingIdx != 0)// white pixel & pre-pixel has been labeled { if(m_pLabelMap[cy][cx] == 0) { nTracedir = 1; ContourTracing(cy, cx - 1, nLabelingIdx, nTracedir);// internal contour } nLabelingIdx = 0; } } if(bBreak == TRUE) return TRUE; } return TRUE; } BOOL CSplineInspect::LabelingCounting() { if(CheckBuffer() == FALSE) return FALSE; int ix,iy; m_nMaxContourIdx = m_nMaxContourCount = 0; ZeroMemory(m_pContourCnt,sizeof(int)*m_lpBuffer->GetHeight()*m_lpBuffer->GetWidth()); for(iy=0;iyGetHeight();iy++) { for(ix=0;ixGetWidth();ix++) { if(m_pContourMap[iy][ix] > 0) { m_pContourCnt[m_pContourMap[iy][ix]]++; if(m_nMaxContourCount < m_pContourCnt[m_pContourMap[iy][ix]]) { m_nMaxContourIdx = m_pContourMap[iy][ix]; m_nMaxContourCount = m_pContourCnt[m_pContourMap[iy][ix]]; } } } } return TRUE; } BOOL CSplineInspect::LabelFiltering( int nFilterCnt ) { if(CheckBuffer() == FALSE) return FALSE; int iLoop; for(iLoop=0;iLoopGetHeight()*m_lpBuffer->GetWidth();iLoop++) { if(m_pContourCnt[iLoop] > 0 && m_pContourCnt[iLoop] <= nFilterCnt) m_pContourCnt[iLoop] = 0; } return TRUE; } int CSplineInspect::GetRectInLabelMaxIndex( CRect &rect ) { if(CheckBuffer() == FALSE) return -1; if(CheckRectToBuffer(rect) == FALSE) return -1; int ix,iy,iLoop; CArray arrIndex; BOOL bFind; for(iy=rect.top;iy<=rect.bottom;iy++) { for(ix=rect.left;ix<=rect.right;ix++) { if(m_pContourMap[iy][ix] > 0) { bFind = FALSE; for(iLoop=0;iLoop nMaxVal) { nMaxVal = m_pContourCnt[nIdx]; nMaxIdx = nIdx; } } return nMaxIdx; } BOOL CSplineInspect::GetLabelPosition( int nIdx ) { m_mapSplinePos.clear(); if(CheckBuffer() == FALSE) return FALSE; int ix,iy,iLoop; CSplinePoint splinePos; m_nSplineOffsetX = m_nSplineOffsetY = INT_MAX; iLoop = 0; for(iy=m_lpBuffer->GetHeight()-1;iy>=0;iy--) { for(ix=0;ixGetWidth();ix++) { if(m_pContourMap[iy][ix] == nIdx) { splinePos.Reset(); if(m_nSplineOffsetX > ix) m_nSplineOffsetX = ix; if(m_nSplineOffsetY > iy) m_nSplineOffsetY = iy; splinePos.origin = splinePos.rotate = CPoint(ix,iy); m_mapSplinePos.insert(std::make_pair(ix, splinePos)); } } } return TRUE; } BOOL CSplineInspect::CheckBuffer() { if(m_lpBuffer == NULL || m_lpBuffer->GetHeight() <= 0 || m_lpBuffer->GetWidth() <= 0) return FALSE; if(m_pLabelMap == NULL || m_pContourMap == NULL || m_pContourCnt == NULL) return FALSE; return TRUE; } BOOL CSplineInspect::CheckRange( int x,int y,CSISBuffer *buffer ) { if(x < 0 || y < 0) return FALSE; if(x >= buffer->GetWidth() || y >= buffer->GetHeight()) return FALSE; return TRUE; } void CSplineInspect::ContourTracing( int cy, int cx, int labelindex, int tracingdirection ) { char tracingstopflag = 0, SearchAgain = 1; int fx, fy, sx = cx, sy = cy; Tracer(&cy, &cx, &tracingdirection); m_pContourMap[cy][cx] = labelindex; DWORD dwStarttime = GetTickCount(); const int MAX_DELAY_TIME = 500; if(cx != sx || cy != sy) { fx = cx; fy = cy; while(SearchAgain) { if((GetTickCount()-dwStarttime) >= MAX_DELAY_TIME) break; tracingdirection = (tracingdirection + 6) % 8; m_pLabelMap[cy][cx] = labelindex; Tracer(&cy, &cx, &tracingdirection); m_pContourMap[cy][cx] = labelindex; if(cx == sx && cy == sy) { tracingstopflag = 1; } else if(tracingstopflag) { if(cx == fx && cy == fy) { SearchAgain = 0; } else { tracingstopflag = 0; } } } } } BOOL CSplineInspect::CheckRectToBuffer( CRect &rect ) { if(rect.left < 0 || rect.right >= m_lpBuffer->GetWidth() || rect.right < 0 || rect.right >= m_lpBuffer->GetWidth()) return FALSE; if(rect.top < 0 || rect.top >= m_lpBuffer->GetHeight() || rect.bottom < 0 || rect.bottom >= m_lpBuffer->GetHeight()) return FALSE; return TRUE; } BOOL CSplineInspect::Tracer( int *cy, int *cx, int *tracingdirection ) { int i, y, x; for(i = 0; i < 7; i++) { y = *cy + g_SearchDirection[*tracingdirection][0]; x = *cx + g_SearchDirection[*tracingdirection][1]; if(CheckRange(x,y,m_lpBuffer) == FALSE) return FALSE; if(*m_lpBuffer->GetDataAddress(x,y) == 0) { m_pLabelMap[y][x] = -1; *tracingdirection = (*tracingdirection + 1) % 8; } else { *cy = y; *cx = x; return TRUE; } } return TRUE; } BOOL CSplineInspect::SetImage( CSISBuffer *lpBuffer ) { if(lpBuffer == NULL || lpBuffer->IsValidBuffer() == FALSE) return FALSE; int i; ReleaseBuffer(); ReleaseBlob(); m_lpBuffer = lpBuffer; m_szImageOrg = CSize(m_lpBuffer->GetWidth(),m_lpBuffer->GetHeight()); if(m_lpBuffer != NULL && m_lpBuffer->GetHeight() > 0 && m_lpBuffer->GetWidth() > 0) { m_pLabelMap = new int*[m_lpBuffer->GetHeight()]; m_pContourMap = new int*[m_lpBuffer->GetHeight()]; for(i=0;iGetHeight();i++) { m_pLabelMap[i] = new int[m_lpBuffer->GetWidth()]; m_pContourMap[i] = new int[m_lpBuffer->GetWidth()]; ZeroMemory(m_pLabelMap[i],sizeof(int)*m_lpBuffer->GetWidth()); ZeroMemory(m_pContourMap[i],sizeof(int)*m_lpBuffer->GetWidth()); } m_pContourCnt = new int[m_lpBuffer->GetHeight()*m_lpBuffer->GetWidth()]; ZeroMemory(m_pContourCnt,sizeof(int)*m_lpBuffer->GetHeight()*m_lpBuffer->GetWidth()); return TRUE; /* CString strFile = "D:\\Image\\Origin.bmp"; CBufferAttach attach(strFile); attach.AttachToFile(*m_lpBuffer); */ } return FALSE; }