#include "StdAfx.h"
|
#include "SplineInspect.h"
|
#include <math.h>
|
#include <algorithm>
|
#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<int, CPoint>::iterator it;
|
for(it=pSpline->m_mapMasterPos.begin();it!=pSpline->m_mapMasterPos.end();it++)
|
{
|
pointOrg = static_cast<CPoint>(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<nCnt;iLoop++)
|
{
|
file.Read(&point,sizeof(CPoint));
|
point.Offset(MASTER_OFFSET,MASTER_OFFSET);
|
m_mapMasterPos.insert(std::make_pair(point.x, point));
|
if(point.x > 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<int, CPoint>::iterator it;
|
for(it=m_mapMasterPos.begin();it!=m_mapMasterPos.end();it++)
|
{
|
pointData = static_cast<CPoint>(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<nCnt;iLoop++)
|
{
|
point = pPoint[iLoop];
|
//point.Offset(-pointOffset.x,-pointOffset.y);
|
str.Format(_T("%d,%d,\n"),point.x,point.y);
|
strContents += str;
|
}
|
|
if(studioF.Open(strFile, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite|CFile::shareDenyWrite, &ex) == FALSE)
|
{
|
return FALSE;
|
}
|
|
if(strContents.GetLength() > 0)
|
studioF.WriteString(strContents);
|
|
studioF.Close();
|
|
return TRUE;
|
}
|
|
BOOL CSplineModel::WriteModelData(CString strFile,CString strRecipe,CString strCut,std::multimap<int, CSplinePoint> *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<int, CSplinePoint>::iterator itData,itLoop;
|
CSplinePoint *splinePos;
|
|
for(itData=pPoint->begin();itData!=pPoint->end();itData++)
|
{
|
splinePos = static_cast<CSplinePoint*>(&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<CSplinePoint*>(&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<int, CSplinePoint> *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<int, CSplinePoint>::iterator itData,itLoop;
|
CSplinePoint *splinePos;
|
|
|
for(itData=pPos->begin();itData!=pPos->end();itData++)
|
{
|
splinePos = static_cast<CSplinePoint*>(&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<int, CSplinePoint> *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<int, CSplinePoint>::iterator it;
|
vector<pair<int,CSplinePoint>> 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<rectLine.bottom;v++)
|
{
|
if(nLinePos[0].y > 0 && nLinePos[1].y > 0)
|
{
|
bRet = TRUE;
|
break;
|
}
|
|
nLineCnt = 0;
|
for(u=rectLine.left;u<rectLine.right;u++)
|
{
|
if(*pBuffer.GetDataAddress(u,v) == 255)
|
nLineCnt++;
|
}
|
if(nLineCnt >= nDetLine)
|
{
|
nLinePos[0].y = v;
|
nLinePos[0].x = rectLine.right;
|
}
|
|
nLineCnt = 0;
|
for(u=rectLine.left-nSkipSize;u<rectLine.right-nSkipSize;u++)
|
{
|
if(*pBuffer.GetDataAddress(u,v) == 255)
|
nLineCnt++;
|
}
|
if(nLineCnt >= 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<rectLine.right;u++)
|
{
|
if(nLinePos[0].x > 0 && nLinePos[1].x > 0)
|
{
|
bRet = TRUE;
|
break;
|
}
|
|
nLineCnt = 0;
|
for(v=rectLine.top;v<rectLine.bottom;v++)
|
{
|
if(*pBuffer.GetDataAddress(u,v) == 255)
|
nLineCnt++;
|
}
|
if(nLineCnt >= nDetLine)
|
{
|
nLinePos[0].x = u;
|
nLinePos[0].y = rectLine.top;
|
}
|
|
nLineCnt = 0;
|
for(v=rectLine.top-nSkipSize;v<rectLine.bottom-nSkipSize;v++)
|
{
|
if(*pBuffer.GetDataAddress(u,v) == 255)
|
nLineCnt++;
|
}
|
if(nLineCnt >= 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<pBin.GetHeight();v++,pointTgt.y++)
|
{
|
if(pointTgt.y >= 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<pOrg.GetHeight();v++)
|
{
|
for(u=pointOrg.x;u<nSize;u++)
|
{
|
pointOrg = CPoint(u,v);
|
RotatePoint(pointOrg,&pointOut,pointBase,sin(M_RADIAN(dTheta)), cos(M_RADIAN(dTheta)));
|
|
pointOut.x += pointTgt.x;
|
pointOut.y += pointTgt.y;
|
if(pointOut.x < 0 || pointOut.x >= 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<int, CPoint>::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<double> 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<int, CPoint> *pMasterData = m_pSpModel->GetMasterData();
|
CPoint ptMasterMin = m_pSpModel->GetptMasterMin();
|
|
pLinedata = new sPoint[nLineSampleDet];
|
for(it=pMasterData->begin();it!=pMasterData->end();it++)
|
{
|
pointOrg = static_cast<CPoint>(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<nLineSampleDet;iCnt++)
|
{
|
pointOrg.x = pointSet.x = (int)pLinedata[iCnt].x;
|
pointOrg.y = pointSet.y = (int)pLinedata[iCnt].y;
|
pointOrg.x -= nDetOffset;
|
|
iHorCnt = 0;
|
for(int iU=-1*nDetOffset;iU<nDetOffset;iU++,pointOrg.x++,iHorCnt++)
|
{
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dAdjustTheta)), cos(M_RADIAN(dAdjustTheta)));
|
nValue = pTgt.GetPixel((int)dOutX,(int)dOutY);
|
//nValue = GetSplineValue(EdgeProc,pTgt,dOutX,dOutY);
|
|
if(nValue > 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<nDetOffset*2;iHorCnt++)
|
{
|
if(pSampleHorCnt[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<double>::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<int, CSplinePoint> *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<int, CSplinePoint>::iterator it;
|
vector<pair<int,CSplinePoint>> 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<int, CSplinePoint> *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<int, CSplinePoint>::iterator itData,itLoop;
|
CSplinePoint *splinePos;
|
|
|
for(itData=pPos->begin();itData!=pPos->end();itData++)
|
{
|
splinePos = static_cast<CSplinePoint*>(&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<CSplinePoint*>(&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<int, CPoint>::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<int, CPoint> *pMasterData = m_pSpModel->GetMasterData();
|
|
for(it=pMasterData->begin();it!=pMasterData->end();it++)
|
{
|
pointData = static_cast<CPoint>(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<rectIns.bottom;v++,dv++)
|
{
|
CopyMemory(pTgt+dv*rectIns.Width(),pOrg+v*szImg.cx+rectIns.left,rectIns.Width());
|
}
|
|
return TRUE;
|
}
|
|
BOOL CSplineInspect::MakeCADLine(CHIP_INS_REGION & insRegion,std::multimap<int, CPoint> &mapData,CPoint &pointMin,CPoint &pointMax,SPLINECHIP_INS_METHOD enOpt)
|
{
|
if(m_pSpModel == NULL)
|
return FALSE;
|
|
std::multimap<int, CPoint> *pMasterData = m_pSpModel->GetMasterData();
|
CPoint ptMasterMin = m_pSpModel->GetptMasterMin();
|
|
if((int)pMasterData->size() <= 0)
|
return FALSE;
|
|
int nStartX,nEndX;
|
CPoint pointData;
|
std::multimap<int, CPoint>::iterator it;
|
std::multimap<int, CPoint>::iterator lowerIter;
|
std::multimap<int, CPoint>::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<CPoint>(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<CPoint>(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<int, CPoint> &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;u++)
|
{
|
pImgPos[u] = -1;
|
pCADPos[u] = -1;
|
}
|
|
BOOL bFirstFind = FALSE;
|
int nPreFind = 0;
|
|
int nFindStartY = nGap;
|
int nFindEndY = pBin.GetHeight();
|
|
for(u=nWidth-1;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<nFindEndY;v++)
|
{
|
if(*pBin.GetDataAddress(u*nSampling,v) == 255)
|
{
|
pImgPos[u] = v;
|
bFirstFind = TRUE;
|
nPreFind = v;
|
break;
|
}
|
}
|
if(pImgPos[u] == 0)
|
pImgPos[u] = -1;
|
}
|
|
std::multimap<int, CPoint>::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<CPoint>(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<nWidth;u++)
|
{
|
if(pCADPos[u] != -1 && pImgPos[u] != -1)
|
{
|
nOffsety += pImgPos[u]-pCADPos[u];
|
nOffsetCnt++;
|
}
|
}
|
|
if(nOffsetCnt > 0)
|
dYPos = (double)nOffsety/(double)nOffsetCnt;
|
|
delete[] pImgPos, pImgPos=NULL;
|
delete[] pCADPos, pCADPos=NULL;
|
|
return dYPos;
|
}
|
|
void CSplineInspect::MakeInspectResultImage(CSISBuffer &pRes,std::multimap<int, CSplinePoint> &mapIns)
|
{
|
std::multimap<int, CSplinePoint>::iterator itData;
|
CSplinePoint splinePos;
|
|
for(itData=mapIns.begin();itData!=mapIns.end();itData++)
|
{
|
splinePos = static_cast<CSplinePoint>(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<int, CPoint> &mapIns)
|
{
|
std::multimap<int, CPoint>::iterator itData;
|
CPoint splinePos;
|
|
for(itData=mapIns.begin();itData!=mapIns.end();itData++)
|
{
|
splinePos = static_cast<CPoint>(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<int, CPoint> *pMaster,std::multimap<int, CSplinePoint> *pData)
|
{
|
std::multimap<int, CPoint>::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<CPoint>(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<int, CSplinePoint>::iterator itData;
|
CSplinePoint splinePos;
|
|
for(itData=pData->begin();itData!=pData->end();itData++)
|
{
|
splinePos = static_cast<CSplinePoint>(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<int, CPoint> &mapData,std::multimap<int, CSplinePoint> &mapIns,double dYPos,SPLINECHIP_INS_METHOD enOpt)
|
{
|
if((int)mapData.size() <= 0)
|
return FALSE;
|
|
int nOffsety = (int)dYPos;
|
std::multimap<int, CPoint>::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<CPoint>(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<nDetOffset;iU++,pointOrg.x++)
|
{
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dTheta)), cos(M_RADIAN(dTheta)));
|
|
nValue = pOrg.GetPixel((int)(dOutX+insRect.left),(int)(dOutY+insRect.top));
|
//nValue = GetSplineValue(EdgeProc,pOrg,dOutX+insRect.left,dOutY+insRect.top);
|
|
if(nValue >= 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<int, CSplinePoint> &mapIns,double dRes,int nJudge,CRect &insRect,BOOL bFlip)
|
{
|
if(m_nDefectCount <= 0)
|
return m_nDefectCount;
|
|
int i;
|
std::multimap<int, CSplinePoint>::iterator it;
|
CSplinePoint *splinePos;
|
std::vector<CChipBlob> vecBlob;
|
int nSize,nDist;
|
int nRange = 2;
|
CPoint ptIns;
|
CRect rect;
|
|
for(i=0;i<m_nDefectCount;i++)
|
{
|
CChipBlob *pChipBlob = &m_ResultDefect[i];
|
|
switch(insRegion.emDir)
|
{
|
case SPLINE_INS_DIRECTION_X:
|
nSize = (int)(pChipBlob->s_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<CSplinePoint*>(&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<CChipBlob>::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<int, CSplinePoint> &mapIns)
|
{
|
std::multimap<int, CSplinePoint>::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<CSplinePoint*>(&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<ptEnd.x ; x++)
|
{
|
nValue = pOrg.GetPixel(x,ptIns.y);
|
if(nValue <= insRegion.nFindThres)
|
{
|
m_ChamferIns.InsertPairing(x-insRect.left,(int)ptIns.y-insRect.top,1,0,0,0,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,FALSE,0);
|
}
|
// else
|
// break;
|
}
|
}
|
}
|
else
|
{
|
for(it=mapIns.begin();it!=mapIns.end();it++)
|
{
|
splinePos = static_cast<CSplinePoint*>(&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<ptEnd.y ; y++)
|
{
|
nValue = pOrg.GetPixel(ptIns.x,y);
|
if(nValue <= insRegion.nFindThres)
|
{
|
m_ChamferIns.InsertPairing((int)ptIns.x-insRect.left,y-insRect.top,1,0,0,0,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,FALSE,0);
|
}
|
// else
|
// break;
|
}
|
}
|
}
|
|
if(m_ChamferIns.GetPairDefectCount() > 0)
|
{
|
std::vector<CChipBlob> vecBlob;
|
m_ChamferIns.BlobDefect_Pixel(vecBlob,0,4);
|
|
if((int)vecBlob.size() > 0)
|
{
|
std::vector<CChipBlob>::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<int, CSplinePoint> &mapIns)
|
{
|
std::multimap<int, CSplinePoint>::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<CSplinePoint*>(&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<ptEnd.x && y<ptEnd.y ; x++)
|
{
|
nValue = pOrg.GetPixel(x, y);
|
|
if(nValue <= insRegion.nFindThres)
|
{
|
int nX = x - insRect.left;
|
int nY = y - insRect.top;
|
|
m_ChamferIns.InsertPairing(nX,nY,1,0,0,0,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,FALSE,0);
|
}
|
}
|
|
/*
|
for(y=ptIns.y ; y<ptEnd.y ; y++)
|
{
|
for(x=ptIns.x ; x<ptEnd.x ; x++)
|
{
|
nValue = pOrg.GetPixel(x, y);
|
|
if(nValue <= insRegion.nFindThres)
|
{
|
int nX = x - insRect.left;
|
int nY = y - insRect.top;
|
|
m_ChamferIns.InsertPairing(nX,nY,1,0,0,0,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,FALSE,0);
|
}
|
}
|
}
|
*/
|
}
|
|
if(m_ChamferIns.GetPairDefectCount() > 0)
|
{
|
std::vector<CChipBlob> vecBlob;
|
m_ChamferIns.BlobDefect_Pixel(vecBlob,0,2);
|
|
if((int)vecBlob.size() > 0)
|
{
|
std::vector<CChipBlob>::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<int, CSplinePoint> &mapIns)
|
{
|
sPoint *pLinedata = NULL;
|
int nLineCnt = 0;
|
double dAdjustTheta;
|
std::multimap<int, CSplinePoint>::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<CSplinePoint*>(&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<CSplinePoint*>(&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<CSplinePoint*> pvecSpPoint;
|
std::vector<CSplinePoint*>::iterator itData;
|
|
pLinedata = new sPoint[nLineSampleDet];
|
for(it=mapIns.begin();it!=mapIns.end();it++)
|
{
|
splinePos = static_cast<CSplinePoint*>(&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<int, CSplinePoint> &mapIns)
|
{
|
std::multimap<int, CSplinePoint>::iterator it;
|
CSplinePoint *splinePos;
|
CResultDefect resDefect;
|
double dOutX,dOutY,dThick;
|
CPoint pointSet;
|
std::vector<CChipPair> vecPair;
|
vector<CChipBlob>::iterator itData;
|
int nDetCnt = 0;
|
|
m_ChamferIns.ResetPairDefect();
|
for(it=mapIns.begin();it!=mapIns.end();it++)
|
{
|
splinePos = static_cast<CSplinePoint*>(&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<CChipBlob> vecBlob;
|
m_ChamferIns.BlobDefect_Pixel(vecBlob,0,4);
|
|
if((int)vecBlob.size() > 0)
|
{
|
std::vector<CChipBlob>::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<int, CPoint> 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<int, CSplinePoint> 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<int, CPoint> 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<int, CSplinePoint> 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<int, CSplinePoint> &mapIns)
|
{
|
std::multimap<int, CSplinePoint>::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<CSplinePoint*>(&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<ptEnd.y ; y++)
|
{
|
for(x=ptIns.x ; x<ptEnd.x ; x++)
|
{
|
nValue = pOrg.GetPixel(x, y);
|
|
if(nValue <= insRegion.nFindThres)
|
{
|
int nX = x - insRect.left;
|
int nY = y - insRect.top;
|
|
if(nX < 0 || pBinBuffer.GetWidth() <= nX )
|
continue;
|
|
if(nY < 0 || pBinBuffer.GetHeight() <= nY )
|
continue;
|
|
pBinBuffer.SetPixel(nX, nY, 255);
|
}
|
}
|
}
|
}
|
|
std::vector<CChipBlob> blobData;
|
|
Blob_OpenCV(&pOrg, &pBinBuffer, insRect, &blobData, CHIPREGTYPE_RIGHT, INS_DEFECT_CHIP, 50, -1, FALSE);
|
|
if((int) blobData.size() > 0)
|
{
|
std::vector<CChipBlob>::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<CChipBlob>* 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<int> 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<int>(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<int>(nIdx, cv::CC_STAT_AREA);
|
int left = matStats.at<int>(nIdx, cv::CC_STAT_LEFT);
|
int top = matStats.at<int>(nIdx, cv::CC_STAT_TOP);
|
int width = matStats.at<int>(nIdx, cv::CC_STAT_WIDTH);
|
int height = matStats.at<int>(nIdx, cv::CC_STAT_HEIGHT);
|
|
int x = (int)matCentrois.at<double>(nIdx, 0);
|
int y = (int)matCentrois.at<double>(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<int, CSplinePoint> &mapIns,double dRes,int nJudge,CRect &insRect,BOOL bFlip)
|
{
|
if(m_nDefectCount <= 0)
|
return m_nDefectCount;
|
|
int i;
|
CSplinePoint *splinePos;
|
std::vector<CChipBlob> vecBlob;
|
int nSizeX, nSizeY;
|
int nRange = 2;
|
CPoint ptIns;
|
CRect rect;
|
|
std::multimap<int, CSplinePoint>::iterator it;
|
std::multimap<int, CSplinePoint>::iterator lowerIter;
|
std::multimap<int, CSplinePoint>::iterator upperIter;
|
|
for(i=0;i<m_nDefectCount;i++)
|
{
|
CChipBlob *pChipBlob = &m_ResultDefect[i];
|
|
nSizeX = (int)(pChipBlob->s_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<CSplinePoint*>(&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<CChipBlob>::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;ix<m_lpBuffer->GetWidth()-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;iy<m_lpBuffer->GetHeight();iy++)
|
{
|
for(ix=0;ix<m_lpBuffer->GetWidth();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;iLoop<m_lpBuffer->GetHeight()*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<int,int> 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<arrIndex.GetSize();iLoop++)
|
{
|
if(m_pContourMap[iy][ix] == arrIndex.GetAt(iLoop))
|
{
|
bFind = TRUE;
|
break;
|
}
|
}
|
if(bFind == FALSE)
|
arrIndex.Add(m_pContourMap[iy][ix]);
|
}
|
}
|
}
|
|
int nMaxIdx = 0,nMaxVal = 0,nIdx=0;
|
nMaxIdx = -1;
|
for(iLoop=0;iLoop<arrIndex.GetSize();iLoop++)
|
{
|
nIdx = arrIndex.GetAt(iLoop);
|
if(m_pContourCnt[nIdx] > 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;ix<m_lpBuffer->GetWidth();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;i<m_lpBuffer->GetHeight();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;
|
}
|