#include "StdAfx.h"
|
#include "BlobStorage.h"
|
#include "math.h"
|
|
#include "StopWatch3.h"
|
|
|
|
|
CBlobStorage::CBlobStorage(void)
|
{
|
m_nBlobSpace= m_maxBlob= m_nBlob= 0;
|
m_pBlobDefect= NULL;
|
}
|
CBlobStorage::~CBlobStorage(void)
|
{
|
if(m_pBlobDefect)
|
delete[] m_pBlobDefect;
|
}
|
|
void CBlobStorage::ResetBlobStorage()
|
{
|
m_nSkipUnpaired = 0;
|
m_nSkipClassify = 0;
|
m_nMoveClassify = 0;
|
m_nSkipMerged = 0;
|
|
int i;
|
int nBlob;
|
|
if(m_nBlobSpace < m_nBlob)
|
nBlob= m_nBlobSpace;
|
else
|
nBlob= m_nBlob;
|
|
for(i= 0; i< nBlob; i++)
|
{
|
m_pBlobDefect[i].Reset();
|
}
|
m_nBlob= 0;
|
}
|
void CBlobStorage::TotalResetBlobStorage()
|
{
|
|
m_nSkipUnpaired = 0;
|
m_nSkipClassify = 0;
|
m_nMoveClassify = 0;
|
m_nSkipMerged = 0;
|
|
int i;
|
for(i= 0; i< m_maxBlob; i++)
|
{
|
m_pBlobDefect[i].Reset();
|
}
|
m_nBlob= 0;
|
}
|
|
|
int CBlobStorage::InitBlobStorage(int maxBlob)
|
{
|
if(maxBlob <= m_nBlobSpace)
|
{
|
m_maxBlob= maxBlob;
|
return m_maxBlob;
|
}
|
|
if(m_pBlobDefect != NULL)
|
{
|
delete[] m_pBlobDefect;
|
}
|
|
// 16°³ÀÇ ¿©ºÐÀ» µÐ´Ù..¿Ö? ³»¸É..
|
int BlobSapce= maxBlob+ 16;
|
m_pBlobDefect= new CDefectBlob[BlobSapce];
|
|
|
if(m_pBlobDefect == NULL)
|
{
|
m_maxBlob= m_nBlobSpace= 0;
|
return m_maxBlob;
|
}
|
|
|
m_maxBlob= m_nBlobSpace= maxBlob;
|
|
TotalResetBlobStorage();// ÃʱâÈ ½Ã°£ ´ÜÃàÀ» À§ÇØ TotalReset °è¿ ÇÔ¼ö Ãß°¡.
|
|
return m_maxBlob;
|
}
|
|
DIT_RESULT CBlobStorage::BlobDefectVert()
|
{
|
DIT_RESULT Ret = DIT_CONV_SUCCESS;
|
|
CStopWatch stopWatch;
|
stopWatch.Start();
|
int x, y;
|
|
|
// Index ¸Å±â±â.
|
ZeroMemory(m_bMerged, m_nPair * sizeof(BOOL));
|
ZeroMemory(m_bTemp, m_nPair * sizeof(BOOL));
|
for (x = 0; x < m_nPair; x++)
|
m_lFirstIndex[x] = x;
|
|
|
CDefectPair *pPair;
|
CDefectPair *pPairNext;
|
m_nSkipClassify= 0;
|
// ÀÎÁ¢ µðÆå ¸ÓÁöÇϱâ.
|
|
// 0. °áÇÔ Çȼ¿ ¹à±â ¿Ö°î º¸Á¤.
|
CPairStorage::CorrectDefGray();
|
// 1. Filtering Pairing to Delete.
|
CPairStorage::Filtering_Vert();
|
|
// 2. Áö¿ì°í ³²Àº Pairing Blob Index ¸¸µé±â.
|
int idx, idy;
|
for(x = 0; x < m_nPair; x++)
|
{
|
pPair= m_pPairDefect+ x;
|
if(pPair->s_DefectType == DEFTYPE_DELETE)
|
continue;
|
|
for (y = x + 1; y < m_nPair; y++)
|
{
|
pPairNext= m_pPairDefect+ y;
|
if(pPairNext->s_DefectType == DEFTYPE_DELETE)
|
continue;
|
|
if (m_bMerged[y] || (pPair->s_DefectType != pPairNext->s_DefectType))
|
continue;
|
|
idx= pPairNext->s_nDefectX- pPair->s_nDefectX;
|
idy= pPairNext->s_nDefectY- pPair->s_nDefectY;
|
|
if(idx > 16)
|
break;
|
|
if((idy > 3 || idy < -3)) //
|
continue;
|
if((idx > 3 || idx < -3)) //
|
continue;
|
|
|
m_lFirstIndex[y] = m_lFirstIndex[x];
|
m_bMerged[y] = TRUE;
|
}
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
int nStart = m_nBlob;
|
|
// µðÆåµéÀÇ ¼ö¸¸Å ó¸®. - Blobing
|
int nBlobNum = 0;
|
int nLevelDiff = 0;
|
|
CDefectBlob *pBlob= m_pBlobDefect+ m_nBlob;
|
CDefectBlob *pBlobNext;
|
for (x = 0; x < m_nPair; x++)
|
{
|
pPair= m_pPairDefect+ x;
|
if (pPair->s_DefectType == DEFTYPE_DELETE)
|
{
|
m_nSkipClassify++;
|
continue;
|
}
|
|
if (!m_bTemp[m_lFirstIndex[x]]) // óÀ½ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
if (m_nBlob >= m_maxBlob)
|
continue;
|
|
// 20150811 °Å´ë CS
|
//////////////////////////////////////////////////////////////////////////
|
//Junho °Å´ëCS
|
if(pPair->s_nZone != 0) // ZONEÀÌ ¾øÀ¸¸é °Å´ë CS´Â ÇÏÁö ¾Ê´Â´Ù.
|
{
|
if(m_Param.m_nCSThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_BLACK)
|
{
|
if(pPair->s_nGraySrc >= m_Param.m_nCSThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
if(m_Param.m_nOriThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_WHITE)
|
{
|
nLevelDiff = static_cast<int>(pPair->s_nGraySrc - pPair->s_nGrayRef);
|
if(nLevelDiff < m_Param.m_nOriThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
}
|
//////////////////////////////////////////////////////////////////////////
|
|
m_bTemp[m_lFirstIndex[x]] = TRUE;
|
|
pBlob->CreateBlob(pPair, m_lFirstIndex[x]);
|
|
|
m_nBlob++;
|
nBlobNum++;
|
pBlob= m_pBlobDefect+ m_nBlob;
|
}
|
else // ³ªÁß¿¡ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
for(y = m_nBlob - 1; y >= 0; y--)
|
{
|
pBlobNext= m_pBlobDefect+ y;
|
if (pBlobNext->s_nIndex == m_lFirstIndex[x])
|
{
|
// 20150811 °Å´ë CS
|
//////////////////////////////////////////////////////////////////////////
|
//Junho °Å´ëCS
|
if(pPair->s_nZone != 0) // ZONEÀÌ ¾øÀ¸¸é °Å´ë CS´Â ÇÏÁö ¾Ê´Â´Ù.
|
{
|
if(m_Param.m_nCSThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_BLACK)
|
{
|
if(pPair->s_nGraySrc >= m_Param.m_nCSThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
if(m_Param.m_nOriThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_WHITE)
|
{
|
nLevelDiff = static_cast<int>(pPair->s_nGraySrc - pPair->s_nGrayRef);
|
if(nLevelDiff < m_Param.m_nOriThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
}
|
//////////////////////////////////////////////////////////////////////////
|
|
pBlobNext->IncludePair(pPair);
|
break;
|
}
|
}
|
}
|
}
|
|
// ÁÂÇ¥ º¸Á¤.
|
for (x = nStart; x < m_nBlob; x++)
|
{
|
pBlob= m_pBlobDefect+ x;
|
if (pBlob->s_nDefectArea > 0)
|
{
|
pBlob->s_nDefectX = pBlob->s_nDefectX / pBlob->s_nDefectArea;
|
pBlob->s_nDefectY = pBlob->s_nDefectY / pBlob->s_nDefectArea;
|
pBlob->s_sLevelSrcAvg = pBlob->s_nLevelSrcSum / pBlob->s_nDefectArea;
|
pBlob->s_sLevelRefAvg = pBlob->s_nLevelRefSum / pBlob->s_nDefectArea;
|
pBlob->s_sLevelDiffAvg = pBlob->s_nLevelDiffSum / pBlob->s_nDefectArea;
|
pBlob->s_sThresholdAvg = pBlob->s_nThresholdSum / pBlob->s_nDefectArea;
|
|
pBlob->s_nRegionType = m_Param.s_nRegionType;
|
pBlob->s_nDefectRScale = CalcRScale(pBlob->s_ptVertex);
|
}
|
else
|
pBlob->s_bRemoved = TRUE;
|
}
|
|
stopWatch.End();
|
m_BlobTime= stopWatch.GetDurationMilliSecond();
|
return Ret;
|
}
|
|
DIT_RESULT CBlobStorage::BlobDefectVert(CPairStorage *pPairStrg)
|
{
|
DIT_RESULT Ret = DIT_CONV_SUCCESS;
|
|
// °áÇÔ Çȼ¿ ¹à±â ¿Ö°î º¸Á¤.
|
pPairStrg->CorrectDefGray();
|
// PairDefect ÇÊÅ͸µÇϱâ.
|
pPairStrg->Filtering_Vert();
|
|
int x, y;
|
|
int nPair= m_nPair;
|
CDefectPair *pPairDefect= m_pPairDefect;
|
if(pPairStrg != NULL)
|
{
|
nPair= pPairStrg->m_nPair;
|
pPairDefect= pPairStrg->m_pPairDefect;
|
}
|
|
|
// Index ¸Å±â±â.
|
ZeroMemory(m_bMerged, nPair * sizeof(BOOL));
|
ZeroMemory(m_bTemp, nPair * sizeof(BOOL));
|
for (x = 0; x < nPair; x++)
|
m_lFirstIndex[x] = x;
|
|
|
CDefectPair *pPair;
|
CDefectPair *pPairNext;
|
m_nSkipClassify= 0;
|
// ÀÎÁ¢ µðÆå ¸ÓÁöÇϱâ.
|
|
|
int idx, idy;
|
for(x = 0; x < nPair; x++)
|
{
|
pPair= pPairDefect+ x;
|
if(pPair->s_DefectType == DEFTYPE_DELETE)
|
continue;
|
|
for (y = x + 1; y < nPair; y++)
|
{
|
pPairNext= pPairDefect+ y;
|
if(pPairNext->s_DefectType == DEFTYPE_DELETE)
|
continue;
|
|
if (m_bMerged[y] || pPair->s_DefectType != pPairNext->s_DefectType)
|
continue;
|
|
idx= pPairNext->s_nDefectX- pPair->s_nDefectX;
|
idy= pPairNext->s_nDefectY- pPair->s_nDefectY;
|
|
if(idx > 16)
|
break;
|
|
if((idy > 3 || idy < -3)) //
|
continue;
|
if((idx > 3 || idx < -3)) //
|
continue;
|
|
|
m_lFirstIndex[y] = m_lFirstIndex[x];
|
m_bMerged[y] = TRUE;
|
}
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
int nStart = m_nBlob;
|
|
// µðÆåµéÀÇ ¼ö¸¸Å ó¸®. - Blobing
|
int nBlobNum = 0;
|
int nLevelDiff = 0;
|
|
CDefectBlob *pBlob= m_pBlobDefect+ m_nBlob;
|
CDefectBlob *pBlobNext;
|
for (x = 0; x < nPair; x++)
|
{
|
pPair= pPairDefect+ x;
|
if (pPair->s_DefectType == DEFTYPE_DELETE)
|
{
|
m_nSkipClassify++;
|
continue;
|
}
|
|
if (!m_bTemp[m_lFirstIndex[x]]) // óÀ½ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
if (m_nBlob >= m_maxBlob)
|
continue;
|
|
// 20150811 °Å´ë CS
|
//////////////////////////////////////////////////////////////////////////
|
//Junho °Å´ëCS
|
if(pPair->s_nZone != 0) // ZONEÀÌ ¾øÀ¸¸é °Å´ë CS´Â ÇÏÁö ¾Ê´Â´Ù.
|
{
|
if(m_Param.m_nCSThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_BLACK)
|
{
|
if(pPair->s_nGraySrc >= m_Param.m_nCSThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
if(m_Param.m_nOriThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_WHITE)
|
{
|
nLevelDiff = static_cast<int>(pPair->s_nGraySrc - pPair->s_nGrayRef);
|
if(nLevelDiff < m_Param.m_nOriThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
}
|
//////////////////////////////////////////////////////////////////////////
|
|
m_bTemp[m_lFirstIndex[x]] = TRUE;
|
|
pBlob->CreateBlob(pPair, m_lFirstIndex[x]);
|
|
|
m_nBlob++;
|
nBlobNum++;
|
pBlob= m_pBlobDefect+ m_nBlob;
|
}
|
else // ³ªÁß¿¡ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
for(y = m_nBlob - 1; y >= 0; y--)
|
{
|
pBlobNext= m_pBlobDefect+ y;
|
if (pBlobNext->s_nIndex == m_lFirstIndex[x])
|
{
|
|
// 20150811 °Å´ë CS
|
//////////////////////////////////////////////////////////////////////////
|
//Junho °Å´ëCS
|
if(pPair->s_nZone != 0) // ZONEÀÌ ¾øÀ¸¸é °Å´ë CS´Â ÇÏÁö ¾Ê´Â´Ù.
|
{
|
if(m_Param.m_nCSThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_BLACK)
|
{
|
if(pPair->s_nGraySrc >= m_Param.m_nCSThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
if(m_Param.m_nOriThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_WHITE)
|
{
|
nLevelDiff = static_cast<int>(pPair->s_nGraySrc - pPair->s_nGrayRef);
|
if(nLevelDiff < m_Param.m_nOriThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
}
|
//////////////////////////////////////////////////////////////////////////
|
|
pBlobNext->IncludePair(pPair);
|
break;
|
}
|
}
|
}
|
}
|
|
// ÁÂÇ¥ º¸Á¤.
|
for (x = nStart; x < m_nBlob; x++)
|
{
|
pBlob= m_pBlobDefect+ x;
|
if (pBlob->s_nDefectArea > 0)
|
{
|
pBlob->s_nDefectX = pBlob->s_nDefectX / pBlob->s_nDefectArea;
|
pBlob->s_nDefectY = pBlob->s_nDefectY / pBlob->s_nDefectArea;
|
pBlob->s_sLevelSrcAvg = pBlob->s_nLevelSrcSum / pBlob->s_nDefectArea;
|
pBlob->s_sLevelRefAvg = pBlob->s_nLevelRefSum / pBlob->s_nDefectArea;
|
pBlob->s_sLevelDiffAvg = pBlob->s_nLevelDiffSum / pBlob->s_nDefectArea;
|
pBlob->s_sThresholdAvg = pBlob->s_nThresholdSum / pBlob->s_nDefectArea;
|
|
pBlob->s_nRegionType = m_Param.s_nRegionType;
|
pBlob->s_nDefectRScale = CalcRScale(pBlob->s_ptVertex);
|
}
|
else
|
pBlob->s_bRemoved = TRUE;
|
}
|
|
|
return Ret;
|
}
|
|
DIT_RESULT CBlobStorage::BlobDefect()
|
{
|
DIT_RESULT Ret = DIT_CONV_SUCCESS;
|
|
int x, y;
|
|
// Index ¸Å±â±â.
|
ZeroMemory(m_bMerged, m_nPairSpace * sizeof(BOOL));
|
ZeroMemory(m_bTemp, m_nPairSpace * sizeof(BOOL));
|
for (x = 0; x < m_nPair; x++)
|
m_lFirstIndex[x] = x;
|
|
|
CDefectPair *pPair;
|
CDefectPair *pPairNext;
|
m_nSkipClassify= 0;
|
|
// °áÇÔ Çȼ¿ ¹à±â ¿Ö°î º¸Á¤.
|
CPairStorage::CorrectDefGray();
|
// PairDefect ÇÊÅ͸µÇϱâ.
|
CPairStorage::Filtering_Hori();
|
|
|
for(x = 0; x < m_nPair; x++)
|
{
|
pPair= m_pPairDefect+ x;
|
if(pPair->s_DefectType == DEFTYPE_DELETE)
|
continue;
|
|
for (y = x + 1; y < m_nPair; y++)
|
{
|
pPairNext= m_pPairDefect+ y;
|
if(pPairNext->s_DefectType == DEFTYPE_DELETE)
|
continue;
|
|
if (m_bMerged[y] || pPair->s_DefectType != pPairNext->s_DefectType)
|
continue;
|
|
if (pPairNext->s_nDefectY - pPair->s_nDefectY > 1) // y´Â xº¸´Ù Å©´Ù.
|
break;
|
|
if (pPairNext->s_nDefectX - pPair->s_nDefectX > 1
|
|| pPairNext->s_nDefectX - pPair->s_nDefectX < -1)
|
continue;
|
|
m_lFirstIndex[y] = m_lFirstIndex[x];
|
m_bMerged[y] = TRUE;
|
}
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
int nStart = m_nBlob;
|
|
// µðÆåµéÀÇ ¼ö¸¸Å ó¸®. - Blobing
|
int nBlobNum = 0;
|
int nLevelDiff = 0;
|
|
CDefectBlob *pBlob= m_pBlobDefect+ m_nBlob;
|
CDefectBlob *pBlobNext;
|
for (x = 0; x < m_nPair; x++)
|
{
|
pPair= m_pPairDefect+ x;
|
if (pPair->s_DefectType == DEFTYPE_DELETE)
|
{
|
m_nSkipClassify++;
|
continue;
|
}
|
|
if (!m_bTemp[m_lFirstIndex[x]]) // óÀ½ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
if (m_nBlob >= m_maxBlob)
|
continue;
|
|
// 20150811 °Å´ë CS
|
//////////////////////////////////////////////////////////////////////////
|
//Junho °Å´ëCS
|
if(pPair->s_nZone != 0) // ZONEÀÌ ¾øÀ¸¸é °Å´ë CS´Â ÇÏÁö ¾Ê´Â´Ù.
|
{
|
if(m_Param.m_nCSThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_BLACK)
|
{
|
if(pPair->s_nGraySrc >= m_Param.m_nCSThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
if(m_Param.m_nOriThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_WHITE)
|
{
|
nLevelDiff = static_cast<int>(pPair->s_nGraySrc - pPair->s_nGrayRef);
|
if(nLevelDiff < m_Param.m_nOriThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
}
|
//////////////////////////////////////////////////////////////////////////
|
m_bTemp[m_lFirstIndex[x]] = TRUE;
|
|
pBlob->CreateBlob(pPair, m_lFirstIndex[x]);
|
|
|
m_nBlob++;
|
nBlobNum++;
|
pBlob= m_pBlobDefect+ m_nBlob;
|
}
|
else // ³ªÁß¿¡ ³ªÅ¸³ °áÇÔ Ã³¸®.
|
{
|
for(y = m_nBlob - 1; y >= 0; y--)
|
{
|
pBlobNext= m_pBlobDefect+ y;
|
if (pBlobNext->s_nIndex != m_lFirstIndex[x])
|
continue;
|
|
// 20150811 °Å´ë CS
|
//////////////////////////////////////////////////////////////////////////
|
//Junho °Å´ëCS
|
if(pPair->s_nZone != 0) // ZONEÀÌ ¾øÀ¸¸é °Å´ë CS´Â ÇÏÁö ¾Ê´Â´Ù.
|
{
|
if(m_Param.m_nCSThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_BLACK)
|
{
|
if(pPair->s_nGraySrc >= m_Param.m_nCSThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
if(m_Param.m_nOriThres[pPair->s_nZone] != 0)
|
{
|
if(pPair->s_DefectType == DEFTYPE_WHITE)
|
{
|
nLevelDiff = static_cast<int>(pPair->s_nGraySrc - pPair->s_nGrayRef);
|
if(nLevelDiff < m_Param.m_nOriThres[pPair->s_nZone])
|
{
|
pPair->s_DefectType = DEFTYPE_DELETE;
|
m_nSkipClassify++;
|
continue;
|
}
|
}
|
}
|
}
|
//////////////////////////////////////////////////////////////////////////
|
|
pBlobNext->IncludePair(pPair);
|
|
break;
|
}
|
}
|
}
|
|
// ÁÂÇ¥ º¸Á¤.
|
for (x = nStart; x < m_nBlob; x++)
|
{
|
pBlob= m_pBlobDefect+ x;
|
if (pBlob->s_nDefectArea > 0)
|
{
|
pBlob->s_nDefectX = pBlob->s_nDefectX / pBlob->s_nDefectArea;
|
pBlob->s_nDefectY = pBlob->s_nDefectY / pBlob->s_nDefectArea;
|
pBlob->s_sLevelSrcAvg = pBlob->s_nLevelSrcSum / pBlob->s_nDefectArea;
|
pBlob->s_sLevelRefAvg = pBlob->s_nLevelRefSum / pBlob->s_nDefectArea;
|
pBlob->s_sLevelDiffAvg = pBlob->s_nLevelDiffSum / pBlob->s_nDefectArea;
|
pBlob->s_sThresholdAvg = pBlob->s_nThresholdSum / pBlob->s_nDefectArea;
|
|
pBlob->s_nRegionType = m_Param.s_nRegionType;
|
pBlob->s_nDefectRScale = CalcRScale(pBlob->s_ptVertex);
|
}
|
else
|
pBlob->s_bRemoved = TRUE;
|
}
|
|
|
return Ret;
|
}
|
|
void CBlobStorage::ShadowFilterVert(int nStart, double yPitch)
|
{
|
CDefectBlob *pBlob;
|
CDefectBlob *pBlobNext;
|
int x, y;
|
|
// Shadow Filtering : unpairÀÇ °æ¿ì... pitch °Ç³Ê¿¡ °áÇÔÀÌ ÀÖ´Ù¸é.. unpair¸¦ Á¦°Å ÇϰڴÙ.
|
CRect rect;
|
CPoint pt;
|
for (x= nStart; x < m_nBlob; x++)
|
{
|
pBlob= m_pBlobDefect+ x;
|
pt.x= pBlob->s_nDefectX;
|
|
if (pBlob->s_DefectPos == DEFPOS_LEFT)
|
{
|
pt.y= (LONG)(pBlob->s_nDefectY+ yPitch);
|
}else if(pBlob->s_DefectPos == DEFPOS_RIGHT)
|
{
|
pt.y= (LONG)(pBlob->s_nDefectY- yPitch);
|
}else
|
{
|
continue;
|
}
|
|
for (y = nStart; y < m_nBlob; y++)
|
{
|
if(x == y) continue;
|
pBlobNext= m_pBlobDefect+ y;
|
rect= pBlobNext->s_DefectRect;
|
rect.left -= 3;
|
rect.top -= 3;
|
rect.right += 3;
|
rect.bottom += 3;
|
if(rect.PtInRect(pt))
|
{
|
pBlob->s_bRemoved = TRUE;
|
break;
|
}
|
}
|
}
|
// ÀÌ°É ÀÌ·± ½ÄÀ¸·Î ÇØ¾ß Çϳª?? ¿ì¼±Àº... Ä«ÇÇÇÏ°í ³ªÁß¿¡ ¼öÁ¤
|
int i;
|
int nRemovedIdx = 0;
|
for (i = nStart; i < m_nBlob; i++)
|
{
|
if (!m_pBlobDefect[i].s_bRemoved)
|
{
|
m_pBlobDefect[nStart+ nRemovedIdx] = m_pBlobDefect[i];
|
nRemovedIdx++;
|
}
|
}
|
m_nBlob = nStart+ nRemovedIdx;
|
}
|
|
void CBlobStorage::ShadowFilter(int nStart, double xPitch)
|
{
|
CDefectBlob *pBlob;
|
CDefectBlob *pBlobNext;
|
int x, y;
|
|
|
// Shadow Filtering : unpairÀÇ °æ¿ì... pitch °Ç³Ê¿¡ °áÇÔÀÌ ÀÖ´Ù¸é.. unpair¸¦ Á¦°Å ÇϰڴÙ.
|
CRect rect;
|
CPoint pt;
|
for (x= nStart; x < m_nBlob; x++)
|
{
|
pBlob= m_pBlobDefect+ x;
|
pt.y= pBlob->s_nDefectY;
|
|
if (pBlob->s_DefectPos == DEFPOS_LEFT)
|
{
|
pt.x= (LONG)(pBlob->s_nDefectX+ xPitch);
|
}else if(pBlob->s_DefectPos == DEFPOS_RIGHT)
|
{
|
pt.x= (LONG)(pBlob->s_nDefectX- xPitch);
|
}else
|
{
|
continue;
|
}
|
|
for (y = nStart; y < m_nBlob; y++)
|
{
|
if(x == y) continue;
|
pBlobNext= m_pBlobDefect+ y;
|
rect= pBlobNext->s_DefectRect;
|
rect.left -= 3;
|
rect.top -= 3;
|
rect.right += 3;
|
rect.bottom += 3;
|
if(rect.PtInRect(pt))
|
{
|
pBlob->s_bRemoved = TRUE;
|
break;
|
}
|
}
|
}
|
// ÀÌ°É ÀÌ·± ½ÄÀ¸·Î ÇØ¾ß Çϳª?? ¿ì¼±Àº... Ä«ÇÇÇÏ°í ³ªÁß¿¡ ¼öÁ¤
|
int i;
|
int nRemovedIdx = 0;
|
for (i = nStart; i < m_nBlob; i++)
|
{
|
if (!m_pBlobDefect[i].s_bRemoved)
|
{
|
m_pBlobDefect[nStart+ nRemovedIdx] = m_pBlobDefect[i];
|
nRemovedIdx++;
|
}
|
}
|
m_nBlob = nStart+ nRemovedIdx;
|
}
|
|
|
DIT_RESULT CBlobStorage::MergeDivision(int nStart, int nMergePixel)
|
{
|
int i, j;
|
// return DIT_CONV_SUCCESS;
|
|
// °³Ã¼ÀÇ °áÇÔÁ¤º¸¸¦ Merge
|
CDefectBlob *pBlob;
|
CDefectBlob *pBlobNext;
|
for (i = nStart; i < m_nBlob; i++)
|
{
|
pBlob= m_pBlobDefect+ i;
|
for (j = i + 1; j < m_nBlob; j++)
|
{
|
pBlobNext= m_pBlobDefect+ j;
|
//choigudal ´Ù¸¥ °áÇÔÀÌ µ¿ÀÏÇÑ À§Ä¡¿¡¼ ÀâÈú °æ¿ì Çϳª¸¸ DefectÀ¸·Î º¸°í. 20090725
|
if (pBlob->s_DefectType != pBlobNext->s_DefectType)
|
continue;
|
|
if (pBlob->s_DefectRect.bottom + nMergePixel < pBlobNext->s_DefectRect.top
|
|| pBlob->s_DefectRect.top - nMergePixel > pBlobNext->s_DefectRect.bottom)
|
continue;
|
|
if (pBlob->s_DefectRect.right + nMergePixel < pBlobNext->s_DefectRect.left
|
|| pBlob->s_DefectRect.left - nMergePixel > pBlobNext->s_DefectRect.right)
|
continue;
|
|
// ÀÎÁ¢ÇØ ÀÖÀ¸¹Ç·Î ÇÕÄ£´Ù.
|
if (!pBlob->s_bRemoved && !pBlobNext->s_bRemoved)
|
{
|
//choigudal ´Ù¸¥ °áÇÔÀÌ µ¿ÀÏÇÑ À§Ä¡¿¡¼ ÀâÈú °æ¿ì Çϳª¸¸ DefectÀ¸·Î º¸°í. 20090725
|
//if(pBlob->s_DefectType == DEFTYPE_WHITE || pBlobNext->s_DefectType == DEFTYPE_WHITE)
|
// pBlob->s_DefectType = DEFTYPE_WHITE;
|
|
//m_pBlobDefect[i] = m_pBlobDefect[i] + m_pBlobDefect[j];
|
pBlob->MergeBlob(*pBlobNext);
|
pBlobNext->s_bRemoved = TRUE;
|
m_nSkipMerged++;
|
}
|
}
|
}
|
|
// °áÇÔÀ» Áö¿î´Ù.
|
int nRemovedIdx = 0;
|
for (i = nStart; i < m_nBlob; i++)
|
{
|
if (!m_pBlobDefect[i].s_bRemoved)
|
{
|
m_pBlobDefect[nStart+ nRemovedIdx] = m_pBlobDefect[i];
|
nRemovedIdx++;
|
}
|
}
|
m_nBlob = nStart+ nRemovedIdx;
|
|
for (i = nStart; i < m_nBlob; i++)
|
m_pBlobDefect[i].s_nDefectRScale = CalcRScale(m_pBlobDefect[i].s_ptVertex);
|
|
return DIT_CONV_SUCCESS;
|
}
|
|
DIT_RESULT CBlobStorage::MergeMix(int nStart, int nMergePixel)
|
{
|
int i, j;
|
|
// °³Ã¼ÀÇ °áÇÔÁ¤º¸¸¦ Merge
|
for (i = nStart; i < m_nBlob; i++)
|
{
|
for (j = m_nBlob - 1; j > i; j--)
|
{
|
if (m_pBlobDefect[j].s_DefectRect.bottom + 1 + nMergePixel < m_pBlobDefect[j].s_DefectRect.top
|
|| m_pBlobDefect[j].s_DefectRect.top - 1 - nMergePixel > m_pBlobDefect[j].s_DefectRect.bottom)
|
continue;
|
|
if (m_pBlobDefect[j].s_DefectRect.right + nMergePixel < m_pBlobDefect[j].s_DefectRect.left
|
|| m_pBlobDefect[j].s_DefectRect.left - nMergePixel > m_pBlobDefect[j].s_DefectRect.right)
|
continue;
|
|
// ÀÎÁ¢ÇØ ÀÖÀ¸¹Ç·Î ÇÕÄ£´Ù. -> TypeÀÌ ´Ù¸£¸é TypeÀ» MIXED·Î ¹Ù²Û´Ù.
|
if (m_pBlobDefect[j].s_DefectType != m_pBlobDefect[j].s_DefectType)
|
m_pBlobDefect[j].s_DefectType = DEFTYPE_MIXED;
|
|
if (!m_pBlobDefect[j].s_bRemoved && !m_pBlobDefect[j].s_bRemoved)
|
{
|
m_pBlobDefect[i].MergeBlob(m_pBlobDefect[j]);
|
m_pBlobDefect[j].s_bRemoved = TRUE;
|
m_nSkipMerged++;
|
}
|
}
|
}
|
|
// °áÇÔÀ» Áö¿î´Ù.
|
int nRemovedIdx = 0;
|
for (i = nStart; i < m_nBlob; i++)
|
{
|
if (!m_pBlobDefect[i].s_bRemoved)
|
{
|
m_pBlobDefect[nStart+ nRemovedIdx] = m_pBlobDefect[i];
|
nRemovedIdx++;
|
}
|
}
|
m_nBlob = nStart+ nRemovedIdx;
|
|
for (i = nStart; i < m_nBlob; i++)
|
m_pBlobDefect[i].s_nDefectRScale = CalcRScale(m_pBlobDefect[i].s_ptVertex);
|
|
return DIT_CONV_SUCCESS;
|
}
|
|
|
void CBlobStorage::CheckDefectRect(CDefectBlob& 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 CBlobStorage::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_Param.s_dConvResolution;
|
dDeltaY = (pVertex[i].y - pVertex[j].y) * m_Param.s_dScanResolution;
|
dTemp = sqrt(dDeltaX * dDeltaX + dDeltaY * dDeltaY);
|
if (dRScale < dTemp)
|
dRScale = dTemp;
|
}
|
}
|
if (dRScale < 0.0)
|
dRScale = 0.0;
|
|
return static_cast<int>(dRScale + 0.5);
|
}
|
|
int CBlobStorage::GetConvolutionValue(int nX, int nY, double dDist, int nSuppress)
|
{
|
LPBYTE lpBuffer = NULL;
|
int nPitch;
|
double dRestRight;
|
double dRestLeft;
|
int nConvWidth, nConvHeight;
|
|
lpBuffer = m_Param.s_lpBuffer;
|
nConvWidth = m_Param.s_nConvWidth;
|
nConvHeight = m_Param.s_nConvHeight;
|
|
// if (dDist < 0) // -10.4
|
// {
|
// dDist -= 1; // -11.4
|
// nPitch = static_cast<int>(dDist); // -11
|
// dRestRight = nPitch - dDist; // 0.4
|
// dRestLeft = 1.0 - dRestRight; // 0.6
|
// }
|
// else // 10.4
|
// {
|
// nPitch = static_cast<int>(dDist); // 10
|
// dRestLeft = dDist - nPitch; // 0.4
|
// dRestRight = 1.0 - dRestLeft; // 0.6
|
// }
|
|
if (dDist < 0) // -10.4
|
{
|
dDist -= 1; // -11.4
|
nPitch = static_cast<int>(dDist); // -11
|
dRestLeft = nPitch - dDist; // 0.4
|
dRestRight = 1.0 - dRestLeft; // 0.6
|
}
|
else // 10.4
|
{
|
nPitch = static_cast<int>(dDist); // 10
|
dRestRight = dDist - nPitch; // 0.4
|
dRestLeft = 1.0 - dRestRight; // 0.6
|
}
|
|
int nConvolution = 0;
|
int nSourColor = 0, nDestColor = 0, nValue;
|
for (int i = 0; i < nConvWidth; i++)
|
{
|
for (int j = 0; j < nConvHeight; j++)
|
{
|
nValue = lpBuffer[(nY + j) * m_Param.s_nFrameWidth + (nX + i)];
|
if (nValue > nSuppress)
|
nValue = nSuppress;
|
nSourColor += nValue;
|
|
nValue = static_cast<int>((lpBuffer[(nY + j) * m_Param.s_nFrameWidth + (nX + i) + nPitch] * dRestLeft) + (lpBuffer[(nY + j) * m_Param.s_nFrameWidth + (nX + i) + nPitch + 1] * dRestRight));
|
if (nValue > nSuppress)
|
nValue = nSuppress;
|
nDestColor += nValue;
|
}
|
}
|
|
nConvolution = nSourColor - nDestColor;
|
|
return nConvolution;
|
}
|
|
int CBlobStorage::GetAreaValue(int nXStart, int nYStart, int nWidth, int nHeight, double dDist, int nSuppress)
|
{
|
LPBYTE lpBuffer = NULL;
|
int nPitch;
|
double dRestRight;
|
double dRestLeft;
|
int nConvWidth, nConvHeight;
|
|
lpBuffer = m_Param.s_lpBuffer;
|
nConvWidth = m_Param.s_nConvWidth;
|
nConvHeight = m_Param.s_nConvHeight;
|
|
nPitch = static_cast<int>(dDist);
|
dRestRight = dDist - nPitch;
|
dRestLeft = 1.0 - dRestRight;
|
|
int nConvolution = 0, nValue;
|
double dSourColor = 0.0, dDestColor = 0.0;
|
for (int i = 0; i < nHeight; i++)
|
{
|
for (int j = 0; j < nWidth; j++)
|
{
|
nValue = lpBuffer[(nYStart + i) * m_Param.s_nFrameWidth + (nXStart + j)];
|
if (nValue > nSuppress)
|
nValue = nSuppress;
|
dSourColor += nValue;
|
|
nValue = static_cast<int>((lpBuffer[(nYStart + j) * m_Param.s_nFrameWidth + (nXStart + i) + nPitch] * dRestLeft) + (lpBuffer[(nYStart + j) * m_Param.s_nFrameWidth + (nXStart + i) + nPitch + 1] * dRestRight));
|
if (nValue > nSuppress)
|
nValue = nSuppress;
|
dDestColor += nValue;
|
}
|
}
|
nConvolution = static_cast<int>((dSourColor - dDestColor) / (nWidth * nHeight));
|
|
return nConvolution;
|
}
|
|
int CBlobStorage::GetConvolutionValueVert(int nX, int nY, double dDist, int nSuppress)
|
{
|
LPBYTE lpBuffer = NULL;
|
int nPitch;
|
double dRestRight;
|
double dRestLeft;
|
int nConvWidth, nConvHeight;
|
|
lpBuffer = m_Param.s_lpBuffer;
|
nConvWidth = m_Param.s_nConvWidth;
|
nConvHeight = m_Param.s_nConvHeight;
|
|
if (dDist < 0) // -10.4
|
{
|
dDist -= 1; // -11.4
|
nPitch = static_cast<int>(dDist); // -11
|
dRestLeft = nPitch - dDist; // 0.4
|
dRestRight = 1.0 - dRestLeft; // 0.6
|
}
|
else // 10.4
|
{
|
nPitch = static_cast<int>(dDist); // 10
|
dRestRight = dDist - nPitch; // 0.4
|
dRestLeft = 1.0 - dRestRight; // 0.6
|
}
|
|
if(nY+nPitch+1 >= m_Param.s_nFrameHeight || nY+nPitch+1 <= 0)
|
return 0;
|
|
int nConvolution = 0;
|
int nSourColor = 0, nDestColor = 0, nValue;
|
for (int i = 0; i < nConvWidth; i++)
|
{
|
for (int j = 0; j < nConvHeight; j++)
|
{
|
nValue = lpBuffer[(nY + j) * m_Param.s_nFrameWidth + (nX + i)];
|
if (nValue > nSuppress)
|
nValue = nSuppress;
|
nSourColor += nValue;
|
|
nValue = static_cast<int>((lpBuffer[(nY + j + nPitch) * m_Param.s_nFrameWidth + (nX + i)] * dRestLeft) + (lpBuffer[(nY + j + nPitch + 1) * m_Param.s_nFrameWidth + (nX + i)] * dRestRight));
|
if (nValue > nSuppress)
|
nValue = nSuppress;
|
nDestColor += nValue;
|
}
|
}
|
|
nConvolution = nSourColor - nDestColor;
|
|
return nConvolution;
|
}
|
|
int CBlobStorage::GetAreaValueVert(int nXStart, int nYStart, int nWidth, int nHeight, double dDist, int nSuppress)
|
{
|
LPBYTE lpBuffer = NULL;
|
int nPitch;
|
double dRestRight;
|
double dRestLeft;
|
int nConvWidth, nConvHeight;
|
|
lpBuffer = m_Param.s_lpBuffer;
|
nConvWidth = m_Param.s_nConvWidth;
|
nConvHeight = m_Param.s_nConvHeight;
|
|
nPitch = static_cast<int>(dDist);
|
dRestRight = dDist - nPitch;
|
dRestLeft = 1.0 - dRestRight;
|
|
if(nYStart+nPitch+1 >= m_Param.s_nFrameHeight)
|
return 0;
|
|
int nConvolution = 0, nValue;
|
double dSourColor = 0.0, dDestColor = 0.0;
|
for (int i = 0; i < nHeight; i++)
|
{
|
for (int j = 0; j < nWidth; j++)
|
{
|
nValue = lpBuffer[(nYStart + i) * m_Param.s_nFrameWidth + (nXStart + j)];
|
if (nValue > nSuppress)
|
nValue = nSuppress;
|
dSourColor += nValue;
|
|
nValue = static_cast<int>((lpBuffer[(nYStart + j + nPitch) * m_Param.s_nFrameWidth + (nXStart + i)] * dRestLeft) + (lpBuffer[(nYStart + j + nPitch + 1) * m_Param.s_nFrameWidth + (nXStart + i)] * dRestRight));
|
if (nValue > nSuppress)
|
nValue = nSuppress;
|
dDestColor += nValue;
|
}
|
}
|
nConvolution = static_cast<int>((dSourColor - dDestColor) / (nWidth * nHeight));
|
|
return nConvolution;
|
}
|
|
// »ó/ÇÏ ÇÇÄ¡¿µ¿ª¿¡¼ °áÇÔ À籸ºÐÇÑ´Ù.
|
DIT_RESULT CBlobStorage::ClassificationDefectVert(int nStart)
|
{
|
|
// ÁÂ/¿ì °Ë»ç¿µ¿ª Àç°Ë»ç.
|
int nPitch = static_cast<int>(m_Param.s_dPitchScanReal * m_Param.s_nPitchCycleScan);
|
double dPitch = m_Param.s_dPitchScanReal * m_Param.s_nPitchCycleScan;
|
int nCR, nCL, nCRValue, nCLValue;
|
int nX, nY;
|
int nStartIdx = m_nBlob - 1;
|
|
int i;
|
CDefectBlob *pBlob;
|
for (i = nStartIdx; i >= nStart; i--)
|
{
|
pBlob= m_pBlobDefect+ i;
|
if (pBlob->s_DefectPos == DEFPOS_LEFT && pBlob->s_DefectPair == DEFPAIR_UNPAIR)
|
{
|
//if (pBlob->s_sDefectPeak * (m_Param.s_nConvWidth * m_Param.s_nConvHeight) > m_Param.s_nSideThreshold)
|
//if (pBlob->s_sDefectPeak > m_Param.s_nThreshold)
|
{
|
nX = pBlob->s_nDefectX;
|
nY = pBlob->s_nDefectY % m_Param.s_nFrameHeight;
|
nCL = GetConvolutionValueVert(nX, nY, dPitch, m_Param.s_nThresholdSupress);
|
nCR = GetConvolutionValueVert(nX, static_cast<int>(nY+dPitch), dPitch, m_Param.s_nThresholdSupress);
|
nCLValue = abs(nCL);
|
nCRValue = abs(nCR);
|
|
if (nCLValue >= m_Param.s_nThreshold && nCRValue < m_Param.s_nThreshold) // À§ÂÊ °áÇÔ.
|
{
|
// ¿ÞÂÊÀ¸·Î Shift
|
// pBlob->s_nDefectY += nPitch;
|
// pBlob->s_DefectRect.top += nPitch;
|
// pBlob->s_DefectRect.bottom += nPitch;
|
if (nCL < 0)
|
pBlob->s_DefectType = DEFTYPE_WHITE;
|
else
|
pBlob->s_DefectType = DEFTYPE_BLACK;
|
pBlob->s_DefectPair = DEFPAIR_SIDE;
|
|
m_nMoveClassify++;
|
}
|
else if (nCLValue >= m_Param.s_nThreshold && nCRValue >= m_Param.s_nThreshold) // À§/¾Æ·¡ ¹à±âÂ÷°¡ °°À¸¸é ÇöÀçÀ§Ä¡ÀÇ °áÇÔÀÌ´Ù.
|
pBlob->s_DefectPair = DEFPAIR_SIDE;
|
}
|
}
|
else if (pBlob->s_DefectPos == DEFPOS_CENTER && pBlob->s_DefectPair == DEFPAIR_UNPAIR)
|
{
|
if (pBlob->s_DefectRect.Width() <= 1 || pBlob->s_DefectRect.Height() <= 1)
|
continue;
|
|
int nXStart = pBlob->s_DefectRect.left;
|
int nYStart = pBlob->s_DefectRect.top % m_Param.s_nFrameHeight;
|
int nWidth = pBlob->s_DefectRect.Width();
|
if (nWidth > nPitch)
|
nWidth = nPitch;
|
int nHeight = pBlob->s_DefectRect.Height();
|
int nThreshold = m_Param.s_nThreshold;// / (m_Param.s_nConvWidth * m_Param.s_nConvHeight);
|
|
nCR = GetAreaValueVert(nXStart, nYStart, nWidth, nHeight, dPitch, m_Param.s_nThresholdSupress);
|
nCL = GetAreaValueVert(nXStart, static_cast<int>(nYStart-dPitch), nWidth, nHeight, dPitch, m_Param.s_nThresholdSupress);
|
nCLValue = abs(nCL);
|
nCRValue = abs(nCR);
|
if (nCRValue <= nThreshold && nCLValue > nThreshold) // À§ÂÊÀÌ °áÇÔÀÌ´Ù.
|
{
|
// À§·Î Shift
|
pBlob->s_nDefectY -= nPitch;
|
pBlob->s_DefectRect.top -= nPitch;
|
pBlob->s_DefectRect.bottom -= nPitch;
|
if (nCL < 0)
|
pBlob->s_DefectType = DEFTYPE_BLACK;
|
else
|
pBlob->s_DefectType = DEFTYPE_WHITE;
|
pBlob->s_DefectPair = DEFPAIR_LARGE;
|
|
m_nMoveClassify++;
|
}
|
else if (nCRValue > nThreshold && nCLValue <= nThreshold) // ¾Æ·¡ÂÊÀÌ °áÇÔÀÌ´Ù.
|
{
|
// ¾Æ·¡ÂÊÀ¸·Î Shift
|
pBlob->s_nDefectY += nPitch;
|
pBlob->s_DefectRect.top += nPitch;
|
pBlob->s_DefectRect.bottom += nPitch;
|
if (nCR > 0)
|
pBlob->s_DefectType = DEFTYPE_BLACK;
|
else
|
pBlob->s_DefectType = DEFTYPE_WHITE;
|
pBlob->s_DefectPair = DEFPAIR_LARGE;
|
|
m_nMoveClassify++;
|
m_nMoveClassify++;
|
}
|
else if (nCRValue > nThreshold && nCLValue > nThreshold) // i¹ø °áÇÔÀ» Áö¿î´Ù.
|
pBlob->s_DefectPair = DEFPAIR_LARGE;
|
}
|
}
|
|
for (i = m_nBlob - 1; i >= nStart; i--)
|
{
|
pBlob= m_pBlobDefect+ i;
|
if (pBlob->s_DefectPair == DEFPAIR_UNPAIR)
|
pBlob->s_bRemoved = TRUE;
|
}
|
|
// °áÇÔÀ» Áö¿î´Ù.
|
int nRemovedIdx = 0;
|
for (i = nStart; i < m_nBlob; i++)
|
{
|
pBlob= m_pBlobDefect+ i;
|
if (!pBlob->s_bRemoved)
|
{
|
m_pBlobDefect[nStart+ nRemovedIdx] = m_pBlobDefect[i];
|
nRemovedIdx++;
|
}
|
}
|
m_nBlob = nStart+ nRemovedIdx;
|
|
return DIT_CONV_SUCCESS;
|
}
|
|
|
|
|
|
BOOL CBlobStorage::ClassifyVertical(int nPairedIdx, int nThreshold)
|
{
|
//////////////////////////////////////////////////////////////////////
|
// Vertical ºñ±³
|
int nVertGab = static_cast<int>(m_Param.s_dPitchScanReal * m_Param.s_nPitchCycleScan);
|
double dVRight = (m_Param.s_dPitchScanReal * m_Param.s_nPitchCycleScan) - nVertGab;
|
double dVLeft = 1 - dVRight;
|
int nVApplyPitch = nVertGab;
|
double dLevelSrc, dLevelTemp, dLevelRef;
|
int nLevelDiff;
|
|
|
if (m_Param.s_RectConv.Height() > nVApplyPitch * 2)
|
{
|
if (m_pPairDefect[nPairedIdx].s_nDefectY + nVApplyPitch + 1 >= m_Param.s_RectConv.bottom)
|
{
|
nVApplyPitch = -nVertGab - 1;
|
double dTemp = dVRight;
|
dVLeft = dVRight;
|
dVRight = dTemp;
|
}
|
|
dLevelSrc = *(m_Param.s_lpBuffer + m_pPairDefect[nPairedIdx].s_nDefectY * m_Param.s_nFrameWidth + m_pPairDefect[nPairedIdx].s_nDefectX);
|
dLevelTemp = *(m_Param.s_lpBuffer + (m_pPairDefect[nPairedIdx].s_nDefectY + nVApplyPitch) * m_Param.s_nFrameWidth + m_pPairDefect[nPairedIdx].s_nDefectX);
|
dLevelRef = dLevelTemp * dVLeft;
|
dLevelTemp = *(m_Param.s_lpBuffer + (m_pPairDefect[nPairedIdx].s_nDefectY + nVApplyPitch + 1) * m_Param.s_nFrameWidth + m_pPairDefect[nPairedIdx].s_nDefectX);
|
dLevelRef += dLevelTemp * dVRight;
|
|
// Pixel ´ÜÀ§·Î ¹®ÅΰªÀ» ³ÑÁö ¾ÊÀ» °æ¿ì »èÁ¦.
|
if (m_pPairDefect[nPairedIdx].s_DefectType == DEFTYPE_BLACK)
|
{
|
nLevelDiff = static_cast<int>(dLevelRef - dLevelSrc);
|
if (nLevelDiff < nThreshold)
|
{
|
m_pPairDefect[nPairedIdx].s_DefectType = DEFTYPE_DELETE;
|
return FALSE;
|
}
|
}
|
else if (m_pPairDefect[nPairedIdx].s_DefectType == DEFTYPE_WHITE)
|
{
|
nLevelDiff = static_cast<int>(dLevelSrc - dLevelRef);
|
if (nLevelDiff < nThreshold)
|
{
|
m_pPairDefect[nPairedIdx].s_DefectType = DEFTYPE_DELETE;
|
return FALSE;
|
}
|
}
|
return TRUE;
|
}
|
|
// °ËÁõÇÒ ¼ö ¾øÀ¸¸é °áÇÔÀ¸·Î ³ÖÁö ¸»¶ó´Â »ÇºüÀÌ ¾ÆÀú¾¾ÀÇ ¸»¾¸.
|
return FALSE;
|
}
|
|
|
BOOL CBlobStorage::ReadBlob(CBlobStorage *pBlobStrg)
|
{
|
if(pBlobStrg == NULL) return FALSE;
|
|
CDefectBlob *pBlob;
|
int nBlob= pBlobStrg->GetBlobCount();
|
for(int iBlob= 0; iBlob < nBlob; iBlob++)
|
{
|
pBlob= pBlobStrg->GetBlobDefect(iBlob);
|
|
if(AddBlob(pBlob) == FALSE)
|
return FALSE;
|
}
|
return TRUE;
|
}
|
BOOL CBlobStorage::AddBlob(CDefectBlob *pBlob)
|
{
|
if(m_nBlob < m_maxBlob)
|
{
|
*GetBlobDefect(m_nBlob)= *pBlob;
|
m_nBlob++;
|
return m_nBlob < m_maxBlob;
|
}
|
return FALSE;
|
}
|