#include "StdAfx.h"
|
#include "NotchCut.h"
|
#include "SISMatch.h"
|
#include <math.h>
|
#include <algorithm>
|
#include "EdgeFind.h"
|
#include "EdgeProc.h"
|
|
#define M_PI acos(-1.0)
|
#define M_RADIAN(x) (((M_PI)*(x))/180.0)
|
//#define SAVE_NOTCH_DEBUG_IMAGE
|
|
#define DETECT_BROKEN_COUNT 5
|
#define DETECT_WHITE_CONTI_COUNT 3
|
#define DETECT_CHIP_MULTI_RATIO 1.1
|
|
CNotchCut::CNotchCut(void)
|
{
|
m_nDefectCount = 0;
|
m_strSavePath = "";
|
m_bSaveDebug = FALSE;
|
}
|
|
CNotchCut::~CNotchCut(void)
|
{
|
|
}
|
|
void CNotchCut::Reset()
|
{
|
m_InsParm.Reset();
|
for(int i=0; i<MAX_NOTCH_SCAN_COUNT; i++)
|
{
|
m_MasterParm[i].Reset();
|
m_AlignMasterParm[i].Reset();
|
}
|
m_ObjectInfo.Reset();
|
ResetData();
|
}
|
|
BOOL CNotchCut::CopyModelData(CNotchCut *pNotch)
|
{
|
if(pNotch == NULL)
|
return FALSE;
|
|
int iDim;
|
std::multimap<int, CPoint>::iterator it;
|
CPoint pointData,pointMove;
|
|
for (iDim=0; iDim<MAX_NOTCH_SCAN_COUNT; iDim++)
|
{
|
m_mapOrgMaster[iDim].clear();
|
m_mapAlignMaster[iDim].clear();
|
|
for(it=pNotch->m_mapOrgMaster[iDim].begin();it!=pNotch->m_mapOrgMaster[iDim].end();it++)
|
{
|
pointData = static_cast<CPoint>(it->second);
|
m_mapOrgMaster[iDim].insert(std::make_pair(pointData.y, pointData));
|
}
|
|
if(pNotch->m_MasterParm[iDim].imgBuf.IsValidBuffer() == TRUE && pNotch->m_MasterParm[iDim].bLoad == TRUE)
|
{
|
m_MasterParm[iDim].imgBuf.SetSize(pNotch->m_MasterParm[iDim].imgBuf.GetDataWidth(),pNotch->m_MasterParm[iDim].imgBuf.GetHeight());
|
CopyMemory(m_MasterParm[iDim].imgBuf.GetDataAddress(),pNotch->m_MasterParm[iDim].imgBuf.GetDataAddress(),sizeof(BYTE)*pNotch->m_MasterParm[iDim].imgBuf.GetDataSize());
|
|
m_MasterParm[iDim].bLoad = pNotch->m_MasterParm[iDim].bLoad;
|
m_MasterParm[iDim].nPosX = pNotch->m_MasterParm[iDim].nPosX;
|
m_MasterParm[iDim].nPosY = pNotch->m_MasterParm[iDim].nPosY;
|
}
|
}
|
|
return TRUE;
|
}
|
|
BOOL CNotchCut::AdjustTilt(int index,double dTheta,double baseCenY)
|
{
|
if(index < 0 || index >= MAX_NOTCH_SCAN_COUNT || (int)m_mapOrgMaster[index].size() <= 0 || (int)m_mapOrgMaster_InsPos[index].size() <= 0)//20140528
|
return FALSE;
|
|
m_mapAlignMaster[index].clear();
|
m_mapAlignMaster_InsPos[index].clear();//20140528
|
|
int nStartY = (int)((double)baseCenY/m_InsParm.dCamRes-(double)(m_MasterParm[index].nPosY));
|
std::multimap<int, CPoint>::iterator it;
|
CPoint pointData,pointMove,pointMax;
|
|
pointMax = CPoint(0,0);
|
for(it=m_mapOrgMaster[index].begin();it!=m_mapOrgMaster[index].end();it++)
|
{
|
pointData = static_cast<CPoint>(it->second);
|
|
pointMove.x = static_cast<int>(static_cast<double>(pointData.x-m_MasterParm[index].nPosX) * cos(dTheta) - static_cast<double>(pointData.y+nStartY) * sin(dTheta));
|
pointMove.y = static_cast<int>(static_cast<double>(pointData.y+nStartY) * cos(dTheta) + static_cast<double>(pointData.x-m_MasterParm[index].nPosX) * sin(dTheta));
|
|
pointMove.Offset(m_MasterParm[index].nPosX,-nStartY);
|
m_mapAlignMaster[index].insert(std::make_pair(pointMove.y, pointMove));
|
|
if(pointMax.x < pointMove.x)
|
pointMax.x = pointMove.x;
|
if(pointMax.y < pointMove.y)
|
pointMax.y = pointMove.y;
|
}
|
|
for(it=m_mapOrgMaster_InsPos[index].begin();it!=m_mapOrgMaster_InsPos[index].end();it++)//20140528
|
{
|
pointData = static_cast<CPoint>(it->second);
|
|
pointMove.x = static_cast<int>(static_cast<double>(pointData.x-m_MasterParm[index].nPosX) * cos(dTheta) - static_cast<double>(pointData.y+nStartY) * sin(dTheta));
|
pointMove.y = static_cast<int>(static_cast<double>(pointData.y+nStartY) * cos(dTheta) + static_cast<double>(pointData.x-m_MasterParm[index].nPosX) * sin(dTheta));
|
|
pointMove.Offset(m_MasterParm[index].nPosX,-nStartY);
|
m_mapAlignMaster_InsPos[index].insert(std::make_pair(pointMove.y, pointMove));
|
}
|
|
if(m_bSaveDebug == TRUE)
|
{
|
COwnerBuffer imgBuf(pointMax.x*2,pointMax.y*2);
|
ZeroMemory(imgBuf.GetDataAddress(),sizeof(BYTE)*imgBuf.GetDataSize());
|
for(it=m_mapAlignMaster[index].begin();it!=m_mapAlignMaster[index].end();it++)
|
{
|
pointData = static_cast<CPoint>(it->second);
|
if(pointData.x < 0 || pointData.y < 0 || pointData.x >= imgBuf.GetWidth() || pointData.y >= imgBuf.GetHeight())
|
continue;
|
|
imgBuf.SetPixel(pointData.x,pointData.y,255);
|
}
|
|
for(it=m_mapAlignMaster_InsPos[index].begin();it!=m_mapAlignMaster_InsPos[index].end();it++)//20140528
|
{
|
pointData = static_cast<CPoint>(it->second);
|
if(pointData.x < 0 || pointData.y < 0 || pointData.x >= imgBuf.GetWidth() || pointData.y >= imgBuf.GetHeight())
|
continue;
|
|
imgBuf.SetPixel(pointData.x,pointData.y,128);
|
}
|
|
{
|
CString str;
|
str.Format(_T("D:\\Image\\TiltAlign.bmp"),m_strSavePath);//20140528
|
CBufferAttach attach(str);
|
attach.AttachToFile(imgBuf);
|
}
|
}
|
|
m_AlignMasterParm[index].nPosX = static_cast<int>(static_cast<double>(m_MasterParm[index].nPosX) * cos(dTheta) - static_cast<double>(m_MasterParm[index].nPosY+nStartY) * sin(dTheta));
|
m_AlignMasterParm[index].nMaxX = static_cast<int>(static_cast<double>(m_MasterParm[index].nMaxX) * cos(dTheta) - static_cast<double>(m_MasterParm[index].nPosY+nStartY) * sin(dTheta));
|
m_AlignMasterParm[index].nPosY = static_cast<int>(static_cast<double>(m_MasterParm[index].nPosY+nStartY) * cos(dTheta) + static_cast<double>(m_MasterParm[index].nPosX) * sin(dTheta));
|
m_AlignMasterParm[index].nPosY -= nStartY;
|
m_AlignMasterParm[index].nMaxY = m_AlignMasterParm[index].nPosY;
|
|
return TRUE;
|
}
|
|
BOOL CNotchCut::LoadData(CString strFile)
|
{
|
BOOL bLoad = FALSE;
|
CString str;
|
CSISImageBuffer imgFile;
|
|
for (int i=0; i<MAX_NOTCH_SCAN_COUNT; i++)
|
{
|
str.Format(_T("%s_[%d].notch"),strFile,i);
|
bLoad |= ReadModelData(str,i);
|
|
str.Format(_T("%s_[%d]_notch.bmp"),strFile,i);
|
if(imgFile.ReadFromFile(str) == TRUE)
|
{
|
m_MasterParm[i].bLoad = TRUE;
|
m_MasterParm[i].imgBuf.SetSize(imgFile.GetDataWidth(),imgFile.GetHeight());
|
CopyMemory(m_MasterParm[i].imgBuf.GetDataAddress(),imgFile.GetDataAddress(),sizeof(BYTE)*imgFile.GetDataSize());
|
imgFile.ReleaseImage();
|
}
|
if(m_MasterParm[i].bLoad == TRUE)
|
{
|
FindCenterPos(m_MasterParm[i].imgBuf,m_MasterParm[i].nPosX,m_MasterParm[i].nPosY);
|
}
|
}
|
|
return bLoad;
|
}
|
|
void CNotchCut::FindRealPos(CSISBuffer &pOrg,CSISBuffer &pBin,int iLeftLine,int &nCenX,int &nCenY
|
,int *nStartX,int *nFisrtY,int *nLastY,int iCam,int iDem,int nSkipSize)
|
{
|
if(pBin.IsValidBuffer() == FALSE || pOrg.IsValidBuffer() == FALSE)
|
return;
|
|
#define DEFECT_EDGE_AUTO_RATIO 0.3
|
#define DEFECT_EDGE_AUTO_PITCH 15
|
#define DEFECT_EDGE_CONTINUE 3
|
#define DETECT_EDGE_HEIGHT 10
|
|
CEdgeFind EdgeFind;
|
CRect rect;
|
int nCalSize = 50;
|
const int nSkipLeft = 40;
|
const int nVMargin = 10;
|
int nLeftLine[2],nMaxLeft;
|
int iStartU = iLeftLine-nSkipLeft;
|
|
if(iStartU < 0)
|
iStartU = 0;
|
|
|
rect = CRect(iStartU,nVMargin,pBin.GetWidth(),nCalSize+nVMargin);//+nSkipSizeÃß°¡
|
nLeftLine[0] = FindLeftLineReal(pBin,rect,0);//50°³ÀÇ Left °ª Æò±Õ(10~60)
|
|
rect = CRect(iStartU,pBin.GetHeight()-nCalSize-nVMargin,pBin.GetWidth(),pBin.GetHeight()-nVMargin);//50°³ÀÇ Left °ª Æò±Õ(pImg.GetHeight()-60~pImg.GetHeight()-10)
|
nLeftLine[1] = FindLeftLineReal(pBin,rect,0);
|
|
nMaxLeft = max(nLeftLine[0],nLeftLine[1]);
|
// nCenX = min(nLeftLine[0],nLeftLine[1]);
|
|
rect = CRect(nMaxLeft+nSkipSize,0,pBin.GetWidth()-1,pBin.GetHeight());
|
FindRealAccumXY(pBin,rect,255,nStartX,nFisrtY,nLastY);
|
nCenY = (int)FindRealAccumYPos(pBin,nSkipSize,255,nLeftLine);
|
if(nCenY <= 0)
|
return;
|
|
rect = CRect(nMaxLeft+nSkipSize,nCenY-DETECT_EDGE_HEIGHT,pOrg.GetWidth()-1,nCenY+DETECT_EDGE_HEIGHT);
|
CCropBuffer cropBuf(pOrg,rect);
|
|
int nRelLeft = EdgeFind.Find_LeftEdge(&cropBuf,DEFECT_EDGE_AUTO_PITCH,m_InsParm.nEdgeThres,DEFECT_EDGE_AUTO_RATIO,DEFECT_EDGE_CONTINUE);
|
if(nRelLeft > 0)
|
nCenX = nRelLeft+rect.left;
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString strImg;
|
strImg.Format(_T("%s\\[%d,%d]EdgeCrop_%d_%d_[%d,%d]_s[%d]_[%d,%d].bmp"),m_strSavePath,iCam,iDem,nMaxLeft+nSkipSize,nCenY,nRelLeft,nCenX,nSkipSize,nLeftLine[0],nLeftLine[1]);
|
CBufferAttach attach(strImg);
|
attach.AttachToFile(cropBuf);
|
}
|
|
//MakeFoldImage(pBin,nCenY);
|
}
|
|
void CNotchCut::FindCenterPos(CSISBuffer &pImg,int &nPosX,int &nPosY,int nSkipSize)
|
{
|
if(pImg.IsValidBuffer() == FALSE)
|
return;
|
|
CRect rect;
|
int nCalSize = 50;
|
const int nSkipLeft = 40;
|
int nLeftLine[2],nMaxLeft;
|
|
rect = CRect(0,nSkipSize,pImg.GetWidth(),nCalSize);
|
nLeftLine[0] = FindLeftLine(pImg,rect,255);
|
|
rect = CRect(0,pImg.GetHeight()-nCalSize-nSkipSize,pImg.GetWidth(),pImg.GetHeight()-nSkipSize);
|
nLeftLine[1] = FindLeftLine(pImg,rect,255);
|
|
nMaxLeft = max(nLeftLine[0],nLeftLine[1]);
|
nPosX = nLeftLine[0];
|
|
rect = CRect(nMaxLeft+nSkipLeft,0,pImg.GetWidth()-1,pImg.GetHeight());
|
nPosY = FindAccumYPos(pImg,rect,255);
|
|
// MakeFoldImage(pImg,nPosY);
|
}
|
|
void CNotchCut::MakeFoldImage(CSISBuffer &pImg,int nPosY)
|
{
|
if(nPosY <= 0)
|
return;
|
|
COwnerBuffer pFoldImg(pImg.GetWidth(),nPosY+1);
|
ZeroMemory(pFoldImg.GetDataAddress(0,0),pFoldImg.GetDataSize());
|
|
int u,v,vPos;
|
|
for(v=0;v<=nPosY;v++)
|
{
|
CopyMemory(pFoldImg.GetDataAddress(0,v),pImg.GetDataAddress(0,v),sizeof(BYTE)*pImg.GetWidth());
|
}
|
|
CRect rect;
|
|
vPos = nPosY+1;
|
for(v=nPosY-1;v>=0;v--,vPos++)
|
{
|
if(pImg.GetHeight() <= vPos)
|
break;
|
|
for(u=0;u<pImg.GetWidth();u++)
|
{
|
if(*pImg.GetDataAddress(u,vPos) == 0 && *pImg.GetDataAddress(u,v) == 0)
|
{
|
pFoldImg.SetPixel(u,v,180);
|
}
|
else if(*pImg.GetDataAddress(u,v) == 0 && *pImg.GetDataAddress(u,vPos) != 0)
|
pFoldImg.SetPixel(u,v,0);
|
else
|
pFoldImg.SetPixel(u,v,80);
|
}
|
}
|
|
CString str;
|
str = "D:\\Image\\NotchCut\\FoldImg.bmp";
|
CBufferAttach attach(str);
|
attach.AttachToFile(pFoldImg);
|
|
}
|
|
void CNotchCut::FindYPosPixel(CSISBuffer &pImg,CRect rect,std::vector<int> *vList,int nThres,int u,BOOL bDir)
|
{
|
int v;
|
|
vList->clear();
|
for(v=rect.top;v<rect.bottom;v++)
|
{
|
if(bDir == TRUE)
|
{
|
if(*pImg.GetDataAddress(u,v) >= nThres)
|
{
|
vList->push_back(v);
|
}
|
}
|
else
|
{
|
if(*pImg.GetDataAddress(u,v) <= nThres)
|
{
|
vList->push_back(v);
|
}
|
}
|
}
|
}
|
|
void CNotchCut::FindYPosMerge(std::vector<int> *vList,std::vector<NOTCH_Merge_STU> *vMergeList)
|
{
|
NOTCH_Merge_STU stuMerge,stuMax;
|
std::vector<int>::iterator it;
|
|
vMergeList->clear();
|
stuMerge.Reset();
|
stuMax.Reset();
|
for(it=vList->begin();it!=vList->end();it++)
|
{
|
if(stuMerge.nStart == -1)
|
stuMerge.nStart = *it;
|
else
|
{
|
if(stuMerge.nEnd == -1)
|
{
|
if(abs(stuMerge.nStart - *it) > 1)
|
{
|
stuMerge.nEnd = *it;
|
stuMerge.nSize = abs(stuMerge.nEnd-stuMerge.nStart)+1;
|
|
if(stuMax.nSize < stuMerge.nSize)
|
stuMax = stuMerge;
|
|
stuMerge.Reset();
|
}
|
else
|
stuMerge.nStart = *it;
|
}
|
}
|
}
|
|
vMergeList->push_back(stuMax);
|
}
|
|
void CNotchCut::FindRealYPosMerge(std::vector<int> *vList,std::vector<NOTCH_Merge_STU> *vMergeList)
|
{
|
NOTCH_Merge_STU stuMerge;
|
std::vector<int>::iterator it;
|
|
vMergeList->clear();
|
stuMerge.Reset();
|
for(it=vList->begin();it!=vList->end();it++)
|
{
|
if(stuMerge.nStart == -1)
|
stuMerge.nStart = *it;
|
else
|
{
|
if(stuMerge.nEnd == -1)
|
{
|
if(abs(stuMerge.nStart - *it) > 1)
|
{
|
stuMerge.nEnd = stuMerge.nStart;
|
stuMerge.nSize = abs(stuMerge.nEnd-stuMerge.nStart)+1;
|
vMergeList->push_back(stuMerge);
|
stuMerge.Reset();
|
stuMerge.nStart = *it;
|
}
|
else
|
stuMerge.nEnd = *it;
|
}
|
else
|
{
|
if(abs(stuMerge.nEnd-*it) > 1)
|
{
|
stuMerge.nSize = abs(stuMerge.nEnd-stuMerge.nStart)+1;
|
vMergeList->push_back(stuMerge);
|
stuMerge.Reset();
|
stuMerge.nStart = *it;
|
}
|
else
|
stuMerge.nEnd = *it;
|
}
|
}
|
}
|
|
if(stuMerge.nStart != -1 && stuMerge.nEnd == -1)
|
{
|
stuMerge.nEnd = stuMerge.nStart;
|
stuMerge.nSize = abs(stuMerge.nEnd-stuMerge.nStart)+1;
|
vMergeList->push_back(stuMerge);
|
}
|
else if(stuMerge.nStart != -1 && stuMerge.nEnd != -1 )//&& (int)vMergeList->size() <= 0)//20140528
|
{
|
stuMerge.nSize = abs(stuMerge.nEnd-stuMerge.nStart)+1;
|
vMergeList->push_back(stuMerge);
|
}
|
}
|
|
/*
|
double CNotchCut::FindRealAccumYPos(CSISBuffer &pImg,CRect rect,int nThres,int *nStartX,int *nFirstY,int *nLastY)
|
{
|
int u;
|
int nYpos = 0,nCount = 0;
|
const int nDetCnt = 20;
|
int nNoDetCnt;
|
const int nBreakCnt = 2;
|
|
std::vector<int> vList;
|
NOTCH_Merge_STU stuMerge,stuMax;
|
std::vector<NOTCH_Merge_STU> vMergeList;
|
std::vector<NOTCH_Merge_STU>::iterator it;
|
|
NOTCH_Circle_STU *pPosList=NULL;
|
int iIndex = 0;
|
int nVLineCnt = 0;
|
|
*nStartX = *nFirstY = *nLastY = 0;
|
nNoDetCnt = 0;
|
|
nVLineCnt = rect.Width()+1;
|
pPosList = new NOTCH_Circle_STU[nVLineCnt];
|
ZeroMemory(pPosList,sizeof(NOTCH_Circle_STU)*nVLineCnt);
|
|
for(u=rect.left;u<rect.right;u++)
|
{
|
//FindYPosPixel(pImg,rect,&vList,nThres,u,FALSE);//ÀÌÁøÈµÈ ¿µ»ó¿¡¼ ¹à±â°¡ 0ÀÎ ºÎºÐÀÇ YÁÂÇ¥¸¦ ã´Â´Ù
|
FindYPosPixel(pImg,rect,&vList,nThres,u);
|
|
FindRealYPosMerge(&vList,&vMergeList);
|
|
if((int)vMergeList.size() <= 0)
|
{
|
nNoDetCnt++;
|
if(nNoDetCnt >= nBreakCnt)
|
break;
|
}
|
else
|
{
|
stuMax.Reset();
|
for(it=vMergeList.begin();it!=vMergeList.end();it++)
|
{
|
stuMerge = *it;
|
|
if(stuMerge.nSize > stuMax.nSize)
|
{
|
stuMax = stuMerge;
|
}
|
}
|
|
if(stuMax.nSize <= 100)
|
continue;
|
|
pPosList[iIndex].pointF = PointD(u,stuMerge.nStart);
|
pPosList[iIndex].pointS = PointD(u,stuMerge.nEnd);
|
iIndex++;
|
|
if(*nFirstY <= 0 && *nLastY <= 0)
|
{
|
*nStartX = u;
|
*nFirstY = stuMax.nStart;
|
*nLastY = stuMax.nEnd;
|
}
|
}
|
}
|
|
if(iIndex <= 10)
|
{
|
delete[] pPosList, pPosList=NULL;
|
return 0;
|
}
|
|
// ÃÑ 6Point¿¡ ´ëÇÑ ¿øÀÇ Á߽ɱ¸Çϱâ
|
int i;
|
NOTCH_Circle_STU nCenterPos[3],nLRPos[3];
|
const int nPointCnt = 6;
|
PointD pointCenter[nPointCnt];
|
|
|
nCenterPos[0] = pPosList[iIndex-1];
|
nCenterPos[1] = pPosList[iIndex-2];
|
nCenterPos[2] = pPosList[iIndex-3];
|
|
nLRPos[0] = pPosList[0];
|
nLRPos[1] = pPosList[1];
|
nLRPos[2] = pPosList[2];
|
|
PointD S,M,E;
|
ZeroMemory(pointCenter,sizeof(PointD)*nPointCnt);
|
|
int iLoop = 0;
|
for(i=0;i<3;i++)
|
{
|
S = nLRPos[0].pointF;
|
M = nCenterPos[0].pointF;
|
E = nLRPos[0].pointS;
|
pointCenter[iLoop] = GetCenterPointFrom3Points(S,M,E);
|
TRACE("Center %d = %.3f,%.3f\n",iLoop,pointCenter[iLoop].X,pointCenter[iLoop].Y);
|
iLoop++;
|
|
M = nCenterPos[0].pointS;
|
pointCenter[iLoop] = GetCenterPointFrom3Points(S,M,E);
|
TRACE("Center %d = %.3f,%.3f\n",iLoop,pointCenter[iLoop].X,pointCenter[iLoop].Y);
|
iLoop++;
|
}
|
|
double dSum,dCount,dAvg,dStd;
|
|
dAvg = dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nPointCnt;iIndex++)
|
{
|
dSum += pointCenter[iIndex].Y;
|
dCount++;
|
}
|
|
if(dCount > 0)
|
dAvg = dSum/dCount;
|
|
dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nPointCnt;iIndex++)
|
{
|
dSum += pow((dAvg-pointCenter[iIndex].Y),2);
|
dCount++;
|
}
|
|
dStd = dCount>0?sqrt(dSum/dCount):0.;
|
|
dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nPointCnt;iIndex++)
|
{
|
if(fabs(pointCenter[iIndex].Y-dAvg) > dStd)
|
continue;
|
|
dSum+=pointCenter[iIndex].Y;
|
dCount++;
|
}
|
|
if(dCount > 0)
|
dAvg = dSum/dCount;
|
|
delete[] pPosList, pPosList=NULL;
|
|
return dAvg;
|
}
|
*/
|
|
PointD CNotchCut::GetCenterPointFrom3Points(const PointD& S, const PointD& M, const PointD& E)
|
{
|
double ma = (M.Y - S.Y) / (M.X - S.X);
|
double mb = (E.Y - M.Y) / (E.X - M.X);
|
|
if (ma >= INT_MAX || ma <= INT_MIN)
|
ma = 1000000000000;
|
|
if (mb >= INT_MAX || mb <= INT_MIN)
|
mb = 1000000000000;
|
|
if (ma == 0)
|
ma = 0.000000000001;
|
|
if (mb == 0)
|
mb = 0.000000000001;
|
|
double centerX = (ma * mb * (S.Y - E.Y) + mb * (S.X + M.X) - ma * (M.X + E.X)) / (2 * (mb - ma));
|
double centerY = (-1 * (centerX - (S.X + M.X) / 2) / ma) + ((S.Y + M.Y) / 2);
|
|
return PointD(centerX, centerY);
|
}
|
|
double CNotchCut::FindRealCenter(CSISBuffer &pImg,CRect rect,int nThres,int *nStartX,int *nFirstY,int *nLastY)
|
{
|
int u;
|
int nYpos = 0,nCount = 0;
|
const int nDetCnt = 20;
|
int nNoDetCnt;
|
const int nBreakCnt = 2;
|
double *dVLine = NULL;
|
int iIndex = 0,nVLineCnt;
|
|
std::vector<int> vList;
|
NOTCH_Merge_STU stuMerge,stuMax;
|
std::vector<NOTCH_Merge_STU> vMergeList;
|
std::vector<NOTCH_Merge_STU>::iterator it;
|
|
*nStartX = *nFirstY = *nLastY = 0;
|
nNoDetCnt = 0;
|
|
nVLineCnt = rect.Width()+1;
|
dVLine = new double[nVLineCnt];
|
ZeroMemory(dVLine,sizeof(double)*nVLineCnt);
|
|
for(u=rect.left;u<rect.right;u++,iIndex++)
|
{
|
//FindYPosPixel(pImg,rect,&vList,nThres,u,FALSE);//ÀÌÁøÈµÈ ¿µ»ó¿¡¼ ¹à±â°¡ 0ÀÎ ºÎºÐÀÇ YÁÂÇ¥¸¦ ã´Â´Ù
|
FindYPosPixel(pImg,rect,&vList,nThres,u);
|
|
FindRealYPosMerge(&vList,&vMergeList);
|
|
if((int)vMergeList.size() <= 0)
|
{
|
nNoDetCnt++;
|
if(nNoDetCnt >= nBreakCnt)
|
break;
|
}
|
else
|
{
|
stuMax.Reset();
|
for(it=vMergeList.begin();it!=vMergeList.end();it++)
|
{
|
stuMerge = *it;
|
|
if(stuMerge.nSize > stuMax.nSize)
|
{
|
stuMax = stuMerge;
|
}
|
}
|
|
if(stuMax.nSize <= 50)
|
continue;
|
|
nYpos = nCount = 0;
|
for(int i=stuMax.nStart;i<=stuMax.nEnd;i++)
|
{
|
nYpos += i;
|
nCount++;
|
}
|
|
if(nCount > 0)
|
{
|
if(iIndex < nVLineCnt)
|
{
|
dVLine[iIndex] = (double)nYpos/(double)nCount;
|
TRACE("VLine : index %d, VLine %.2f\n",iIndex,dVLine[iIndex]);
|
}
|
}
|
|
if(*nFirstY <= 0 && *nLastY <= 0)
|
{
|
*nStartX = u;
|
*nFirstY = stuMax.nStart;
|
*nLastY = stuMax.nEnd;
|
}
|
}
|
}
|
|
double dSum,dCount,dAvg,dStd;
|
|
dAvg = dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nVLineCnt;iIndex++)
|
{
|
if(dVLine[iIndex] <= 0)
|
continue;
|
dSum += dVLine[iIndex];
|
dCount++;
|
}
|
|
if(dCount > 0)
|
dAvg = dSum/dCount;
|
|
dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nVLineCnt;iIndex++)
|
{
|
if(dVLine[iIndex] <= 0)
|
continue;
|
|
dSum += pow((dAvg-dVLine[iIndex]),2);
|
dCount++;
|
}
|
|
dStd = dCount>0?sqrt(dSum/dCount):0.;
|
|
dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nVLineCnt;iIndex++)
|
{
|
if(dVLine[iIndex] <= 0)
|
continue;
|
|
if(fabs(dVLine[iIndex]-dAvg) > dStd)
|
continue;
|
|
dSum+=dVLine[iIndex];
|
dCount++;
|
}
|
|
if(dCount > 0)
|
dAvg = dSum/dCount;
|
|
delete[] dVLine, dVLine=NULL;
|
|
return dAvg;
|
}
|
|
void CNotchCut::FindRealAccumXY(CSISBuffer &pImg,CRect rect,int nThres,int *nStartX,int *nFirstY,int *nLastY)
|
{
|
int u;
|
std::vector<int> vList;
|
NOTCH_Merge_STU stuMerge,stuMax;
|
std::vector<NOTCH_Merge_STU> vMergeList;
|
std::vector<NOTCH_Merge_STU>::iterator it;
|
|
*nStartX = *nFirstY = *nLastY = 0;
|
|
for(u=rect.left;u<rect.right;u++)
|
{
|
//FindYPosPixel(pImg,rect,&vList,nThres,u,FALSE);//ÀÌÁøÈµÈ ¿µ»ó¿¡¼ ¹à±â°¡ 0ÀÎ ºÎºÐÀÇ YÁÂÇ¥¸¦ ã´Â´Ù
|
FindYPosPixel(pImg,rect,&vList,nThres,u);
|
|
FindRealYPosMerge(&vList,&vMergeList);
|
|
if((int)vMergeList.size() <= 0)
|
{
|
continue;
|
}
|
else
|
{
|
stuMax.Reset();
|
for(it=vMergeList.begin();it!=vMergeList.end();it++)
|
{
|
stuMerge = *it;
|
|
if(stuMerge.nSize > stuMax.nSize)
|
{
|
stuMax = stuMerge;
|
}
|
}
|
|
if(stuMax.nSize <= 100)
|
continue;
|
|
*nStartX = u;
|
*nFirstY = stuMax.nStart;
|
*nLastY = stuMax.nEnd;
|
break;
|
}
|
}
|
}
|
|
double CNotchCut::FindRealAccumYPos(CSISBuffer &pImg,int nSkipSize,int nThres,int *iLeftLine)
|
{
|
if(iLeftLine[0] <= 0 || iLeftLine[1] <= 0)
|
return 0.;
|
|
int u;
|
int nYpos = 0,nCount = 0;
|
const int nDetCnt = 20;
|
int nNoDetCnt;
|
const int nBreakCnt = 4;
|
double *dVLine = NULL;
|
int iIndex = 0,nVLineCnt;
|
int nMinLeft = min(iLeftLine[0],iLeftLine[1]);
|
int nLoopCnt = 100;
|
int iUp,iDw;
|
CRect rect;
|
const int nSIZE_FILTER= 50;
|
|
std::vector<int> vUpList,vDwList;
|
NOTCH_Merge_STU stuMerge,stuUpMax,stuDwMax;
|
std::vector<NOTCH_Merge_STU> vUpMergeList,vDwMergeList;
|
std::vector<NOTCH_Merge_STU>::iterator it;
|
|
nNoDetCnt = 0;
|
|
nVLineCnt = nLoopCnt+1;
|
dVLine = new double[nVLineCnt];
|
ZeroMemory(dVLine,sizeof(double)*nVLineCnt);
|
|
iUp = iLeftLine[0]+nSkipSize;
|
iDw = iLeftLine[1]+nSkipSize;
|
|
rect = CRect(0,0,0,pImg.GetHeight());
|
|
for(u=0;u<nLoopCnt;u++,iIndex++,iUp++,iDw++)
|
{
|
if(nNoDetCnt >= nBreakCnt)
|
break;
|
|
FindYPosPixel(pImg,rect,&vUpList,nThres,iUp);
|
FindRealYPosMerge(&vUpList,&vUpMergeList);
|
|
if((int)vUpMergeList.size() <= 0)
|
{
|
nNoDetCnt++;
|
continue;
|
}
|
|
stuUpMax.Reset();
|
for(it=vUpMergeList.begin();it!=vUpMergeList.end();it++)
|
{
|
stuMerge = *it;
|
if(stuMerge.nSize > stuUpMax.nSize)
|
stuUpMax = stuMerge;
|
}
|
if(stuUpMax.nSize <= nSIZE_FILTER)
|
{
|
nNoDetCnt++;
|
continue;
|
}
|
|
FindYPosPixel(pImg,rect,&vDwList,nThres,iDw);
|
FindRealYPosMerge(&vDwList,&vDwMergeList);
|
|
if((int)vDwMergeList.size() <= 0)
|
{
|
nNoDetCnt++;
|
continue;
|
}
|
|
stuDwMax.Reset();
|
for(it=vDwMergeList.begin();it!=vDwMergeList.end();it++)
|
{
|
stuMerge = *it;
|
if(stuMerge.nSize > stuDwMax.nSize)
|
stuDwMax = stuMerge;
|
}
|
if(stuDwMax.nSize <= nSIZE_FILTER)
|
{
|
nNoDetCnt++;
|
continue;
|
}
|
|
if(stuUpMax.nStart >= stuDwMax.nEnd)
|
{
|
nNoDetCnt++;
|
continue;
|
}
|
|
nYpos = nCount = 0;
|
for(int i=stuUpMax.nStart;i<=stuDwMax.nEnd;i++)
|
{
|
nYpos += i;
|
nCount++;
|
}
|
|
if(nCount > 0)
|
dVLine[iIndex] = ((double)nYpos/(double)nCount)+1;
|
TRACE("VLine : index %d, VLine Up[%d],Dw[%d] %.2f\n",iIndex,iUp,iDw,dVLine[iIndex]);
|
}
|
|
double dSum,dCount,dAvg,dStd;
|
|
dAvg = dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nVLineCnt;iIndex++)
|
{
|
if(dVLine[iIndex] <= 0)
|
continue;
|
dSum += dVLine[iIndex];
|
dCount++;
|
}
|
|
if(dCount > 0)
|
dAvg = dSum/dCount;
|
|
dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nVLineCnt;iIndex++)
|
{
|
if(dVLine[iIndex] <= 0)
|
continue;
|
|
dSum += pow((dAvg-dVLine[iIndex]),2);
|
dCount++;
|
}
|
|
dStd = dCount>0?sqrt(dSum/dCount):0.;
|
|
dSum = dCount = 0.;
|
for(iIndex=0;iIndex<nVLineCnt;iIndex++)
|
{
|
if(dVLine[iIndex] <= 0)
|
continue;
|
|
if(fabs(dVLine[iIndex]-dAvg) > dStd)
|
continue;
|
|
dSum+=dVLine[iIndex];
|
dCount++;
|
}
|
|
if(dCount > 0)
|
dAvg = (dSum/dCount)+0.5;
|
|
delete[] dVLine, dVLine=NULL;
|
|
return dAvg;
|
}
|
|
|
int CNotchCut::FindAccumYPos(CSISBuffer &pImg,CRect rect,int nThres)
|
{
|
int u;
|
int nYpos = 0,nCount = 0;
|
int nNoDetCnt;
|
const int nBreakCnt = 5;
|
|
std::vector<int> vList;
|
std::vector<NOTCH_Merge_STU> vMergeList;
|
NOTCH_Merge_STU stuMerge,stuMax;
|
std::vector<NOTCH_Merge_STU>::iterator it;
|
|
nNoDetCnt = 0;
|
for(u=rect.left;u<rect.right;u++)
|
{
|
FindYPosPixel(pImg,rect,&vList,nThres,u);
|
|
FindYPosMerge(&vList,&vMergeList);
|
|
if((int)vMergeList.size() <= 0)
|
{
|
nNoDetCnt++;
|
if(nNoDetCnt >= nBreakCnt)
|
break;
|
}
|
else
|
{
|
stuMax.Reset();
|
for(it=vMergeList.begin();it!=vMergeList.end();it++)
|
{
|
stuMerge = *it;
|
|
if(stuMerge.nSize > stuMax.nSize)
|
{
|
stuMax = stuMerge;
|
}
|
}
|
|
if(stuMax.nSize <= 0)
|
continue;
|
|
for(int i=stuMax.nStart;i<=stuMax.nEnd;i++)
|
{
|
nYpos += i;
|
nCount++;
|
}
|
}
|
}
|
|
return nCount>0?nYpos/nCount:-1;
|
}
|
|
int CNotchCut::FindLeftLine(CSISBuffer &pImg,CRect rect,int nThres)
|
{
|
int u,v;
|
int nLeft = 0,nCount = 0;
|
|
for(v=rect.top;v<rect.bottom;v++)
|
{
|
for(u=rect.left;u<rect.right;u++)
|
{
|
if(*pImg.GetDataAddress(u,v) >= nThres)
|
{
|
nLeft += u;
|
nCount++;
|
break;
|
}
|
}
|
}
|
|
return nCount>0?nLeft/nCount:-1;
|
}
|
|
int CNotchCut::FindLeftLineReal(CSISBuffer &pImg,CRect rect,int nThres)
|
{
|
int u,v;
|
int nLeft = 0,nCount = 0;
|
|
for(v=rect.top;v<rect.bottom;v++)
|
{
|
for(u=rect.left;u<rect.right;u++)
|
{
|
if(*pImg.GetDataAddress(u,v) <= nThres)
|
{
|
nLeft += u;
|
nCount++;
|
break;
|
}
|
}
|
}
|
|
return nCount>0?nLeft/nCount:-1;
|
}
|
|
void CNotchCut::SetParm(NOTCH_Parm_STU &parm)
|
{
|
m_InsParm = parm;
|
}
|
|
void CNotchCut::AssertRect(CRect &rect,CSISBuffer pOrg)
|
{
|
if(rect.left < 0) rect.left = 0;
|
if(rect.top < 0) rect.top = 0;
|
if(rect.right < 0) rect.right = 0;
|
if(rect.bottom < 0) rect.bottom = 0;
|
|
if(rect.left > rect.right) std::swap(rect.left,rect.right);
|
if(rect.top > rect.bottom) std::swap(rect.top,rect.bottom);
|
}
|
|
void CNotchCut::ResetData()
|
{
|
m_mapMaster.clear();
|
m_mapMaster_InsPos.clear();//20140528
|
m_mapChipData.clear();
|
m_nDefectCount = 0;
|
m_bSaveDebug = FALSE;
|
m_nNoDetCount = m_nTotalCount = 0;
|
}
|
|
int CNotchCut::NotchExecute(CSISBuffer &pOrg,double *dResult,double *dResult_Dy,pNOTCH_RangePos_STU pRangeRes,pNOTCH_RangePos_STU pRangeRes_Dy,pNOTCH_RangePos_STU pRangeRes_Cham, int nRangeCnt,COwnerBuffer &pRes,COwnerBuffer &pRes_Dy, COwnerBuffer &pRes_Cham, double *dAvgThick, int iDimension
|
, double *dFeedbackXY, int icam,double *dGlassXY,double dAlign2GlassX,int iLeftLine,BOOL bSaveDebug,CString strSavePath, double dTheta)//20140528
|
{
|
ResetData();
|
|
m_bSaveDebug = bSaveDebug;
|
ZeroMemory(pRangeRes,sizeof(NOTCH_RangePos_STU)*nRangeCnt);
|
ZeroMemory(pRangeRes_Dy,sizeof(NOTCH_RangePos_STU)*nRangeCnt);
|
ZeroMemory(pRangeRes_Cham,sizeof(NOTCH_RangePos_STU)*nRangeCnt);//20140528
|
ZeroMemory(dResult,sizeof(double)*2);
|
ZeroMemory(dResult_Dy,sizeof(double)*2);
|
ZeroMemory(dFeedbackXY,sizeof(double)*2);
|
ZeroMemory(dGlassXY,sizeof(double)*2);
|
*dAvgThick = 0.;
|
|
|
if(m_InsParm.bChipIns == FALSE && m_InsParm.bSizeIns == FALSE)
|
return NORMAL_EXE;
|
|
if(pOrg.IsValidBuffer() == FALSE)
|
return ERR_NO_ORGIMG;
|
|
int nErrCode = NORMAL_EXE;
|
CRect rectOrg;
|
|
if(m_bSaveDebug == TRUE)
|
{
|
m_strSavePath.Format(_T("%s\\NotchCut"),strSavePath);
|
CString str;
|
CreateDirectory(m_strSavePath,NULL);
|
str.Format(_T("%s\\1.Notch_Org_%d_%d.bmp"),m_strSavePath,icam,iDimension);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pOrg);
|
}
|
|
|
CRect rectEdge;
|
CEdgeProc EdgeProc;
|
// CEdgeFind EdgeFind;
|
|
// #define DEFECT_EDGE_AUTO_RATIO 0.3
|
// #define DEFECT_EDGE_AUTO_PITCH 15
|
// #define DEFECT_EDGE_CONTINUE 3
|
// rectEdge = CRect(0,0,pOrg.GetWidth(),100);
|
// CSISBuffer EdgeBuf(pOrg.GetDataAddress(),pOrg.GetDataWidth(),100);
|
// //m_ObjectInfo.nEdgeTop = (int)EdgeFind.FindGlassHorizontalLine(pOrg.GetDataAddress(0,0),CSize(pOrg.GetDataWidth(),pOrg.GetHeight()),rectEdge,m_InsParm.nEdgeThres,TRUE);
|
// m_ObjectInfo.nEdgeTop = EdgeFind.Find_LeftEdge(&EdgeBuf,DEFECT_EDGE_AUTO_PITCH,m_InsParm.nEdgeThres,DEFECT_EDGE_AUTO_RATIO,DEFECT_EDGE_CONTINUE);
|
|
// rectEdge = CRect(0,pOrg.GetHeight()-100,pOrg.GetWidth(),pOrg.GetHeight());
|
// m_ObjectInfo.nEdgeBot = (int)m_EdgeFind.FindGlassHorizontalLine(pOrg.GetDataAddress(0,0),CSize(pOrg.GetDataWidth(),pOrg.GetHeight()),rectEdge,m_InsParm.nEdgeThres,TRUE);
|
|
COwnerBuffer pBinImg(pOrg.GetWidth(),pOrg.GetHeight());
|
ZeroMemory(pBinImg.GetDataAddress(0,0),pBinImg.GetDataSize());
|
|
rectEdge = CRect(10,pOrg.GetHeight()/2-20,52,pOrg.GetHeight()/2+20);
|
CChamferInspect ChamferIns;
|
|
int nBlankThres = (int)(ChamferIns.GetAreaAVG(pOrg.GetDataAddress(),CRect(0,0,pOrg.GetDataWidth(),pOrg.GetHeight()),rectEdge));
|
|
m_InsParm.nDetThres = (int)((double)nBlankThres * 1.4);
|
|
if(m_InsParm.dBlank2EdgeRatio <= 0)
|
m_InsParm.dBlank2EdgeRatio = 0.8;
|
m_InsParm.nSizeThres = (int)((double)nBlankThres * m_InsParm.dBlank2EdgeRatio);
|
// EdgeFind.Adaptive_Binarization(pOrg.GetDataAddress(0,0),pOrg.GetWidth(),pOrg.GetHeight(),pOrg.GetDataWidth(),20,0.2,pBinImg.GetDataAddress(0,0),rectEdge);
|
|
rectEdge = CRect(0,0,pOrg.GetDataWidth(),pOrg.GetHeight());
|
CSISBuffer::CopyBtoA(pBinImg,0,0,pOrg,rectEdge);
|
EdgeProc.ThresholdProcessing(pBinImg.GetDataAddress(0,0),CSize(pBinImg.GetDataWidth(),pBinImg.GetHeight()),m_InsParm.nDetThres,0);
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\2.Notch_Bin_%d_%d_[%d].bmp"),m_strSavePath,icam,iDimension,m_InsParm.nDetThres);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pBinImg);
|
}
|
|
COwnerBuffer pBin(pOrg.GetWidth(),pOrg.GetHeight());
|
|
CopyMemory(pBin.GetDataAddress(0,0),pOrg.GetDataAddress(0,0),pOrg.GetDataSize());
|
EdgeProc.ThresholdProcessing(pBin.GetDataAddress(0,0),CSize(pBin.GetDataWidth(),pBin.GetHeight()),m_InsParm.nSizeThres,0);
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\3.Notch_Ins_Bin_%d_%d.bmp"),m_strSavePath,icam,iDimension);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pBin);
|
}
|
|
int nCenX,nCenY;
|
int nStartX,nFirstY,nLastY;
|
|
nCenX = nCenY = 0;
|
|
FindRealPos(pOrg,pBinImg,iLeftLine,nCenX,nCenY,&nStartX,&nFirstY,&nLastY,icam,iDimension
|
,(int)((double)m_InsParm.nSkipSize/m_InsParm.dCamRes));
|
|
// nCenX = (int)dAlign2GlassX;//m_ObjectInfo.nEdgeTop;
|
|
MakeReal2AlignCad(pOrg,nCenY,(int)dAlign2GlassX,iDimension,icam);
|
|
if(m_InsParm.bChipIns == TRUE)
|
{
|
Exe_ChipInspect(pBin,pOrg,icam);
|
}
|
|
double dAvgThickTemp=0,dChamferThick;//Chamfer
|
|
//if(m_InsParm.bSizeIns == TRUE)
|
{
|
std::multimap<int,CSplinePoint> mapDist;
|
std::multimap<int,CSplinePoint> mapDist_Dy;
|
std::multimap<int,CSplinePoint> mapChamfer;//20140528
|
|
Inspection_Size(pOrg,pRes,pRes_Dy,pRes_Cham,pBinImg,pBin,&dChamferThick,&dAvgThickTemp,nCenX,nCenY,(int)dAlign2GlassX,dFeedbackXY,iDimension,icam,&mapDist,&mapDist_Dy,dGlassXY,dResult,&mapChamfer,dTheta); //20140528
|
|
//CalRangeVal(&mapDist,dResult,pRangeRes,nRangeCnt,nCenX,nCenY,nStartX,nFirstY,nLastY);//20140528
|
|
CalRangeVal_New(&mapDist,&mapDist_Dy,dResult,dResult_Dy,pRangeRes,pRangeRes_Dy,pRangeRes_Cham,nRangeCnt,nCenX,nCenY,nStartX,nFirstY,nLastY,&mapChamfer);//20140528
|
}
|
|
if(m_InsParm.bChipIns == TRUE)
|
{
|
CRect rectImg(0,0,pOrg.GetWidth(),pOrg.GetHeight());
|
|
AnalysisThick(rectImg,m_InsParm.dCamRes,m_InsParm.nChipDiff,dAvgThickTemp*m_InsParm.dCamRes);
|
}
|
|
*dAvgThick = dChamferThick;
|
|
if(m_nTotalCount > 0)
|
{
|
double dRate = (double)m_nNoDetCount/(double)m_nTotalCount;
|
|
if(dRate >= 0.1)
|
{
|
dResult[1] += ((double)200*m_InsParm.dCamRes);
|
}
|
}
|
|
if(m_nTotalCount > 0)
|
{
|
double dRate = (double)m_nNoDetCount/(double)m_nTotalCount;
|
|
if(dRate >= 0.1)
|
{
|
dResult_Dy[1] += ((double)200*m_InsParm.dCamRes);
|
}
|
}
|
|
SetNotchImgResPoint(&pRes,pRangeRes,nRangeCnt);
|
SetNotchImgResPoint(&pRes_Dy,pRangeRes_Dy,nRangeCnt);
|
SetNotchImgResPoint(&pRes_Cham,pRangeRes_Cham,nRangeCnt);//20140528
|
|
return nErrCode;
|
}
|
|
void CNotchCut::SetNotchImgResPoint(COwnerBuffer *pRes,pNOTCH_RangePos_STU RangeVal,int nRangeCnt)
|
{
|
int iPoint;
|
|
for(iPoint=0;iPoint<nRangeCnt;iPoint++)
|
{
|
bresenham_Line(pRes,RangeVal[iPoint].pointCAD,RangeVal[iPoint].pointImg,255);
|
}
|
}
|
|
// Bresenham's line algorithm
|
void CNotchCut::bresenham_Line(COwnerBuffer *pRes,CPoint posStart,CPoint posEnd,BYTE color)
|
{
|
if(posStart.x <= 0 || posStart.y <= 0 || posEnd.x <= 0 || posEnd.y <= 0)
|
return;
|
|
const bool steep = (abs(posEnd.y - posStart.y) > abs(posEnd.x - posStart.x));
|
|
if(steep)
|
{
|
std::swap(posStart.x, posStart.y);
|
std::swap(posEnd.x, posEnd.y);
|
}
|
|
if(posStart.x > posEnd.x)
|
{
|
std::swap(posStart.x, posEnd.x);
|
std::swap(posStart.y, posEnd.y);
|
}
|
|
const int dx = posEnd.x - posStart.x;
|
const int dy = abs(posEnd.y - posStart.y);
|
|
float error = (float)dx / 2.0f;
|
const int ystep = (posStart.y < posEnd.y) ? 1 : -1;
|
int y = (int)posStart.y;
|
|
const int maxX = (int)posEnd.x;
|
|
for(int x=(int)posStart.x; x<maxX; x++)
|
{
|
if(steep)
|
{
|
pRes->SetPixel(y,x, color);
|
}
|
else
|
{
|
pRes->SetPixel(x,y, color);
|
}
|
|
error -= dy;
|
if(error < 0)
|
{
|
y += ystep;
|
error += dx;
|
}
|
}
|
}
|
|
int CNotchCut::AnalysisThick(CRect rectImg,double dRes,int nJudgeThick,double dAvgThick)
|
{
|
vector<pair<int,CSplinePoint>>::iterator it;
|
CSplinePoint *splinePos;
|
double dThick;
|
std::vector<CChipPair> vecPair;
|
vector<CChipBlob>::iterator itData;
|
CChamferInspect ChamferIns;
|
int nChipSize = (int)((double)nJudgeThick*DETECT_CHIP_MULTI_RATIO);
|
|
for(it=m_mapChipData.begin();it!=m_mapChipData.end();it++)
|
{
|
splinePos = static_cast<CSplinePoint*>(&it->second);
|
if(splinePos == NULL || splinePos->dThick <= 0)
|
continue;
|
|
dThick = fabs((splinePos->dThick*dRes)-dAvgThick);
|
if(dThick > nChipSize)
|
{
|
ChamferIns.InsertPairing(splinePos->rotate.x,splinePos->rotate.y,1,0,0,0,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,FALSE,dAvgThick+dThick);
|
}
|
}
|
|
#define CONTINUE_DEFECT_CNT 3
|
if(ChamferIns.GetPairDefectCount() > 0)
|
{
|
std::vector<CChipBlob> vecBlob;
|
ChamferIns.BlobDefect_Pixel(vecBlob,0,5);
|
|
if((int)vecBlob.size() > 0)
|
{
|
std::vector<CChipBlob>::iterator itBlob;
|
|
for(itBlob=vecBlob.begin();itBlob!=vecBlob.end();itBlob++)
|
{
|
if(m_nDefectCount >= MAX_NOTCH_DEFECT_COUNT)
|
return m_nDefectCount;
|
|
if(itBlob->s_nDefectArea < CONTINUE_DEFECT_CNT)
|
continue;
|
|
CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount];
|
if(pChipBlob == NULL)
|
continue;
|
|
*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;
|
pChipBlob->s_DefectPosType = CHIPPOSTYPE_CEN;
|
pChipBlob->s_DefectRect = CRect(pChipBlob->s_nDefectX,pChipBlob->s_nDefectY,pChipBlob->s_nDefectX,pChipBlob->s_nDefectY);
|
pChipBlob->s_DefectRect.InflateRect(pChipBlob->s_nDefectRScale/2,pChipBlob->s_nDefectRScale/2);
|
|
m_nDefectCount++;
|
}
|
}
|
}
|
|
return m_nDefectCount;
|
}
|
|
void CNotchCut::Inspection_Size(CSISBuffer &pOrg,COwnerBuffer &pRes,COwnerBuffer &pRes_Dy,COwnerBuffer &pRes_Cham,CSISBuffer &pBinEdge,CSISBuffer &pBin,double *dChamferAvgThick,double *dChipAvgThick,int nCenX,int nCenY,int nGlass2Edge,double *dFeedbackXY
|
,int iDimension, int icam, std::multimap<int,CSplinePoint> *mapDist,std::multimap<int,CSplinePoint> *mapDist_Dy,double *dGlassXY,double *dResult,std::multimap<int,CSplinePoint> *mapChamfer,double dTheta)//20140528
|
{
|
int nUpVPos,nDwVPos;
|
|
nUpVPos = 0;
|
nDwVPos = INT_MAX;
|
DistInspection_New(pBin,pOrg,dChamferAvgThick,dChipAvgThick,nCenX,nCenY,nGlass2Edge,dFeedbackXY,iDimension
|
,icam,mapDist,mapDist_Dy,dGlassXY,&nUpVPos,&nDwVPos,mapChamfer,dTheta);//20140528
|
// ZeroMemory(dResult,sizeof(double)*2);
|
// double dRangeRes[5];
|
// DistInspection(pBin,pOrg,dResult,dRangeRes,dAvgThick,nCenX,nCenY,nGlass2Edge,dFeedbackXY,0,icam);
|
|
if(m_bSaveDebug == TRUE)
|
{
|
COwnerBuffer pBin2(pOrg.GetWidth(),pOrg.GetHeight());
|
CEdgeProc EdgeProc;
|
|
CopyMemory(pBin2.GetDataAddress(0,0),pOrg.GetDataAddress(0,0),pOrg.GetDataSize());
|
EdgeProc.ThresholdProcessing(pBin2.GetDataAddress(0,0),CSize(pBin2.GetDataWidth(),pBin2.GetHeight()),m_InsParm.nChipThres,1);
|
|
CString str;
|
str.Format(_T("%s\\4.Notch_Ins_Bin_2_%d_%d.bmp"),m_strSavePath,icam,iDimension);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pBin2);
|
}
|
|
double dThickness = FindCenterThickness(pOrg,pBin,nCenX,nCenY,icam,iDimension);
|
if(dThickness > 0)
|
{
|
*dChamferAvgThick = dThickness;
|
}
|
|
Inspection_SpChip(pBin,pOrg,nGlass2Edge,nUpVPos,nDwVPos);
|
|
|
MakeReal2Cad_Image(pOrg,pRes,128);
|
MakeReal2Cad_Image(pOrg,pRes_Dy,128);
|
MakeReal2Cad_Image(pOrg,pRes_Cham,128);//20140528
|
}
|
|
double CNotchCut::FindCenterThickness(CSISBuffer &pOrg,CSISBuffer &pBin,int nCenX,int nCenY,int icam,int iDimension)
|
{
|
double dThickness = -1;
|
CRect rectCen;
|
int nHorMargin = 400,nVerMargin = 60;
|
CChamferInspect ChamferIns;
|
int nWidth;
|
|
rectCen = CRect(nCenX-nHorMargin,nCenY-nVerMargin,nCenX+nHorMargin,nCenY+nVerMargin);
|
if(rectCen.left < 0)
|
{
|
rectCen.left = 0;
|
nWidth = align_4byte(rectCen.Width());
|
rectCen.right = rectCen.left+nWidth;
|
}
|
if(rectCen.right >= pOrg.GetWidth())
|
{
|
rectCen.right = pOrg.GetWidth()-1;
|
nWidth = align_4byte(rectCen.Width());
|
rectCen.left = rectCen.right-nWidth;
|
}
|
if(rectCen.top < 0 || rectCen.bottom >= pOrg.GetHeight())
|
{
|
rectCen = CRect(nCenX-nHorMargin,pOrg.GetHeight()/2-nVerMargin,nCenX+nHorMargin,pOrg.GetHeight()/2+nVerMargin);
|
}
|
|
if(m_bSaveDebug == TRUE)
|
{
|
COwnerBuffer pCenImg(rectCen.Width(),rectCen.Height());
|
ChamferIns.CopyRectImg(pOrg.GetDataAddress(),pCenImg.GetDataAddress(),CSize(pOrg.GetDataWidth(),pOrg.GetHeight()),rectCen);
|
|
CString str;
|
str.Format(_T("%s\\Notch_Cen_2_%d_%d.bmp"),m_strSavePath,icam,iDimension);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pCenImg);
|
}
|
|
CRect rectChip(0,0,0,0);
|
int nThres = m_InsParm.nChipThres;//(int)((double)m_InsParm.nSizeThres*1.2);
|
int nResult;
|
ChipErrCode errCode = ChamferIns.Inspection(&nResult,pOrg.GetDataAddress(),pOrg.GetWidth(),rectCen,nThres,FALSE,TRUE,rectChip,rectChip,rectChip,0,0,0,0,0,m_bSaveDebug,NULL,THRESMODE_FIXED);
|
if(errCode == ERR_CHIP_SUCCESS)
|
{
|
dThickness = ChamferIns.GetAvgThick();
|
}
|
|
return dThickness;
|
}
|
|
void CNotchCut::ThinImage(CSISBuffer &pBinThin,int iscan, int icam)
|
{
|
BOOL bThin = FALSE;
|
for(int y=0; y<pBinThin.GetHeight(); y++)
|
{
|
bThin = FALSE;
|
for(int x=0; x<pBinThin.GetWidth(); x++)
|
{
|
if(*pBinThin.GetDataAddress(x,y)==255)
|
{
|
if(bThin == TRUE)
|
pBinThin.SetPixel(x,y,0);
|
|
bThin=TRUE;
|
}
|
}
|
}
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\6.ThinImage_%d_%d.bmp"),m_strSavePath,icam,iscan);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pBinThin);
|
}
|
}
|
|
void CNotchCut::GetSpChipData(vector<pair<int,CPoint>> *pVec,CRect *rectIns)
|
{
|
vector<pair<int,CPoint>>::iterator it;
|
CPoint pointOrg;
|
|
for(it=m_mapMaster.begin();it!=m_mapMaster.end();it++)//m_mapMaster´Â cad µµ¸éÀÇ Áß½ÉÀ» À̹ÌÁöÀÇ Áß½ÉÀ¸·Î offset½ÃŲ Cadµµ¸é
|
{
|
pointOrg = static_cast<CPoint>(it->second);
|
|
if(rectIns->PtInRect(pointOrg) == TRUE)
|
{
|
pVec->push_back(std::make_pair(pointOrg.y, pointOrg));
|
}
|
}
|
}
|
|
double CNotchCut::Detect_Position(CSISBuffer &pBin,CSISBuffer &pOrg,std::multimap<double,CDetectPoint> *mapDist
|
,vector<pair<int,CPoint>> *vecData)
|
{
|
vector<pair<int,CPoint>>::iterator it;
|
CPoint pointOrg,pointSet;
|
int nCount=0,nLineSampleDet = 10,nDetOffset=200;
|
sPoint *pLinedata = NULL;
|
double dAdjustTheta;
|
CEdgeProc EdgeProc;
|
int iCnt,nValue,nOrgVal,nInterval;
|
double dOutX,dOutY,dDist;
|
CSplinePoint splinePos,spDist;
|
CDetectPoint DetPos;
|
double dSumThick,dThickCnt;
|
int nNoDetCount = 0;
|
int nConti;
|
int nWhiteThres = (int)((double)m_InsParm.nChipThres*1.5);
|
|
mapDist->clear();
|
dSumThick = dThickCnt = 0.;
|
pLinedata = new sPoint[nLineSampleDet];
|
for(it=vecData->begin();it!=vecData->end();it++)//m_mapMaster´Â cad µµ¸éÀÇ Áß½ÉÀ» À̹ÌÁöÀÇ Áß½ÉÀ¸·Î offset½ÃŲ Cadµµ¸é
|
{
|
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);
|
nCount = 0;
|
|
//TRACE("X=%d Y=%d Theta=%.2f\n",pointOrg.x,pointOrg.y,dAdjustTheta);
|
|
for(iCnt=0;iCnt<nLineSampleDet;iCnt++)
|
{
|
pointOrg.x = pointSet.x = (int)pLinedata[iCnt].x;
|
pointOrg.y = pointSet.y = (int)pLinedata[iCnt].y;
|
if(dAdjustTheta <= 90)
|
{
|
pointOrg.x -= nDetOffset;
|
nInterval = 1;
|
}
|
else
|
{
|
pointOrg.x += nDetOffset;
|
nInterval = -1;
|
}
|
|
spDist.Reset();
|
spDist.dThick = INT_MAX;
|
spDist.bFind = FALSE;
|
splinePos.Reset();
|
splinePos.dThick = INT_MAX;
|
splinePos.bFind = FALSE;
|
DetPos.Reset();
|
|
nConti = 0;
|
double dOrgX,dOrgY;
|
for(int iU=-1*nDetOffset;iU<nDetOffset;iU++)
|
{
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dAdjustTheta)), cos(M_RADIAN(dAdjustTheta)));
|
|
if(dOutX < 0 || dOutY < 0 || (int)dOutX >= pBin.GetWidth() || (int)dOutY >= pBin.GetHeight())
|
continue;
|
|
nValue = *pBin.GetDataAddress((int)dOutX,(int)dOutY);
|
|
if(nValue > 0 && spDist.bFind == FALSE)
|
{
|
if(nConti == 0)
|
{
|
dOrgX = dOutX;
|
dOrgY = dOutY;
|
}
|
nConti++;
|
if(nConti > DETECT_WHITE_CONTI_COUNT)
|
{
|
dDist = sqrt(pow(((double)pointSet.x-dOrgX),2)+pow(((double)pointSet.y-dOrgY),2));
|
spDist.rotate = CPoint((int)dOrgX,(int)dOrgY);
|
spDist.origin = pointSet;
|
spDist.dTheta = dAdjustTheta;
|
spDist.dThick = dDist;
|
spDist.bFind = TRUE;
|
}
|
}
|
else
|
nConti = 0;
|
|
nOrgVal = *pOrg.GetDataAddress((int)dOutX,(int)dOutY);
|
if(nOrgVal >= nWhiteThres && splinePos.bFind == FALSE)
|
{
|
dDist = sqrt(pow(((double)pointSet.x-dOutX),2)+pow(((double)pointSet.y-dOutY),2));
|
splinePos.dThick = dDist;
|
splinePos.origin = pointSet;
|
splinePos.rotate = CPoint((int)dOutX,(int)dOutY);
|
splinePos.dTheta = dAdjustTheta;
|
splinePos.bFind = TRUE;
|
}
|
|
pointOrg.x += nInterval;
|
}
|
|
if(spDist.bFind == TRUE && splinePos.bFind == TRUE)
|
{
|
DetPos.orgX = spDist.rotate.x;
|
DetPos.orgY = spDist.rotate.y;
|
DetPos.imgX = splinePos.rotate.x;
|
DetPos.imgY = splinePos.rotate.y;
|
DetPos.dTheta = dAdjustTheta;
|
DetPos.dDist = sqrt(pow(((double)spDist.rotate.x-(double)splinePos.rotate.x),2)+pow(((double)spDist.rotate.y-(double)splinePos.rotate.y),2));
|
mapDist->insert(std::make_pair(DetPos.orgY, DetPos));
|
dSumThick += DetPos.dDist;
|
dThickCnt++;
|
}
|
|
m_nTotalCount++;
|
if(spDist.bFind == FALSE)
|
{
|
nNoDetCount++;
|
if(m_nNoDetCount < nNoDetCount)
|
m_nNoDetCount = nNoDetCount;
|
}
|
else
|
{
|
nNoDetCount = 0;
|
}
|
}
|
}
|
}
|
|
delete[] pLinedata, pLinedata=NULL;
|
|
return dThickCnt>0?dSumThick/dThickCnt:0.;
|
}
|
|
void CNotchCut::SetBrokenDefect(CPoint pointBroken)
|
{
|
CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount];
|
if(pChipBlob != NULL)
|
{
|
pChipBlob->s_nDefectX = pointBroken.x;
|
pChipBlob->s_nDefectY = pointBroken.y;
|
pChipBlob->s_DefectType = CHIPDEFTYPE_BLACK;
|
pChipBlob->s_dThick = 100;
|
pChipBlob->s_nDefectArea = 100;
|
pChipBlob->s_nDefectRScale = 50;
|
pChipBlob->s_DefectRect = CRect(pChipBlob->s_nDefectX,pChipBlob->s_nDefectY,pChipBlob->s_nDefectX,pChipBlob->s_nDefectY);
|
pChipBlob->s_DefectRect.InflateRect(pChipBlob->s_nDefectRScale/2,pChipBlob->s_nDefectRScale/2);
|
|
m_nDefectCount++;
|
}
|
}
|
|
int CNotchCut::Defect_Analyze(std::multimap<double,CDetectPoint> *mapDist,double dAvgThick)
|
{
|
if(dAvgThick <= 0 || (int)mapDist->size() <= 0)
|
return m_nDefectCount;
|
|
std::multimap<double,CDetectPoint>::iterator it;
|
CDetectPoint DetectPos;
|
CChamferInspect ChamferIns;
|
double dThick;
|
std::vector<CChipPair> vecPair;
|
vector<CChipBlob>::iterator itData;
|
int nChipSize = (int)((double)m_InsParm.nChipDiff*DETECT_CHIP_MULTI_RATIO);
|
|
for(it=mapDist->begin();it!=mapDist->end();it++)
|
{
|
DetectPos = static_cast<CDetectPoint>(it->second);
|
|
dThick = fabs((DetectPos.dDist*m_InsParm.dCamRes)-dAvgThick);
|
if(dThick > nChipSize)
|
{
|
ChamferIns.InsertPairing((int)DetectPos.orgX,(int)DetectPos.orgY,1,0,0,0,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,FALSE,dThick);
|
}
|
}
|
|
#define CONTINUE_DEFECT_CNT 3
|
if(ChamferIns.GetPairDefectCount() > 0)
|
{
|
std::vector<CChipBlob> vecBlob;
|
ChamferIns.BlobDefect_Pixel(vecBlob,0,3);
|
|
if((int)vecBlob.size() > 0)
|
{
|
std::vector<CChipBlob>::iterator itBlob;
|
|
for(itBlob=vecBlob.begin();itBlob!=vecBlob.end();itBlob++)
|
{
|
if(m_nDefectCount >= MAX_NOTCH_DEFECT_COUNT)
|
return m_nDefectCount;
|
|
if(itBlob->s_nDefectArea < CONTINUE_DEFECT_CNT)
|
continue;
|
|
CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount];
|
if(pChipBlob == NULL)
|
continue;
|
|
*pChipBlob = *itBlob;
|
|
pChipBlob->s_nDefectRScale = (int)pChipBlob->s_dThick;
|
pChipBlob->s_DefectRect = CRect(pChipBlob->s_nDefectX,pChipBlob->s_nDefectY,pChipBlob->s_nDefectX,pChipBlob->s_nDefectY);
|
pChipBlob->s_DefectRect.InflateRect(pChipBlob->s_nDefectRScale/2,pChipBlob->s_nDefectRScale/2);
|
pChipBlob->s_DefectPosType = CHIPPOSTYPE_SP;
|
|
m_nDefectCount++;
|
}
|
}
|
}
|
|
return m_nDefectCount;
|
}
|
|
BOOL CNotchCut::Inspection_SpChip(CSISBuffer &pBin,CSISBuffer &pOrg,int nGlass2Edge,int nUpVPos,int nDwVPos)
|
{
|
if(pBin.IsValidBuffer() == FALSE || pOrg.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
CRect rectIns;
|
int nSkipSize = (int)((double)m_InsParm.nSkipSize/m_InsParm.dCamRes);
|
int nSPInsSize;
|
vector<pair<int,CPoint>> vecData;
|
std::multimap<double,CDetectPoint> mapDist;
|
double dAvgThick;
|
|
if(m_InsParm.bSplineChip[0] == TRUE && nUpVPos != 0)
|
{
|
nSPInsSize = (int)((double)m_InsParm.nSpInsSize[0]/m_InsParm.dCamRes);
|
rectIns = CRect(nGlass2Edge-nSkipSize,nUpVPos-nSPInsSize,nGlass2Edge+nSkipSize,nUpVPos);
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\UpImg.bmp"),m_strSavePath);
|
CCropBuffer cropBuf(pOrg,rectIns);
|
CBufferAttach attach(str);
|
attach.AttachToFile(cropBuf);
|
}
|
|
|
GetSpChipData(&vecData,&rectIns);
|
if((int)vecData.size() > 0)
|
{
|
std::sort(vecData.begin(),vecData.end(),ResSortYPos());
|
|
dAvgThick = Detect_Position(pBin,pOrg,&mapDist,&vecData);
|
|
Defect_Analyze(&mapDist,dAvgThick*m_InsParm.dCamRes);
|
}
|
}
|
|
if(m_InsParm.bSplineChip[1] == TRUE && nDwVPos != INT_MAX)
|
{
|
vecData.clear();
|
nSPInsSize = (int)((double)m_InsParm.nSpInsSize[1]/m_InsParm.dCamRes);
|
rectIns = CRect(nGlass2Edge-nSkipSize,nDwVPos,nGlass2Edge+nSkipSize,nDwVPos+nSPInsSize);
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\DwImg.bmp"),m_strSavePath);
|
CCropBuffer cropBuf(pOrg,rectIns);
|
CBufferAttach attach(str);
|
attach.AttachToFile(cropBuf);
|
}
|
|
|
GetSpChipData(&vecData,&rectIns);
|
if((int)vecData.size() > 0)
|
{
|
std::sort(vecData.begin(),vecData.end(),ResSortYPos());
|
|
mapDist.clear();
|
dAvgThick = Detect_Position(pBin,pOrg,&mapDist,&vecData);
|
|
Defect_Analyze(&mapDist,dAvgThick*m_InsParm.dCamRes);
|
}
|
}
|
|
return TRUE;
|
}
|
|
void CNotchCut::Exe_ChipInspect(CSISBuffer &pBin,CSISBuffer &pOrg,int iCam)
|
{
|
if(pBin.IsValidBuffer() == FALSE || pOrg.IsValidBuffer() == FALSE)
|
return;
|
|
vector<pair<int,CPoint>>::iterator it;
|
CPoint pointOrg,pointSet,pointMax;
|
int nCount=0,nLineSampleDet = 10;
|
sPoint *pLinedata = NULL;
|
double dAdjustTheta;
|
int nDetOffset = 80,nBlankSize=10;
|
int iCnt,nValue;
|
double dOutX,dOutY;
|
CEdgeFind EdgeFind;
|
CEdgeProc EdgeProc;
|
int nInterval,nSkipSize,nDetPos,nChipSize;
|
BOOL bBlackFind;
|
int nPreChipPos,nChipContiCnt,iTerCnt;
|
std::vector<CChipPair> vecPair;
|
CChamferInspect ChamferIns;
|
int nConti = 0;
|
|
nSkipSize = (int)((double)(m_InsParm.nChamferSize+m_InsParm.nChamferDiff)/m_InsParm.dCamRes);
|
nChipSize = (int)(((double)(m_InsParm.nChipDiff)/m_InsParm.dCamRes)*2);
|
|
|
COwnerBuffer pChip(pOrg.GetDataWidth(),pOrg.GetHeight());
|
if(m_bSaveDebug == TRUE)
|
{
|
CopyMemory(pChip.GetDataAddress(),pOrg.GetDataAddress(),pOrg.GetDataSize());
|
}
|
|
nPreChipPos = -1;
|
nChipContiCnt = iTerCnt = 0;
|
pLinedata = new sPoint[nLineSampleDet];
|
for(it=m_mapMaster.begin();it!=m_mapMaster.end();it++)//m_mapMaster´Â cad µµ¸éÀÇ Áß½ÉÀ» À̹ÌÁöÀÇ Áß½ÉÀ¸·Î offset½ÃŲ Cadµµ¸é
|
{
|
pointOrg = static_cast<CPoint>(it->second);
|
|
if(pointOrg.y <= nBlankSize || pointOrg.y >= pBin.GetHeight()-nBlankSize)
|
continue;
|
|
|
pLinedata[nCount].x = pointOrg.x;
|
pLinedata[nCount].y = pointOrg.y;
|
nCount++;
|
if(nCount >= nLineSampleDet)
|
{
|
dAdjustTheta = EdgeProc.GetTheta(pLinedata,nLineSampleDet,5);
|
nCount = 0;
|
|
for(iCnt=0;iCnt<nLineSampleDet;iCnt++,iTerCnt++)
|
{
|
pointOrg.x = pointSet.x = (int)pLinedata[iCnt].x;
|
pointOrg.y = pointSet.y = (int)pLinedata[iCnt].y;
|
if(dAdjustTheta <= 90)
|
{
|
pointOrg.x -= nDetOffset;
|
nInterval = 1;
|
}
|
else
|
{
|
pointOrg.x += nDetOffset;
|
nInterval = -1;
|
}
|
|
bBlackFind = FALSE;
|
nDetPos = nConti = 0;
|
pointMax = pointOrg;
|
pointMax.x += (nInterval*(nDetOffset*2));
|
|
int iU;
|
for(iU=-1*nDetOffset;iU<nDetOffset;iU++)
|
{
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dAdjustTheta)), cos(M_RADIAN(dAdjustTheta)));
|
|
if(dOutX < 0 || dOutY < 0 || (int)dOutX >= pBin.GetWidth() || (int)dOutY >= pBin.GetHeight())
|
continue;
|
|
nValue = *pBin.GetDataAddress((int)dOutX,(int)dOutY);
|
|
if(bBlackFind == FALSE && nValue > 0)
|
{
|
nConti++;
|
if(nConti > DETECT_WHITE_CONTI_COUNT)
|
{
|
nDetPos = iU-DETECT_WHITE_CONTI_COUNT;
|
bBlackFind = TRUE;
|
break;
|
}
|
}
|
else
|
nConti = 0;
|
pointOrg.x += nInterval;
|
}
|
|
if(bBlackFind == TRUE)
|
{
|
pointOrg.x += (nInterval*(nSkipSize+m_InsParm.nDetSkipSize));
|
}
|
else
|
{
|
pointOrg = pointSet;
|
pointOrg.x += (nInterval*(nSkipSize+m_InsParm.nNoDetSkipSize));
|
nDetPos = 0;
|
}
|
|
int nLoopCnt = nDetPos + abs(pointMax.x-pointOrg.x);
|
for(iU=nDetPos;iU<nLoopCnt;iU++)
|
{
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dAdjustTheta)), cos(M_RADIAN(dAdjustTheta)));
|
|
if(dOutX < 0 || dOutY < 0 || (int)dOutX >= pOrg.GetWidth() || (int)dOutY >= pOrg.GetHeight())
|
continue;
|
|
nValue = *pOrg.GetDataAddress((int)dOutX,(int)dOutY);
|
|
if(nValue < m_InsParm.nChipThres)
|
{
|
ChamferIns.InsertPairing((int)dOutX,(int)dOutY,1,0,0,0,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,FALSE,1);
|
|
if(m_bSaveDebug == TRUE)
|
{
|
pChip.SetPixel((int)dOutX,(int)dOutY,200);
|
}
|
}
|
|
pointOrg.x += nInterval;
|
}
|
}
|
}
|
}
|
|
if(ChamferIns.GetPairDefectCount() > 0)
|
{
|
std::vector<CChipBlob> vecBlob;
|
ChamferIns.BlobDefect_Pixel(vecBlob,0,3);
|
|
std::vector<CChipBlob>::iterator itBlob;
|
|
for(itBlob=vecBlob.begin();itBlob!=vecBlob.end();itBlob++)
|
{
|
if(m_nDefectCount >= MAX_NOTCH_DEFECT_COUNT)
|
return;
|
|
if(itBlob->s_DefectRect.Width() < nChipSize || itBlob->s_DefectRect.Height() <= 2)
|
continue;
|
|
CChipBlob *pChipBlob = &m_ResultDefect[m_nDefectCount];
|
if(pChipBlob == NULL)
|
continue;
|
|
*pChipBlob = *itBlob;
|
pChipBlob->s_DefectPosType = CHIPPOSTYPE_BIN;
|
|
m_nDefectCount++;
|
}
|
}
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\4.[%d]_ChipInsImg.bmp"),m_strSavePath,iCam);//20140528
|
CBufferAttach attach(str);
|
attach.AttachToFile(pChip);
|
}
|
}
|
|
BOOL CNotchCut::DistInspection_New(CSISBuffer &pBin,CSISBuffer &pOrg,double *dChamferThick,double *dChipAvgThick,int nCenX,int nCenY,int nGlass2Edge
|
, double *dFeedbackXY,int iDimension, int icam, std::multimap<int,CSplinePoint> *mapDist,std::multimap<int,CSplinePoint> *mapDist_Dy,double *dGlassXY
|
,int *nUpVPos,int *nDwVPos,std::multimap<int,CSplinePoint> *mapChamfer,double dTheta)//20140528
|
{
|
ZeroMemory(dGlassXY,sizeof(double)*2);
|
|
if(pBin.IsValidBuffer() == FALSE || pOrg.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
vector<pair<int,CPoint>>::iterator it;
|
CPoint pointOrg,pointOrg_Dy,pointSet;
|
int nCount=0,nLineSampleDet = 10;
|
sPoint *pLinedata = NULL;
|
double dAdjustTheta,dDist,dDist_Dy;
|
const int nDetOffset = 200;
|
int iCnt,nValue,nOrgVal;
|
double dOutX,dOutY;
|
CSplinePoint splinePos,spDist,spDist_Dy,spDistBlack;
|
int nInterval,nInterval_Dy;
|
CEdgeFind EdgeFind;
|
CEdgeProc EdgeProc;
|
double dSumThick,dThickCnt;
|
double dChamferSumThick,dChamferThickCnt;
|
int nNoDetCount,nConti,nConti_Dy,nWhiteConti;
|
int nWhiteThres = (int)((double)m_InsParm.nChipThres*1.6);
|
int nCenSkipRange[2],nSkipMargin=50;
|
int nFeedbackYOffset = 100;
|
int nCalFeedbackPosX = m_AlignMasterParm[iDimension].nPosX+nFeedbackYOffset;
|
BOOL bFindFeedbackY[2];
|
int nFeedbackYPos[2];
|
bFindFeedbackY[0] = bFindFeedbackY[1] = FALSE;
|
nFeedbackYPos[0] = nFeedbackYPos[1] = -9999;
|
|
// int nStartY = (int)((double)baseCenY/m_InsParm.dCamRes-(double)(m_MasterParm[index].nPosY));
|
|
if(nCenX > 0 && nCenY > 0)
|
{
|
dFeedbackXY[0] = nCenX - m_AlignMasterParm[iDimension].nMaxX;
|
dFeedbackXY[1] = nCenY - m_AlignMasterParm[iDimension].nMaxY;
|
dGlassXY[0] = nCenX;
|
dGlassXY[1] = nCenY;
|
}
|
else
|
{
|
dFeedbackXY[0] = -9999;
|
dFeedbackXY[1] = -9999;
|
dGlassXY[0] = m_AlignMasterParm[iDimension].nMaxX;
|
dGlassXY[1] = m_AlignMasterParm[iDimension].nMaxY;
|
}
|
|
nCenSkipRange[0] = pOrg.GetHeight()/2-nSkipMargin;
|
nCenSkipRange[1] = pOrg.GetHeight()/2+nSkipMargin;
|
|
dSumThick = dThickCnt = dChamferSumThick = dChamferThickCnt = 0.;
|
|
*nUpVPos = 0;
|
*nDwVPos = INT_MAX;
|
|
nNoDetCount = 0;
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\[%d]_DistInspection_Bin.bmp"),m_strSavePath,icam);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pBin);
|
}
|
|
int nSkipsize = (int)((double)m_InsParm.nSkipSize/m_InsParm.dCamRes);
|
const int nContinueBlackCnt = 20;
|
int nConBlack;
|
|
pLinedata = new sPoint[nLineSampleDet];
|
for(it=m_mapMaster.begin();it!=m_mapMaster.end();it++)//m_mapMaster´Â cad µµ¸éÀÇ Áß½ÉÀ» À̹ÌÁöÀÇ Áß½ÉÀ¸·Î offset½ÃŲ Cadµµ¸é
|
{
|
pointOrg = static_cast<CPoint>(it->second);
|
|
if(pointOrg.x < nGlass2Edge+nSkipsize)
|
{
|
if(pointOrg.y < nCenY)
|
{
|
if(*nUpVPos < pointOrg.y)
|
*nUpVPos = pointOrg.y;
|
}
|
else
|
{
|
if(*nDwVPos > pointOrg.y)
|
*nDwVPos = pointOrg.y;
|
}
|
continue;
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
// if(pointOrg.x == nCalFeedbackPosX && pointOrg.y < m_AlignMasterParm[iDimension].nMaxY && bFindFeedbackY[0] == FALSE)
|
// {
|
// for (int i=m_AlignMasterParm[iDimension].nMaxY; i>0; i--)
|
// {
|
// nValue = *pBin.GetDataAddress(nCalFeedbackPosX,i);
|
//
|
// if(nValue>0)
|
// {
|
// nFeedbackYPos[0] = i - pointOrg.y;
|
// bFindFeedbackY[0] = TRUE;
|
// break;
|
// }
|
// }
|
// }
|
//
|
// if(pointOrg.x == nCalFeedbackPosX && pointOrg.y > m_AlignMasterParm[iDimension].nMaxY && bFindFeedbackY[1] == FALSE)
|
// {
|
// for (int i=m_AlignMasterParm[iDimension].nMaxY; i<pBin.GetHeight(); i++)
|
// {
|
// nValue = *pBin.GetDataAddress(nCalFeedbackPosX,i);
|
//
|
// if(nValue>0)
|
// {
|
// nFeedbackYPos[1] = i - pointOrg.y;
|
// bFindFeedbackY[1] = TRUE;
|
// break;
|
// }
|
// }
|
// }
|
//////////////////////////////////////////////////////////////////////////
|
//notch ¿µ»ó centerÁß°£ ½ºÅµ
|
// if(nCenSkipRange[0] <= pointOrg.y && pointOrg.y <= nCenSkipRange[1])
|
// continue;
|
|
pLinedata[nCount].x = pointOrg.x;
|
pLinedata[nCount].y = pointOrg.y;
|
nCount++;
|
if(nCount >= nLineSampleDet)
|
{
|
dAdjustTheta = EdgeProc.GetTheta(pLinedata,nLineSampleDet,5);
|
nCount = 0;
|
|
for(iCnt=0;iCnt<nLineSampleDet;iCnt++)
|
{
|
pointOrg.x = pointOrg_Dy.x = pointSet.x = (int)pLinedata[iCnt].x;
|
pointOrg.y = pointOrg_Dy.y = pointSet.y = (int)pLinedata[iCnt].y;
|
|
if(dAdjustTheta <= 90)
|
{
|
pointOrg.x -= nDetOffset;
|
nInterval = 1;
|
}
|
else
|
{
|
pointOrg.x += nDetOffset;
|
nInterval = -1;
|
}
|
|
pointOrg_Dy.x -= nDetOffset;
|
nInterval_Dy = 1;
|
|
spDist.Reset();
|
spDist.bFind = FALSE;
|
spDist.dThick = INT_MAX;
|
spDist_Dy.Reset();
|
spDist_Dy.bFind = FALSE;
|
spDist_Dy.dThick = INT_MAX;
|
splinePos.Reset();
|
splinePos.bFind = FALSE;
|
splinePos.dThick = INT_MAX;
|
spDistBlack.Reset();
|
spDistBlack.bFind = FALSE;
|
spDistBlack.dThick = INT_MAX;
|
nConBlack = nConti = nConti_Dy = nWhiteConti = 0;
|
|
double dOrgX,dOrgY,dOrgX_Dy,dOrgY_Dy,dWhiteX,dWhiteY;
|
int nOutX,nOutY;
|
|
dOrgX = dOrgY = dOrgX_Dy = dOrgY_Dy = dWhiteX = dWhiteY = 0.;
|
for(int iU=-1*nDetOffset;iU<nDetOffset;iU++)
|
{
|
//////////////////////////////////////////////////////////////////////////
|
//EdgeProc.RotatePoint(pointOrg_Dy,dOutX,dOutY,sin((dTheta)), cos((dTheta)));
|
EdgeProc.RotatePoint(pointOrg_Dy,dOutX,dOutY,pointSet,sin(dTheta), cos(dTheta));
|
|
nValue = *pBin.GetDataAddress((int)dOutX,(int)dOutY);
|
nOutX = (int)dOutX;
|
nOutY = (int)dOutY;
|
|
if(spDist_Dy.bFind == FALSE && nValue > 0)
|
{
|
if(nConti_Dy == 0)
|
{
|
dOrgX_Dy = dOutX;
|
dOrgY_Dy = dOutY;
|
}
|
nConti_Dy++;
|
if(nConti_Dy >DETECT_WHITE_CONTI_COUNT)
|
{
|
dDist_Dy = sqrt(pow(((double)pointSet.x-dOrgX_Dy),2)+pow(((double)pointSet.y-dOrgY_Dy),2));
|
if(pointSet.x < dOrgX_Dy) //20140721
|
dDist_Dy *= -1;
|
|
spDist_Dy.rotate = CPoint((int)dOrgX_Dy,(int)dOrgY_Dy);
|
spDist_Dy.origin = pointSet;
|
spDist_Dy.dTheta = dAdjustTheta;
|
spDist_Dy.dThick = dDist_Dy;
|
spDist_Dy.bFind = TRUE;
|
//mapDist->insert(std::make_pair(spDist.rotate.y, spDist));//20140528
|
mapDist_Dy->insert(std::make_pair(spDist_Dy.origin.y, spDist_Dy));//20140528
|
}
|
}
|
else
|
nConti_Dy = 0;
|
|
dOutX = dOutY = 0.;
|
//////////////////////////////////////////////////////////////////////////
|
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dAdjustTheta)), cos(M_RADIAN(dAdjustTheta)));
|
|
if(dOutX < 0 || dOutY < 0 || (int)dOutX >= pBin.GetWidth() || (int)dOutY >= pBin.GetHeight())
|
continue;
|
|
nValue = *pBin.GetDataAddress((int)dOutX,(int)dOutY);
|
|
if(spDist.bFind == FALSE && nValue > 0)
|
{
|
if(nConti == 0)
|
{
|
dOrgX = dOutX;
|
dOrgY = dOutY;
|
}
|
nConti++;
|
if(nConti > DETECT_WHITE_CONTI_COUNT)
|
{
|
dDist = sqrt(pow(((double)pointSet.x-dOrgX),2)+pow(((double)pointSet.y-dOrgY),2));
|
if(pointSet.x < dOrgX) //20140721
|
dDist *= -1;
|
|
spDist.rotate = CPoint((int)dOrgX,(int)dOrgY);
|
spDist.origin = pointSet;
|
spDist.dTheta = dAdjustTheta;
|
spDist.dThick = dDist;
|
spDist.bFind = TRUE;
|
//mapDist->insert(std::make_pair(spDist.rotate.y, spDist));//20140528
|
mapDist->insert(std::make_pair(spDist.origin.y, spDist));//20140528
|
}
|
}
|
else
|
nConti = 0;
|
|
if(spDistBlack.bFind == FALSE)
|
{
|
if(spDist.bFind == TRUE && nValue == 0)
|
{
|
if(nConBlack == 0)
|
{
|
dDist = sqrt(pow(((double)spDist.rotate.x-dOutX),2)+pow(((double)spDist.rotate.y-dOutY),2));
|
|
spDistBlack.rotate = CPoint((int)dOutX,(int)dOutY);
|
//spDistBlack.origin = spDist.rotate;//20140528
|
spDistBlack.origin = spDist.origin;//20140528
|
spDistBlack.dTheta = dAdjustTheta;
|
spDistBlack.dThick = dDist;
|
}
|
|
nConBlack++;
|
if(nConBlack >= nContinueBlackCnt)
|
{
|
spDistBlack.bFind = TRUE;
|
dChamferSumThick += spDistBlack.dThick;
|
dChamferThickCnt++;
|
mapChamfer->insert(std::make_pair(spDistBlack.origin.y, spDistBlack));//20140528
|
}
|
}
|
else
|
{
|
nConBlack = 0;
|
spDistBlack.Reset();
|
spDistBlack.bFind = FALSE;
|
spDistBlack.dThick = INT_MAX;
|
}
|
}
|
|
if(splinePos.bFind == FALSE)
|
{
|
nOrgVal = *pOrg.GetDataAddress((int)dOutX,(int)dOutY);
|
if(nOrgVal >= nWhiteThres)
|
{
|
if(nWhiteConti == 0)
|
{
|
dWhiteX = dOutX;
|
dWhiteY = dOutY;
|
}
|
nWhiteConti++;
|
if(nWhiteConti > DETECT_WHITE_CONTI_COUNT)
|
{
|
dDist = sqrt(pow(((double)pointSet.x-dWhiteX),2)+pow(((double)pointSet.y-dWhiteY),2));
|
splinePos.dThick = dDist;
|
splinePos.origin = pointSet;
|
splinePos.rotate = CPoint((int)dWhiteX,(int)dWhiteY);
|
splinePos.dTheta = dAdjustTheta;
|
splinePos.bFind = TRUE;
|
}
|
}
|
else
|
nWhiteConti = 0;
|
}
|
pointOrg.x += nInterval;
|
pointOrg_Dy.x += nInterval_Dy;
|
}
|
|
if(splinePos.bFind == TRUE && spDist.bFind == TRUE)
|
{
|
splinePos.origin = spDist.rotate;
|
splinePos.dThick = sqrt(pow(((double)spDist.rotate.x-(double)splinePos.rotate.x),2)+pow(((double)spDist.rotate.y-(double)splinePos.rotate.y),2));
|
m_mapChipData.push_back(std::make_pair(splinePos.rotate.y, splinePos));
|
|
dSumThick += splinePos.dThick;
|
dThickCnt++;
|
}
|
|
m_nTotalCount++;
|
if(spDist.bFind == FALSE)
|
{
|
nNoDetCount++;
|
if(m_nNoDetCount < nNoDetCount)
|
m_nNoDetCount = nNoDetCount;
|
}
|
else
|
{
|
nNoDetCount = 0;
|
}
|
}
|
}
|
}
|
|
if(dChamferThickCnt > 0)
|
*dChamferThick = dChamferSumThick/dChamferThickCnt;
|
|
if(dThickCnt > 0)
|
*dChipAvgThick = dSumThick/dThickCnt;
|
|
// if(nFeedbackYPos[0] != -9999 && nFeedbackYPos[1] != -9999)
|
// dFeedbackXY[1] = (nFeedbackYPos[0] + nFeedbackYPos[1]) / 2.;
|
|
return TRUE;
|
}
|
|
BOOL CNotchCut::DistInspection(CSISBuffer &pTgt,CSISBuffer &pOrg,double *dResult,double *dRangeRes,double *dAvgThick,int nCenX,int nCenY,int nGlass2Edge, double *dFeedbackXY,int iscan, int icam)
|
{
|
if(pTgt.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
vector<pair<int,CPoint>>::iterator it;
|
CPoint pointOrg,pointSet;
|
int nCount=0,nLineSampleDet = 10;
|
sPoint *pLinedata = NULL;
|
double dAdjustTheta,dSumThick,dThickCnt;
|
const int nDetOffset = 200;
|
const int nDEF_LINE_COUNT = nLineSampleDet/3;
|
int iCnt,nValue,nOrgVal;
|
CDetectPoint *pDetPoint;
|
CSplinePoint pSpPoint;
|
double dSumDist,dSumCnt,dMaxAvg;
|
double dAvg=0.,dSum=0.,dDist=0.;
|
double dOutX,dOutY;
|
std::vector<double> vecDist;
|
CSplinePoint splinePos;
|
double dtemp[2];
|
int nCountDy = 0;
|
CPoint pointCadCenter;
|
CPoint pointGlassCenter;
|
CRect rectEdge;
|
int nInterval;
|
int nWhiteThres = (int)((double)m_InsParm.nChipThres*1.5);
|
|
ZeroMemory(dtemp,sizeof(double)*2);
|
|
for(it=m_mapMaster.begin();it!=m_mapMaster.end();it++)
|
{
|
pointOrg = static_cast<CPoint>(it->second);
|
if(pointOrg.y == pOrg.GetHeight()/2)
|
{
|
pointCadCenter.x=pointOrg.x;
|
pointCadCenter.y=pointOrg.y;
|
}
|
}
|
|
rectEdge = CRect(0,nCenY-1,pOrg.GetWidth(),nCenY+1);
|
|
CEdgeFind EdgeFind;
|
CEdgeProc EdgeProc;
|
|
pointGlassCenter.x = (int)EdgeFind.FindGlassHorizontalLine(pOrg.GetDataAddress(0,0),CSize(pOrg.GetDataWidth(),pOrg.GetHeight()),rectEdge,m_InsParm.nEdgeThres,TRUE);
|
pointGlassCenter.y = nCenY;
|
|
dFeedbackXY[0] = pointGlassCenter.x - pointCadCenter.x;
|
dFeedbackXY[1] = pointGlassCenter.y - pointCadCenter.y;
|
|
TRACE("=====================================================================\r\n");
|
TRACE("Inspect Start\r\n");
|
|
//m_Log.DisplayEdgeLog("=====================================================================");
|
//m_Log.DisplayEdgeLog("Inspect Start icam [%d] iscan [%d]",icam,iscan);
|
|
*dAvgThick = dSumThick = dThickCnt = 0.;
|
dSumDist = dSumCnt = dMaxAvg = 0;
|
|
pLinedata = new sPoint[nLineSampleDet];
|
pDetPoint = new CDetectPoint[nLineSampleDet];
|
for(it=m_mapMaster.begin();it!=m_mapMaster.end();it++)//m_mapMaster´Â cad µµ¸éÀÇ Áß½ÉÀ» À̹ÌÁöÀÇ Áß½ÉÀ¸·Î offset½ÃŲ Cadµµ¸é
|
{
|
pointOrg = static_cast<CPoint>(it->second);
|
|
if(pointOrg.x < nGlass2Edge+10)
|
continue;
|
|
pLinedata[nCount].x = pointOrg.x;
|
pLinedata[nCount].y = pointOrg.y;
|
nCount++;
|
if(nCount >= nLineSampleDet)
|
{
|
dAdjustTheta = EdgeProc.GetTheta(pLinedata,nLineSampleDet,5);
|
ZeroMemory(pDetPoint,sizeof(CDetectPoint)*nLineSampleDet);
|
nCount = 0;
|
|
TRACE("X=%d Y=%d Theta=%.2f\n",pointOrg.x,pointOrg.y,dAdjustTheta);
|
|
for(iCnt=0;iCnt<nLineSampleDet;iCnt++)
|
{
|
pointOrg.x = pointSet.x = (int)pLinedata[iCnt].x;
|
pointOrg.y = pointSet.y = (int)pLinedata[iCnt].y;
|
if(dAdjustTheta <= 90)
|
{
|
pointOrg.x -= nDetOffset;
|
nInterval = 1;
|
}
|
else
|
{
|
pointOrg.x += nDetOffset;
|
nInterval = -1;
|
}
|
|
pDetPoint[iCnt].dDist = INT_MAX;
|
pDetPoint[iCnt].bFind = FALSE;
|
|
splinePos.Reset();
|
splinePos.dThick = INT_MAX;
|
|
for(int iU=-1*nDetOffset;iU<nDetOffset;iU++)
|
{
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dAdjustTheta)), cos(M_RADIAN(dAdjustTheta)));
|
|
if(dOutX < 0 || dOutY < 0 || (int)dOutX >= pTgt.GetWidth() || (int)dOutY >= pTgt.GetHeight())
|
continue;
|
|
//nValue = m_Labelling.GetSplineValue(m_EdgeFind,pTgt,dOutX,dOutY);
|
|
nValue = *pTgt.GetDataAddress((int)dOutX,(int)dOutY);
|
|
if(pDetPoint[iCnt].bFind == FALSE)
|
{
|
if(nValue > 0)
|
{
|
dDist = sqrt(pow(((double)pointSet.x-dOutX),2)+pow(((double)pointSet.y-dOutY),2));
|
|
if(pDetPoint[iCnt].dDist > dDist)
|
{
|
pDetPoint[iCnt].orgX = pointSet.x;
|
pDetPoint[iCnt].orgY = pointSet.y;
|
pDetPoint[iCnt].imgX = dOutX;
|
pDetPoint[iCnt].imgY = dOutY;
|
pDetPoint[iCnt].dTheta = dAdjustTheta;
|
pDetPoint[iCnt].dDist = dDist;
|
pDetPoint[iCnt].bFind = TRUE;
|
}
|
}
|
}
|
|
if(splinePos.bFind == FALSE)
|
{
|
// if(m_InsParm.bChipIns == TRUE)
|
{
|
nOrgVal = *pOrg.GetDataAddress((int)dOutX,(int)dOutY);
|
if(nOrgVal >= nWhiteThres)
|
{
|
dDist = sqrt(pow(((double)pointSet.x-dOutX),2)+pow(((double)pointSet.y-dOutY),2));
|
if(splinePos.dThick > dDist)
|
{
|
splinePos.dThick = dDist;
|
splinePos.origin = pointSet;
|
splinePos.rotate = CPoint((int)dOutX,(int)dOutY);
|
splinePos.dTheta = dAdjustTheta;
|
splinePos.bFind = TRUE;
|
}
|
}
|
}
|
}
|
//TRACE("pDetPoint[iCnt].orgX = %d pDetPoint[iCnt].orgY = %d pDetPoint[iCnt].imgX = %d pDetPoint[iCnt].imgY = %d pDetPoint[iCnt].dDist = %.2f splinePos.rotate.x = %d splinePos.rotate.y = %d splinePos.dThick = %.2f\n", (int)pDetPoint[iCnt].orgX,(int)pDetPoint[iCnt].orgY,(int)pDetPoint[iCnt].imgX,(int)pDetPoint[iCnt].imgY,pDetPoint[iCnt].dDist,splinePos.rotate.x,splinePos.rotate.y,splinePos.dThick);
|
//TRACE("pointSet.x %d pointSet.y %d pointOrg.x %d pointSet.y %d dOutX %d dOutY %d\n",pointSet.x,pointSet.y,pointOrg.x,pointSet.y,(int)dOutX,(int)dOutY);
|
pointOrg.x += nInterval;
|
}
|
|
if(splinePos.dThick != INT_MAX && pDetPoint[iCnt].dDist != INT_MAX)
|
{
|
splinePos.dThick = sqrt(pow(((double)pDetPoint[iCnt].imgX-splinePos.rotate.x),2)+pow(((double)pDetPoint[iCnt].imgY-splinePos.rotate.y),2));
|
m_mapChipData.push_back(std::make_pair(splinePos.origin.y, splinePos));
|
|
if(splinePos.dThick < 20)
|
{
|
dSumThick += splinePos.dThick;
|
dThickCnt++;
|
}
|
|
//TRACE("pDetPoint[iCnt].orgX = %d pDetPoint[iCnt].orgY = %d pDetPoint[iCnt].imgX = %d pDetPoint[iCnt].imgY = %d pDetPoint[iCnt].dDist = %.2f splinePos.rotate.x = %d splinePos.rotate.y = %d splinePos.dThick = %.2f\n", (int)pDetPoint[iCnt].orgX,(int)pDetPoint[iCnt].orgY,(int)pDetPoint[iCnt].imgX,(int)pDetPoint[iCnt].imgY,pDetPoint[iCnt].dDist,splinePos.rotate.x,splinePos.rotate.y,splinePos.dThick);
|
}
|
|
if(splinePos.dThick == INT_MAX)
|
{
|
while(!splinePos.bFind)
|
{
|
pointOrg.x += nInterval;
|
|
EdgeProc.RotatePoint(pointOrg,dOutX,dOutY,pointSet,sin(M_RADIAN(dAdjustTheta)), cos(M_RADIAN(dAdjustTheta)));
|
|
if(dOutX < 0 || dOutY < 0 || (int)dOutX >= pTgt.GetWidth() || (int)dOutY >= pTgt.GetHeight())
|
break;
|
|
if(splinePos.bFind == FALSE)
|
{
|
// if(m_InsParm.bChipIns == TRUE)
|
{
|
nOrgVal = *pOrg.GetDataAddress((int)dOutX,(int)dOutY);
|
if(nOrgVal >= m_InsParm.nChipThres)
|
{
|
dDist = sqrt(pow(((double)pointSet.x-dOutX),2)+pow(((double)pointSet.y-dOutY),2));
|
if(splinePos.dThick > dDist)
|
{
|
splinePos.dThick = dDist;
|
splinePos.origin = pointSet;
|
splinePos.rotate = CPoint((int)dOutX,(int)dOutY);
|
splinePos.dTheta = dAdjustTheta;
|
splinePos.bFind = TRUE;
|
}
|
}
|
}
|
}
|
}
|
//TRACE("pDetPoint[iCnt].orgX = %d pDetPoint[iCnt].orgY = %d pDetPoint[iCnt].imgX = %d pDetPoint[iCnt].imgY = %d pDetPoint[iCnt].dDist = %.2f splinePos.rotate.x = %d splinePos.rotate.y = %d splinePos.dThick = %.2f\n", (int)pDetPoint[iCnt].orgX,(int)pDetPoint[iCnt].orgY,(int)pDetPoint[iCnt].imgX,(int)pDetPoint[iCnt].imgY,pDetPoint[iCnt].dDist,splinePos.rotate.x,splinePos.rotate.y,splinePos.dThick);
|
|
if(splinePos.dThick != INT_MAX)
|
{
|
splinePos.dThick = sqrt(pow(((double)pDetPoint[iCnt].imgX-splinePos.rotate.x),2)+pow(((double)pDetPoint[iCnt].imgY-splinePos.rotate.y),2));
|
m_mapChipData.push_back(std::make_pair(splinePos.origin.y, splinePos));
|
}
|
}
|
|
//m_Log.DisplayEdgeLog("icam [%d] iscan [%d] pDetPoint[iCnt].orgX = %d pDetPoint[iCnt].orgY = %d pDetPoint[iCnt].imgX = %d pDetPoint[iCnt].imgY = %d pDetPoint[iCnt].dDist = %.2f splinePos.rotate.x = %d splinePos.rotate.y = %d splinePos.dThick = %.2f\n", icam,iscan,(int)pDetPoint[iCnt].orgX,(int)pDetPoint[iCnt].orgY,(int)pDetPoint[iCnt].imgX,(int)pDetPoint[iCnt].imgY,pDetPoint[iCnt].dDist,splinePos.rotate.x,splinePos.rotate.y,splinePos.dThick);
|
}
|
|
int iHorCnt,nDetCnt=0;
|
double dSum=0;
|
dAvg = 0;
|
for(iHorCnt=0;iHorCnt<nLineSampleDet;iHorCnt++)
|
{
|
if(/*pDetPoint[iHorCnt].dDist > 1 && */pDetPoint[iHorCnt].bFind == TRUE)
|
{
|
dSum += pDetPoint[iHorCnt].dDist;
|
nDetCnt++;
|
}
|
}
|
|
if(nDetCnt >= nDEF_LINE_COUNT)
|
{
|
if(dSum == 0)
|
dAvg = 0;
|
else
|
dAvg = dSum/(double)nDetCnt;
|
}
|
|
if(dMaxAvg < dAvg)
|
dMaxAvg = dAvg;
|
|
/*if(dAvg > 1)*/
|
{
|
// DrawImgRect(pTgt,pDetPoint[nDetIdx].imgX,pDetPoint[nDetIdx].imgY,100);
|
|
dSumDist += dAvg;
|
dSumCnt++;
|
}
|
|
vecDist.push_back(dAvg);
|
}
|
}
|
|
delete[] pLinedata, pLinedata=NULL;
|
delete[] pDetPoint, pDetPoint=NULL;
|
|
TRACE("=====================================================================\r\n");
|
//m_Log.DisplayEdgeLog("=====================================================================");
|
|
dResult[0] = dMaxAvg;
|
if(dSumCnt > 0)
|
dResult[1] = dSumDist/dSumCnt;
|
else
|
dResult[1] = 0;
|
|
if((int)vecDist.size() > 5)
|
{
|
int nJumpVal = (int)vecDist.size()/5;
|
int nIndex = 0;
|
|
if(nJumpVal <= 0)
|
return TRUE;
|
|
dSumDist = 0;
|
dSumCnt = 1;
|
for(std::vector<double>::iterator it=vecDist.begin();it!=vecDist.end();it++,dSumCnt++)
|
{
|
dSumDist += *it;
|
|
if(nIndex == 4)
|
{
|
if(dSumCnt >= (nJumpVal+vecDist.size()%5))
|
{
|
if(nIndex >= 5)
|
break;
|
|
dRangeRes[nIndex] = dSumDist/dSumCnt;
|
|
dSumDist = dSumCnt = 0;
|
nIndex++;
|
}
|
}
|
else
|
{
|
if(dSumCnt >= nJumpVal)
|
{
|
if(nIndex >= 5)
|
break;
|
|
dRangeRes[nIndex] = dSumDist/dSumCnt;
|
|
dSumDist = dSumCnt = 0;
|
nIndex++;
|
}
|
}
|
}
|
}
|
|
if(dThickCnt > 0)
|
*dAvgThick = dSumThick/dThickCnt;
|
|
TRACE("dAvgThick=%.2f, dSumThick=%.2f, dThickCnt=%.2f\n",*dAvgThick,dSumThick,dThickCnt);
|
|
return TRUE;
|
}
|
|
int CNotchCut::CropDataXY2(std::multimap<int,CSplinePoint> *mapCrop,std::multimap<int,CSplinePoint> *mapDist,int nStartX,int nFirstY,int nLastY,double *dResDist)
|
{
|
std::multimap<int,CSplinePoint>::iterator it;
|
CSplinePoint spPoint;
|
double dSum,dCnt;
|
int nContiBrokenCnt = 0;
|
BOOL bBroken = FALSE;
|
// CPoint pointBroken = CPoint(0,0);
|
// int nBrokenSize = (int)((double)m_InsParm.nSizeDiff/m_InsParm.dCamRes*2);
|
|
dSum = dCnt = 0;
|
dResDist[0] = dResDist[1] = -1;
|
|
for(it=mapDist->begin();it!=mapDist->end();it++)
|
{
|
spPoint = static_cast<CSplinePoint>(it->second);
|
|
if(spPoint.rotate.x < nStartX || spPoint.rotate.y < nFirstY || spPoint.rotate.y > nLastY)
|
{
|
TRACE("[%d,%d] [%d,%d] => [%.3f] nStartX[%d] nFirstY[%d] nLastY[%d]\n",spPoint.origin.x,spPoint.origin.y,spPoint.rotate.x,spPoint.rotate.y,spPoint.dThick,nStartX,nFirstY,nLastY);//20140528
|
continue;
|
}
|
|
// mapCrop->insert(std::make_pair(spPoint.rotate.y, spPoint));//20140528
|
mapCrop->insert(std::make_pair(spPoint.origin.y, spPoint));//20140528
|
dSum += fabs(spPoint.dThick);
|
dCnt++;
|
if(fabs(spPoint.dThick) > dResDist[0])
|
dResDist[0] = spPoint.dThick;
|
|
// if(spPoint.dThick >= nBrokenSize && bBroken == FALSE)
|
// {
|
// if(nContiBrokenCnt == 0)
|
// {
|
// pointBroken = spPoint.origin;
|
// }
|
// nContiBrokenCnt++;
|
// if(nContiBrokenCnt >= DETECT_BROKEN_COUNT)
|
// bBroken = TRUE;
|
// }
|
// else
|
// {
|
// nContiBrokenCnt = 0;
|
// }
|
|
// TRACE("[%d,%d] [%d,%d] => [%.3f]\n",spPoint.origin.x,spPoint.origin.y,spPoint.rotate.x,spPoint.rotate.y,spPoint.dThick);//20140528
|
}
|
|
if(dCnt > 0)
|
dResDist[1] = dSum/dCnt;
|
|
// if(bBroken == TRUE)
|
// {
|
// SetBrokenDefect(pointBroken);
|
// }
|
|
return (int)mapCrop->size();
|
}
|
|
int CNotchCut::CropDataXY2_Chamfer(std::multimap<int,CSplinePoint> *mapCrop,std::multimap<int,CSplinePoint> *mapChamfer,int nStartX,int nFirstY,int nLastY)//20140528
|
{
|
std::multimap<int,CSplinePoint>::iterator it;
|
CSplinePoint spPoint;
|
|
for(it=mapChamfer->begin();it!=mapChamfer->end();it++)
|
{
|
spPoint = static_cast<CSplinePoint>(it->second);
|
|
if(spPoint.rotate.x < nStartX || spPoint.rotate.y < nFirstY || spPoint.rotate.y > nLastY)
|
{
|
TRACE("[%d,%d] [%d,%d] => [%.3f] nStartX[%d] nFirstY[%d] nLastY[%d]\n",spPoint.origin.x,spPoint.origin.y,spPoint.rotate.x,spPoint.rotate.y,spPoint.dThick,nStartX,nFirstY,nLastY);
|
continue;
|
}
|
|
mapCrop->insert(std::make_pair(spPoint.origin.y, spPoint));
|
}
|
|
return (int)mapCrop->size();
|
}
|
|
CSplinePoint CNotchCut::FindCenter2Vec(std::multimap<int,CSplinePoint> *mapCrop,int nCenY,int *nPosition)
|
{
|
CSplinePoint spPoint,vecPoint;
|
int nDist = INT_MAX,nLoop = 0;
|
std::multimap<int,CSplinePoint>::iterator it;
|
|
spPoint.rotate = CPoint(INT_MAX,INT_MAX);
|
|
*nPosition = -1;
|
for(it=mapCrop->begin();it!=mapCrop->end();it++,nLoop++)
|
{
|
vecPoint = static_cast<CSplinePoint>(it->second);
|
if(abs(vecPoint.rotate.y-nCenY) < nDist)
|
{
|
spPoint = vecPoint;
|
nDist = abs(vecPoint.rotate.y-nCenY);
|
*nPosition = nLoop;
|
}
|
}
|
|
return spPoint;
|
}
|
|
void CNotchCut::GetRangeAvgThick(std::multimap<int,CSplinePoint> *mapCrop,pNOTCH_RangePos_STU pReangeRes,CSplinePoint spCenter,int nRangeCnt)
|
{
|
double dSum,dCnt;
|
int nMin,nMax;
|
std::multimap<int,CSplinePoint>::iterator itFirst,itLast;
|
|
nMin = spCenter.rotate.y - nRangeCnt/2;
|
nMax = spCenter.rotate.y + nRangeCnt/2;
|
|
itFirst = mapCrop->lower_bound(nMin);
|
itLast = mapCrop->upper_bound(nMax);
|
|
if(itFirst == mapCrop->end() || itLast == mapCrop->end())
|
return;
|
|
dSum = dCnt = 0;
|
CSplinePoint vecPoint;
|
for(;itFirst!=itLast;itFirst++)
|
{
|
vecPoint = static_cast<CSplinePoint>(itFirst->second);
|
|
dSum += vecPoint.dThick;
|
dCnt++;
|
if(dCnt == (nRangeCnt/2+1))
|
{
|
pReangeRes->pointCAD = vecPoint.origin;
|
pReangeRes->pointImg = vecPoint.rotate;
|
}
|
}
|
|
pReangeRes->dDist = dCnt>0?dSum/dCnt:0;
|
}
|
|
void CNotchCut::GetRangeAvgThick_New(std::multimap<int,CSplinePoint> *mapCrop,pNOTCH_RangePos_STU pReangeRes,CPoint point,int nRangeCnt)//20140528
|
{
|
double dSum,dCnt;
|
int nMin,nMax;
|
std::multimap<int,CSplinePoint>::iterator itFirst,itLast;
|
|
nMin = point.y - nRangeCnt/2;
|
nMax = point.y + nRangeCnt/2;
|
|
itFirst = mapCrop->lower_bound(nMin);
|
itLast = mapCrop->upper_bound(nMax);
|
|
if(itFirst == mapCrop->end() || itLast == mapCrop->end())
|
return;
|
|
dSum = dCnt = 0;
|
CSplinePoint vecPoint;
|
for(;itFirst!=itLast;itFirst++)
|
{
|
vecPoint = static_cast<CSplinePoint>(itFirst->second);
|
|
dSum += vecPoint.dThick;
|
dCnt++;
|
if(dCnt == (nRangeCnt/2+1))
|
{
|
pReangeRes->pointCAD = vecPoint.origin;
|
pReangeRes->pointImg = vecPoint.rotate;
|
}
|
}
|
|
if(dCnt > 0)
|
{
|
pReangeRes->dDist = dSum/dCnt;
|
pReangeRes->nInsCount = (int)dCnt;
|
}
|
else
|
{
|
vecPoint = static_cast<CSplinePoint>(itFirst->second);
|
pReangeRes->pointCAD = vecPoint.origin;
|
pReangeRes->pointImg = vecPoint.rotate;
|
pReangeRes->dDist = vecPoint.dThick;
|
pReangeRes->nInsCount = 1;
|
}
|
}
|
|
void CNotchCut::GetRangeAvgThick_New_Cham(std::multimap<int,CSplinePoint> *mapCropChamfer,pNOTCH_RangePos_STU pReangeRes,CPoint point,int nRangeCnt)
|
{
|
double dSum,dCnt;
|
int nMin,nMax;
|
std::multimap<int,CSplinePoint>::iterator itFirst,itLast;
|
|
nMin = point.y - nRangeCnt/2;
|
nMax = point.y + nRangeCnt/2;
|
|
itFirst = mapCropChamfer->lower_bound(nMin);
|
itLast = mapCropChamfer->upper_bound(nMax);
|
|
if(itFirst == mapCropChamfer->end() || itLast == mapCropChamfer->end())
|
return;
|
|
dSum = dCnt = 0;
|
CSplinePoint vecPoint;
|
for(;itFirst!=itLast;itFirst++)
|
{
|
vecPoint = static_cast<CSplinePoint>(itFirst->second);
|
|
dSum += vecPoint.dThick;
|
dCnt++;
|
if(dCnt == (nRangeCnt/2+1))
|
{
|
pReangeRes->pointCAD = vecPoint.origin;
|
pReangeRes->pointImg = vecPoint.rotate;
|
}
|
}
|
|
if(dCnt > 0)
|
{
|
pReangeRes->dDist = dSum/dCnt;
|
pReangeRes->nInsCount = (int)dCnt;
|
}
|
else
|
{
|
vecPoint = static_cast<CSplinePoint>(itFirst->second);
|
pReangeRes->pointCAD = vecPoint.origin;
|
pReangeRes->pointImg = vecPoint.rotate;
|
pReangeRes->dDist = vecPoint.dThick;
|
pReangeRes->nInsCount = 1;
|
}
|
}
|
|
int CNotchCut::GetRangeDivThick(std::multimap<int, CSplinePoint> *mapCrop,CSplinePoint spCenter,int nCenterPos,pNOTCH_RangePos_STU pRangeRes,int nRangeCnt,BOOL bOpt,int nDivRange)
|
{
|
int nDivCnt,iCnt,iIndex;
|
int nHalfCnt = nRangeCnt/2;
|
std::multimap<int, CSplinePoint>::iterator it,itCenter;
|
|
itCenter = mapCrop->lower_bound(spCenter.rotate.y);
|
if(itCenter == mapCrop->end())
|
return 0;
|
|
CSplinePoint spPoint;
|
double dSum,dCnt;
|
if(bOpt == TRUE)
|
{
|
nDivCnt = nCenterPos/(nHalfCnt+1);
|
iCnt = iIndex = 0;
|
dSum = dCnt = 0.;
|
for(it=mapCrop->begin();it!=itCenter;it++,iCnt++)
|
{
|
if(iCnt >= nDivCnt-nDivRange)
|
{
|
spPoint = static_cast<CSplinePoint>(it->second);
|
dSum += spPoint.dThick;
|
dCnt++;
|
|
if(iCnt == nDivCnt)
|
{
|
if(iIndex >= nRangeCnt)
|
return iIndex;
|
pRangeRes[iIndex].pointCAD = spPoint.origin;
|
pRangeRes[iIndex].pointImg = spPoint.rotate;
|
}
|
else if(iCnt >= nDivCnt+nDivRange)
|
{
|
iCnt = 0;
|
pRangeRes[iIndex].dDist = dSum/dCnt;
|
dSum = dCnt = 0.;
|
iIndex++;
|
}
|
}
|
}
|
}
|
else
|
{
|
iIndex = nHalfCnt+1;
|
|
nDivCnt = (int)(mapCrop->size()-nCenterPos)/(nHalfCnt+1);
|
iCnt = 0;
|
dSum = dCnt = 0.;
|
for(it=itCenter;it!=mapCrop->end();it++,iCnt++)
|
{
|
if(iCnt >= nDivCnt-nDivRange)
|
{
|
spPoint = static_cast<CSplinePoint>(it->second);
|
dSum += spPoint.dThick;
|
dCnt++;
|
|
if(iCnt == nDivCnt)
|
{
|
if(iIndex >= nRangeCnt)
|
return iIndex;
|
pRangeRes[iIndex].pointCAD = spPoint.origin;
|
pRangeRes[iIndex].pointImg = spPoint.rotate;
|
}
|
else if(iCnt >= nDivCnt+nDivRange)
|
{
|
iCnt = 0;
|
pRangeRes[iIndex].dDist = dSum/dCnt;
|
dSum = dCnt = 0.;
|
iIndex++;
|
}
|
}
|
}
|
}
|
|
return iIndex;
|
}
|
|
void CNotchCut::CalRangeVal(std::multimap<int,CSplinePoint> *mapDist,double *dResDist,pNOTCH_RangePos_STU dRangeRes,int nRangeCnt,int nCenX,int nCenY,int nStartX,int nFirstY,int nLastY)
|
{
|
if(dRangeRes == NULL || nRangeCnt <= 0 || (int)mapDist->size() <= 0)
|
{
|
return;
|
}
|
|
std::multimap<int, CSplinePoint> mapCrop;
|
|
if(CropDataXY2(&mapCrop,mapDist,nStartX,nFirstY,nLastY,dResDist) <= 0)
|
{
|
return;
|
}
|
|
CSplinePoint spCenter;
|
int nCenterPosition;
|
|
spCenter = FindCenter2Vec(&mapCrop,nCenY,&nCenterPosition);
|
if(nCenterPosition <= 0 || spCenter.rotate.x == INT_MAX || spCenter.rotate.y == INT_MAX)
|
{
|
return;
|
}
|
|
const int RANGE_AVG_COUNT = 5;
|
int nHalfCnt = nRangeCnt/2;
|
|
GetRangeAvgThick(&mapCrop,&dRangeRes[nHalfCnt],spCenter,RANGE_AVG_COUNT);
|
|
if(nHalfCnt > 0)
|
{
|
GetRangeDivThick(&mapCrop,spCenter,nCenterPosition,dRangeRes,nRangeCnt,TRUE,RANGE_AVG_COUNT/2);
|
GetRangeDivThick(&mapCrop,spCenter,nCenterPosition,dRangeRes,nRangeCnt,FALSE,RANGE_AVG_COUNT/2);
|
}
|
}
|
|
void CNotchCut::CalRangeVal_New(std::multimap<int,CSplinePoint> *mapDist,std::multimap<int,CSplinePoint> *mapDist_Dy,double *dResDist,double *dResDist_Dy,pNOTCH_RangePos_STU dRangeRes,pNOTCH_RangePos_STU dRangeRes_Dy,pNOTCH_RangePos_STU dRangeRes_Cham,int nRangeCnt,int nCenX,int nCenY,int nStartX,int nFirstY,int nLastY,std::multimap<int,CSplinePoint> *mapChamfer)//20140528
|
{
|
if(dRangeRes == NULL || dRangeRes_Dy == NULL || dRangeRes_Cham == NULL || nRangeCnt <= 0 || (int)mapDist->size() <= 0 || (int)mapDist_Dy->size() <= 0)
|
{
|
return;
|
}
|
|
std::multimap<int, CSplinePoint> mapCrop;
|
|
if(CropDataXY2(&mapCrop,mapDist,nStartX,nFirstY,nLastY,dResDist) <= 0)
|
{
|
return;
|
}
|
|
std::multimap<int, CSplinePoint> mapCrop_Dy;
|
|
if(CropDataXY2(&mapCrop_Dy,mapDist_Dy,nStartX,nFirstY,nLastY,dResDist_Dy) <= 0)
|
{
|
return;
|
}
|
|
std::multimap<int, CSplinePoint> mapCropChamfer;
|
|
if(CropDataXY2_Chamfer(&mapCropChamfer,mapChamfer,nStartX,nFirstY,nLastY) <= 0)
|
{
|
return;
|
}
|
|
const int RANGE_AVG_COUNT = m_InsParm.nPointInsAveCount;
|
vector<pair<int,CPoint>>::iterator it;
|
CPoint pointData;
|
int nIndex;
|
|
//for (int i=0; i<nRangeCnt; i++)
|
{
|
for(it=m_mapMaster_InsPos.begin();it!=m_mapMaster_InsPos.end();it++)
|
{
|
nIndex = static_cast<int>(it->first);
|
pointData = static_cast<CPoint>(it->second);
|
|
GetRangeAvgThick_New(&mapCrop,&dRangeRes[nIndex],pointData,RANGE_AVG_COUNT);
|
GetRangeAvgThick_New(&mapCrop_Dy,&dRangeRes_Dy[nIndex],pointData,RANGE_AVG_COUNT);
|
GetRangeAvgThick_New_Cham(&mapCropChamfer,&dRangeRes_Cham[nIndex],pointData,RANGE_AVG_COUNT);
|
}
|
}
|
}
|
|
void CNotchCut::DrawImgRect(CSISBuffer &pOrg,double dX,double dY,int nValue)
|
{
|
CRect rect;
|
int nRange = 5;
|
int u,v;
|
|
rect.left = (int)dX - nRange;
|
rect.right = rect.left + nRange*2;
|
rect.top = (int)dY - nRange;
|
rect.bottom = rect.top + nRange*2;
|
|
AssertRect(rect,pOrg);
|
|
for(u=rect.left;u<=rect.right;u++)
|
{
|
pOrg.SetPixel(u,rect.top,nValue);
|
pOrg.SetPixel(u,rect.bottom,nValue);
|
}
|
|
for(v=rect.top;v<=rect.bottom;v++)
|
{
|
pOrg.SetPixel(rect.left,v,nValue);
|
pOrg.SetPixel(rect.right,v,nValue);
|
}
|
}
|
|
void CNotchCut::MakeReal2Cad_Image(CSISBuffer &pOrg,COwnerBuffer &pRes,int nValue)
|
{
|
if((int)m_mapMaster.size() <= 0)
|
return;
|
|
pRes.SetSize(pOrg.GetWidth(),pOrg.GetHeight());
|
|
CopyMemory(pRes.GetDataAddress(0,0),pOrg.GetDataAddress(0,0),pOrg.GetDataSize());
|
|
vector<pair<int,CPoint>>::iterator it;
|
CPoint pointData;
|
|
for(it=m_mapMaster.begin();it!=m_mapMaster.end();it++)
|
{
|
pointData = static_cast<CPoint>(it->second);
|
|
if(pointData.x < 0 || pointData.y < 0 || pointData.x >= pOrg.GetWidth() || pointData.y >= pOrg.GetHeight())
|
continue;
|
|
pRes.SetPixel(pointData.x,pointData.y,nValue);
|
}
|
}
|
|
void CNotchCut::MakeReal2AlignCad(CSISBuffer &pOrg,int nCenY,int nForeX, int iDimension, int icam)
|
{
|
if(iDimension < 0 || iDimension >= MAX_NOTCH_SCAN_COUNT || (int)m_mapAlignMaster[iDimension].size() <= 0)
|
return;
|
|
COwnerBuffer pTgt(pOrg.GetWidth(),pOrg.GetHeight());
|
|
CopyMemory(pTgt.GetDataAddress(0,0),pOrg.GetDataAddress(0,0),pOrg.GetDataSize());
|
|
std::multimap<int, CPoint>::iterator it;
|
CPoint pointData,pointMove;
|
|
pointMove.x = nForeX-m_AlignMasterParm[iDimension].nPosX;
|
pointMove.y = pOrg.GetHeight()/2-m_AlignMasterParm[iDimension].nPosY;
|
|
m_AlignMasterParm[iDimension].nMaxX += pointMove.x;
|
m_AlignMasterParm[iDimension].nPosX += pointMove.x;
|
m_AlignMasterParm[iDimension].nMaxY += pointMove.y;
|
|
for(it=m_mapAlignMaster[iDimension].begin();it!=m_mapAlignMaster[iDimension].end();it++)
|
{
|
pointData = static_cast<CPoint>(it->second);
|
|
pointData.Offset(pointMove.x,pointMove.y);
|
|
if(pointData.x < 0 || pointData.y < 0 || pointData.x >= pOrg.GetWidth() || pointData.y >= pOrg.GetHeight())
|
continue;
|
|
pTgt.SetPixel(pointData.x,pointData.y,200);
|
|
m_mapMaster.push_back(std::make_pair(pointData.y, pointData));
|
}
|
|
std::sort(m_mapMaster.begin(),m_mapMaster.end(),SortYPos());
|
|
int nIndex = 0;//20140528
|
|
for(it=m_mapAlignMaster_InsPos[iDimension].begin();it!=m_mapAlignMaster_InsPos[iDimension].end();it++)//20140528
|
{
|
pointData = static_cast<CPoint>(it->second);
|
|
pointData.Offset(pointMove.x,pointMove.y);
|
|
if(pointData.x < 0 || pointData.y < 0 || pointData.x >= pOrg.GetWidth() || pointData.y >= pOrg.GetHeight())
|
continue;
|
|
pTgt.SetPixel(pointData.x,pointData.y,128);
|
|
m_mapMaster_InsPos.push_back(std::make_pair(nIndex++, pointData));
|
}
|
|
std::sort(m_mapMaster_InsPos.begin(),m_mapMaster_InsPos.end(),ResSortYPos());//20140528
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\5.Real2Cad_%d_%d_[%d,%d].bmp"),m_strSavePath,icam,iDimension,m_AlignMasterParm[iDimension].nMaxX,m_AlignMasterParm[iDimension].nMaxY);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pTgt);
|
}
|
}
|
|
void CNotchCut::MakeReal2Cad(CSISBuffer &pOrg,int nCenX,int nCenY, int iDimension, int icam)
|
{
|
if(iDimension < 0 || iDimension >= MAX_NOTCH_SCAN_COUNT || (int)m_mapOrgMaster[iDimension].size() <= 0)
|
return;
|
|
COwnerBuffer pTgt(pOrg.GetWidth(),pOrg.GetHeight());
|
|
CopyMemory(pTgt.GetDataAddress(0,0),pOrg.GetDataAddress(0,0),pOrg.GetDataSize());
|
|
std::multimap<int, CPoint>::iterator it;
|
CPoint pointData,pointMove;
|
|
pointMove.x = nCenX-m_MasterParm[iDimension].nPosX;
|
pointMove.y = pOrg.GetHeight()/2-m_MasterParm[iDimension].nPosY;
|
TRACE("¿øº» ¿µ»ó X=%d, Y=%d, ¿µ»ó ÀÚü Y=%d, CAD X=%d, Y=%d\n",nCenX,nCenY,pOrg.GetHeight()/2,m_MasterParm[iDimension].nPosX,m_MasterParm[iDimension].nPosY);
|
for(it=m_mapOrgMaster[iDimension].begin();it!=m_mapOrgMaster[iDimension].end();it++)
|
{
|
pointData = static_cast<CPoint>(it->second);
|
|
pointData.Offset(pointMove.x,pointMove.y);
|
|
if(pointData.x < 0 || pointData.y < 0 || pointData.x >= pOrg.GetWidth() || pointData.y >= pOrg.GetHeight())
|
continue;
|
|
pTgt.SetPixel(pointData.x,pointData.y,200);
|
|
m_mapMaster.push_back(std::make_pair(pointData.y, pointData));
|
}
|
|
std::sort(m_mapMaster.begin(),m_mapMaster.end(),SortYPos());
|
|
if(m_bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\5.Real2Cad_%d_%d.bmp"),m_strSavePath,icam,iDimension);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pTgt);
|
}
|
}
|
|
BOOL CNotchCut::ReadModelData(CString strFile, int index)
|
{
|
if(index < 0 || index >= MAX_NOTCH_SCAN_COUNT)
|
return FALSE;
|
|
m_mapOrgMaster[index].clear();
|
m_mapAlignMaster[index].clear();
|
|
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));
|
m_mapOrgMaster[index].insert(std::make_pair(point.y, point));
|
if(m_MasterParm[index].nMaxX < point.x)
|
m_MasterParm[index].nMaxX = point.x;
|
if(m_MasterParm[index].nMaxY < point.y)
|
m_MasterParm[index].nMaxY = point.y;
|
}
|
|
file.Close();
|
|
return TRUE;
|
}
|
|
BOOL CNotchCut::WriteModelData(CString strFile,CString strRecipe,CString strCut,std::multimap<int, CSplinePoint> *pPoint)
|
{
|
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;
|
|
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->origin,sizeof(CPoint));
|
|
if(pointMax.x < splinePos->origin.x) pointMax.x = splinePos->origin.x;
|
if(pointMax.y < splinePos->origin.y) pointMax.y = splinePos->origin.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->origin.x < 0 || splinePos->origin.y < 0
|
|| splinePos->origin.x >= ownerBuf.GetWidth() || splinePos->origin.y >= ownerBuf.GetHeight())
|
continue;
|
|
ownerBuf.SetPixel(splinePos->origin.x,splinePos->origin.y,255);
|
}
|
|
CString strimg;
|
strimg.Format(_T("C:\\EdgeInspector_App\\Notch\\%s_%s_org.bmp"),strRecipe,strCut);
|
CBufferAttach attach(strimg);
|
attach.AttachToFile(ownerBuf);
|
|
return TRUE;
|
}
|
|
void CNotchCut::SetNotchInsPoint( std::vector<CPoint> *InsPoint , int index)//20140528
|
{
|
std::vector<CPoint>::iterator it;
|
CPoint point;
|
|
m_mapOrgMaster_InsPos[index].clear();
|
|
for(it=InsPoint->begin();it!=InsPoint->end();it++)
|
{
|
|
point = *it;
|
|
if(point.x < 0 || point.y < 0)
|
continue;
|
|
m_mapOrgMaster_InsPos[index].insert(std::make_pair(point.y, point));
|
}
|
}
|