// ChamferInspect.cpp : implementation file
|
//
|
|
#include "stdafx.h"
|
#include "ChamferInspect.h"
|
#include <math.h>
|
#include <numeric>
|
#include "EdgeFind.h"
|
#include "EdgeProc.h"
|
#include "BLOB_Tool.h"
|
#include "Edge_Log.h"
|
|
#ifdef _DEBUG
|
#define new DEBUG_NEW
|
#undef THIS_FILE
|
static char THIS_FILE[] = __FILE__;
|
#endif
|
|
#define PATH_DEFECTFOLDER _T("D:\\EdgeInspector_App\\Defect")
|
#define PATH_DEBUGFOLDER _T("D:\\Image\\CutArea")
|
|
/////////////////////////////////////////////////////////////////////////////
|
// CChamferInspect
|
|
CChamferInspect::CChamferInspect()
|
{
|
m_dConvResolution = 0.;
|
m_nForeEdgeLine[0] = m_nForeEdgeLine[1] = 0;
|
m_pGlassEdgeLine = NULL;
|
m_nGlassEdgeLineCnt = 0;
|
m_nSaveIndex = 0;
|
m_pCannyWidthCnt = NULL;
|
m_nDefectCnt = 0;
|
|
m_DefectBlob = new CChipBlob[MAX_CHIP_DEFECT_COUNT];
|
m_pChipPairBuf = new CChipPair[MAX_CHIP_PAIR_DEFECT_COUNT];
|
m_bMerged = new BOOL[MAX_CHIP_PAIR_DEFECT_COUNT];
|
m_bTemp = new BOOL[MAX_CHIP_PAIR_DEFECT_COUNT];
|
m_lFirstIndex = new int[MAX_CHIP_PAIR_DEFECT_COUNT];
|
}
|
|
CChamferInspect::~CChamferInspect()
|
{
|
ReleaseBuffer();
|
ResetValue();
|
|
if(m_DefectBlob != NULL)
|
delete[] m_DefectBlob;
|
m_DefectBlob = NULL;
|
|
if(m_pChipPairBuf != NULL)
|
delete[] m_pChipPairBuf;
|
m_pChipPairBuf = NULL;
|
|
if(m_bMerged != NULL)
|
delete[] m_bMerged;
|
m_bMerged = NULL;
|
|
if(m_bTemp != NULL)
|
delete[] m_bTemp;
|
m_bTemp = NULL;
|
|
if(m_lFirstIndex != NULL)
|
delete[] m_lFirstIndex;
|
m_lFirstIndex = NULL;
|
}
|
|
CChipPair *CChamferInspect::GetPairDefect(int iIndex)
|
{
|
if(iIndex < 0 || iIndex >= MAX_CHIP_PAIR_DEFECT_COUNT)
|
return NULL;
|
|
return &m_pChipPairBuf[iIndex];
|
}
|
|
BOOL CChamferInspect::InsertPairing(int x, int y, int sub, int threshold, int graySrc, int grayRef,ChipResionType s_RegionType,DefectPosType s_DefectPos,BOOL bEdgeDefect, double dThick)
|
{
|
if(GetPairDefectCount() >= MAX_CHIP_PAIR_DEFECT_COUNT)
|
{
|
return FALSE;
|
}
|
|
int iPiar = GetPairDefectCount();
|
CChipPair *pPair = GetPairDefect(iPiar);
|
|
if(pPair == NULL)
|
return FALSE;
|
|
pPair->s_DefectPair= CHIPDEFPAIR_PPAIR;
|
if(sub > 0)
|
pPair->s_DefectType= CHIPDEFTYPE_BLACK;
|
else
|
pPair->s_DefectType= CHIPDEFTYPE_WHITE;
|
|
pPair->s_RegionType = s_RegionType;
|
pPair->s_fDefectPeak= (float)abs(sub);
|
pPair->s_DefectPosType = s_DefectPos;
|
|
pPair->s_nDefectX= x;
|
pPair->s_nDefectY= y;
|
pPair->s_nGraySrc= graySrc;
|
pPair->s_nGrayRef= grayRef;
|
pPair->s_dThick = dThick;
|
pPair->s_bCornerChip = bEdgeDefect;
|
|
m_nChipPairIndex++;
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::BlobDefect_Pixel(std::vector<CChipBlob> &vecBlob,int nChipThres,int nMergeDist)
|
{
|
if(GetPairDefectCount() <= 0)
|
return TRUE;
|
|
int i, j;
|
int nPair = GetPairDefectCount();
|
int nBlob = 0;
|
|
// Index ¸Å±â±â.
|
ZeroMemory(m_bMerged, nPair * sizeof(BOOL));
|
ZeroMemory(m_bTemp, nPair * sizeof(BOOL));
|
for (i = 0; i < nPair; i++)
|
{
|
m_lFirstIndex[i] = i;
|
}
|
|
CChipPair *pPair,*pPairCom;
|
|
// ÀÎÁ¢ µðÆå ¸ÓÁöÇϱâ.
|
for(i = 0; i < nPair; i++)
|
{
|
pPair = GetPairDefect(i);
|
if(pPair == NULL)
|
continue;
|
|
for (j = i + 1; j < nPair; j++)
|
{
|
if (m_bMerged[j])// || vecPair[i].s_DefectType != vecPair[j].s_DefectType)
|
continue;
|
|
pPairCom = GetPairDefect(j);
|
if(pPairCom == NULL)
|
continue;
|
|
if (abs(pPairCom->s_nDefectY - pPair->s_nDefectY) > nMergeDist) // j´Â iº¸´Ù Å©´Ù.
|
continue;
|
|
if (abs(pPairCom->s_nDefectX - pPair->s_nDefectX) > nMergeDist)
|
continue;
|
|
m_lFirstIndex[j] = m_lFirstIndex[i];
|
m_bMerged[j] = TRUE;
|
}
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
int nStart = 0;
|
BOOL Ret = TRUE;
|
|
// µðÆåµéÀÇ ¼ö¸¸Å ó¸®. - Blobing
|
int nBlobNum = 0;
|
int nDiffGray, nThres=nChipThres;
|
CChipBlob chipBlob;
|
|
for (i = 0; i < nPair; i++)
|
{
|
pPair = GetPairDefect(i);
|
if(pPair == NULL)
|
continue;
|
|
if (pPair->s_DefectType == CHIPDEFTYPE_DELETE)
|
{
|
continue;
|
}
|
|
if (!m_bTemp[m_lFirstIndex[i]]) // óÀ½ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
if (nBlob >= nPair || nBlobNum >= 1000)
|
continue;
|
|
m_bTemp[m_lFirstIndex[i]] = TRUE;
|
|
chipBlob.Reset();
|
CheckDefectRect(chipBlob, pPair->s_nDefectX, pPair->s_nDefectY);
|
|
chipBlob.SetDefectPair(pPair->s_DefectPair);
|
chipBlob.s_nIndex = m_lFirstIndex[i];
|
chipBlob.s_nDefectArea++;
|
chipBlob.s_nDefectX += pPair->s_nDefectX;
|
chipBlob.s_nDefectY += pPair->s_nDefectY;
|
chipBlob.s_DefectType = pPair->s_DefectType; //½ÇÁ¦ ¹é°áÇÔÀº 1,Èæ°áÇÔÀº 0
|
chipBlob.s_sThreshold = nThres;
|
chipBlob.s_RegionType = pPair->s_RegionType;
|
chipBlob.s_dThick = pPair->s_dThick;
|
chipBlob.s_bCornerChip |= pPair->s_bCornerChip;
|
chipBlob.s_DefectJudgeType = pPair->s_DefectPosType;
|
|
// Gray ±¸Çϱâ
|
if (pPair->s_nGraySrc > chipBlob.s_sLevelSrcMax)
|
{
|
chipBlob.s_sLevelSrcMax = pPair->s_nGraySrc;
|
chipBlob.s_xLevelSrcMax = pPair->s_nDefectX;
|
chipBlob.s_yLevelSrcMax = pPair->s_nDefectY;
|
}
|
if (pPair->s_nGraySrc < chipBlob.s_sLevelSrcMin)
|
chipBlob.s_sLevelSrcMin = pPair->s_nGraySrc;
|
chipBlob.s_nLevelSrcSum += pPair->s_nGraySrc;
|
|
if (pPair->s_nGrayRef > chipBlob.s_sLevelRefMax)
|
chipBlob.s_sLevelRefMax = pPair->s_nGrayRef;
|
if (pPair->s_nGrayRef < chipBlob.s_sLevelRefMin)
|
chipBlob.s_sLevelRefMin = pPair->s_nGrayRef;
|
chipBlob.s_nLevelRefSum += pPair->s_nGrayRef;
|
|
nDiffGray = abs(pPair->s_nGraySrc - pPair->s_nGrayRef);
|
if (nDiffGray > chipBlob.s_sLevelDiffMax)
|
{
|
chipBlob.s_sLevelDiffMax = nDiffGray;
|
chipBlob.s_sDefectPeak = abs(chipBlob.s_sLevelDiffMax) - nThres;
|
//chipBlob.s_sDefectPeak = abs(chipBlob.s_sLevelDiffMax / 8) - nThres;
|
}
|
if (nDiffGray < chipBlob.s_sLevelDiffMin)
|
chipBlob.s_sLevelDiffMin = nDiffGray;
|
chipBlob.s_nLevelDiffSum += nDiffGray;
|
|
vecBlob.push_back(chipBlob);
|
nBlob++;
|
nBlobNum++;
|
}
|
else // ³ªÁß¿¡ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
for(j = nBlob - 1; j >= 0; j--)
|
{
|
if (vecBlob[j].s_nIndex != m_lFirstIndex[i])
|
continue;
|
|
CheckDefectRect(vecBlob[j], pPair->s_nDefectX, pPair->s_nDefectY);
|
|
if(vecBlob[j].s_DefectJudgeType == INS_DEFECT_CHIP)
|
{
|
if(pPair->s_DefectPosType == INS_DEFECT_CRACK || pPair->s_DefectPosType == INS_DEFECT_BROKEN)
|
vecBlob[j].s_DefectJudgeType = pPair->s_DefectPosType;
|
}
|
else if(vecBlob[j].s_DefectJudgeType == INS_DEFECT_CRACK)
|
{
|
if(pPair->s_DefectPosType == INS_DEFECT_BROKEN)
|
vecBlob[j].s_DefectJudgeType = pPair->s_DefectPosType;
|
}
|
|
vecBlob[j].SetDefectPair(pPair->s_DefectPair);
|
vecBlob[j].s_nDefectArea++;
|
vecBlob[j].s_nDefectX += pPair->s_nDefectX;
|
vecBlob[j].s_nDefectY += pPair->s_nDefectY;
|
vecBlob[j].s_bCornerChip |= pPair->s_bCornerChip;
|
if (nThres > vecBlob[j].s_sThreshold)
|
vecBlob[j].s_sThreshold = nThres;
|
|
// Gray ±¸Çϱâ
|
if (pPair->s_nGraySrc > vecBlob[j].s_sLevelSrcMax)
|
{
|
vecBlob[j].s_sLevelSrcMax = pPair->s_nGraySrc;
|
vecBlob[j].s_xLevelSrcMax = pPair->s_nDefectX;
|
vecBlob[j].s_yLevelSrcMax = pPair->s_nDefectY;
|
}
|
if (pPair->s_nGraySrc < vecBlob[j].s_sLevelSrcMin)
|
vecBlob[j].s_sLevelSrcMin = pPair->s_nGraySrc;
|
vecBlob[j].s_nLevelSrcSum += pPair->s_nGraySrc;
|
|
if (pPair->s_nGrayRef > vecBlob[j].s_sLevelRefMax)
|
vecBlob[j].s_sLevelRefMax = pPair->s_nGrayRef;
|
if (pPair->s_nGrayRef < vecBlob[j].s_sLevelRefMin)
|
vecBlob[j].s_sLevelRefMin = pPair->s_nGrayRef;
|
vecBlob[j].s_nLevelRefSum += pPair->s_nGrayRef;
|
|
nDiffGray = abs(pPair->s_nGraySrc - pPair->s_nGrayRef);
|
if (nDiffGray > vecBlob[j].s_sLevelDiffMax)
|
{
|
vecBlob[j].s_sLevelDiffMax = nDiffGray;
|
vecBlob[j].s_sDefectPeak = abs(vecBlob[j].s_sLevelDiffMax) - nThres;
|
//vecBlob[j].s_sDefectPeak = abs(vecBlob[j].s_sLevelDiffMax / 8) - nThres;
|
}
|
if (nDiffGray < vecBlob[j].s_sLevelDiffMin)
|
vecBlob[j].s_sLevelDiffMin = nDiffGray;
|
vecBlob[j].s_nLevelDiffSum += nDiffGray;
|
|
if(vecBlob[j].s_dThick < pPair->s_dThick)
|
vecBlob[j].s_dThick = pPair->s_dThick;
|
|
break;
|
}
|
}
|
}
|
|
// ÁÂÇ¥ º¸Á¤.
|
for (i = nStart; i < nBlob; i++)
|
{
|
if (vecBlob[i].s_nDefectArea > 0)
|
{
|
vecBlob[i].s_nDefectX = vecBlob[i].s_nDefectX / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_nDefectY = vecBlob[i].s_nDefectY / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_sLevelSrcAvg = vecBlob[i].s_nLevelSrcSum / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_sLevelRefAvg = vecBlob[i].s_nLevelRefSum / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_sLevelDiffAvg = vecBlob[i].s_nLevelDiffSum / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_nDefectRScale = CalcRScale(vecBlob[i].s_ptVertex);
|
}
|
else
|
vecBlob[i].s_bRemoved = TRUE;
|
}
|
|
MergeMix(vecBlob);
|
|
return Ret;
|
}
|
|
BOOL CChamferInspect::MergeDivision(std::vector<CChipBlob> &vecBlob, int nMergePixel)
|
{
|
int i,j;
|
|
//µðÆå·ºÆ®·Î ¸ÓÁö
|
CChipBlob Blob;
|
CChipBlob BlobNext;
|
|
int nSize = (int)vecBlob.size();
|
for(i=0; i<nSize; i++)
|
{
|
Blob = vecBlob[i];
|
for(j=i+1; j<nSize; j++)
|
{
|
BlobNext = vecBlob[j];
|
|
//ŸÀÔÀÌ ´Ù¸£¸é ¸ÓÁö ¾ÈÇÑ´Ù.
|
if(Blob.s_DefectType != BlobNext.s_DefectType)
|
continue;
|
|
if(Blob.s_DefectRect.bottom + nMergePixel < BlobNext.s_DefectRect.top || Blob.s_DefectRect.top - nMergePixel > BlobNext.s_DefectRect.bottom)
|
continue;
|
|
if(Blob.s_DefectRect.right + nMergePixel < BlobNext.s_DefectRect.left || Blob.s_DefectRect.left - nMergePixel > BlobNext.s_DefectRect.right)
|
continue;
|
|
//ÀÎÁ¢ÇØ ÀÖÀ¸¹Ç·Î ÇÕÄ£´Ù.
|
if(!Blob.s_bRemoved && !BlobNext.s_bRemoved)
|
{
|
vecBlob[i] = vecBlob[i] + vecBlob[j];
|
Blob=vecBlob[i];
|
vecBlob[j].s_bRemoved = TRUE;
|
}
|
}
|
}
|
|
//ÇÕÄ£°Ç Áö¿ö¼ À籸¼º
|
std::vector<CChipBlob>vecTemp;
|
for(i=0; i<nSize; i++)
|
{
|
if(!vecBlob[i].s_bRemoved)
|
{
|
vecTemp.push_back(vecBlob[i]);
|
}
|
}
|
|
vecBlob.clear();
|
vecBlob.resize(vecTemp.size());
|
copy(vecTemp.begin(),vecTemp.end(),vecBlob.begin());
|
nSize = (int)vecBlob.size();
|
for(i=0; i<nSize; i++)
|
vecBlob[i].s_nDefectRScale = CalcRScale(vecBlob[i].s_ptVertex);
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::MergeMix(std::vector<CChipBlob> &vecBlob, int nMergePixel)
|
{
|
int i,j;
|
|
//µðÆå·ºÆ®·Î ¸ÓÁö
|
CChipBlob Blob;
|
CChipBlob BlobNext;
|
|
int nSize = (int)vecBlob.size();
|
for(i=0; i<nSize; i++)
|
{
|
Blob = vecBlob[i];
|
for(j=i+1; j<nSize; j++)
|
{
|
BlobNext = vecBlob[j];
|
|
if(Blob.s_DefectRect.bottom + nMergePixel < BlobNext.s_DefectRect.top || Blob.s_DefectRect.top - nMergePixel > BlobNext.s_DefectRect.bottom)
|
continue;
|
|
if(Blob.s_DefectRect.right + nMergePixel < BlobNext.s_DefectRect.left || Blob.s_DefectRect.left - nMergePixel > BlobNext.s_DefectRect.right)
|
continue;
|
|
//ÀÎÁ¢ÇØ ÀÖÀ¸¹Ç·Î ÇÕÄ£´Ù.
|
if(!Blob.s_bRemoved && !BlobNext.s_bRemoved)
|
{
|
vecBlob[i] = vecBlob[i] + vecBlob[j];
|
if(Blob.s_DefectType != BlobNext.s_DefectType)
|
vecBlob[i].s_DefectType = CHIPDEFTYPE_BLACK;
|
Blob=vecBlob[i];
|
vecBlob[j].s_bRemoved = TRUE;
|
}
|
}
|
}
|
|
//ÇÕÄ£°Ç Áö¿ö¼ À籸¼º
|
std::vector<CChipBlob>vecTemp;
|
for(i=0; i<nSize; i++)
|
{
|
if(!vecBlob[i].s_bRemoved)
|
{
|
vecTemp.push_back(vecBlob[i]);
|
}
|
}
|
|
vecBlob.clear();
|
vecBlob.resize(vecTemp.size());
|
copy(vecTemp.begin(),vecTemp.end(),vecBlob.begin());
|
nSize = (int)vecBlob.size();
|
for(i=0; i<nSize; i++)
|
vecBlob[i].s_nDefectRScale = CalcRScale(vecBlob[i].s_ptVertex);
|
|
return TRUE;
|
}
|
|
void CChamferInspect::CheckDefectRect(CChipBlob& Defect, int nX, int nY) // CPoint* pVertex, CRect* pRect, int nX, int nY)
|
{
|
CPoint *points= Defect.s_ptVertex;
|
if (nY <= Defect.s_DefectRect.top)
|
{
|
Defect.s_DefectRect.top = nY;
|
if (Defect.s_ptVertex[2].y == nY) // Top Left
|
{
|
if (nX < Defect.s_ptVertex[2].x)
|
{
|
Defect.s_ptVertex[2].x = nX;
|
Defect.s_ptVertex[2].y = nY;
|
}
|
}
|
else
|
{
|
Defect.s_ptVertex[2].x = nX;
|
Defect.s_ptVertex[2].y = nY;
|
}
|
if (Defect.s_ptVertex[3].y == nY) // Top Right
|
{
|
if (nX + 1 > Defect.s_ptVertex[3].x)
|
{
|
Defect.s_ptVertex[3].x = nX + 1;
|
Defect.s_ptVertex[3].y = nY;
|
}
|
}
|
else
|
{
|
Defect.s_ptVertex[3].x = nX + 1;
|
Defect.s_ptVertex[3].y = nY;
|
}
|
}
|
if (nY + 1 >= Defect.s_DefectRect.bottom)
|
{
|
Defect.s_DefectRect.bottom = nY + 1;
|
if (Defect.s_ptVertex[6].y == nY + 1) // Bottom Left
|
{
|
if (nX < Defect.s_ptVertex[6].x)
|
{
|
Defect.s_ptVertex[6].x = nX;
|
Defect.s_ptVertex[6].y = nY + 1;
|
}
|
}
|
else
|
{
|
Defect.s_ptVertex[6].x = nX;
|
Defect.s_ptVertex[6].y = nY + 1;
|
}
|
if (Defect.s_ptVertex[7].y == nY + 1) // Bottom Right
|
{
|
if (nX + 1 > Defect.s_ptVertex[7].x)
|
{
|
Defect.s_ptVertex[7].x = nX + 1;
|
Defect.s_ptVertex[7].y = nY + 1;
|
}
|
}
|
else
|
{
|
Defect.s_ptVertex[7].x = nX + 1;
|
Defect.s_ptVertex[7].y = nY + 1;
|
}
|
}
|
if (nX <= Defect.s_DefectRect.left)
|
{
|
Defect.s_DefectRect.left = nX;
|
if (Defect.s_ptVertex[1].x == nX) // Left Bottom
|
{
|
if (nY + 1 > Defect.s_ptVertex[1].y)
|
{
|
Defect.s_ptVertex[1].x = nX;
|
Defect.s_ptVertex[1].y = nY + 1;
|
}
|
}
|
else
|
{
|
Defect.s_ptVertex[1].x = nX;
|
Defect.s_ptVertex[1].y = nY + 1;
|
}
|
if (Defect.s_ptVertex[0].x == nX) // Left Top
|
{
|
if (nY < Defect.s_ptVertex[0].y)
|
{
|
Defect.s_ptVertex[0].x = nX;
|
Defect.s_ptVertex[0].y = nY;
|
}
|
}
|
else
|
{
|
Defect.s_ptVertex[0].x = nX;
|
Defect.s_ptVertex[0].y = nY;
|
}
|
}
|
if (nX + 1 >= Defect.s_DefectRect.right)
|
{
|
Defect.s_DefectRect.right = nX + 1;
|
if (Defect.s_ptVertex[5].x == nX + 1) // Right Bottom
|
{
|
if (nY + 1 > Defect.s_ptVertex[5].y)
|
{
|
Defect.s_ptVertex[5].x = nX + 1;
|
Defect.s_ptVertex[5].y = nY + 1;
|
}
|
}
|
else
|
{
|
Defect.s_ptVertex[5].x = nX + 1;
|
Defect.s_ptVertex[5].y = nY + 1;
|
}
|
if (Defect.s_ptVertex[4].x == nX + 1) // Right Top
|
{
|
if (nY < Defect.s_ptVertex[4].y)
|
{
|
Defect.s_ptVertex[4].x = nX + 1;
|
Defect.s_ptVertex[4].y = nY;
|
}
|
}
|
else
|
{
|
Defect.s_ptVertex[4].x = nX + 1;
|
Defect.s_ptVertex[4].y = nY;
|
}
|
}
|
}
|
|
int CChamferInspect::CalcRScale(CPoint* pVertex)
|
{
|
double dDeltaX, dDeltaY;
|
double dTemp, dRScale = 0.0;
|
for (int i = 0; i < 8; i++)
|
{
|
for (int j = i; j < 8; j++)
|
{
|
#ifdef MOSIS_DELETE_CalcRScale
|
if (pVertex[i].x == 0 || pVertex[i].x == 32760 || pVertex[i].y == 0 ||pVertex[i].y == 32760
|
|| pVertex[j].x == 0 || pVertex[j].x == 32760 || pVertex[j].y == 0 ||pVertex[j].y == 32760)
|
continue;
|
#endif
|
dDeltaX = (pVertex[i].x - pVertex[j].x);// * m_dConvResolution;
|
dDeltaY = (pVertex[i].y - pVertex[j].y);// * m_dScanResolution;
|
dTemp = sqrt(dDeltaX * dDeltaX + dDeltaY * dDeltaY);
|
if (dRScale < dTemp)
|
dRScale = dTemp;
|
}
|
}
|
if (dRScale < 0.0)
|
dRScale = 0.0;
|
|
dRScale *= m_dConvResolution;
|
|
return static_cast<int>(dRScale + 0.5);
|
}
|
|
void CChamferInspect::ReleaseBuffer()
|
{
|
if(m_pGlassEdgeLine != NULL && m_nGlassEdgeLineCnt > 0)
|
{
|
for(int i=0;i<m_nGlassEdgeLineCnt;i++)
|
{
|
m_pGlassEdgeLine[i].Reset();
|
}
|
delete[] m_pGlassEdgeLine,m_pGlassEdgeLine=NULL;
|
}
|
|
if(m_pCannyWidthCnt != NULL)
|
delete[] m_pCannyWidthCnt, m_pCannyWidthCnt=NULL;
|
}
|
|
void CChamferInspect::ResetValue()
|
{
|
m_nForeEdgeLine[0] = m_nForeEdgeLine[1] = 0;
|
m_dAvgThick = 0;
|
ReleaseChipBuffer();
|
}
|
|
void CChamferInspect::ReleaseChipBuffer()
|
{
|
m_nDefectCnt = 0;
|
}
|
|
BOOL CChamferInspect::CopyBuffer(CSISBuffer &bufferOrg,COwnerBuffer &bufferTgt)
|
{
|
if(bufferOrg.IsValidBuffer() == FALSE || bufferOrg.GetDataWidth() <= 0 || bufferOrg.GetHeight() <= 0)
|
return FALSE;
|
|
bufferTgt.ReleaseSpace();
|
bufferTgt.SetSize(bufferOrg.GetDataWidth(),bufferOrg.GetHeight());
|
|
if(bufferTgt.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
CopyMemory(bufferTgt.GetDataAddress(0,0),bufferOrg.GetDataAddress(0,0),bufferOrg.GetDataSize());
|
|
return TRUE;
|
}
|
|
double CChamferInspect::GetAreaAVG(LPBYTE pImg,CRect &rectIns,CRect &rect)
|
{
|
double dAvg,dSum,dCount;
|
int i,j;
|
|
dAvg = dSum = dCount = 0.;
|
for(i=rect.left;i<rect.right;i++)
|
{
|
for(j=rect.top;j<rect.bottom;j++)
|
{
|
dSum += pImg[j*rectIns.Width()+i];
|
dCount++;
|
}
|
}
|
|
if(dCount > 0)
|
dAvg = dSum/dCount;
|
|
return dAvg;
|
}
|
|
#define CANNY_MIN_THRESHOLD 8
|
BOOL CChamferInspect::PreProcessing(LPBYTE pImg,CRect &rectIns,COwnerBuffer &BufferCanny)
|
{
|
if(pImg == NULL)
|
return FALSE;
|
|
const int nAreaSize = 10;
|
|
BufferCanny.SetSize(rectIns.Width(),rectIns.Height());
|
if(BufferCanny.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
CopyMemory(BufferCanny.GetDataAddress(0,0),pImg,sizeof(BYTE)*rectIns.Width()*(rectIns.Height()));
|
|
CRect rectBin(0,rectIns.top,nAreaSize,rectIns.bottom);
|
|
int nThres = (int)GetAreaAVG(pImg,rectIns,rectBin)/2;
|
if(nThres < CANNY_MIN_THRESHOLD)
|
nThres = CANNY_MIN_THRESHOLD;
|
|
//int nThres = OtsuoBinary(m_BufferCanny,rectBin);
|
|
CEdgeProc EdgeProc;
|
EdgeProc.CannyEdgeProcessing(pImg,rectIns,GM_Prewitt,(int)nThres,BufferCanny);
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::FindEdgeLine(LPBYTE pImg,CRect &rectIns)
|
{
|
if(pImg == NULL)
|
return FALSE;
|
|
int u,v;
|
int nValue,nPos;
|
int nMin,nMax;
|
CArray<int,int> arrU;
|
|
nPos = rectIns.top+1;
|
for(v=1;v<rectIns.Height()-1;v++,nPos++)
|
{
|
if(m_nGlassEdgeLineCnt <= nPos)
|
break;
|
|
m_pGlassEdgeLine[nPos].Reset();
|
nMin = INT_MAX;
|
nMax = INT_MIN;
|
arrU.RemoveAll();
|
|
for(u=1;u<rectIns.Width()-1;u++)
|
{
|
nValue = *(pImg+v*rectIns.Width()+u);
|
if(nValue == 255)
|
{
|
arrU.Add(u);
|
if(u < nMin) nMin = u;
|
if(u > nMax) nMax = u;
|
m_pCannyWidthCnt[u]++;
|
}
|
}
|
|
m_pGlassEdgeLine[nPos].nPosCnt = (int)arrU.GetCount();
|
if(m_pGlassEdgeLine[nPos].nPosCnt > 0)
|
{
|
m_pGlassEdgeLine[nPos].pPos = new int[m_pGlassEdgeLine[nPos].nPosCnt];
|
ZeroMemory(m_pGlassEdgeLine[nPos].pPos,sizeof(int)*m_pGlassEdgeLine[nPos].nPosCnt);
|
for(u=0;u<m_pGlassEdgeLine[nPos].nPosCnt;u++)
|
{
|
m_pGlassEdgeLine[nPos].pPos[u] = arrU.GetAt(u);
|
}
|
}
|
if(nMax != INT_MIN && nMin != INT_MAX)
|
m_pGlassEdgeLine[nPos].nWidth = abs(nMax-nMin)+1;
|
}
|
|
return TRUE;
|
}
|
|
int CChamferInspect::FindForeCastLine(CSISBuffer &pBuffer,CRect &rectIns,int &nforecast_S,int &nforecast_E,BOOL bChamfer)
|
{
|
nforecast_S = nforecast_E = -1;
|
|
if(m_pGlassEdgeLine == NULL)
|
return nforecast_S;
|
|
int u,v;
|
int nValue;
|
int *nPosCnt = NULL;
|
int nStart,nEnd;
|
int iLoop,nDev;
|
|
nStart = nEnd = nDev = 0;
|
|
nPosCnt = new int[rectIns.Width()+1];
|
ZeroMemory(nPosCnt,sizeof(int)*(rectIns.Width()+1));
|
|
nStart = 3;
|
nEnd = rectIns.Width();
|
for(v=rectIns.top;v<rectIns.bottom;v++)
|
{
|
if(m_nGlassEdgeLineCnt <= v)
|
break;
|
|
if(m_pGlassEdgeLine[v].nPosCnt > 0 && m_pGlassEdgeLine[v].pPos != NULL)
|
{
|
for(u=0;u<m_pGlassEdgeLine[v].nPosCnt;u++)
|
{
|
nValue = m_pGlassEdgeLine[v].pPos[u];
|
nPosCnt[nValue]++;
|
}
|
}
|
}
|
|
if(nPosCnt != NULL)
|
{
|
EDGEPOS edgePos;
|
std::vector<EDGEPOS> vecPos;
|
std::vector<EDGEPOS>::iterator it;
|
CRect rectLeft,rectRight;
|
int nAreaSize = 4;
|
int iDiv,nLoopCnt = 3;
|
int nSkipH = (pBuffer.GetHeight()-(nAreaSize*4))/(nLoopCnt-1);
|
int nVertical;
|
double dSumLeft,dSumRight,dSumCnt;
|
|
#define EDGE_FORE_RATIO 0.15
|
nDev = (int)((double)rectIns.Height()*EDGE_FORE_RATIO);
|
|
for(iLoop=nStart;iLoop<nEnd;iLoop++)
|
{
|
if(nDev <= nPosCnt[iLoop])
|
{
|
dSumLeft = dSumRight = dSumCnt = 0.;
|
for(iDiv=0;iDiv<nLoopCnt;iDiv++)
|
{
|
nVertical = nSkipH*iDiv+nAreaSize-nAreaSize/2;
|
rectLeft.SetRect(0,nVertical,0,nVertical+nAreaSize/2);
|
if(rectLeft.bottom >= pBuffer.GetHeight())
|
break;
|
|
rectRight = rectLeft;
|
rectLeft.right = iLoop-1;
|
rectLeft.left = rectLeft.right-nAreaSize;
|
if(rectLeft.left < 0)
|
continue;
|
|
rectRight.left = iLoop+1;
|
rectRight.right = rectRight.left+nAreaSize;
|
if(rectRight.right >= pBuffer.GetWidth())
|
continue;
|
|
dSumLeft += GetAreaAVG(pBuffer.GetDataAddress(0,0),rectIns,rectLeft);
|
dSumRight += GetAreaAVG(pBuffer.GetDataAddress(0,0),rectIns,rectRight);
|
dSumCnt++;
|
}
|
|
if(dSumCnt <= 0)
|
continue;
|
edgePos.dLeft = dSumLeft/dSumCnt;
|
edgePos.dRight = dSumRight/dSumCnt;
|
edgePos.nPos = iLoop;
|
|
vecPos.push_back(edgePos);
|
}
|
}
|
|
double dDiff,dMaxDiff = INT_MAX;
|
for(it=vecPos.begin();it!=vecPos.end();it++)
|
{
|
edgePos = *it;
|
dDiff = edgePos.dLeft-edgePos.dRight;
|
|
if(bChamfer == TRUE)
|
{
|
if(nforecast_S == -1 && dDiff > 0)
|
{
|
nforecast_S = edgePos.nPos;
|
continue;
|
}
|
}
|
else
|
{
|
//chamfer °Ë»ç ¾ÈÇÏ´Â °æ¿ì
|
if(nforecast_S == -1 && dDiff < 0)
|
{
|
nforecast_S = edgePos.nPos;
|
continue;
|
}
|
}
|
|
if(nforecast_S > 0)
|
{
|
if(dMaxDiff > dDiff)
|
{
|
dMaxDiff = dDiff;
|
nforecast_E = edgePos.nPos;
|
}
|
}
|
}
|
}
|
else
|
{
|
nforecast_S = -2;
|
}
|
|
if(0 > nforecast_S)
|
nforecast_S = 0;
|
if(0 > nforecast_E)
|
nforecast_E = 0;
|
|
if(nPosCnt != NULL)
|
delete[] nPosCnt, nPosCnt=NULL;
|
|
return nforecast_S;
|
}
|
|
BOOL CChamferInspect::Binarization(CSISBuffer &pOrg,COwnerBuffer &pBin,int nSetThres)
|
{
|
pBin.SetSize(pOrg.GetWidth(),pOrg.GetHeight());
|
CopyMemory(pBin.GetDataAddress(0,0),pOrg.GetDataAddress(0,0),pOrg.GetDataSize());
|
|
CSize szImg = CSize(pBin.GetWidth(),pBin.GetHeight());
|
CEdgeProc EdgeProc;
|
EdgeProc.ThresholdProcessing(pBin.GetDataAddress(0,0),szImg,nSetThres,0);
|
|
return TRUE;
|
}
|
|
// BOOL CChamferInspect::FindRightLine(CSISBuffer &pBuffer,int &nforecast_S,double &dRightLine)
|
// {
|
// int nSumLine,nSumCnt;
|
// int u,v;
|
// int nBCnt,nContinCnt=3;
|
//
|
// dRightLine = -1;
|
// nSumLine = nSumCnt = 0;
|
// for(v=0;v<pBuffer.GetHeight();v++)
|
// {
|
// nBCnt = 0;
|
// for(u=nforecast_S+1;u<pBuffer.GetWidth();u++)
|
// {
|
// if(*pBuffer.GetDataAddress(u,v) == 0)
|
// {
|
// nSumLine += u;
|
// nSumCnt++;
|
// break;
|
// }
|
// /*if(*pBuffer.GetDataAddress(u,v) == 0)
|
// nBCnt++;
|
// else
|
// nBCnt = 0;
|
//
|
// if(nBCnt >= nContinCnt)
|
// {
|
// if(nMinRightEdge > (u-nContinCnt-1))
|
// nMinRightEdge = (u-nContinCnt-1);
|
// nSumLine += (u-(nContinCnt-1));
|
// nSumCnt++;
|
// break;
|
// }*/
|
// }
|
// }
|
//
|
// if(nSumCnt > 0)
|
// {
|
// dRightLine = (double)nSumLine/(double)nSumCnt;
|
// }
|
//
|
// return TRUE;
|
// }
|
|
BOOL CChamferInspect::FindRightLine_Bin(CSISBuffer &pBuffer,int &nforecast_S,double &dRightLine)
|
{
|
int nSumLine,nSumCnt;
|
int u,v;
|
int nBCnt,nContinCnt=3;
|
int nRightOffset = 3;
|
|
dRightLine = -1;
|
nSumLine = nSumCnt = 0;
|
for(v=0;v<pBuffer.GetHeight();v++)
|
{
|
nBCnt = 0;
|
for(u=nforecast_S+nRightOffset; u<pBuffer.GetWidth();u++)
|
{
|
if(*pBuffer.GetDataAddress(u,v) == 0)
|
{
|
nBCnt++;
|
}
|
else
|
{
|
nBCnt = 0;
|
}
|
|
if(nBCnt >= nContinCnt)
|
{
|
nSumLine += (u-(nContinCnt-1));
|
nSumCnt++;
|
break;
|
}
|
|
/*if(*pBuffer.GetDataAddress(u,v) == 0)
|
nBCnt++;
|
else
|
nBCnt = 0;
|
|
if(nBCnt >= nContinCnt)
|
{
|
if(nMinRightEdge > (u-nContinCnt-1))
|
nMinRightEdge = (u-nContinCnt-1);
|
nSumLine += (u-(nContinCnt-1));
|
nSumCnt++;
|
break;
|
}*/
|
}
|
}
|
|
if(nSumCnt > 0 && nSumCnt >= pBuffer.GetHeight() *0.3)
|
dRightLine = (double)nSumLine/(double)nSumCnt;
|
|
if(nforecast_S+nRightOffset > dRightLine)
|
dRightLine = nforecast_S;
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::FindRightLine(CSISBuffer &pBuffer,CRect &rtIns,double dLeftLine,double &dRightLine,int nThres)
|
{
|
int nSumLine,nSumCnt;
|
int u,v;
|
int nBCnt,nWCnt,nContinCnt=3;
|
int nRightOffset = 3;
|
|
dRightLine = -1;
|
nSumLine = nSumCnt = 0;
|
|
int uStart,uEnd;
|
|
uStart = (int)dLeftLine+1;
|
uEnd = rtIns.right-1;
|
|
for(v=rtIns.top;v<rtIns.bottom;v++)
|
{
|
nBCnt = 0;
|
for(u=uStart; u<uEnd;u++)
|
{
|
if(*pBuffer.GetDataAddress(u,v) <= nThres)
|
{
|
nBCnt++;
|
}
|
else
|
{
|
nBCnt = 0;
|
}
|
|
if(nBCnt >= nContinCnt)
|
{
|
nWCnt = 0;
|
for(int u1=u+1; u1<uEnd;u1++)
|
{
|
if(*pBuffer.GetDataAddress(u1,v) > nThres)
|
{
|
nWCnt++;
|
}
|
else
|
{
|
nWCnt = 0;
|
}
|
|
if(nWCnt >= nContinCnt)
|
{
|
nSumLine += (u1-nContinCnt);
|
nSumCnt++;
|
break;
|
}
|
}
|
break;
|
}
|
}
|
}
|
if(dLeftLine+nRightOffset > dRightLine || nSumCnt < pBuffer.GetHeight() *0.5)
|
dRightLine = dLeftLine;
|
|
if(nSumCnt > 0)
|
{
|
dRightLine = (double)nSumLine/(double)nSumCnt;
|
}
|
|
return TRUE;
|
}
|
|
#define SUBPIXEL_THRESHOLD 3
|
double CChamferInspect::GetSubPixelThick(CSISBuffer &pBuffer,int nForecast_S,double dForecast_E,int nThres,double &dLeftEdge,double &dRightEdge)
|
{
|
const int nLoopCnt = 3;
|
CSize szImg = CSize(pBuffer.GetWidth(),pBuffer.GetHeight());
|
int nStartLine,nVertSize = szImg.cy/10;
|
CRect rectSubPixel,rectArea;
|
int i,nSubMargin = 4,nKernelSize=2;
|
double dSumValue,dSumCnt;
|
int nDiv;
|
|
if(nVertSize < 10)
|
nVertSize = 10;
|
|
nDiv = (szImg.cy-nVertSize*2)/nLoopCnt;
|
|
CEdgeFind EdgeFind;
|
dSumValue = dSumCnt = 0.;
|
for(i=0;i<nLoopCnt;i++)
|
{
|
nStartLine = i*nDiv-nVertSize/2+nVertSize/2;
|
rectSubPixel = CRect(nForecast_S-nSubMargin,nStartLine,nForecast_S,nStartLine+nVertSize);
|
|
// nThres = (int)GetAreaAVG(pBuffer.GetDataAddress(0,0),CRect(0,0,pBuffer.GetWidth(),pBuffer.GetHeight()),rectSubPixel)/4;
|
// if(nThres <= SUBPIXEL_THRESHOLD)
|
// nThres = SUBPIXEL_THRESHOLD;
|
|
nThres = SUBPIXEL_THRESHOLD;
|
rectSubPixel.right = nForecast_S+nSubMargin;
|
|
dLeftEdge = EdgeFind.FindLineSubPixel(pBuffer.GetDataAddress(0,0),szImg,rectSubPixel,nThres,-1*nThres,DIR_HORIZONTAL,SearchTypeIn2Out,EdgeTypeNegative,nKernelSize);
|
if(dLeftEdge > 0)
|
{
|
dSumValue += dLeftEdge;
|
dSumCnt++;
|
}
|
}
|
|
if(dSumCnt > 0)
|
dLeftEdge = dSumValue/dSumCnt;
|
else
|
dLeftEdge = nForecast_S;
|
|
//////////////////////////////////////////////////////////////////////////
|
// Right
|
dRightEdge = dForecast_E;
|
|
/*int nRight = (int)dForecast_E;
|
dSumValue = dSumCnt = 0.;
|
for(i=0;i<nLoopCnt;i++)
|
{
|
nStartLine = i*nDiv-nVertSize/2+nVertSize/2;
|
rectSubPixel = CRect(nRight-nSubMargin,nStartLine,nRight,nStartLine+nVertSize);
|
|
nThres = (int)GetAreaAVG(pBuffer.GetDataAddress(0,0),CRect(0,0,pBuffer.GetWidth(),pBuffer.GetHeight()),rectSubPixel)/2;
|
if(nThres <= SUBPIXEL_THRESHOLD)
|
nThres = SUBPIXEL_THRESHOLD;
|
|
rectSubPixel.right = nRight+nSubMargin;
|
|
dRightEdge = FindLineSubPixel(pBuffer.GetDataAddress(0,0),szImg,rectSubPixel,nThres,-1*nThres,DIR_HORIZONTAL,SearchTypeIn2Out,EdgeTypePositive,nKernelSize);
|
if(dRightEdge > 0)
|
{
|
dSumValue += dRightEdge;
|
dSumCnt++;
|
}
|
}
|
|
if(dSumCnt > 0)
|
{
|
dRightEdge = dSumValue/dSumCnt;
|
if(fabs(dRightEdge-dForecast_E) >= 2)
|
dRightEdge = dForecast_E;
|
}
|
else
|
dRightEdge = dForecast_E;*/
|
|
return (dRightEdge-dLeftEdge)+1;
|
}
|
|
void CChamferInspect::VConvolutionConvC(CSISBuffer &pImg,int nThres,ChipResionType s_RegionType,DefectPosType s_DefectPos,int nSetPitch,CRect &rectInsReg)
|
{
|
int sx, ex, sy, ey;
|
sx= sy = 0;
|
sx = rectInsReg.left;
|
sy = rectInsReg.top;
|
ex= rectInsReg.right;
|
ey= rectInsReg.bottom;
|
|
int nPitch = nSetPitch;
|
int nPitch_p = nPitch+1;
|
CSize szConv = CSize(1,1);
|
|
ex -= szConv.cx;
|
ey -= szConv.cy;
|
|
if(ey < nSetPitch*3 || ex <= szConv.cx)
|
return;
|
|
CRect rectIns;
|
int nPitch2;
|
|
//0~pitch °Å¸®±îÁö
|
nPitch2 = nPitch*2;
|
rectIns = CRect(sx,sy,ex,sy+ nPitch_p);
|
VertCalPitchConv(pImg,nThres,s_RegionType,s_DefectPos,rectIns,szConv,nPitch,nPitch2);
|
|
//pitch~pitch °Å¸®±îÁö
|
nPitch2 = -1*nPitch;
|
rectIns = CRect(sx,sy+nPitch_p,ex,ey-nPitch_p);
|
VertCalPitchConv(pImg,nThres,s_RegionType,s_DefectPos,rectIns,szConv,nPitch,nPitch2);
|
|
//0~pitch °Å¸®±îÁö
|
rectIns = CRect(sx,ey-nPitch_p,ex,ey);
|
nPitch = -1*nPitch;
|
nPitch2 = nPitch*2;
|
VertCalPitchConv(pImg,nThres,s_RegionType,s_DefectPos,rectIns,szConv,nPitch,nPitch2);
|
}
|
|
void CChamferInspect::BinalizeFind_Chip( CSISBuffer &pImg,int nThres,ChipResionType s_RegionType,DefectPosType s_DefectPos,CRect &rectInsReg,CSISBuffer &pImgSave, BOOL bSaveImage,BOOL bPolar )
|
{
|
int sx, ex, sy, ey;
|
sx= sy = 0;
|
sx = rectInsReg.left;
|
sy = rectInsReg.top;
|
ex= rectInsReg.right;
|
ey= rectInsReg.bottom;
|
|
int Threshold = nThres;
|
|
int SrcValue = 0;
|
int i = 0;
|
int j;
|
|
if(bPolar == TRUE) // black
|
{
|
for( j = sy; j < ey; j++)
|
{
|
for( i = sx; i < ex; i++)
|
{
|
SrcValue = *pImg.GetDataAddress(i,j);
|
|
if (SrcValue < Threshold)
|
{
|
if(!InsertPairing(i,j,SrcValue,Threshold,SrcValue, SrcValue,s_RegionType,s_DefectPos))
|
return;
|
|
if(bSaveImage)
|
{
|
pImgSave.SetPixel(i,j,0);
|
}
|
}
|
}
|
}
|
}
|
else // white
|
{
|
for( j = sy; j < ey; j++)
|
{
|
for( i = sx; i < ex; i++)
|
{
|
SrcValue = *pImg.GetDataAddress(i,j);
|
|
if (SrcValue > Threshold)
|
{
|
if(!InsertPairing(i,j,SrcValue,Threshold,SrcValue, SrcValue,s_RegionType,s_DefectPos))
|
return;
|
|
if(bSaveImage)
|
{
|
pImgSave.SetPixel(i,j,0);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
BOOL CChamferInspect::VertCalPitchConv(CSISBuffer &pImg,int nThres,ChipResionType s_RegionType,DefectPosType s_DefectPos,CRect &rectIns,CSize szConv,int nPitch,int nPitch2)
|
{
|
if(pImg.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
if(pImg.GetWidth() <= rectIns.right)
|
rectIns.right = pImg.GetWidth()-1;
|
if(rectIns.left < 0)
|
rectIns.left = 0;
|
if(pImg.GetHeight() <= rectIns.bottom)
|
rectIns.bottom = pImg.GetHeight()-1;
|
if(rectIns.top < 0)
|
rectIns.top = 0;
|
|
int u,v,iLoopX,iLoopY;
|
int SubValue,SubValue2Pitch,SrcValue,DestValue1,DestValue2;
|
int NegThres = -1*nThres;
|
|
for( v = rectIns.top; v < rectIns.bottom; v++)
|
{
|
for( u = rectIns.left; u < rectIns.right; u++)
|
{
|
SrcValue = DestValue1 = DestValue2 = 0;
|
for(iLoopX=u;iLoopX<u+szConv.cx;iLoopX++)
|
{
|
for(iLoopY=v;iLoopY<v+szConv.cy;iLoopY++)
|
{
|
SrcValue += *pImg.GetDataAddress(iLoopX,iLoopY);
|
DestValue1 += *pImg.GetDataAddress(iLoopX,iLoopY+nPitch);
|
DestValue2 += *pImg.GetDataAddress(iLoopX,iLoopY+nPitch2);
|
}
|
}
|
|
SubValue = DestValue1 - SrcValue;
|
SubValue2Pitch = DestValue2 - SrcValue;
|
|
// if ((SubValue > nThres && SubValue2Pitch > nThres) ||
|
// (SubValue < NegThres && SubValue2Pitch < NegThres))
|
if (SubValue > nThres && SubValue2Pitch > nThres)
|
{
|
|
if(!InsertPairing(u,v,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,nThres,SrcValue, DestValue2,s_RegionType,s_DefectPos))
|
return FALSE;
|
}
|
}
|
}
|
|
return TRUE;
|
}
|
|
void CChamferInspect::VConvolutionConvC_Com(COwnerBuffer &pRes,CSISBuffer &pImg,int nThres,ChipResionType s_RegionType,DefectPosType s_DefectPos,int nSetPitch,CRect &rectInsReg)
|
{
|
int sx, ex, sy, ey;
|
sx= sy = 0;
|
sx = rectInsReg.left;
|
sy = rectInsReg.top;
|
ex= rectInsReg.right;
|
ey= rectInsReg.bottom;
|
|
int nPitch = nSetPitch;
|
int nPitch_p = nPitch+1;
|
CSize szConv = CSize(1,1);
|
|
ex -= szConv.cx;
|
ey -= szConv.cy;
|
|
if(ey < nSetPitch*3 || ex <= szConv.cx)
|
return;
|
|
CRect rectIns;
|
int nPitch2;
|
|
//0~pitch °Å¸®±îÁö
|
nPitch2 = nPitch*2;
|
rectIns = CRect(sx,sy,ex,sy+ nPitch_p);
|
VertCalPitchConv_Com(pRes,pImg,nThres,s_RegionType,s_DefectPos,rectIns,szConv,nPitch,nPitch2);
|
|
//pitch~pitch °Å¸®±îÁö
|
nPitch2 = -1*nPitch;
|
rectIns = CRect(sx,sy+nPitch_p,ex,ey-nPitch_p);
|
VertCalPitchConv_Com(pRes,pImg,nThres,s_RegionType,s_DefectPos,rectIns,szConv,nPitch,nPitch2);
|
|
//0~pitch °Å¸®±îÁö
|
rectIns = CRect(sx,ey-nPitch_p,ex,ey);
|
nPitch = -1*nPitch;
|
nPitch2 = nPitch*2+1;
|
VertCalPitchConv_Com(pRes,pImg,nThres,s_RegionType,s_DefectPos,rectIns,szConv,nPitch,nPitch2);
|
}
|
|
BOOL CChamferInspect::VertCalPitchConv_Com(COwnerBuffer &pRes,CSISBuffer &pImg,int nThres,ChipResionType s_RegionType,DefectPosType s_DefectPos,CRect &rectIns,CSize szConv,int nPitch,int nPitch2)
|
{
|
if(pImg.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
if(pImg.GetWidth() <= rectIns.right)
|
rectIns.right = pImg.GetWidth()-1;
|
if(rectIns.left < 0)
|
rectIns.left = 0;
|
if(pImg.GetHeight() <= rectIns.bottom)
|
rectIns.bottom = pImg.GetHeight()-1;
|
if(rectIns.top < 0)
|
rectIns.top = 0;
|
|
int u,v,iLoopX,iLoopY;
|
int SubValue,SubValue2Pitch,SrcValue,DestValue1,DestValue2;
|
int NegThres = -1*nThres;
|
|
for( v = rectIns.top; v < rectIns.bottom; v++)
|
{
|
for( u = rectIns.left; u < rectIns.right; u++)
|
{
|
SrcValue = DestValue1 = DestValue2 = 0;
|
for(iLoopX=u;iLoopX<u+szConv.cx;iLoopX++)
|
{
|
for(iLoopY=v;iLoopY<v+szConv.cy;iLoopY++)
|
{
|
SrcValue += *pImg.GetDataAddress(iLoopX,iLoopY);
|
DestValue1 += *pImg.GetDataAddress(iLoopX,iLoopY+nPitch);
|
DestValue2 += *pImg.GetDataAddress(iLoopX,iLoopY+nPitch2);
|
}
|
}
|
|
SubValue = DestValue1 - SrcValue;
|
SubValue2Pitch = DestValue2 - SrcValue;
|
|
// if ((SubValue > nThres && SubValue2Pitch > nThres) ||
|
// (SubValue < NegThres && SubValue2Pitch < NegThres))
|
if (SubValue > nThres && SubValue2Pitch > nThres)
|
{
|
pRes.SetPixel(u,v,255);
|
}
|
}
|
}
|
|
return TRUE;
|
}
|
|
#define CHIP_INS_PITCH 10
|
BOOL CChamferInspect::ChipInspection(LPBYTE lpHeader,int nFrameWidth,CRect &rectChip,int nChipThres,int nBurrThres,int nEdgeLeft,int nEdgeRight)
|
{
|
if(lpHeader == NULL)
|
return FALSE;
|
|
ReleaseChipBuffer();
|
|
std::vector<CChipBlob> blobData;
|
|
const int nImgMargin = 0;
|
const int nMergeMargin = 4;
|
CRect rectIns,rectTmp;
|
|
//if(CopyRectImg(lpHeader,imgbuf.GetDataAddress(),CSize(nFrameWidth,rectChamfer.Height()+2),rectChamfer) == FALSE)
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : Inspection Right",m_nCurCamId,m_nCurScanIdx);
|
|
int nInsPitch = (rectChip.Height()-(int)((double)rectChip.Height()*0.2))/3;
|
if(nInsPitch < CHIP_INS_PITCH)
|
nInsPitch = CHIP_INS_PITCH;
|
|
CSISBuffer ChipBuffer(lpHeader,nFrameWidth,rectChip.Height()+1);
|
|
// Right Inspection
|
rectIns = CRect(0,rectChip.top,rectChip.Width(),rectChip.bottom);
|
rectIns.OffsetRect(nEdgeRight+nImgMargin,0);
|
VConvolutionConvC(ChipBuffer,nChipThres,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,nInsPitch,rectIns);
|
|
|
// Left Inspection
|
rectIns = CRect(0,rectChip.top,0,rectChip.bottom);
|
rectIns.OffsetRect(nEdgeLeft-nImgMargin,0);
|
rectIns.left -= rectChip.Width();
|
VConvolutionConvC(ChipBuffer,nBurrThres,CHIPREGTYPE_LEFT,INS_DEFECT_BURR,nInsPitch,rectIns);
|
|
BlobDefect_Pixel(blobData,nChipThres,nMergeMargin);
|
|
FilteringEdgeBlob(blobData,nEdgeLeft,nEdgeRight,nImgMargin,0);
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : End",m_nCurCamId,m_nCurScanIdx);
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::AssertRect(CRect rect,CSize szImg)
|
{
|
if(rect.left < 0 || rect.right >= szImg.cx || rect.left >= rect.right)
|
return FALSE;
|
if(rect.top < 0 || rect.top >= rect.bottom)
|
return FALSE;
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::ChipInspection_Binarization(LPBYTE lpHeader,int nFrameWidth,CRect &rectChip,CRect &rectCrack,CRect &rectBroken,int nChipThres,int nChipDiffThres,int nCrackThres,int nBrokenThres
|
,int nBurrThres,int nEdgeLeft,int nEdgeRight,BOOL bSaveDebug,int iFrame)
|
{
|
if(lpHeader == NULL)
|
return FALSE;
|
|
ReleaseChipBuffer();
|
|
std::vector<CChipBlob> blobData;
|
|
const int nImgMargin = 2;
|
const int nImgBurrMargin = 2;
|
const int nFirstImgMargin = 4;
|
const int nMergeMargin = 4;
|
const int nTempSize = 10;
|
CRect rectIns,rectTmp;
|
|
//if(CopyRectImg(lpHeader,imgbuf.GetDataAddress(),CSize(nFrameWidth,rectChamfer.Height()+2),rectChamfer) == FALSE)
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : Inspection Right",m_nCurCamId,m_nCurScanIdx);
|
|
CSISBuffer ChipBuffer(lpHeader,nFrameWidth,rectChip.Height()+1);
|
COwnerBuffer ChipBufferSave;
|
|
if (bSaveDebug)
|
{
|
ChipBufferSave.SetSize(nFrameWidth,rectChip.Height()+1);
|
|
CRect rectChamfer = CRect(0,0,nFrameWidth,rectChip.Height()+1);
|
if(CopyRectImg(lpHeader,ChipBufferSave.GetDataAddress(),CSize(nFrameWidth,rectChip.Height()+1),rectChamfer) == FALSE)
|
return ERR_CHIP_IMAGE_NULL_01;
|
}
|
|
const int nMinSize = 5;
|
//if((int)vecPairtemp.size() > 0)
|
{
|
// Chip Inspection
|
rectIns = CRect(0,0,rectChip.Width(),rectChip.Height());
|
rectIns.OffsetRect(nEdgeRight+nImgMargin,0);
|
if(AssertRect(rectIns,CSize(nFrameWidth,rectIns.Height())) == TRUE)
|
{
|
rectTmp = rectIns;
|
rectTmp.right = rectTmp.left + nTempSize;
|
if(nChipThres != 0)
|
{
|
if(rectTmp.Width() > nMinSize && rectTmp.Height() > nMinSize && rectTmp.right < rectIns.right)
|
{
|
BinalizeFind_Chip(ChipBuffer,nChipThres,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,rectTmp,ChipBufferSave,bSaveDebug);
|
|
if(GetPairDefectCount() > 0)
|
{
|
m_nChipPairIndex = 0;
|
BinalizeFind_Chip(ChipBuffer,nChipThres,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,rectIns,ChipBufferSave,bSaveDebug);
|
|
BlobDefect_Pixel(blobData,nChipThres,nMergeMargin);
|
}
|
}
|
}
|
|
if(nChipDiffThres != 255)
|
{
|
int nInsPitch = rectChip.Height()/5;
|
if(nInsPitch < CHIP_INS_PITCH)
|
nInsPitch = CHIP_INS_PITCH;
|
|
if(rectTmp.Width() > nMinSize && rectTmp.Height() > nMinSize && rectTmp.right < rectIns.right)
|
{
|
m_nChipPairIndex = 0;
|
|
VConvolutionConvC(ChipBuffer,nChipDiffThres,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,nInsPitch,rectTmp);
|
|
if(GetPairDefectCount() > 0)
|
{
|
m_nChipPairIndex = 0;
|
|
VConvolutionConvC(ChipBuffer,nChipDiffThres,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,nInsPitch,rectIns);
|
|
BlobDefect_Pixel(blobData,nChipThres,nMergeMargin);
|
}
|
}
|
}
|
}
|
|
// Crack Inspection
|
rectIns = CRect(0,0,rectCrack.Width(),rectCrack.Height());
|
rectIns.OffsetRect(nEdgeRight+nImgMargin,0);
|
|
if(AssertRect(rectIns,CSize(nFrameWidth,rectIns.Height())) == TRUE)
|
{
|
rectTmp = rectIns;
|
rectTmp.right = rectTmp.left + nTempSize;
|
if(nCrackThres != 0)
|
{
|
if(rectTmp.Width() > nMinSize && rectTmp.Height() > nMinSize && rectTmp.right < rectIns.right)
|
{
|
m_nChipPairIndex = 0;
|
BinalizeFind_Chip(ChipBuffer,nChipThres,CHIPREGTYPE_RIGHT,INS_DEFECT_CRACK,rectTmp,ChipBufferSave,bSaveDebug);
|
|
if(GetPairDefectCount() > 0)
|
{
|
m_nChipPairIndex = 0;
|
if(rectIns.Width() > nMinSize && rectCrack.Height() > nMinSize)
|
{
|
BinalizeFind_Chip(ChipBuffer,nChipThres,CHIPREGTYPE_RIGHT,INS_DEFECT_CRACK,rectIns,ChipBufferSave,bSaveDebug);
|
}
|
|
BlobDefect_Pixel(blobData,nChipThres,nMergeMargin);
|
}
|
}
|
}
|
}
|
|
// Broken Inspection
|
rectIns = CRect(0,0,rectBroken.Width(),rectBroken.Height());
|
rectIns.OffsetRect(nEdgeRight+nImgMargin,0);
|
if(AssertRect(rectIns,CSize(nFrameWidth,rectIns.Height())) == TRUE)
|
{
|
rectTmp = rectIns;
|
rectTmp.right = rectTmp.left + nTempSize;
|
if(nBrokenThres != 0)
|
{
|
if(rectTmp.Width() > nMinSize && rectTmp.Height() > nMinSize && rectTmp.right < rectIns.right)
|
{
|
m_nChipPairIndex = 0;
|
BinalizeFind_Chip(ChipBuffer,nChipThres,CHIPREGTYPE_RIGHT,INS_DEFECT_BROKEN,rectIns,ChipBufferSave,bSaveDebug);
|
|
if(GetPairDefectCount() > 0)
|
{
|
m_nChipPairIndex = 0;
|
if(rectIns.Width() > nMinSize && rectIns.Height() > nMinSize)
|
{
|
BinalizeFind_Chip(ChipBuffer,nBrokenThres,CHIPREGTYPE_RIGHT,INS_DEFECT_BROKEN,rectIns,ChipBufferSave,bSaveDebug);
|
}
|
|
BlobDefect_Pixel(blobData,nChipThres,nMergeMargin);
|
}
|
}
|
}
|
}
|
}
|
|
// Burr Inspection
|
if(nBurrThres != 255)
|
{
|
rectIns = CRect(nEdgeLeft-rectChip.Width(),0,nEdgeLeft,rectChip.Height());
|
rectIns.OffsetRect(-nImgBurrMargin,0);
|
if(rectIns.left < 0)
|
rectIns.left = 0;
|
if(rectIns.right >= nFrameWidth)
|
rectIns.right = nFrameWidth-1;
|
|
if(AssertRect(rectIns,CSize(nFrameWidth,rectIns.Height())) == TRUE)
|
{
|
rectTmp = rectIns;
|
rectTmp.left = rectTmp.right - nTempSize;
|
if(rectTmp.Width() > nMinSize && rectTmp.Height() > nMinSize)
|
{
|
int nInsPitch = rectIns.Height()/5;
|
if(nInsPitch < CHIP_INS_PITCH)
|
nInsPitch = CHIP_INS_PITCH;
|
|
m_nChipPairIndex = 0;
|
VConvolutionConvC(ChipBuffer,nBurrThres,CHIPREGTYPE_LEFT,INS_DEFECT_BURR,nInsPitch,rectTmp);
|
|
if(GetPairDefectCount() > 0)
|
{
|
m_nChipPairIndex = 0;
|
if(rectIns.Width() > nMinSize && rectIns.Height() > nMinSize)
|
{
|
VConvolutionConvC(ChipBuffer,nBurrThres,CHIPREGTYPE_LEFT,INS_DEFECT_BURR,nInsPitch,rectIns);
|
}
|
|
BlobDefect_Pixel(blobData,nChipThres,nMergeMargin);
|
}
|
}
|
}
|
|
}
|
|
if (bSaveDebug)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Chip.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(ChipBufferSave);
|
}
|
|
|
FilteringEdgeBlob(blobData,nEdgeLeft,nEdgeRight,nImgMargin,nImgBurrMargin+1);
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : End",m_nCurCamId,m_nCurScanIdx);
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::ChipInspection_Binarization_OpenCV(LPBYTE lpHeader,int nFrameWidth,CRect &rectChip,CRect &rectCrack,CRect &rectBroken,InspectParam insParam,int nEdgeLeft,int nEdgeRight,BOOL bSaveDebug,int iFrame)
|
{
|
if(lpHeader == NULL)
|
return FALSE;
|
|
ReleaseChipBuffer();
|
|
std::vector<CChipBlob> blobData;
|
|
const int nImgMargin = 2;
|
const int nImgBurrMargin = 2;
|
const int nFirstImgMargin = 4;
|
const int nMergeMargin = 4;
|
CRect rectIns,rectTmp;
|
|
CSISBuffer ChipBuffer(lpHeader,nFrameWidth,rectChip.Height()+1);
|
COwnerBuffer ChipBufferSave;
|
|
if (bSaveDebug)
|
{
|
ChipBufferSave.SetSize(nFrameWidth,rectChip.Height()+1);
|
|
CRect rectChamfer = CRect(0,0,nFrameWidth,rectChip.Height()+1);
|
if(CopyRectImg(lpHeader,ChipBufferSave.GetDataAddress(),CSize(nFrameWidth,rectChip.Height()+1),rectChamfer) == FALSE)
|
return ERR_CHIP_IMAGE_NULL_01;
|
}
|
|
// Chip Inspection
|
if(insParam.bUse_ChipIns)
|
{
|
rectIns = CRect(0,0,rectChip.Width(),rectChip.Height());
|
rectIns.OffsetRect(nEdgeRight+nImgMargin,0);
|
if(AssertRect(rectIns,CSize(nFrameWidth,rectIns.Height())) == TRUE)
|
{
|
int nInsPitch = rectChip.Height()/5;
|
|
if(nInsPitch < CHIP_INS_PITCH)
|
nInsPitch = CHIP_INS_PITCH;
|
|
int nChipThres = insParam.nChipThres;
|
int nChipDiffThres = insParam.nChipDiffThres;
|
int nMinSize = insParam.nChipMinSize;
|
int nSideFilterSize = insParam.nChipSideFilterSize;
|
|
nChipThres = (nChipThres <= 0) ? 0 : (255 <= nChipThres ) ? 255 : nChipThres;
|
nChipDiffThres = (nChipDiffThres <= 0) ? 0 : (255 <= nChipDiffThres ) ? 255 : nChipDiffThres;
|
nMinSize = (nMinSize <= 0) ? 1 : nMinSize;
|
nSideFilterSize = (nSideFilterSize <= 0) ? 0 : nSideFilterSize;
|
|
if(nChipThres != 0)
|
{
|
COwnerBuffer binBuffer;
|
|
Binarization_OpenCV(&ChipBuffer, &binBuffer, rectIns, nChipThres, 255, nChipDiffThres, nInsPitch,iFrame,bSaveDebug);
|
|
Blob_OpenCV(&ChipBuffer, &binBuffer, rectIns, &blobData, CHIPREGTYPE_RIGHT, INS_DEFECT_CHIP, nMinSize, nSideFilterSize);
|
|
if (bSaveDebug)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_ChipBin.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(binBuffer);
|
}
|
|
binBuffer.ReleaseSpace();
|
}
|
|
if(nChipDiffThres != 255)
|
{
|
COwnerBuffer binBuffer(rectIns.Width(), rectIns.Height());
|
COwnerBuffer insBuffer(rectIns.Width(), rectIns.Height());
|
ZeroMemory(binBuffer.GetDataAddress(), binBuffer.GetSize());
|
ZeroMemory(insBuffer.GetDataAddress(), binBuffer.GetSize());
|
|
CopyRectImg(ChipBuffer.GetDataAddress(),insBuffer.GetDataAddress(),CSize(ChipBuffer.GetWidth(),ChipBuffer.GetHeight()),rectIns);
|
|
CRect rectTmp = CRect(0,0,rectIns.Width(), rectIns.Height());
|
|
VConvolutionConvC_Com(binBuffer,insBuffer,nChipDiffThres,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP,nInsPitch,rectTmp);
|
|
Blob_OpenCV(&ChipBuffer, &binBuffer, rectIns, &blobData, CHIPREGTYPE_RIGHT, INS_DEFECT_CHIP, nMinSize, nSideFilterSize);
|
|
binBuffer.ReleaseSpace();
|
insBuffer.ReleaseSpace();
|
}
|
}
|
}
|
|
// Crack Inspection
|
if(insParam.bUse_CrackIns)
|
{
|
rectIns = CRect(0,0,rectCrack.Width(),rectCrack.Height());
|
rectIns.OffsetRect(nEdgeRight+nImgMargin,0);
|
|
if(AssertRect(rectIns,CSize(nFrameWidth,rectIns.Height())) == TRUE)
|
{
|
int nCrackThres = insParam.nCrackThres;
|
int nMinSize = insParam.nCrackMinSize;
|
int nSideFilterSize = insParam.nCrackSideFilterSize;
|
|
nCrackThres = (nCrackThres <= 0) ? 0 : (255 <= nCrackThres ) ? 255 : nCrackThres;
|
nMinSize = (nMinSize <= 0) ? 1 : nMinSize;
|
nSideFilterSize = (nSideFilterSize <= 0) ? 0 : nSideFilterSize;
|
|
if(nCrackThres != 0)
|
{
|
COwnerBuffer binBuffer;
|
|
Binarization_OpenCV(&ChipBuffer, &binBuffer, rectIns, nCrackThres, 255);
|
|
Blob_OpenCV(&ChipBuffer, &binBuffer, rectIns, &blobData, CHIPREGTYPE_RIGHT, INS_DEFECT_CRACK, nMinSize, nSideFilterSize);
|
|
binBuffer.ReleaseSpace();
|
}
|
}
|
}
|
|
// Broken Inspection
|
if(insParam.bUse_BrokenIns)
|
{
|
rectIns = CRect(0,0,rectBroken.Width(),rectBroken.Height());
|
rectIns.OffsetRect(nEdgeRight+nImgMargin,0);
|
if(AssertRect(rectIns,CSize(nFrameWidth,rectIns.Height())) == TRUE)
|
{
|
int nBrokenThres = insParam.nBrokenThres;
|
int nMinSize = insParam.nBrokenMinSize;
|
int nSideFilterSize = insParam.nBrokenSideFilterSize;
|
|
nBrokenThres = (nBrokenThres <= 0) ? 0 : (255 <= nBrokenThres ) ? 255 : nBrokenThres;
|
nMinSize = (nMinSize <= 0) ? 1 : nMinSize;
|
nSideFilterSize = (nSideFilterSize <= 0) ? 0 : nSideFilterSize;
|
|
if(nBrokenThres != 0)
|
{
|
nBrokenThres = (nBrokenThres <= 0) ? 0 : (255 <= nBrokenThres ) ? 255 : nBrokenThres;
|
|
COwnerBuffer binBuffer;
|
|
Binarization_OpenCV(&ChipBuffer, &binBuffer, rectIns, nBrokenThres, 255);
|
|
Blob_OpenCV(&ChipBuffer, &binBuffer, rectIns, &blobData, CHIPREGTYPE_RIGHT, INS_DEFECT_BROKEN, nMinSize, nSideFilterSize);
|
|
binBuffer.ReleaseSpace();
|
}
|
}
|
}
|
|
// Burr Inspection
|
if(insParam.bUse_BurrIns)
|
{
|
rectIns = CRect(nEdgeLeft-rectChip.Width(),0,nEdgeLeft,rectChip.Height());
|
rectIns.OffsetRect(-nImgBurrMargin,0);
|
if(rectIns.left < 0)
|
rectIns.left = 0;
|
if(rectIns.right >= nFrameWidth)
|
rectIns.right = nFrameWidth-1;
|
|
if(AssertRect(rectIns,CSize(nFrameWidth,rectIns.Height())) == TRUE)
|
{
|
int nBurrThres = insParam.nBurrThres;
|
int nMinSize = insParam.nBurrMinSize;
|
int nSideFilterSize = insParam.nBurrSideFilterSize;
|
|
nBurrThres = (nBurrThres <= 0) ? 0 : (255 <= nBurrThres ) ? 255 : nBurrThres;
|
|
int nInsPitch = rectChip.Height()/5;
|
|
if(nInsPitch < CHIP_INS_PITCH)
|
nInsPitch = CHIP_INS_PITCH;
|
|
if(nBurrThres != 255)
|
{
|
COwnerBuffer binBuffer(rectIns.Width(), rectIns.Height());
|
COwnerBuffer insBuffer(rectIns.Width(), rectIns.Height());
|
ZeroMemory(binBuffer.GetDataAddress(), binBuffer.GetSize());
|
ZeroMemory(insBuffer.GetDataAddress(), binBuffer.GetSize());
|
|
CopyRectImg(ChipBuffer.GetDataAddress(),insBuffer.GetDataAddress(),CSize(ChipBuffer.GetWidth(),ChipBuffer.GetHeight()),rectIns);
|
|
CRect rectTmp = CRect(0,0,rectIns.Width(), rectIns.Height());
|
|
VConvolutionConvC_Com(binBuffer,insBuffer,nBurrThres,CHIPREGTYPE_LEFT,INS_DEFECT_BURR,nInsPitch,rectTmp);
|
|
Blob_OpenCV(&ChipBuffer, &binBuffer, rectIns, &blobData, CHIPREGTYPE_LEFT, INS_DEFECT_BURR, nMinSize, nSideFilterSize);
|
|
if (bSaveDebug)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_BurrRes.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(binBuffer);
|
}
|
|
binBuffer.ReleaseSpace();
|
insBuffer.ReleaseSpace();
|
}
|
}
|
}
|
|
if (bSaveDebug)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Chip.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(ChipBufferSave);
|
}
|
|
InsertEdgeBlobToDefect(blobData);
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::FilteringEdgeBlob(std::vector<CChipBlob> &vecBlob,int nBaseLeft,int nBaseRight,int nDetMargin,int nImgBurrMargin)
|
{
|
std::vector<CChipBlob> vecTmp;
|
std::vector<CChipBlob>::iterator it;
|
|
for(it=vecBlob.begin();it!=vecBlob.end();it++)
|
{
|
if(it->s_RegionType == CHIPREGTYPE_LEFT)
|
{
|
if(abs(it->s_DefectRect.right-nBaseLeft) > nImgBurrMargin)
|
continue;
|
}
|
else if(it->s_RegionType == CHIPREGTYPE_RIGHT)
|
{
|
if(abs(it->s_DefectRect.left-nBaseRight) > nDetMargin)
|
continue;
|
}
|
|
if(m_nDefectCnt >= MAX_CHIP_DEFECT_COUNT)
|
return FALSE;
|
|
CChipBlob *pBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pBlob == NULL)
|
continue;
|
|
*pBlob = *it;
|
m_nDefectCnt++;
|
}
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::InsertEdgeBlobToDefect(std::vector<CChipBlob> &vecBlob)
|
{
|
std::vector<CChipBlob> vecTmp;
|
std::vector<CChipBlob>::iterator it;
|
|
for(it=vecBlob.begin();it!=vecBlob.end();it++)
|
{
|
if(m_nDefectCnt >= MAX_CHIP_DEFECT_COUNT)
|
return FALSE;
|
|
CChipBlob *pBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pBlob == NULL)
|
continue;
|
|
*pBlob = *it;
|
m_nDefectCnt++;
|
}
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::CopyRectImg(LPBYTE pOrg,LPBYTE pTgt,CSize szImg,CRect &rectIns)
|
{
|
if(rectIns.Width() > szImg.cx || rectIns.top < 0 || rectIns.top > rectIns.bottom || rectIns.bottom < 0 || rectIns.bottom > szImg.cy)
|
return FALSE;
|
if(rectIns.left >= rectIns.right || rectIns.left < 0 || rectIns.right > szImg.cx)
|
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;
|
}
|
|
double CChamferInspect::FindTraceLine(CSISBuffer &CannyImg,int nStart)
|
{
|
int nCount = 0;
|
int u,v,uS,uE;
|
double dRatio = 0;
|
|
uS = nStart-1;
|
uE = nStart+1;
|
if(uS < 0)
|
{
|
uS = 0;
|
uE = uS + 2;
|
}
|
if(uE >= CannyImg.GetWidth())
|
{
|
uE=CannyImg.GetWidth()-1;
|
uS = uE-2;
|
}
|
|
for(v=1;v<CannyImg.GetHeight()-1;v++)
|
{
|
for(u=uS;u<=uE;u++)
|
{
|
if(*CannyImg.GetDataAddress(u,v) == 255)
|
{
|
nCount++;
|
break;
|
}
|
}
|
}
|
|
if(nCount > 0)
|
{
|
dRatio = (double)nCount/(double)(CannyImg.GetHeight()-2);
|
}
|
|
return dRatio;
|
}
|
|
BOOL CChamferInspect::FindAdptThres(CSISBuffer &pOrg,CSISBuffer &CannyImg,int &nSetThres,int nForecast_S,ChipThresMode emThresMode)
|
{
|
#define FIND_ADPT_LINE_RATIO 0.4
|
#define RE_FIND_ADPT_LINE_RATIO 0.8
|
int u;
|
double dWidthRatio;
|
EDGEPOS EdgePos;
|
int nWSize = 4;
|
CRect rect,rectImg;
|
int nVSize = (CannyImg.GetHeight()/6)/2;
|
int nVS = CannyImg.GetHeight()/2-nVSize;
|
int nVE = CannyImg.GetHeight()/2+nVSize;
|
int nStart,nEnd,nDiff;
|
|
nStart = nForecast_S+1;
|
nEnd = nStart + (CannyImg.GetWidth()-nWSize-nForecast_S)/2;
|
nDiff = 0;
|
for(u=nStart;u<nEnd;u++)
|
{
|
dWidthRatio = (double)m_pCannyWidthCnt[u]/(double)(CannyImg.GetHeight()-2);
|
if(dWidthRatio >= FIND_ADPT_LINE_RATIO)
|
{
|
rect = CRect(u+1,nVS,u+1+nWSize,nVE);
|
if(rect.right >= pOrg.GetWidth())
|
continue;
|
EdgePos.dRight = GetAreaAVG(pOrg.GetDataAddress(),rectImg,rect);
|
|
rect = CRect(u-nWSize-1,nVS,u-1,nVE);
|
if(rect.left < 0)
|
continue;
|
EdgePos.dLeft = GetAreaAVG(pOrg.GetDataAddress(),rectImg,rect);
|
|
if(EdgePos.dRight < EdgePos.dLeft)
|
continue;
|
|
dWidthRatio = FindTraceLine(CannyImg,u);
|
if(dWidthRatio < RE_FIND_ADPT_LINE_RATIO)
|
continue;
|
|
if(emThresMode == THRESMODE_ADAPTIVE)
|
{
|
nSetThres = (int)(EdgePos.dLeft*1.2+EdgePos.dRight)/2;
|
break;
|
}
|
else
|
{
|
if((int)(EdgePos.dRight-EdgePos.dLeft) > nDiff)
|
{
|
nDiff = (int)(EdgePos.dRight-EdgePos.dLeft);
|
nSetThres = (int)(EdgePos.dLeft*1.2+EdgePos.dRight)/2;
|
}
|
}
|
}
|
}
|
|
return TRUE;
|
}
|
|
ChipErrCode CChamferInspect::Inspection(int *nResult, LPBYTE lpHeader,int nFrameWidth,CRect &rectChamfer,int nChamferThres,BOOL bChipIns,BOOL bChamfer,CRect &rectChip,CRect &rectCrack,CRect &rectBroken
|
,int nChipThres,int nChipIDiffThres,int nCrackThres,int nBrokenThres,int nBurrThres,BOOL bSaveDebug,int *nPreForeLine,ChipThresMode emThresMode,int iFrame)
|
{
|
ReleaseBuffer();
|
ResetValue();
|
|
if(lpHeader == NULL)
|
return ERR_CHIP_IMAGE_NULL_01;
|
|
COwnerBuffer imgbuf(rectChamfer.Width(),rectChamfer.Height());
|
|
if(CopyRectImg(lpHeader,imgbuf.GetDataAddress(),CSize(nFrameWidth,rectChamfer.Height()+2),rectChamfer) == FALSE)
|
return ERR_CHIP_IMAGE_NULL_02;
|
|
if(bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Org.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(imgbuf);
|
|
// CSISBuffer bfrOrg(lpHeader,nFrameWidth,rectChamfer.Height()+1);
|
// str.Format(_T("%s\\%03d_OrgFull.bmp"),PATH_DEBUGFOLDER,m_nSaveIndex);
|
// CBufferAttach attach2(str);
|
// attach2.AttachToFile(bfrOrg);
|
}
|
|
CRect rectIns = CRect(0,0,rectChamfer.Width(),rectChamfer.Height());
|
COwnerBuffer BufferCanny;
|
if(PreProcessing(imgbuf.GetDataAddress(),rectIns,BufferCanny) == FALSE)
|
{
|
ReleaseBuffer();
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass Find Inspection ½ÇÆÐ: PreProcess",m_nCurCamId,m_nCurScanIdx);
|
return ERR_CHIP_PREPROCESS;
|
}
|
|
if(BufferCanny.IsValidBuffer() == FALSE)
|
{
|
return ERR_CHIP_IMAGE_NULL_03;
|
}
|
|
if(bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Can.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(BufferCanny);
|
}
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass Find Inspection : Find Edge Line",m_nCurCamId,m_nCurScanIdx);
|
|
int nForecast_S,nForecast_E;
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass Find Inspection : Find ForeCast Line",m_nCurCamId,m_nCurScanIdx);
|
|
m_pGlassEdgeLine = new GLASSFINDDATA[rectIns.Height()+1];
|
m_nGlassEdgeLineCnt = rectIns.Height()+1;
|
m_pCannyWidthCnt = new int[BufferCanny.GetWidth()];
|
ZeroMemory(m_pCannyWidthCnt,sizeof(int)*BufferCanny.GetWidth());
|
|
FindEdgeLine(BufferCanny.GetDataAddress(0,0),rectIns);
|
*nResult = FindForeCastLine(imgbuf,rectIns,nForecast_S,nForecast_E,bChamfer);
|
|
// nForecast_S = (int)CalEdgetoBin(BufferCanny.GetDataAddress(0,0),CSize(BufferCanny.GetDataWidth(),BufferCanny.GetHeight()),0.5);
|
|
double dLeftEdge=0,dRightEdge=0;
|
|
dLeftEdge = dRightEdge = m_nForeEdgeLine[0] = m_nForeEdgeLine[1] = nForecast_E = nForecast_S;
|
if(nForecast_S <= 0)
|
{
|
if(nPreForeLine != NULL)
|
nForecast_S = nPreForeLine[0];
|
else
|
{
|
ReleaseBuffer();
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass Find ForeCastLine ½ÇÆÐ : FilteringEdge s[%d],e[%d]",m_nCurCamId,m_nCurScanIdx,nForecast_S,nForecast_E);
|
return ERR_CHIP_FIND_FORELINE;
|
}
|
}
|
|
if(bChamfer == TRUE)
|
{
|
if(emThresMode >= THRESMODE_ADAPTIVE)
|
{
|
FindAdptThres(imgbuf,BufferCanny,nChamferThres,nForecast_S,emThresMode);
|
}
|
|
COwnerBuffer pInsBin;
|
Binarization(imgbuf,pInsBin,nChamferThres);
|
if(pInsBin.IsValidBuffer() == FALSE)
|
{
|
return ERR_CHIP_IMAGE_NULL_03;
|
}
|
|
if(bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Bin.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pInsBin);
|
}
|
|
FindRightLine_Bin(pInsBin,nForecast_S,dRightEdge);
|
|
nForecast_E = (int)dRightEdge;
|
dLeftEdge = m_nForeEdgeLine[0] = nForecast_S;
|
dRightEdge = m_nForeEdgeLine[1] = nForecast_E;
|
if(nForecast_S <= 0 || nForecast_E <= 0 || nForecast_S > nForecast_E)
|
{
|
if(nPreForeLine != NULL)
|
{
|
nForecast_E = nPreForeLine[1];
|
m_dAvgThick = nForecast_E - nForecast_S;
|
}
|
else
|
{
|
ReleaseBuffer();
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass Find Inspection ½ÇÆÐ : FindLine s[%d],e[%d]",m_nCurCamId,m_nCurScanIdx,nForecast_S,nForecast_E);
|
return ERR_CHIP_FIND_RIGHTLINE;
|
}
|
}
|
else
|
{
|
m_dAvgThick = GetSubPixelThick(imgbuf,nForecast_S,dRightEdge,nChamferThres,dLeftEdge,dRightEdge);
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass Find Inspection : FilteringEdge s[%.3f],e[%.3f],Thick[%.3f]",m_nCurCamId,m_nCurScanIdx,dLeftEdge,dRightEdge,m_dAvgThick);
|
if(m_dAvgThick < 0 || dLeftEdge < 0 || dRightEdge < 0 || dLeftEdge > dRightEdge)
|
{
|
ReleaseBuffer();
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass Find Inspection ½ÇÆÐ : AvgThick is Minus s[%.3f],e[%.3f],Thick[%.3f]",m_nCurCamId,m_nCurScanIdx,dLeftEdge,dRightEdge,m_dAvgThick);
|
return ERR_CHIP_SUBPIXEL;
|
}
|
}
|
|
m_nForeEdgeLine[0] = (int)dLeftEdge+rectChamfer.left;
|
m_nForeEdgeLine[1] = (int)dRightEdge+rectChamfer.left;
|
}
|
else
|
{
|
m_nForeEdgeLine[0] += rectChamfer.left;
|
m_nForeEdgeLine[1] += rectChamfer.left;
|
}
|
|
if(bChipIns == TRUE)
|
{
|
m_nChipPairIndex = 0;
|
|
ChipInspection_Binarization(lpHeader,nFrameWidth,rectChip,rectCrack,rectBroken,nChipThres,nChipIDiffThres,nCrackThres,nBrokenThres,nBurrThres,m_nForeEdgeLine[0],m_nForeEdgeLine[1],bSaveDebug,iFrame);//20140613
|
|
}
|
|
if(bSaveDebug == TRUE)
|
{
|
if(imgbuf.IsValidBuffer() == TRUE && (int)dLeftEdge >= 0 && (int)dLeftEdge < imgbuf.GetWidth()
|
&& (int)dRightEdge >= 0 && (int)dRightEdge < imgbuf.GetWidth())
|
{
|
int i;
|
for(i=0;i<imgbuf.GetHeight();i++)
|
{
|
//if(i%2 == 0)
|
// continue;
|
imgbuf.SetPixel((int)dLeftEdge,i,255);
|
imgbuf.SetPixel((int)dRightEdge,i,0);
|
}
|
}
|
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Res.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(imgbuf);
|
|
m_nSaveIndex++;
|
}
|
|
return ERR_CHIP_SUCCESS;
|
}
|
|
ChipErrCode CChamferInspect::Inspection(int *nResult,LPBYTE lpHeader,int nFrameWidth,CRect &rectChamfer,int nChamferThres,BOOL bChipIns,BOOL bChamfer,CRect &rectChip,CRect &rectCrack,CRect &rectBroken, InspectParam insParam, BOOL bSaveDebug/*=FALSE*/,int *nPreForeLine/*=NULL*/,ChipThresMode emThresMode/*=THRESMODE_FIXED*/,int iFrame /*= 0*/)
|
{
|
ResetValue();
|
|
if(lpHeader == NULL)
|
return ERR_CHIP_IMAGE_NULL_01;
|
|
double dLeftEdge=0,dRightEdge=0;
|
CSISBuffer imgbuf(lpHeader,nFrameWidth,rectChamfer.Height());
|
|
//bSaveDebug = TRUE;
|
|
if(bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Org.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(imgbuf);
|
}
|
|
dLeftEdge = dRightEdge = m_nForeEdgeLine[0] = m_nForeEdgeLine[1] = rectChamfer.CenterPoint().x;
|
|
if(bChamfer == TRUE)
|
{
|
FindRightLine(imgbuf,rectChamfer,dLeftEdge,dRightEdge,nChamferThres);
|
|
m_dAvgThick = dRightEdge - dLeftEdge;
|
|
m_nForeEdgeLine[0] = (int)dLeftEdge;
|
m_nForeEdgeLine[1] = (int)dRightEdge;
|
}
|
|
if(bChipIns == TRUE)
|
{
|
m_nChipPairIndex = 0;
|
|
ChipInspection_Binarization_OpenCV(lpHeader,nFrameWidth,rectChip,rectCrack,rectBroken,insParam,m_nForeEdgeLine[0],m_nForeEdgeLine[1],bSaveDebug,iFrame); //20201114
|
}
|
|
if(bSaveDebug == TRUE)
|
{
|
COwnerBuffer dispbuf(imgbuf.GetWidth(),imgbuf.GetHeight());
|
|
CopyMemory(dispbuf.GetDataAddress(),imgbuf.GetDataAddress(),dispbuf.GetDataSize());
|
|
if(dispbuf.IsValidBuffer() == TRUE && (int)dLeftEdge >= 0 && (int)dLeftEdge < dispbuf.GetWidth()
|
&& (int)dRightEdge >= 0 && (int)dRightEdge < dispbuf.GetWidth())
|
{
|
int i;
|
for(i=0;i<dispbuf.GetHeight();i++)
|
{
|
//if(i%2 == 0)
|
// continue;
|
dispbuf.SetPixel((int)dLeftEdge,i,255);
|
dispbuf.SetPixel((int)dRightEdge,i,0);
|
}
|
}
|
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Res.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(dispbuf);
|
|
m_nSaveIndex++;
|
}
|
|
return ERR_CHIP_SUCCESS;
|
}
|
|
/*
|
ChipErrCode CChamferInspect::Inspection(int *nResult,LPBYTE lpHeader,int nFrameWidth,CRect &rectChamfer,int nChamferThres,BOOL bChipIns,BOOL bChamfer,CRect &rectChip,CRect &rectCrack,CRect &rectBroken, InspectParam insParam, BOOL bSaveDebug,int *nPreForeLine,ChipThresMode emThresMode,int iFrame)
|
{
|
ReleaseBuffer();
|
ResetValue();
|
|
if(lpHeader == NULL)
|
return ERR_CHIP_IMAGE_NULL_01;
|
|
COwnerBuffer imgbuf(rectChamfer.Width(),rectChamfer.Height());
|
|
if(CopyRectImg(lpHeader,imgbuf.GetDataAddress(),CSize(nFrameWidth,rectChamfer.Height()+2),rectChamfer) == FALSE)
|
return ERR_CHIP_IMAGE_NULL_02;
|
|
if(bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Org.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(imgbuf);
|
}
|
|
CRect rectIns = CRect(0,0,rectChamfer.Width(),rectChamfer.Height());
|
COwnerBuffer BufferCanny;
|
if(PreProcessing(imgbuf.GetDataAddress(),rectIns,BufferCanny) == FALSE)
|
{
|
ReleaseBuffer();
|
return ERR_CHIP_PREPROCESS;
|
}
|
|
if(BufferCanny.IsValidBuffer() == FALSE)
|
{
|
return ERR_CHIP_IMAGE_NULL_03;
|
}
|
|
if(bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Can.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(BufferCanny);
|
}
|
|
int nForecast_S,nForecast_E;
|
|
m_pGlassEdgeLine = new GLASSFINDDATA[rectIns.Height()+1];
|
|
m_nGlassEdgeLineCnt = rectIns.Height()+1;
|
|
m_pCannyWidthCnt = new int[BufferCanny.GetWidth()];
|
|
ZeroMemory(m_pCannyWidthCnt,sizeof(int)*BufferCanny.GetWidth());
|
|
FindEdgeLine(BufferCanny.GetDataAddress(0,0),rectIns);
|
*nResult = FindForeCastLine(imgbuf,rectIns,nForecast_S,nForecast_E,bChamfer);
|
|
double dLeftEdge=0,dRightEdge=0;
|
|
dLeftEdge = dRightEdge = m_nForeEdgeLine[0] = m_nForeEdgeLine[1] = nForecast_E = nForecast_S;
|
if(nForecast_S <= 0)
|
{
|
if(nPreForeLine != NULL)
|
nForecast_S = nPreForeLine[0];
|
else
|
{
|
ReleaseBuffer();
|
|
return ERR_CHIP_FIND_FORELINE;
|
}
|
}
|
|
if(bChamfer == TRUE)
|
{
|
if(emThresMode >= THRESMODE_ADAPTIVE)
|
{
|
FindAdptThres(imgbuf,BufferCanny,nChamferThres,nForecast_S,emThresMode);
|
}
|
|
COwnerBuffer pInsBin;
|
Binarization(imgbuf,pInsBin,nForecast_S,nChamferThres);
|
if(pInsBin.IsValidBuffer() == FALSE)
|
{
|
return ERR_CHIP_IMAGE_NULL_03;
|
}
|
|
if(bSaveDebug == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Bin.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(pInsBin);
|
}
|
|
FindRightLine(pInsBin,nForecast_S,dRightEdge);
|
|
nForecast_E = (int)dRightEdge;
|
dLeftEdge = m_nForeEdgeLine[0] = nForecast_S;
|
dRightEdge = m_nForeEdgeLine[1] = nForecast_E;
|
if(nForecast_S <= 0 || nForecast_E <= 0 || nForecast_S > nForecast_E)
|
{
|
if(nPreForeLine != NULL)
|
{
|
nForecast_E = nPreForeLine[1];
|
m_dAvgThick = nForecast_E - nForecast_S;
|
}
|
else
|
{
|
ReleaseBuffer();
|
|
return ERR_CHIP_FIND_RIGHTLINE;
|
}
|
}
|
else
|
{
|
m_dAvgThick = GetSubPixelThick(imgbuf,nForecast_S,dRightEdge,nChamferThres,dLeftEdge,dRightEdge);
|
|
if(m_dAvgThick < 0 || dLeftEdge < 0 || dRightEdge < 0 || dLeftEdge > dRightEdge)
|
{
|
ReleaseBuffer();
|
|
return ERR_CHIP_SUBPIXEL;
|
}
|
}
|
|
m_nForeEdgeLine[0] = (int)dLeftEdge+rectChamfer.left;
|
m_nForeEdgeLine[1] = (int)dRightEdge+rectChamfer.left;
|
}
|
else
|
{
|
m_nForeEdgeLine[0] += rectChamfer.left;
|
m_nForeEdgeLine[1] += rectChamfer.left;
|
}
|
|
if(bChipIns == TRUE)
|
{
|
m_nChipPairIndex = 0;
|
|
ChipInspection_Binarization_OpenCV(lpHeader,nFrameWidth,rectChip,rectCrack,rectBroken,insParam,m_nForeEdgeLine[0],m_nForeEdgeLine[1],bSaveDebug,iFrame); //20201114
|
}
|
|
if(bSaveDebug == TRUE)
|
{
|
if(imgbuf.IsValidBuffer() == TRUE && (int)dLeftEdge >= 0 && (int)dLeftEdge < imgbuf.GetWidth()
|
&& (int)dRightEdge >= 0 && (int)dRightEdge < imgbuf.GetWidth())
|
{
|
int i;
|
for(i=0;i<imgbuf.GetHeight();i++)
|
{
|
//if(i%2 == 0)
|
// continue;
|
imgbuf.SetPixel((int)dLeftEdge,i,255);
|
imgbuf.SetPixel((int)dRightEdge,i,0);
|
}
|
}
|
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_Res.bmp"),PATH_DEBUGFOLDER,iFrame,m_nSaveIndex);
|
CBufferAttach attach(str);
|
attach.AttachToFile(imgbuf);
|
|
m_nSaveIndex++;
|
}
|
|
return ERR_CHIP_SUCCESS;
|
}
|
*/
|
|
#define DEFINE_MIN_BMPOSLINE 1
|
double CChamferInspect::FindBPosLine(CSISBuffer &bufferOrg,int nThres)
|
{
|
if(bufferOrg.IsValidBuffer() == FALSE)
|
return -1;
|
|
COwnerBuffer pBin(bufferOrg.GetWidth(),bufferOrg.GetHeight());
|
if(pBin.IsValidBuffer() == FALSE)
|
return -1;
|
CopyMemory(pBin.GetDataAddress(0,0),bufferOrg.GetDataAddress(0,0),bufferOrg.GetDataSize());
|
|
CRect rectIns,rect;
|
int nCropWidth = pBin.GetWidth()/10;
|
|
rectIns = CRect(pBin.GetWidth()-nCropWidth-1,0,pBin.GetWidth()-1,pBin.GetHeight());
|
rect = CRect(0,0,pBin.GetDataWidth(),pBin.GetHeight());
|
|
// int nAreaValue = (int)GetAreaAVG(pBin.GetDataAddress(0,0),rectIns,rect);
|
// nThres = nAreaValue+10;
|
//nThres = (int)AdaptiveThreshold(pBin.GetDataAddress(0,0),pBin.GetWidth(),pBin.GetHeight(),pBin.GetDataWidth(),nThres);
|
|
CEdgeProc EdgeProc;
|
EdgeProc.ThresholdProcessing(pBin.GetDataAddress(0,0),CSize(pBin.GetDataWidth(),pBin.GetHeight()),nThres,1);
|
|
ListEdgeBlobData blobResultList;
|
ListEdgeBlobDataIt it;
|
CEdgeBlobData *pBlob;
|
|
// CString strImg;
|
// strImg.Format("D:\\Image\\TestOrg.bmp");
|
// CBufferAttach attach1(strImg);
|
// attach1.AttachToFile(bufferOrg);
|
//
|
// strImg.Format("D:\\Image\\TestBin.bmp");
|
// CBufferAttach attach2(strImg);
|
// attach2.AttachToFile(pBin);
|
|
COwnerBuffer pBlobImg(pBin.GetWidth(),pBin.GetHeight());
|
if(pBlobImg.IsValidBuffer() == FALSE)
|
return -1;
|
|
CopyMemory(pBlobImg.GetDataAddress(0,0),pBin.GetDataAddress(0,0),pBin.GetDataSize());
|
|
CBlobTool BlobTool;
|
if (!BlobTool.BlobAnalysis(pBlobImg.GetDataAddress(0,0), pBlobImg.GetWidth(), pBlobImg.GetHeight(), pBlobImg.GetDataWidth(), blobResultList, 2))
|
return -1;
|
|
CRect rectBlob,rectMax(0,0,0,0);
|
int nMaxArea = 0;
|
for(it=blobResultList.begin();it!=blobResultList.end();it++)
|
{
|
pBlob = *it;
|
if(pBlob == NULL)
|
continue;
|
|
if(pBlob->nPixelCount > nMaxArea)
|
{
|
rectBlob = CRect(pBlob->nLeft,pBlob->nTop,pBlob->nRight,pBlob->nBottom);
|
rectMax = rectBlob;
|
}
|
|
delete pBlob;
|
}
|
blobResultList.clear();
|
|
if(rectMax.Width() < DEFINE_MIN_BMPOSLINE || rectMax.Height() < (int)((double)bufferOrg.GetHeight()*0.6))
|
return -1;
|
|
int nPos = rectMax.right;
|
CRect rectCon(nPos-4,bufferOrg.GetHeight()/2-5,nPos+4,bufferOrg.GetHeight()/2+5);
|
|
CEdgeFind EdgeFind;
|
double dAvgPos = EdgeFind.FindLineSubPixel(bufferOrg.GetDataAddress(0,0),CSize(bufferOrg.GetDataWidth(),bufferOrg.GetHeight()),rectCon,3,-3,DIR_HORIZONTAL,SearchTypeIn2Out,EdgeTypeNegative);
|
if(dAvgPos <= 0)
|
dAvgPos = nPos;
|
|
return dAvgPos;
|
}
|
|
void CChamferInspect::VConvolutionConvC_Polygon(CSISBuffer &pSaveImg,BOOL bSaveImage,int nCamID,int iScan, int iFrame,CString strHpanelID, CSISBuffer &pImg,int nThres,std::vector<CChipPair> &vecPair,int nSetPitch, double dGradient, double dIntercept, int nDetMargin, double dLeft, int nOffset, int nOffsetY)
|
{
|
if(dGradient == 0)
|
return;
|
|
int sx, ex, sy, ey;
|
sx= 0;
|
sy = nOffsetY;
|
|
if(sx > pImg.GetWidth())
|
return;
|
|
ex= pImg.GetWidth();
|
ey= pImg.GetHeight();
|
|
int nConvWidth = 1;
|
int nConvHeight = 1;
|
|
nSetPitch = pImg.GetHeight() / 4;
|
|
if(ey < nSetPitch*3 || ex <= nConvWidth)
|
return;
|
|
int nPitch = nSetPitch;
|
|
int Threshold = nThres*(nConvWidth*nConvHeight);
|
int NegThres = Threshold*-1;
|
|
int n2Pitch = nSetPitch*2;
|
|
double dYBoundary = dGradient * dLeft + dIntercept;
|
double dXBoundary = dIntercept / dGradient * -1.;
|
|
int SrcValue = 0;
|
int DestValue = 0;
|
int DestValue1 = 0;
|
int DestValue2 = 0;
|
int SubValue = 0;
|
int i = 0;
|
int SubValue2Pitch = 0;
|
int j;
|
|
double x,y;
|
BOOL bEdgeDefect;
|
double dDist;
|
|
sx = (int)dLeft + nOffset;
|
|
//0~pitch °Å¸®±îÁö
|
for( j = sy; j < ey-n2Pitch; j++)
|
{
|
if(j+nPitch >= ey || j+n2Pitch >= ey)
|
continue;
|
|
for( i = sx; i < ex; i++)
|
{
|
////////////////////////////////////////////////////////
|
//¿©±â¼ °ø¿µ¿ª(Á¦¿Ü¿µ¿ª)À» °É·¯³½´Ù -´Ù°¢°Ë»ç
|
//double dGradient : ±â¿ï±â
|
//double dIntercept : ÀýÆí
|
//y = dGradient * x + dIntercept
|
//x = (y - dIntercept) / dGradient
|
// ¦£¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¤
|
// ¦¢ °ø¿µ¿ª / ¦¢
|
// ¦¢(Á¦¿Ü¿µ¿ª)/ ¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ / ±Û¶ó½º¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ /(°Ë»ç¿µ¿ª)¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ B¦¢ ¦¢
|
// ¦¢ u¦¢ ¦¢
|
// ¦¢ r¦¢ ¦¢
|
// ¦¢ r¦¢ ¦¢
|
// ¦¢ ¦¢ ¦¢
|
// ¦¢ ¦¢ ¦¢
|
// ¦¢ ¦¢ ¦¢
|
// ¦¦¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¥
|
y = dGradient * i + dIntercept;
|
x = (double)(j - dIntercept) / dGradient;
|
if(j < (y + nOffsetY)|| i < (x + nOffset))
|
continue;
|
////////////////////////////////////////////////////////
|
|
SrcValue = *pImg.GetDataAddress(i,j);
|
|
bEdgeDefect = FALSE;
|
if(SrcValue <= Threshold)
|
{
|
dDist = fabs(dGradient * i - j + dIntercept) / sqrt(dGradient*dGradient + 1);
|
if((nDetMargin + nOffset >= dDist && dYBoundary >= j && dXBoundary >= i) //´ë°¢¼±
|
|| (nDetMargin + nOffset + dLeft >= i && dYBoundary < j) //¼öÁ÷¼±
|
|| (nDetMargin + nOffsetY >= j && dXBoundary < i)) //¼öÆò¼±¿¡ ºÙ¾îÀִ°͸¸ µðÆåÀ¸·Î ÀÎÁ¤
|
bEdgeDefect = TRUE;
|
|
if(!InsertPairing(i,j,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,Threshold,SrcValue, DestValue2,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP, bEdgeDefect))
|
continue;
|
if(bSaveImage)
|
pSaveImg.SetPixel(i,j,0);
|
}
|
|
/*
|
|
DestValue1 = *pImg.GetDataAddress(i,j+nPitch);
|
DestValue2 = *pImg.GetDataAddress(i,j+n2Pitch);
|
|
SubValue = DestValue1 - SrcValue;
|
SubValue2Pitch = DestValue2 - SrcValue;
|
|
bEdgeDefect = FALSE;
|
|
// if ((SubValue > Threshold && SubValue2Pitch > Threshold) ||
|
// (SubValue < NegThres && SubValue2Pitch < NegThres))
|
if ((SubValue > Threshold && SubValue2Pitch > Threshold))
|
{
|
//´ë°¢¼±¿¡ ÀÎÁ¢ÇÑ°Ç Æ¯º°Ãë±Þ
|
//Á¡°ú ¼±»çÀÌÀÇ °Å¸® = abs(ax + by + c) / squt(a*a+b*b)
|
//a = dGradient, b = -1, c = dIntercept
|
|
dDist = fabs(dGradient * i - j + dIntercept) / sqrt(dGradient*dGradient + 1);
|
if((nDetMargin + nOffset >= dDist && dYBoundary >= j && dXBoundary >= i) //´ë°¢¼±
|
|| (nDetMargin + nOffset + dLeft >= i && dYBoundary < j) //¼öÁ÷¼±
|
|| (nDetMargin + nOffset >= j && dXBoundary < i)) //¼öÆò¼±¿¡ ºÙ¾îÀִ°͸¸ µðÆåÀ¸·Î ÀÎÁ¤
|
bEdgeDefect = TRUE;
|
|
if(!InsertPairing(vecPair,i,j,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,Threshold,SrcValue, DestValue2,CHIPREGTYPE_RIGHT, bEdgeDefect))
|
return;
|
if(bSaveImage)
|
pSaveImg.SetPixel(i,j,0);
|
|
}
|
//Burr °áÇÔ
|
else if(SubValue < NegThres && SubValue2Pitch < NegThres && i < dLeft - nOffset)
|
{
|
if(dLeft - nOffset - nDetMargin <= i)
|
bEdgeDefect = TRUE;
|
|
if(!InsertPairing(vecPair,i,j,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,Threshold,SrcValue, DestValue2,CHIPREGTYPE_LEFT, bEdgeDefect))
|
return;
|
if(bSaveImage)
|
pSaveImg.SetPixel(i,j,1);
|
}
|
|
*/
|
}
|
|
}
|
|
//0~pitch °Å¸®±îÁö
|
for( j = ey-1; j >= ey-n2Pitch; j--)
|
{
|
if(j-nPitch < 0 || j-n2Pitch < 0)
|
continue;
|
|
for( i = sx; i < ex; i++)
|
{
|
|
////////////////////////////////////////////////////////
|
//¿©±â¼ °ø¿µ¿ª(Á¦¿Ü¿µ¿ª)À» °É·¯³½´Ù -´Ù°¢°Ë»ç
|
//double dGradient : ±â¿ï±â
|
//double dIntercept : ÀýÆí
|
//y = dGradient * x + dIntercept
|
//x = (y - dIntercept) / dGradient
|
// ¦£¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¤
|
// ¦¢ °ø¿µ¿ª / ¦¢
|
// ¦¢(Á¦¿Ü¿µ¿ª)/ ¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ / ±Û¶ó½º¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ /(°Ë»ç¿µ¿ª)¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ / ¦¢
|
// ¦¢ B¦¢ ¦¢
|
// ¦¢ u¦¢ ¦¢
|
// ¦¢ r¦¢ ¦¢
|
// ¦¢ r¦¢ ¦¢
|
// ¦¢ ¦¢ ¦¢
|
// ¦¢ ¦¢ ¦¢
|
// ¦¢ ¦¢ ¦¢
|
// ¦¦¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¥
|
y = dGradient * i + dIntercept;
|
x = (j - dIntercept) / dGradient;
|
if(j < (y + nOffsetY)|| i < (x + nOffset))
|
continue;
|
////////////////////////////////////////////////////////
|
|
SrcValue = *pImg.GetDataAddress(i,j);
|
|
bEdgeDefect = FALSE;
|
if(SrcValue <= Threshold)
|
{
|
dDist = fabs(dGradient * i - j + dIntercept) / sqrt(dGradient*dGradient + 1);
|
if((nDetMargin + nOffset >= dDist && dYBoundary >= j && dXBoundary >= i) //´ë°¢¼±
|
|| (nDetMargin + nOffset + dLeft >= i && dYBoundary < j) //¼öÁ÷¼±
|
|| (nDetMargin + nOffsetY >= j && dXBoundary < i)) //¼öÆò¼±¿¡ ºÙ¾îÀִ°͸¸ µðÆåÀ¸·Î ÀÎÁ¤
|
bEdgeDefect = TRUE;
|
|
if(!InsertPairing(i,j,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,Threshold,SrcValue, DestValue2,CHIPREGTYPE_RIGHT,INS_DEFECT_CHIP, bEdgeDefect))
|
continue;
|
if(bSaveImage)
|
pSaveImg.SetPixel(i,j,0);
|
}
|
|
/*
|
DestValue1 = *pImg.GetDataAddress(i,j-nPitch);
|
DestValue2 = *pImg.GetDataAddress(i,j-n2Pitch);
|
|
SubValue = DestValue1 - SrcValue;
|
SubValue2Pitch = DestValue2 - SrcValue;
|
|
// if ((SubValue > Threshold && SubValue2Pitch > Threshold) ||
|
// (SubValue < NegThres && SubValue2Pitch < NegThres))
|
if ((SubValue > Threshold && SubValue2Pitch > Threshold))
|
{
|
//´ë°¢¼±¿¡ ÀÎÁ¢ÇÑ°Ç Æ¯º°Ãë±Þ
|
//Á¡°ú ¼±»çÀÌÀÇ °Å¸® = abs(ax + by + c) / squt(a*a+b*b)
|
//a = dGradient, b = -1, c = dIntercept
|
bEdgeDefect = FALSE;
|
dDist = fabs(dGradient * i - j + dIntercept) / sqrt(dGradient*dGradient + 1);
|
if((nDetMargin + nOffset >= dDist && dYBoundary >= j && dXBoundary >= i) //´ë°¢¼±
|
|| (nDetMargin + nOffset + dLeft >= i && dYBoundary < j) //¼öÁ÷¼±
|
|| (nDetMargin + nOffset >= j && dXBoundary < i)) //¼öÆò¼±¿¡ ºÙ¾îÀִ°͸¸ µðÆåÀ¸·Î ÀÎÁ¤
|
bEdgeDefect = TRUE;
|
|
if(!InsertPairing(vecPair,i,j,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,Threshold,SrcValue, DestValue2, CHIPREGTYPE_RIGHT, bEdgeDefect))
|
return;
|
if(bSaveImage)
|
pSaveImg.SetPixel(i,j,0);
|
}
|
//Burr °áÇÔ
|
else if(SubValue < NegThres && SubValue2Pitch < NegThres && i < dLeft - nOffset)
|
{
|
if(dLeft - nOffset - nDetMargin <= i)
|
bEdgeDefect = TRUE;
|
|
if(!InsertPairing(vecPair,i,j,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,Threshold,SrcValue, DestValue2,CHIPREGTYPE_LEFT, bEdgeDefect))
|
return;
|
if(bSaveImage)
|
pSaveImg.SetPixel(i,j,1);
|
}
|
*/
|
}
|
}
|
|
if(bSaveImage)
|
{
|
CString strFileName;
|
CString strFolderName;
|
CString strPath;
|
|
strFileName.Format(_T("Diagonal_%d_%d_%d.bmp"), nCamID,iScan, iFrame);
|
strFolderName.Format(_T("D:\\Image\\Corner\\%s"), strHpanelID);
|
CreateDirectory(strFolderName,NULL);
|
strPath.Format(_T("%s\\%s"),strFolderName,strFileName);
|
CBufferAttach attach(strPath);
|
attach.AttachToFile(pSaveImg);
|
}
|
|
}
|
|
BOOL CChamferInspect::BlobDefect_Pixel_TypeRegionFilter(std::vector<CChipBlob> &vecBlob,std::vector<CChipPair> &vecPair,int nChipThres,int nMergeDist)
|
{
|
if((int)vecPair.size() <= 0)
|
return TRUE;
|
|
int i, j;
|
BOOL *bMerged,*bTemp;
|
int *lFirstIndex;
|
int nPair = (int)vecPair.size();
|
int nBlob = 0;
|
|
bMerged = new BOOL[nPair];
|
bTemp = new BOOL[nPair];
|
lFirstIndex = new int[nPair];
|
|
// Index ¸Å±â±â.
|
ZeroMemory(bMerged, nPair * sizeof(BOOL));
|
ZeroMemory(bTemp, nPair * sizeof(BOOL));
|
for (i = 0; i < nPair; i++)
|
{
|
lFirstIndex[i] = i;
|
}
|
|
// ÀÎÁ¢ µðÆå ¸ÓÁöÇϱâ.
|
for(i = 0; i < nPair; i++)
|
{
|
for (j = i + 1; j < nPair; j++)
|
{
|
if (bMerged[j])// || vecPair[i].s_DefectType != vecPair[j].s_DefectType || vecPair[i].s_RegionType != vecPair[j].s_RegionType)
|
continue;
|
|
if (abs(vecPair[j].s_nDefectY - vecPair[i].s_nDefectY) > nMergeDist) // j´Â iº¸´Ù Å©´Ù.
|
continue;
|
|
if (abs(vecPair[j].s_nDefectX - vecPair[i].s_nDefectX) > nMergeDist)
|
continue;
|
|
lFirstIndex[j] = lFirstIndex[i];
|
bMerged[j] = TRUE;
|
}
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
int nStart = 0;
|
BOOL Ret = TRUE;
|
|
// µðÆåµéÀÇ ¼ö¸¸Å ó¸®. - Blobing
|
int nBlobNum = 0;
|
int nDiffGray, nThres=nChipThres;
|
CChipBlob chipBlob;
|
|
for (i = 0; i < nPair; i++)
|
{
|
if (vecPair[i].s_DefectType == CHIPDEFTYPE_DELETE)
|
{
|
continue;
|
}
|
|
if (!bTemp[lFirstIndex[i]]) // óÀ½ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
if (nBlob >= nPair || nBlobNum >= 1000)
|
continue;
|
|
bTemp[lFirstIndex[i]] = TRUE;
|
|
chipBlob.Reset();
|
CheckDefectRect(chipBlob, vecPair[i].s_nDefectX, vecPair[i].s_nDefectY);
|
|
chipBlob.SetDefectPair(vecPair[i].s_DefectPair);
|
chipBlob.s_nIndex = lFirstIndex[i];
|
chipBlob.s_nDefectArea++;
|
chipBlob.s_nDefectX += vecPair[i].s_nDefectX;
|
chipBlob.s_nDefectY += vecPair[i].s_nDefectY;
|
chipBlob.s_DefectType = vecPair[i].s_DefectType; //½ÇÁ¦ ¹é°áÇÔÀº 1,Èæ°áÇÔÀº 0
|
chipBlob.s_sThreshold = nThres;
|
chipBlob.s_RegionType = vecPair[i].s_RegionType;
|
chipBlob.s_dThick = vecPair[i].s_dThick;
|
chipBlob.s_bCornerChip |= vecPair[i].s_bCornerChip;
|
|
// Gray ±¸Çϱâ
|
if (vecPair[i].s_nGraySrc > chipBlob.s_sLevelSrcMax)
|
{
|
chipBlob.s_sLevelSrcMax = vecPair[i].s_nGraySrc;
|
chipBlob.s_xLevelSrcMax = vecPair[i].s_nDefectX;
|
chipBlob.s_yLevelSrcMax = vecPair[i].s_nDefectY;
|
}
|
if (vecPair[i].s_nGraySrc < chipBlob.s_sLevelSrcMin)
|
chipBlob.s_sLevelSrcMin = vecPair[i].s_nGraySrc;
|
chipBlob.s_nLevelSrcSum += vecPair[i].s_nGraySrc;
|
|
if (vecPair[i].s_nGrayRef > chipBlob.s_sLevelRefMax)
|
chipBlob.s_sLevelRefMax = vecPair[i].s_nGrayRef;
|
if (vecPair[i].s_nGrayRef < chipBlob.s_sLevelRefMin)
|
chipBlob.s_sLevelRefMin = vecPair[i].s_nGrayRef;
|
chipBlob.s_nLevelRefSum += vecPair[i].s_nGrayRef;
|
|
nDiffGray = abs(vecPair[i].s_nGraySrc - vecPair[i].s_nGrayRef);
|
if (nDiffGray > chipBlob.s_sLevelDiffMax)
|
{
|
chipBlob.s_sLevelDiffMax = nDiffGray;
|
chipBlob.s_sDefectPeak = abs(chipBlob.s_sLevelDiffMax) - nThres;
|
//chipBlob.s_sDefectPeak = abs(chipBlob.s_sLevelDiffMax / 8) - nThres;
|
}
|
if (nDiffGray < chipBlob.s_sLevelDiffMin)
|
chipBlob.s_sLevelDiffMin = nDiffGray;
|
chipBlob.s_nLevelDiffSum += nDiffGray;
|
|
vecBlob.push_back(chipBlob);
|
nBlob++;
|
nBlobNum++;
|
}
|
else // ³ªÁß¿¡ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
for(j = nBlob - 1; j >= 0; j--)
|
{
|
if (vecBlob[j].s_nIndex != lFirstIndex[i])
|
continue;
|
|
CheckDefectRect(vecBlob[j], vecPair[i].s_nDefectX, vecPair[i].s_nDefectY);
|
|
vecBlob[j].SetDefectPair(vecPair[i].s_DefectPair);
|
vecBlob[j].s_nDefectArea++;
|
vecBlob[j].s_nDefectX += vecPair[i].s_nDefectX;
|
vecBlob[j].s_nDefectY += vecPair[i].s_nDefectY;
|
vecBlob[j].s_bCornerChip |= vecPair[i].s_bCornerChip;
|
if (nThres > vecBlob[j].s_sThreshold)
|
vecBlob[j].s_sThreshold = nThres;
|
|
// Gray ±¸Çϱâ
|
if (vecPair[i].s_nGraySrc > vecBlob[j].s_sLevelSrcMax)
|
{
|
vecBlob[j].s_sLevelSrcMax = vecPair[i].s_nGraySrc;
|
vecBlob[j].s_xLevelSrcMax = vecPair[i].s_nDefectX;
|
vecBlob[j].s_yLevelSrcMax = vecPair[i].s_nDefectY;
|
}
|
if (vecPair[i].s_nGraySrc < vecBlob[j].s_sLevelSrcMin)
|
vecBlob[j].s_sLevelSrcMin = vecPair[i].s_nGraySrc;
|
vecBlob[j].s_nLevelSrcSum += vecPair[i].s_nGraySrc;
|
|
if (vecPair[i].s_nGrayRef > vecBlob[j].s_sLevelRefMax)
|
vecBlob[j].s_sLevelRefMax = vecPair[i].s_nGrayRef;
|
if (vecPair[i].s_nGrayRef < vecBlob[j].s_sLevelRefMin)
|
vecBlob[j].s_sLevelRefMin = vecPair[i].s_nGrayRef;
|
vecBlob[j].s_nLevelRefSum += vecPair[i].s_nGrayRef;
|
|
nDiffGray = abs(vecPair[i].s_nGraySrc - vecPair[i].s_nGrayRef);
|
if (nDiffGray > vecBlob[j].s_sLevelDiffMax)
|
{
|
vecBlob[j].s_sLevelDiffMax = nDiffGray;
|
vecBlob[j].s_sDefectPeak = abs(vecBlob[j].s_sLevelDiffMax) - nThres;
|
//vecBlob[j].s_sDefectPeak = abs(vecBlob[j].s_sLevelDiffMax / 8) - nThres;
|
}
|
if (nDiffGray < vecBlob[j].s_sLevelDiffMin)
|
vecBlob[j].s_sLevelDiffMin = nDiffGray;
|
vecBlob[j].s_nLevelDiffSum += nDiffGray;
|
|
if(vecBlob[j].s_dThick < vecPair[i].s_dThick)
|
vecBlob[j].s_dThick = vecPair[i].s_dThick;
|
|
break;
|
}
|
}
|
}
|
|
// ÁÂÇ¥ º¸Á¤.
|
for (i = nStart; i < nBlob; i++)
|
{
|
if (vecBlob[i].s_nDefectArea > 0)
|
{
|
//vecBlob[i].s_nDefectX = vecBlob[i].s_nDefectX / vecBlob[i].s_nDefectArea;
|
//vecBlob[i].s_nDefectY = vecBlob[i].s_nDefectY / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_nDefectX = vecBlob[i].s_DefectRect.CenterPoint().x;
|
vecBlob[i].s_nDefectY = vecBlob[i].s_DefectRect.CenterPoint().y;
|
vecBlob[i].s_sLevelSrcAvg = vecBlob[i].s_nLevelSrcSum / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_sLevelRefAvg = vecBlob[i].s_nLevelRefSum / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_sLevelDiffAvg = vecBlob[i].s_nLevelDiffSum / vecBlob[i].s_nDefectArea;
|
vecBlob[i].s_nDefectRScale = CalcRScale(vecBlob[i].s_ptVertex);
|
}
|
else
|
vecBlob[i].s_bRemoved = TRUE;
|
}
|
|
delete[] bMerged;
|
delete[] bTemp;
|
delete[] lFirstIndex;
|
|
MergeDivision(vecBlob);
|
|
return Ret;
|
}
|
|
BOOL CChamferInspect::FilteringDiagonalEdgeBlob(std::vector<CChipBlob> &vecBlob)
|
{
|
std::vector<CChipBlob> vecTmp;
|
std::vector<CChipBlob>::iterator it;
|
|
for(it=vecBlob.begin();it!=vecBlob.end();it++)
|
{
|
if(it->s_bCornerChip == FALSE)
|
continue;
|
|
vecTmp.push_back(*it);
|
}
|
|
vecBlob.clear();
|
for(it=vecTmp.begin();it!=vecTmp.end();it++)
|
vecBlob.push_back(*it);
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::ChipInspection_Corner(int nMergeRange,BOOL bSaveImage,CString strHpanelID, int nCamID,int iScan, int iThread,int iFrame,CSISBuffer &ChipBuffer,int nChipThres,int nChipInsWidth,int nEdgeRight, double dGradient, double dIntercept, int nDetMargin, int nMargin, int nMarginY)
|
{
|
if(ChipBuffer.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
if(ChipBuffer.GetHeight() < CHIP_INS_PITCH * 4)
|
return FALSE;
|
|
CRect rectIns;
|
CString strImg;
|
|
nChipInsWidth= nEdgeRight + nChipInsWidth - (nEdgeRight + nChipInsWidth)%4;
|
if(nChipInsWidth <= 0)
|
return FALSE;
|
|
/*strImg.Format("D:\\Image\\CutArea\\ChipInsOrg.bmp");
|
CBufferAttach attachOrg(strImg);
|
attachOrg.AttachToFile(ChipBuffer);*/
|
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : MakeChipImage Right",m_nCurCamId,m_nCurScanIdx);
|
|
COwnerBuffer InsRightBuffer, InsRightSaveBuffer;
|
int nBaseRight;
|
|
InsRightBuffer.SetSize(nChipInsWidth,ChipBuffer.GetHeight());
|
InsRightSaveBuffer.SetSize(nChipInsWidth,ChipBuffer.GetHeight());
|
if(InsRightBuffer.IsValidBuffer() == FALSE)
|
return FALSE;
|
if(InsRightSaveBuffer.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
rectIns = CRect(0,0,nChipInsWidth,ChipBuffer.GetHeight());
|
|
if(rectIns.left < 0) rectIns.left = 0;
|
if(rectIns.right >= ChipBuffer.GetWidth()) rectIns.right = ChipBuffer.GetWidth()-1;
|
if(rectIns.Width() <= 0 || rectIns.Height() <= 0 || rectIns.top > rectIns.bottom)
|
return FALSE;
|
CSISBuffer::CopyBtoA(InsRightBuffer,0,0,ChipBuffer,rectIns);
|
CSISBuffer::CopyBtoA(InsRightSaveBuffer,0,0,ChipBuffer,rectIns);
|
|
nBaseRight = rectIns.left;
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : MakeChipImage Right end[%d,%d]",m_nCurCamId,m_nCurScanIdx,InsRightBuffer.GetWidth(),InsRightBuffer.GetHeight());
|
|
//CopyBuffer(InsRightBuffer,pChipRight);
|
/*
|
strImg.Format("D:\\Image\\CutArea\\%d_%d_%d_%.0f_%.0f_%d_%d[%d %d %d %d].bmp",iThread,iFrame,nChipThres,dGradient, dIntercept, nDetMargin, nEdgeRight
|
,rectIns.left,rectIns.top,rectIns.right,rectIns.bottom);
|
CBufferAttach attachPre(strImg);
|
attachPre.AttachToFile(InsRightBuffer);
|
|
strImg.Format("D:\\Image\\CutArea\\ChipInsLeft.bmp");
|
CBufferAttach attachLeft(strImg);
|
attachLeft.AttachToFile(InsLeftBuffer); */
|
|
std::vector<CChipPair> vecPair;
|
std::vector<CChipBlob> blobRight;
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : Inspection Right",m_nCurCamId,m_nCurScanIdx);
|
VConvolutionConvC_Polygon(InsRightSaveBuffer,bSaveImage,nCamID,iScan,iFrame,strHpanelID, InsRightBuffer,nChipThres,vecPair,CHIP_INS_PITCH, dGradient, dIntercept, nDetMargin, nEdgeRight, nMargin,nMarginY);
|
BlobDefect_Pixel_TypeRegionFilter(blobRight,vecPair,nChipThres,nMergeRange);
|
FilteringDiagonalEdgeBlob(blobRight);
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : Inspection Right End",m_nCurCamId,m_nCurScanIdx);
|
|
std::vector<CChipBlob>::iterator itBlob;
|
|
ReleaseChipBuffer();
|
if((int)blobRight.size() > 0)
|
{
|
for(itBlob=blobRight.begin();itBlob!=blobRight.end();itBlob++)
|
{
|
if(m_nDefectCnt >= MAX_CHIP_DEFECT_COUNT)
|
return FALSE;
|
|
CChipBlob *pBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pBlob == NULL)
|
continue;
|
|
*pBlob = *itBlob;
|
pBlob->s_DefectRect.OffsetRect(nBaseRight,0);
|
pBlob->s_nDefectX += nBaseRight;
|
m_nDefectCnt++;
|
}
|
blobRight.clear();
|
}
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : End",m_nCurCamId,m_nCurScanIdx);
|
|
return TRUE;
|
}
|
|
void CChamferInspect::SetCutAreaExpPos(int nSide,int nPosY, int nSize, int nERType, int nPosX, int nSizeX)
|
{
|
STU_CHIPPINGINS_EXP_POS expPos;
|
|
expPos.nSide = nSide;
|
expPos.nPosY = nPosY;
|
expPos.nSize = nSize;
|
expPos.nERType = nERType;
|
expPos.nPosX = nPosX;
|
expPos.nSizeX = nSizeX;
|
|
//m_Log.DisplayEdgeLog("SetCutAreaExpPos %d,%d,%d,%d,%d,%d",nSide,nPosY,nSize,nERType,nPosX,nSizeX);
|
|
m_expInsArea.push_back(expPos);
|
}
|
|
void CChamferInspect::GetCutAreaExpPos(CRect rectInsOrg,int nEdgeLeft, int nGlassStartLine, CRect &rectExpRegion,int nChipInsWidth, double dFindLeft)
|
{
|
CRect recttemp;
|
rectExpRegion=CRect(-1,-1,-1,-1);
|
|
std::vector<STU_CHIPPINGINS_EXP_POS>::iterator it;
|
STU_CHIPPINGINS_EXP_POS expPos;
|
|
for(it=m_expInsArea.begin();it!=m_expInsArea.end();it++)
|
{
|
expPos = *it;
|
|
recttemp.left = nEdgeLeft + expPos.nPosX;
|
recttemp.right = nEdgeLeft + expPos.nPosX + expPos.nSizeX;
|
recttemp.top = expPos.nPosY + nGlassStartLine;
|
recttemp.bottom = expPos.nPosY + expPos.nSize + nGlassStartLine;
|
|
if(rectInsOrg.top > recttemp.bottom )
|
continue;
|
if(rectInsOrg.bottom < recttemp.top)
|
continue;
|
if(nEdgeLeft+nChipInsWidth < recttemp.left)
|
continue;
|
if(nEdgeLeft > recttemp.right)
|
continue;
|
|
//m_Log.DisplayEdgeLog(" recttemp %d %d %d %d",recttemp.left,recttemp.top,recttemp.right,recttemp.bottom);
|
//m_Log.DisplayEdgeLog(" rectInsOrg %f %d %f %d",dFindLeft,rectInsOrg.top,dFindLeft+nChipInsWidth,rectInsOrg.bottom);
|
//m_Log.DisplayEdgeLog(" ½ÃÀÛ rectExpRegion %d %d %d %d",rectExpRegion.left,rectExpRegion.top,rectExpRegion.right,rectExpRegion.bottom);
|
|
if(rectInsOrg.top >= recttemp.top)
|
rectExpRegion.top = rectInsOrg.top;
|
else if(rectInsOrg.top <= recttemp.top)
|
rectExpRegion.top = recttemp.top;
|
|
if(rectInsOrg.bottom <= recttemp.bottom)
|
rectExpRegion.bottom = rectInsOrg.bottom;
|
else if(rectInsOrg.bottom >= recttemp.bottom)
|
rectExpRegion.bottom = recttemp.bottom;
|
|
if(nEdgeLeft >= recttemp.left)
|
rectExpRegion.left = (long)dFindLeft;
|
else if(nEdgeLeft <= recttemp.left)
|
rectExpRegion.left = recttemp.left;
|
|
if(nEdgeLeft+nChipInsWidth <= recttemp.right)
|
rectExpRegion.right = (long)(dFindLeft+nChipInsWidth);
|
else if(nEdgeLeft+nChipInsWidth >= recttemp.right)
|
rectExpRegion.right = recttemp.right;
|
|
//m_Log.DisplayEdgeLog(" OffsetRect Àü rectExpRegion %d %d %d %d",rectExpRegion.left,rectExpRegion.top,rectExpRegion.right,rectExpRegion.bottom);
|
|
rectExpRegion.OffsetRect(-(int)dFindLeft,-rectInsOrg.top);
|
|
//m_Log.DisplayEdgeLog(" ³¡ rectExpRegion %d %d %d %d",rectExpRegion.left,rectExpRegion.top,rectExpRegion.right,rectExpRegion.bottom);
|
break;
|
}
|
}
|
|
ChipErrCode CChamferInspect::InspectCorner_ExtraPoly(CSISBuffer &BufferIns,int nThres,int nTop,int nLeft,STU_EXTRA_POLY &stuPoly,BOOL bReset,int nMergeReange)
|
{
|
if(BufferIns.IsValidBuffer() == FALSE)
|
return ERR_CHIP_IMAGE_NULL_01;
|
|
int x,y,iIter;
|
int nXStart,nXEnd,nInsW,nData;
|
std::vector<CChipPair> vecPair;
|
std::vector<CChipBlob> blobTmp;
|
LPBYTE pImg;
|
|
// COwnerBuffer imgbuf(BufferIns.GetWidth(),BufferIns.GetHeight());
|
|
// CopyMemory(imgbuf.GetDataAddress(0,0),BufferIns.GetDataAddress(0,0),BufferIns.GetWidth()*BufferIns.GetHeight());
|
|
nInsW = (stuPoly.nEL-stuPoly.nSL);
|
for(y=stuPoly.nST,iIter=stuPoly.nTheHeight;y<=stuPoly.nEB;y++,iIter++)
|
{
|
nXStart = (int)(static_cast<double>(stuPoly.nSL) * cos(stuPoly.dTheta) - static_cast<double>(iIter) * sin(stuPoly.dTheta));
|
nXEnd = nXStart+nInsW;
|
|
pImg = BufferIns.GetDataAddress(nXStart,y);
|
for(x=nXStart;x<=nXEnd;x++,pImg++)
|
{
|
nData = *pImg;
|
if(nData <= nThres)
|
{
|
// imgbuf.SetPixel(x,y,0);
|
|
if(!InsertPairing(x,y,nData,nThres,nData,nData,CHIPREGTYPE_LEFT,INS_DEFECT_CHIP))
|
break;
|
}
|
}
|
}
|
|
// CString strImg;
|
// strImg.Format("D:\\Image\\CornerChip\\result_nSL[%d]_nST[%d]_nEB[%d]_nEL[%d].bmp",stuPoly.nSL,stuPoly.nST,stuPoly.nEB,stuPoly.nEL);
|
// CBufferAttach attach(strImg);
|
// attach.AttachToFile(imgbuf);
|
|
if(GetPairDefectCount() <= 0)
|
return ERR_CHIP_SUCCESS;
|
|
BlobDefect_Pixel(blobTmp,nThres,nMergeReange);
|
|
if((int)blobTmp.size() > 0)
|
{
|
std::vector<CChipBlob>::iterator itBlob;
|
|
if(bReset == TRUE)
|
ReleaseChipBuffer();
|
|
for(itBlob=blobTmp.begin();itBlob!=blobTmp.end();itBlob++)
|
{
|
if(m_nDefectCnt >= MAX_CHIP_DEFECT_COUNT)
|
return ERR_CHIP_SUCCESS;
|
|
CChipBlob *pBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pBlob == NULL)
|
continue;
|
|
*pBlob = *itBlob;
|
|
pBlob->s_DefectRect.OffsetRect(nLeft,nTop);
|
|
pBlob->s_nDefectX += nLeft;
|
pBlob->s_nDefectY += nTop;
|
|
m_nDefectCnt++;
|
}
|
blobTmp.clear();
|
}
|
|
return ERR_CHIP_SUCCESS;
|
}
|
|
BOOL CChamferInspect::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;
|
}
|
|
ChipErrCode CChamferInspect::InspectCorner_Extra(CSISBuffer &BufferIns,int nThres,int nTop,int nLeft,BOOL bReset,int nMergeReange)
|
{
|
if(BufferIns.IsValidBuffer() == FALSE)
|
return ERR_CHIP_IMAGE_NULL_01;
|
|
std::vector<CChipBlob> blobTmp;
|
LPBYTE pImg = BufferIns.GetDataAddress();
|
|
int x,y,iLoop;
|
|
for(iLoop=0;iLoop<BufferIns.GetDataSize();iLoop++,pImg++)
|
{
|
if(*pImg <= nThres)
|
{
|
y = iLoop/BufferIns.GetWidth();
|
x = iLoop%BufferIns.GetWidth();
|
|
if(!InsertPairing(x,y,*pImg,nThres,*pImg, *pImg,CHIPREGTYPE_LEFT,INS_DEFECT_CHIP))
|
break;
|
}
|
}
|
|
if(GetPairDefectCount() <= 0)
|
return ERR_CHIP_SUCCESS;
|
|
BlobDefect_Pixel(blobTmp,nThres,nMergeReange);
|
|
if((int)blobTmp.size() > 0)
|
{
|
std::vector<CChipBlob>::iterator itBlob;
|
|
if(bReset == TRUE)
|
ReleaseChipBuffer();
|
|
for(itBlob=blobTmp.begin();itBlob!=blobTmp.end();itBlob++)
|
{
|
if(m_nDefectCnt >= MAX_CHIP_DEFECT_COUNT)
|
return ERR_CHIP_SUCCESS;
|
|
CChipBlob *pBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pBlob == NULL)
|
continue;
|
|
*pBlob = *itBlob;
|
|
pBlob->s_DefectRect.OffsetRect(nLeft,nTop);
|
|
pBlob->s_nDefectX += nLeft;
|
pBlob->s_nDefectY += nTop;
|
|
m_nDefectCnt++;
|
}
|
blobTmp.clear();
|
}
|
|
return ERR_CHIP_SUCCESS;
|
}
|
|
void CChamferInspect::BinalizeFind_CornerChip(CSISBuffer &pSaveImg,BOOL bSaveImage,CString strHpanelID, CSISBuffer &pImg,int nThres,std::vector<CChipPair> &vecPair,ChipResionType s_RegionType,int nSetPitch, CRect rectExpRegion, int iFrame, int nIndex, int nCamID, int iScan, int nChippingInsOffset)//130115
|
{
|
int sx, ex, sy, ey;
|
sx = nChippingInsOffset;//130115
|
sy = 0;//130115
|
ex= pImg.GetWidth();
|
ey= pImg.GetHeight();
|
|
int Threshold = nThres;//*(nConvWidth*nConvHeight);
|
|
int SrcValue = 0;
|
int i = 0;
|
int j;
|
|
// if(rectExpRegion.left != -1)
|
// {
|
// m_Log.DisplayEdgeLog(" BinalizeFind_CornerChip rectExpRegion %d %d %d %d",rectExpRegion.left,rectExpRegion.top,rectExpRegion.right,rectExpRegion.bottom);
|
// m_Log.DisplayEdgeLog(" BinalizeFind_CornerChip sy %d ey %d sx %d ex %d",sy,ey,sx,ex);
|
// }
|
|
//0~pitch °Å¸®±îÁö
|
// if(s_RegionType == CHIPREGTYPE_RIGHT)
|
// {
|
for( j = sy; j < ey; j++)
|
{
|
for( i = sx; i < ex; i++)
|
{
|
if(j>=rectExpRegion.top && j<=rectExpRegion.bottom && i>=rectExpRegion.left && i<=rectExpRegion.right)
|
{
|
// // bSaveImage = TRUE;
|
// // pSaveImg.SetPixel(i,j,0);
|
continue;
|
}
|
|
SrcValue = *pImg.GetDataAddress(i,j);
|
if (SrcValue < Threshold)
|
{
|
if(!InsertPairing(i,j,SrcValue,Threshold,SrcValue, SrcValue,s_RegionType,INS_DEFECT_CHIP))
|
return;
|
// if(bSaveImage)
|
// {
|
// pSaveImg.SetPixel(i,j,0);
|
// }
|
}
|
}
|
}
|
// }
|
// else
|
// {
|
// for( j = sy; j < ey; j++)
|
// {
|
// for( i = sx; i < ex; i++)
|
// {
|
// SrcValue = *pImg.GetDataAddress(i,j);
|
// if (SrcValue < Threshold)
|
// {
|
// if(!InsertPairing(vecPair,i,j,SrcValue,Threshold,SrcValue, SrcValue,s_RegionType))
|
// return;
|
// // if(bSaveImage)
|
// // {
|
// // pSaveImg.SetPixel(i,j,0);
|
// // }
|
// }
|
// }
|
// }
|
// }
|
|
if(bSaveImage)
|
{
|
CString strFileName;
|
CString strFolderName;
|
CString strPath;
|
strFileName.Format(_T("Straight_%d_%d_%d_%d_%d_PCnt[%d].bmp"), nCamID,iScan, iFrame, nIndex,s_RegionType,(int)vecPair.size());
|
strFolderName.Format(_T("D:\\%s"), strHpanelID);
|
CreateDirectory(strFolderName,NULL);
|
strPath.Format(_T("%s\\%s"),strFolderName,strFileName);
|
CBufferAttach attach(strPath);
|
attach.AttachToFile(pSaveImg);
|
}
|
}
|
|
void CChamferInspect::BinalizeFind_CornerChip_White(CSISBuffer &pSaveImg,BOOL bSaveImage,CString strHpanelID, CSISBuffer &pImg,int nThres,std::vector<CChipPair> &vecPair,ChipResionType s_RegionType,int nSetPitch, CRect rectInsOrg,int nGlassStartLine,int nGlassEndLine, int nFrameHeight,int nCPosXOffset, int nDPosXOffset, int nCPosYOffsetStart, int nCPosYOffsetEnd, int nDPosYOffsetStart, int nDPosYOffsetEnd, CRect rectExpRegion, int iFrame, int nIndex, int nCamID, int iScan)
|
{
|
int sx, ex, sy, ey;
|
|
//sx= RICHT_WHITECHIP_OFFSET;//C¸é ±âÁØ
|
sy= 0;
|
ex= pImg.GetWidth();
|
ey= pImg.GetHeight();
|
|
// int nStartOffset_Y = 260;
|
// int nEndOffset_Y = 0;
|
//
|
// if(iScan == 1)
|
// nEndOffset_Y = 18610;
|
// else if(iScan == 2)
|
// nEndOffset_Y = 29679;
|
|
int nStartOffset_Y,nEndOffset_Y;
|
|
nStartOffset_Y = nEndOffset_Y = 0;
|
if(iScan == 3)//C¸é
|
{
|
sx = nCPosXOffset;
|
nStartOffset_Y = nCPosYOffsetStart;
|
nEndOffset_Y = nCPosYOffsetEnd;
|
}
|
else if(iScan == 2)//D¸é
|
{
|
sx = nDPosXOffset;
|
nStartOffset_Y = nDPosYOffsetEnd;
|
nEndOffset_Y = nDPosYOffsetStart;
|
}
|
|
if(rectInsOrg.top<(nGlassStartLine+nStartOffset_Y))
|
sy=nGlassStartLine+nStartOffset_Y - rectInsOrg.top;
|
|
if(rectInsOrg.bottom > (nGlassStartLine+nEndOffset_Y))
|
ey=ey-(rectInsOrg.bottom-(nGlassStartLine+nEndOffset_Y));
|
|
//m_Log.DisplayEdgeLog(" iFrame %d nIndex %d nCamID %d iScans %d sx %d ex %d sy %d ey %d left %d top %d right %d bottom %d nGlassStartLine %d nGlassEndLine %d nStartOffset_Y %d nEndOffset_Y %d",iFrame, nIndex, nCamID, iScan, sx, ex, sy, ey,rectInsOrg.left,rectInsOrg.top,rectInsOrg.right,rectInsOrg.bottom,nGlassStartLine,nGlassEndLine,nStartOffset_Y,nEndOffset_Y);
|
|
int Threshold = nThres;//*(nConvWidth*nConvHeight);
|
|
int SrcValue = 0;
|
int i = 0;
|
int j;
|
|
// if(rectExpRegion.left != -1)
|
// {
|
// m_Log.DisplayEdgeLog(" BinalizeFind_CornerChip_White rectExpRegion %d %d %d %d",rectExpRegion.left,rectExpRegion.top,rectExpRegion.right,rectExpRegion.bottom);
|
// m_Log.DisplayEdgeLog(" BinalizeFind_CornerChip_White sy %d ey %d sx %d ex %d",sy,ey,sx,ex);
|
// }
|
|
//0~pitch °Å¸®±îÁö
|
// if(s_RegionType == CHIPREGTYPE_RIGHT)
|
// {
|
for( j = sy; j < ey; j++)
|
{
|
for( i = sx; i < ex; i++)
|
{
|
if(j>=rectExpRegion.top && j<=rectExpRegion.bottom && i>=rectExpRegion.left && i<=rectExpRegion.right)
|
{
|
// bSaveImage = TRUE;
|
// pSaveImg.SetPixel(i,j,0);
|
continue;
|
}
|
|
SrcValue = *pImg.GetDataAddress(i,j);
|
if (SrcValue > Threshold)
|
{
|
if(!InsertPairing(i,j,Threshold-SrcValue,Threshold,SrcValue, SrcValue,s_RegionType,INS_DEFECT_CHIP))
|
return;
|
// if(bSaveImage)
|
// {
|
// pSaveImg.SetPixel(i,j,0);
|
// }
|
}
|
}
|
}
|
// }
|
// else
|
// {
|
// for( j = sy; j < ey; j++)
|
// {
|
// for( i = sx; i < ex; i++)
|
// {
|
// SrcValue = *pImg.GetDataAddress(i,j);
|
// if (SrcValue < Threshold)
|
// {
|
// if(!InsertPairing(vecPair,i,j,SrcValue,Threshold,SrcValue, SrcValue,s_RegionType))
|
// return;
|
// // if(bSaveImage)
|
// // {
|
// // pSaveImg.SetPixel(i,j,0);
|
// // }
|
// }
|
// }
|
// }
|
// }
|
|
|
if(bSaveImage)
|
{
|
CString strFileName;
|
CString strFolderName;
|
CString strPath;
|
|
strFileName.Format(_T("Straight_White_%d_%d_%d_%d_%d.bmp"), nCamID,iScan, iFrame, nIndex,s_RegionType);
|
strFolderName.Format(_T("D:\\Image\\Corner\\%s"), strHpanelID);
|
CreateDirectory(strFolderName,NULL);
|
strPath.Format(_T("%s\\%s"),strFolderName,strFileName);
|
CBufferAttach attach(strPath);
|
attach.AttachToFile(pSaveImg);
|
}
|
}
|
|
BOOL CChamferInspect::FilteringEdgeBlob_TypeFilter(std::vector<CChipBlob> &vecBlob,ChipResionType emSide,int nBaseLine,int nDetMargin)
|
{
|
std::vector<CChipBlob> vecTmp;
|
std::vector<CChipBlob>::iterator it;
|
|
for(it=vecBlob.begin();it!=vecBlob.end();it++)
|
{
|
if(emSide == CHIPREGTYPE_LEFT)
|
{
|
if(abs(it->s_DefectRect.right-nBaseLine) > nDetMargin)
|
continue;
|
}
|
else if(emSide == CHIPREGTYPE_RIGHT)
|
{
|
if(abs(it->s_DefectRect.left-nBaseLine) > nDetMargin)
|
continue;
|
}
|
|
vecTmp.push_back(*it);
|
}
|
|
vecBlob.clear();
|
for(it=vecTmp.begin();it!=vecTmp.end();it++)
|
vecBlob.push_back(*it);
|
|
return TRUE;
|
}
|
|
void CChamferInspect::VConvolutionConvC_CornerChip(CSISBuffer &pSaveImg,BOOL bSaveImage,CString strHpanelID, CSISBuffer &pImg,int nThres,std::vector<CChipPair> &vecPair,ChipResionType s_RegionType,int nSetPitch,int iFrame, int nIndex, int nCamID, int iScan)
|
{
|
int sx, ex, sy, ey;
|
sx= sy = 0;
|
ex= pImg.GetWidth();
|
ey= pImg.GetHeight();
|
|
|
int nConvWidth = 1;
|
int nConvHeight = 1;
|
|
if(ey < nSetPitch*4 || ex <= nConvWidth)
|
return;
|
|
nSetPitch = pImg.GetHeight() / 4;
|
int nPitch = nSetPitch;
|
|
int Threshold = nThres*(nConvWidth*nConvHeight);
|
int NegThres = Threshold*-1;
|
|
int n2Pitch = nSetPitch*2;
|
|
int SrcValue = 0;
|
int DestValue = 0;
|
int DestValue1 = 0;
|
int DestValue2 = 0;
|
int SubValue = 0;
|
int i = 0;
|
int SubValue2Pitch;
|
int j;
|
|
BOOL bDefect = FALSE;
|
|
//0~pitch °Å¸®±îÁö
|
for( j = sy; j < ey-n2Pitch; j++)
|
{
|
if(j+nPitch >= ey || j+n2Pitch >= ey)
|
continue;
|
|
for( i = sx; i < ex; i++)
|
{
|
SrcValue = *pImg.GetDataAddress(i,j);
|
DestValue1 = *pImg.GetDataAddress(i,j+nPitch);
|
DestValue2 = *pImg.GetDataAddress(i,j+n2Pitch);
|
|
SubValue = DestValue1 - SrcValue;
|
SubValue2Pitch = DestValue2 - SrcValue;
|
|
if ((SubValue > Threshold && SubValue2Pitch > Threshold) ||
|
(SubValue < NegThres && SubValue2Pitch < NegThres))
|
//if ((SubValue > Threshold && SubValue2Pitch > Threshold))
|
{
|
|
if(!InsertPairing(i,j,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,Threshold,SrcValue, DestValue2,s_RegionType,INS_DEFECT_CHIP))
|
return;
|
if(bSaveImage)
|
{
|
if(s_RegionType == CHIPREGTYPE_RIGHT)
|
pSaveImg.SetPixel(i,j,0);
|
else
|
pSaveImg.SetPixel(i,j,1);
|
}
|
bDefect = TRUE;
|
}
|
}
|
}
|
|
//0~pitch °Å¸®±îÁö
|
for( j = ey-1; j >= ey-n2Pitch; j--)
|
{
|
if(j-nPitch < 0 || j-n2Pitch < 0)
|
continue;
|
|
for( i = sx; i < ex; i++)
|
{
|
SrcValue = *pImg.GetDataAddress(i,j);
|
DestValue1 = *pImg.GetDataAddress(i,j-nPitch);
|
DestValue2 = *pImg.GetDataAddress(i,j-n2Pitch);
|
|
SubValue = DestValue1 - SrcValue;
|
SubValue2Pitch = DestValue2 - SrcValue;
|
|
if ((SubValue > Threshold && SubValue2Pitch > Threshold) ||
|
(SubValue < NegThres && SubValue2Pitch < NegThres))
|
//if ((SubValue > Threshold && SubValue2Pitch > Threshold))
|
{
|
|
if(!InsertPairing(i,j,abs(SubValue)>abs(SubValue2Pitch)?SubValue:SubValue2Pitch,Threshold,SrcValue, DestValue2,s_RegionType,INS_DEFECT_CHIP))
|
return;
|
if(bSaveImage)
|
{
|
if(s_RegionType == CHIPREGTYPE_RIGHT)
|
pSaveImg.SetPixel(i,j,0);
|
else
|
pSaveImg.SetPixel(i,j,1);
|
}
|
bDefect = TRUE;
|
}
|
}
|
}
|
if(bSaveImage && bDefect)
|
{
|
CString strFileName;
|
CString strFolderName;
|
CString strPath;
|
|
strFileName.Format(_T("Straight_%d_%d_%d_%d_%d.bmp"), nCamID,iScan, iFrame, nIndex,s_RegionType);
|
strFolderName.Format(_T("%s\\%s"),PATH_DEFECTFOLDER, strHpanelID);
|
CreateDirectory(strFolderName,NULL);
|
strPath.Format(_T("%s\\%s"),strFolderName,strFileName);
|
CBufferAttach attach(strPath);
|
attach.AttachToFile(pSaveImg);
|
}
|
}
|
|
BOOL CChamferInspect::OnlyChipInspection(int nMergeRange,BOOL bSaveImage,CString strHpanelID, int nCamID, int iScan,int iFrame, int nIndex,CSISBuffer &ChipBuffer,int nChipThres
|
, int nChipThres_L,int nChipInsWidth,int nEdgeLeft,int nEdgeRight, CRect rectInsOrg, int nGlassStartLine,int nGlassEndLine, int nFrameHeight
|
, int nCPosXOffset, int nDPosXOffset, int nCPosYOffsetStart, int nCPosYOffsetEnd, int nDPosYOffsetStart, int nDPosYOffsetEnd, int nDetMargin
|
, int nChippingInsOffset, double dFindLeft,int nAirThres)
|
{
|
if(ChipBuffer.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
CRect rectIns, rectInsLeft, rectInsRight_White;
|
CString strImg;
|
|
nChipInsWidth= nChipInsWidth- nChipInsWidth%4;
|
if(nChipInsWidth <= 0)
|
return FALSE;
|
|
// strImg.Format("D:\\Image\\CutArea\\ChipInsOrg.bmp");
|
// CBufferAttach attachOrg(strImg);
|
// attachOrg.AttachToFile(ChipBuffer);
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : MakeChipImage Right",m_nCurCamId,m_nCurScanIdx);
|
|
COwnerBuffer InsRightBuffer, InsLeftBuffer,InsRightSaveBuffer, InsLeftSaveBuffer;
|
COwnerBuffer InsRightSaveBuffer_White;
|
InsRightBuffer.SetSize(nChipInsWidth,ChipBuffer.GetHeight());
|
InsLeftBuffer.SetSize(nChipInsWidth,ChipBuffer.GetHeight());
|
InsRightSaveBuffer.SetSize(nChipInsWidth,ChipBuffer.GetHeight());
|
InsLeftSaveBuffer.SetSize(nChipInsWidth,ChipBuffer.GetHeight());
|
InsRightSaveBuffer_White.SetSize(nChipInsWidth,ChipBuffer.GetHeight());
|
|
if(InsRightBuffer.IsValidBuffer() == FALSE)
|
return FALSE;
|
if(InsLeftBuffer.IsValidBuffer() == FALSE)
|
return FALSE;
|
if(InsRightSaveBuffer.IsValidBuffer() == FALSE)
|
return FALSE;
|
if(InsLeftSaveBuffer.IsValidBuffer() == FALSE)
|
return FALSE;
|
if(InsRightSaveBuffer_White.IsValidBuffer() == FALSE)
|
return FALSE;
|
|
rectIns = CRect(nEdgeRight,0,nEdgeRight+nChipInsWidth,ChipBuffer.GetHeight());
|
|
if(rectIns.left < 0) rectIns.left = 0;
|
if(rectIns.right >= ChipBuffer.GetWidth()) rectIns.right = ChipBuffer.GetWidth()-1;
|
if(rectIns.Width() <= 0 || rectIns.Height() <= 0 || rectIns.top > rectIns.bottom)
|
return FALSE;
|
CSISBuffer::CopyBtoA(InsRightBuffer,0,0,ChipBuffer,rectIns);
|
CSISBuffer::CopyBtoA(InsRightSaveBuffer,0,0,ChipBuffer,rectIns);
|
|
//nBaseRight = rectIns.left;
|
|
rectInsLeft = CRect(nEdgeLeft- nChipInsWidth,0,nEdgeLeft,ChipBuffer.GetHeight());
|
|
if(rectInsLeft.left < 0) rectInsLeft.left = 0;
|
if(rectInsLeft.right >= ChipBuffer.GetWidth()) rectInsLeft.right = ChipBuffer.GetWidth()-1;
|
if(rectInsLeft.Width() <= 0 || rectInsLeft.Height() <= 0 || rectInsLeft.top > rectInsLeft.bottom)
|
return FALSE;
|
CSISBuffer::CopyBtoA(InsLeftBuffer,0,0,ChipBuffer,rectInsLeft);
|
CSISBuffer::CopyBtoA(InsLeftSaveBuffer,0,0,ChipBuffer,rectInsLeft);
|
|
rectInsRight_White = CRect(nEdgeRight,0,nEdgeRight+nChipInsWidth,ChipBuffer.GetHeight());
|
|
if(rectInsRight_White.left < 0) rectInsRight_White.left = 0;
|
if(rectInsRight_White.right >= ChipBuffer.GetWidth()) rectInsRight_White.right = ChipBuffer.GetWidth()-1;
|
if(rectInsRight_White.Width() <= 0 || rectInsRight_White.Height() <= 0 || rectInsRight_White.top > rectInsRight_White.bottom)
|
return FALSE;
|
CSISBuffer::CopyBtoA(InsRightSaveBuffer_White,0,0,ChipBuffer,rectInsRight_White);
|
|
//nBaseLeft = rectInsLeft.left;
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : MakeChipImage Right end[%d,%d]",m_nCurCamId,m_nCurScanIdx,InsRightBuffer.GetWidth(),InsRightBuffer.GetHeight());
|
|
//CopyBuffer(InsRightBuffer,pChipRight);
|
|
/*strImg.Format("D:\\Image\\CutArea\\ChipInsRight.bmp");
|
CBufferAttach attachPre(strImg);
|
attachPre.AttachToFile(InsBuffer);
|
|
strImg.Format("D:\\Image\\CutArea\\ChipInsLeft.bmp");
|
CBufferAttach attachLeft(strImg);
|
attachLeft.AttachToFile(InsLeftBuffer); */
|
|
std::vector<CChipPair> vecPair;
|
std::vector<CChipBlob> blobRight,blobLeft;
|
std::vector<CChipBlob> blobRight_White;
|
|
CRect rectExpRegion;
|
GetCutAreaExpPos(rectInsOrg,nEdgeLeft,nGlassStartLine, rectExpRegion,nChipInsWidth, dFindLeft);
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : Inspection Right",m_nCurCamId,m_nCurScanIdx);
|
#define FINDDEFECT_METHOD_BINALIZE
|
//#undef FINDDEFECT_METHOD_BINALIZE
|
#ifdef FINDDEFECT_METHOD_BINALIZE
|
BinalizeFind_CornerChip(InsRightSaveBuffer,bSaveImage,strHpanelID, InsRightBuffer,nChipThres,vecPair,CHIPREGTYPE_RIGHT,CHIP_INS_PITCH,rectExpRegion,iFrame, nIndex, nCamID, iScan, nChippingInsOffset);
|
#else
|
VConvolutionConvC_CornerChip(InsRightSaveBuffer,bSaveImage,strHpanelID, InsRightBuffer,nChipThres,vecPair,CHIPREGTYPE_RIGHT,CHIP_INS_PITCH,iFrame, nIndex, nCamID, iScan);
|
#endif
|
BlobDefect_Pixel_TypeRegionFilter(blobRight,vecPair,nChipThres,nMergeRange);
|
|
// if(bSaveImage)
|
// {
|
// CString strFileName;
|
// CString strFolderName;
|
// CString strPath;
|
// strFileName.Format("Straight_%d_%d_%d_%d_BCnt_Pre[%d].bmp", nCamID,iScan, iFrame, nIndex,(int)blobRight.size());
|
// strFolderName.Format("D:\\%s", strHpanelID);
|
// CreateDirectory(strFolderName,NULL);
|
// strPath.Format("%s\\%s",strFolderName,strFileName);
|
// CBufferAttach attach(strPath);
|
// attach.AttachToFile(InsRightSaveBuffer);
|
// }
|
//
|
FilteringEdgeBlob_TypeFilter(blobRight,CHIPREGTYPE_RIGHT,0,nDetMargin);//¸ð¸£°Ú´Ù.
|
//
|
// if(bSaveImage)
|
// {
|
// CString strFileName;
|
// CString strFolderName;
|
// CString strPath;
|
// strFileName.Format("Straight_%d_%d_%d_%d_BCnt[%d].bmp", nCamID,iScan, iFrame, nIndex,(int)blobRight.size());
|
// strFolderName.Format("D:\\%s", strHpanelID);
|
// CreateDirectory(strFolderName,NULL);
|
// strPath.Format("%s\\%s",strFolderName,strFileName);
|
// CBufferAttach attach(strPath);
|
// attach.AttachToFile(InsRightSaveBuffer);
|
// }
|
vecPair.clear();
|
|
#ifdef FINDDEFECT_METHOD_BINALIZE
|
BinalizeFind_CornerChip(InsLeftSaveBuffer,bSaveImage,strHpanelID, InsLeftBuffer,nChipThres_L,vecPair,CHIPREGTYPE_LEFT,CHIP_INS_PITCH,rectExpRegion,iFrame, nIndex, nCamID, iScan);
|
#else
|
VConvolutionConvC_CornerChip(InsLeftSaveBuffer,bSaveImage,strHpanelID, InsLeftBuffer,nChipThres_L,vecPair,CHIPREGTYPE_LEFT,CHIP_INS_PITCH,iFrame, nIndex, nCamID, iScan);
|
#endif
|
BlobDefect_Pixel_TypeRegionFilter(blobLeft,vecPair,nChipThres_L,nMergeRange);
|
FilteringEdgeBlob_TypeFilter(blobLeft,CHIPREGTYPE_LEFT,rectInsLeft.right-rectInsLeft.left,nDetMargin);
|
vecPair.clear();
|
|
#define RICHT_WHITECHIP_OFFSET 28
|
if(nCamID == 0 && (iScan == 2 || iScan == 3))
|
{
|
int nChipThres_White = nAirThres;
|
BinalizeFind_CornerChip_White(InsRightSaveBuffer_White,bSaveImage,strHpanelID, InsRightBuffer,nAirThres,vecPair,CHIPREGTYPE_RIGHT_WHITE,CHIP_INS_PITCH,rectInsOrg,nGlassStartLine,nGlassEndLine,nFrameHeight, nCPosXOffset, nDPosXOffset, nCPosYOffsetStart, nCPosYOffsetEnd, nDPosYOffsetStart, nDPosYOffsetEnd, rectExpRegion, iFrame, nIndex, nCamID, iScan);
|
BlobDefect_Pixel_TypeRegionFilter(blobRight_White,vecPair,nAirThres,nMergeRange);
|
//FilteringEdgeBlob_TypeFilter(blobRight_White,CHIPREGTYPE_RIGHT,rectInsRight_White.left+RICHT_WHITECHIP_OFFSET,nDetMargin);
|
}
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : Inspection Right End",m_nCurCamId,m_nCurScanIdx);
|
|
std::vector<CChipBlob>::iterator itBlob;
|
|
ReleaseChipBuffer();
|
|
for(itBlob=blobRight.begin();itBlob!=blobRight.end();itBlob++)
|
{
|
if(m_nDefectCnt >= MAX_CHIP_DEFECT_COUNT)
|
return FALSE;
|
|
CChipBlob *pBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pBlob == NULL)
|
continue;
|
|
*pBlob = *itBlob;
|
|
pBlob->s_DefectRect.OffsetRect(rectIns.left,0);
|
|
pBlob->s_nDefectX += rectIns.left;
|
|
m_nDefectCnt++;
|
}
|
blobRight.clear();
|
|
for(itBlob=blobLeft.begin();itBlob!=blobLeft.end();itBlob++)
|
{
|
if(m_nDefectCnt >= MAX_CHIP_DEFECT_COUNT)
|
return FALSE;
|
|
CChipBlob *pBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pBlob == NULL)
|
continue;
|
|
*pBlob = *itBlob;
|
|
pBlob->s_DefectRect.OffsetRect(rectInsLeft.left,0);
|
pBlob->s_nDefectX += rectInsLeft.left;
|
|
m_nDefectCnt++;
|
}
|
blobLeft.clear();
|
|
for(itBlob=blobRight_White.begin();itBlob!=blobRight_White.end();itBlob++)
|
{
|
if(m_nDefectCnt >= MAX_CHIP_DEFECT_COUNT)
|
return FALSE;
|
|
CChipBlob *pBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pBlob == NULL)
|
continue;
|
|
*pBlob = *itBlob;
|
|
pBlob->s_DefectRect.OffsetRect(rectInsRight_White.left,0);
|
|
pBlob->s_nDefectX += rectInsRight_White.left;
|
|
m_nDefectCnt++;
|
}
|
blobRight_White.clear();
|
|
//m_Log.DisplayEdgeLog("Cam[%d] Scan[%d] Glass ChipInspection : End",m_nCurCamId,m_nCurScanIdx);
|
|
return TRUE;
|
}
|
|
void CChamferInspect::SetBrokenDefect(CRect rectDefect)
|
{
|
CChipBlob *pChipBlob = &m_DefectBlob[m_nDefectCnt];
|
if(pChipBlob != NULL)
|
{
|
pChipBlob->s_nDefectX = rectDefect.CenterPoint().x;
|
pChipBlob->s_nDefectY = rectDefect.CenterPoint().y;
|
pChipBlob->s_DefectType = CHIPDEFTYPE_BLACK;
|
pChipBlob->s_dThick = rectDefect.Width();
|
pChipBlob->s_nDefectArea = rectDefect.Width()*rectDefect.Height();
|
pChipBlob->s_nDefectRScale = rectDefect.Width()*rectDefect.Height();
|
pChipBlob->s_DefectRect = rectDefect;
|
|
m_nDefectCnt++;
|
}
|
}
|
|
ChipErrCode CChamferInspect::Inspection_OnlyChip(int nMergeRange,BOOL bSaveImage,CString strHpanelID, int nCamID, int iScan,int iFrame
|
, int nIndex,CRect &rectIns,CSISBuffer &ChipBuffer,int nChipInsWidth,int nChipThres, int nChipThres_L
|
,BOOL bChipIns, int nDetMargin, double dLeftThres, CRect rectInsOrg
|
, int nGlassStartLine,int nGlassEndLine, int nFrameHeight,int nCPosXOffset, int nDPosXOffset, int nCPosYOffsetStart
|
, int nCPosYOffsetEnd, int nDPosYOffsetStart, int nDPosYOffsetEnd, int nChippingInsOffset, double dFindLeft, int nAirThres)
|
{
|
ResetValue();
|
|
//¿ÞÂÊ ¿§Áö¸¦ ã´Â´Ù.
|
CRect EdgeRect;
|
EdgeRect = rectIns;
|
|
int nForecast_S,nForecast_E;
|
CEdgeFind EdgeFind;
|
int nDist = rectIns.Width()/10;
|
|
if(nDist < 5)
|
nDist = 5;
|
|
nForecast_S = rectIns.CenterPoint().x;
|
double dLeft = EdgeFind.FindGlassHorizontalLine(ChipBuffer.GetDataAddress(),CSize(rectIns.Width(),rectIns.Height()),EdgeRect,(int)dLeftThres,TRUE, nDist);
|
if(dLeft > 0)
|
nForecast_S = (int)dLeft;
|
|
double dLeftEdge,dRightEdge;
|
|
dRightEdge = nForecast_S;
|
|
nForecast_E = (int)dRightEdge;
|
dLeftEdge = dRightEdge;
|
m_nForeEdgeLine[0] = nForecast_S;
|
m_nForeEdgeLine[1] = nForecast_E;
|
|
if(nForecast_S <= 0)
|
{
|
SetBrokenDefect(rectIns);
|
ReleaseBuffer();
|
return ERR_CHIP_FIND_RIGHTLINE;
|
}
|
|
m_nForeEdgeLine[0] = (int)dLeftEdge;
|
m_nForeEdgeLine[1] = (int)dRightEdge;
|
|
if(m_nForeEdgeLine[0]-nChipInsWidth < 0)
|
{
|
m_nForeEdgeLine[0] = nChipInsWidth+1;
|
}
|
|
if(m_nForeEdgeLine[1]+nChipInsWidth >= ChipBuffer.GetWidth())
|
{
|
m_nForeEdgeLine[1] = ChipBuffer.GetWidth()-nChipInsWidth-1;
|
}
|
|
if(m_nForeEdgeLine[0] <= 0 || m_nForeEdgeLine[1] <= 0)
|
{
|
SetBrokenDefect(rectIns);
|
ReleaseBuffer();
|
return ERR_CHIP_CHECK_CHIPRECT;
|
}
|
|
if(bChipIns == TRUE)
|
{
|
OnlyChipInspection(nMergeRange,bSaveImage,strHpanelID, nCamID,iScan,iFrame, nIndex,ChipBuffer,nChipThres, nChipThres_L,nChipInsWidth
|
,m_nForeEdgeLine[0],m_nForeEdgeLine[1],rectInsOrg,nGlassStartLine,nGlassEndLine,nFrameHeight, nCPosXOffset, nDPosXOffset, nCPosYOffsetStart, nCPosYOffsetEnd
|
, nDPosYOffsetStart, nDPosYOffsetEnd,nDetMargin,nChippingInsOffset,dFindLeft,nAirThres);
|
}
|
|
return ERR_CHIP_SUCCESS;
|
}
|
|
BOOL CChamferInspect::Binarization_OpenCV( CSISBuffer* pOriginImg, COwnerBuffer* pBinImage, CRect rtInsRect, int nThresholdLow, int nThresholdHigh )
|
{
|
if(pOriginImg == NULL || pBinImage == NULL || pOriginImg->IsValidBuffer() == FALSE || rtInsRect.IsRectEmpty() || rtInsRect.IsRectNull())
|
return FALSE;
|
|
if (pOriginImg->GetWidth() == 0 || pOriginImg->GetHeight() == 0)
|
return FALSE;
|
|
pBinImage->ReleaseSpace();
|
|
pBinImage->SetSize(rtInsRect.Width(), rtInsRect.Height());
|
ZeroMemory(pBinImage->GetDataAddress(), pBinImage->GetSize());
|
|
IplImage* pOriginImage = cvCreateImage(cvSize(pBinImage->GetWidth(), pBinImage->GetHeight()), 8, 1);
|
|
for(int i=0; i<pBinImage->GetHeight(); i++)
|
{
|
int nX = rtInsRect.left;
|
int nY = rtInsRect.top + i;
|
memcpy(&pOriginImage->imageData[i*pOriginImage->widthStep], pOriginImg->GetDataAddress(nX,nY), pBinImage->GetWidth());
|
}
|
|
IplImage* pBinImage_Low = cvCreateImage(cvSize(pBinImage->GetWidth(), pBinImage->GetHeight()), 8, 1);
|
IplImage* pBinImage_Hight = cvCreateImage(cvSize(pBinImage->GetWidth(), pBinImage->GetHeight()), 8, 1);
|
|
cvZero(pBinImage_Low);
|
cvZero(pBinImage_Hight);
|
|
cvThreshold(pOriginImage, pBinImage_Low, (double) nThresholdLow, 255.0, CV_THRESH_BINARY_INV);
|
cvThreshold(pOriginImage, pBinImage_Hight, (double) nThresholdHigh, 255.0, CV_THRESH_BINARY);
|
|
for (int i = 0; i < rtInsRect.Height(); i++)
|
{
|
for (int j = 0; j < rtInsRect.Width(); j++)
|
{
|
if(pBinImage_Low->imageData[i*pBinImage_Low->widthStep + j] == 0 &&
|
pBinImage_Hight->imageData[i*pBinImage_Hight->widthStep + j] == 0)
|
continue;
|
|
pBinImage->SetPixel(j,i,255);
|
}
|
}
|
|
cvReleaseImage(&pBinImage_Low);
|
cvReleaseImage(&pBinImage_Hight);
|
cvReleaseImage(&pOriginImage);
|
|
return TRUE;
|
}
|
|
BOOL CChamferInspect::Binarization_OpenCV( CSISBuffer* pOriginImg, COwnerBuffer* pBinImage, CRect rtInsRect, int nThresholdLow, int nThresholdHigh, int nThresholdPitch, int nPitch ,int iFram, BOOL bSave)
|
{
|
if(pOriginImg == NULL || pBinImage == NULL || pOriginImg->IsValidBuffer() == FALSE || rtInsRect.IsRectEmpty() || rtInsRect.IsRectNull())
|
return FALSE;
|
|
if (pOriginImg->GetWidth() == 0 || pOriginImg->GetHeight() == 0)
|
return FALSE;
|
|
pBinImage->ReleaseSpace();
|
|
pBinImage->SetSize(rtInsRect.Width(), rtInsRect.Height());
|
ZeroMemory(pBinImage->GetDataAddress(), pBinImage->GetSize());
|
|
IplImage* pOriginImage = cvCreateImage(cvSize(pBinImage->GetWidth(), pBinImage->GetHeight()), 8, 1);
|
|
for(int i=0; i<pBinImage->GetHeight(); i++)
|
{
|
int nX = rtInsRect.left;
|
int nY = rtInsRect.top + i;
|
memcpy(&pOriginImage->imageData[i*pOriginImage->widthStep], pOriginImg->GetDataAddress(nX,nY), pBinImage->GetWidth());
|
}
|
|
IplImage* pBinImage_Low = cvCreateImage(cvSize(pBinImage->GetWidth(), pBinImage->GetHeight()), 8, 1);
|
IplImage* pBinImage_Hight = cvCreateImage(cvSize(pBinImage->GetWidth(), pBinImage->GetHeight()), 8, 1);
|
|
cvZero(pBinImage_Low);
|
cvZero(pBinImage_Hight);
|
|
if(nThresholdLow > 0 && nThresholdLow < 255)
|
{
|
cvThreshold(pOriginImage, pBinImage_Low, (double) nThresholdLow, 255.0, CV_THRESH_BINARY_INV);
|
|
CopyMemory(pBinImage->GetDataAddress(),pBinImage_Low->imageData,sizeof(BYTE)*pBinImage_Low->width*pBinImage_Low->height);
|
}
|
if(nThresholdHigh > 0 && nThresholdHigh < 255)
|
{
|
cvThreshold(pOriginImage, pBinImage_Hight, (double) nThresholdHigh, 255.0, CV_THRESH_BINARY_INV);
|
|
CopyMemory(pBinImage->GetDataAddress(),pBinImage_Hight->imageData,sizeof(BYTE)*pBinImage_Hight->width*pBinImage_Hight->height);
|
}
|
|
if(bSave == TRUE)
|
{
|
CString str;
|
str.Format(_T("%s\\%03d_%03d_ChipBinLow.bmp"),PATH_DEBUGFOLDER,iFram,m_nSaveIndex);
|
|
COwnerBuffer binBuffer(pBinImage_Low->width,pBinImage_Low->height);
|
CopyMemory(binBuffer.GetDataAddress(),pBinImage_Low->imageData,sizeof(BYTE)*pBinImage_Low->width*pBinImage_Low->height);
|
|
CBufferAttach attach(str);
|
attach.AttachToFile(binBuffer);
|
|
COwnerBuffer binBufferHigh(pBinImage_Hight->width,pBinImage_Hight->height);
|
CopyMemory(binBuffer.GetDataAddress(),pBinImage_Hight->imageData,sizeof(BYTE)*pBinImage_Hight->width*pBinImage_Hight->height);
|
|
str.Format(_T("%s\\%03d_%03d_ChipBinHigh.bmp"),PATH_DEBUGFOLDER,iFram,m_nSaveIndex);
|
CBufferAttach attach2(str);
|
attach2.AttachToFile(binBufferHigh);
|
}
|
|
cvReleaseImage(&pBinImage_Low);
|
cvReleaseImage(&pBinImage_Hight);
|
cvReleaseImage(&pOriginImage);
|
|
return TRUE;
|
}
|