#include "stdafx.h"
|
|
#include "DefectStorage.h"
|
#include "MosisBuffer/MosisBuffer.h"
|
#include "MosisAssem/BlobStorage.h"
|
#include "MosisAssem/AssemParam.h"
|
#include "ZoneReference.h"
|
#include "FilterInspect.h"
|
|
#include "Reinspector.h"
|
|
CDefectStorage::CDefectStorage(void)
|
{
|
m_nDefect= m_maxDefect= 0;
|
m_pDefect= NULL;
|
InitializeCriticalSection(&m_csDefect);
|
}
|
|
CDefectStorage::~CDefectStorage(void)
|
{
|
if(m_pDefect)
|
delete[] m_pDefect;
|
DeleteCriticalSection(&m_csDefect);
|
}
|
|
void CDefectStorage::ResetDefectStorage()
|
{
|
|
int i;
|
for(i= 0; i< m_maxDefect; i++)
|
{
|
m_pDefect[i].Reset();
|
}
|
m_nDefect= 0;
|
}
|
|
|
int CDefectStorage::InitDefectStorage(int maxDefect)
|
{
|
if(maxDefect <= m_nDefectSpace)
|
{
|
m_maxDefect= maxDefect;
|
return m_maxDefect;
|
}
|
|
if(m_pDefect != NULL)
|
{
|
delete[] m_pDefect;
|
}
|
|
// 16°³ÀÇ ¿©ºÐÀ» µÐ´Ù..¿Ö? ³»¸É..
|
int DefectSapce= maxDefect+ 16;
|
m_pDefect= new CDefect[DefectSapce];
|
|
if(m_pDefect == NULL)
|
{
|
m_maxDefect= m_nDefectSpace= 0;
|
return m_maxDefect;
|
}
|
|
|
m_maxDefect= m_nDefectSpace= maxDefect;
|
|
|
return m_maxDefect;
|
}
|
|
void CDefectStorage::CheckDefectRect(CPoint* pVertex, CRect* pRect, int nX, int nY)
|
{
|
if (!pVertex || !pRect)
|
return;
|
|
// Rect
|
if (nY <= pRect->top)
|
{
|
pRect->top = nY;
|
if (pVertex[2].y == nY) // Top Left
|
{
|
if (nX < pVertex[2].x)
|
{
|
pVertex[2].x = nX;
|
pVertex[2].y = nY;
|
}
|
}
|
else
|
{
|
pVertex[2].x = nX;
|
pVertex[2].y = nY;
|
}
|
if (pVertex[3].y == nY) // Top Right
|
{
|
if (nX + 1 > pVertex[3].x)
|
{
|
pVertex[3].x = nX + 1;
|
pVertex[3].y = nY;
|
}
|
}
|
else
|
{
|
pVertex[3].x = nX + 1;
|
pVertex[3].y = nY;
|
}
|
}
|
if (nY + 1 >= pRect->bottom)
|
{
|
pRect->bottom = nY + 1;
|
if (pVertex[6].y == nY + 1) // Bottom Left
|
{
|
if (nX < pVertex[6].x)
|
{
|
pVertex[6].x = nX;
|
pVertex[6].y = nY + 1;
|
}
|
}
|
else
|
{
|
pVertex[6].x = nX;
|
pVertex[6].y = nY + 1;
|
}
|
if (pVertex[7].y == nY + 1) // Bottom Right
|
{
|
if (nX + 1 > pVertex[7].x)
|
{
|
pVertex[7].x = nX + 1;
|
pVertex[7].y = nY + 1;
|
}
|
}
|
else
|
{
|
pVertex[7].x = nX + 1;
|
pVertex[7].y = nY + 1;
|
}
|
}
|
if (nX <= pRect->left)
|
{
|
pRect->left = nX;
|
if (pVertex[1].x == nX) // Left Bottom
|
{
|
if (nY + 1 > pVertex[1].y)
|
{
|
pVertex[1].x = nX;
|
pVertex[1].y = nY + 1;
|
}
|
}
|
else
|
{
|
pVertex[1].x = nX;
|
pVertex[1].y = nY + 1;
|
}
|
if (pVertex[0].x == nX) // Left Top
|
{
|
if (nY < pVertex[0].y)
|
{
|
pVertex[0].x = nX;
|
pVertex[0].y = nY;
|
}
|
}
|
else
|
{
|
pVertex[0].x = nX;
|
pVertex[0].y = nY;
|
}
|
}
|
if (nX + 1 >= pRect->right)
|
{
|
pRect->right = nX + 1;
|
if (pVertex[5].x == nX + 1) // Right Bottom
|
{
|
if (nY + 1 > pVertex[5].y)
|
{
|
pVertex[5].x = nX + 1;
|
pVertex[5].y = nY + 1;
|
}
|
}
|
else
|
{
|
pVertex[5].x = nX + 1;
|
pVertex[5].y = nY + 1;
|
}
|
if (pVertex[4].x == nX + 1) // Right Top
|
{
|
if (nY < pVertex[4].y)
|
{
|
pVertex[4].x = nX + 1;
|
pVertex[4].y = nY;
|
}
|
}
|
else
|
{
|
pVertex[4].x = nX + 1;
|
pVertex[4].y = nY;
|
}
|
}
|
}
|
|
|
int CDefectStorage::ExtractDefect(CZoneReference *pZoneReference, CBlobStorage *pBlobStorage, CInspectParam *pParam, int iModel, int nCosmicThreshold, BOOL bDelBlack, BOOL bDelWhite, int filterSize, BOOL bDelGeneral)
|
{
|
EnterCriticalSection(&m_csDefect);
|
if(m_nDefect >= m_maxDefect)
|
{
|
LeaveCriticalSection(&m_csDefect);
|
return m_nDefect;
|
}
|
|
//int iFrame= pParam->m_nFrameNo;
|
//int iScan= pParam->m_nScanIdx;
|
|
int nBlob, iBlob;
|
nBlob= pBlobStorage->GetBlobCount();
|
|
CDefectBlob *pBlob;
|
|
BOOL bCosmicray;
|
CMosisBuffer MosisBuffer(pParam->s_lpBuffer, pParam->s_nFrameWidth, pParam->s_nFrameHeight);
|
|
CFilterInspect filter;
|
for(iBlob= 0; iBlob < nBlob; iBlob++)
|
{
|
if(m_nDefect >= m_maxDefect)
|
break;
|
|
pBlob= pBlobStorage->GetBlobDefect(iBlob);
|
bCosmicray= FALSE;
|
if(pBlob->s_DefectType == DEFTYPE_NODEFECT)
|
continue;
|
if(bDelBlack)
|
{
|
if(pBlob->s_DefectType == DEFTYPE_BLACK)
|
continue;
|
}
|
if(bDelWhite)
|
{
|
if(pBlob->s_DefectType == DEFTYPE_WHITE)
|
continue;
|
}
|
if(filterSize > 0)
|
{
|
if(pBlob->s_nDefectArea <= filterSize)
|
continue;
|
}
|
|
if(pParam->m_ConvMode == ConvMode_Pixel && pZoneReference != NULL)
|
{
|
if(pZoneReference->Is_Cutoff(pBlob->s_sZonePixelCount, pBlob->s_DefectType))
|
continue;
|
// if(pZoneReference->Is_CutoffAfterShiftHigher(pBlob->s_sZonePixelCount))
|
// continue;
|
}
|
|
if(pParam->m_bUseMatchFilter && pParam->m_ConvDir == ConvDir_Vert)
|
{
|
//if(! filter.FilteringTiltVertImpl(pParam->m_MatchFilter2by2, pParam->s_lpBuffer, CSize(pParam->s_nFrameWidth, pParam->s_nFrameHeight), pBlob->s_sThreshold, pParam->GetRealScanPitch(), CPoint(pBlob->s_nDefectX, pBlob->s_nDefectY), pParam->s_RectConv, pParam->s_nThresholdSupress))
|
if(! filter.FilteringTiltVertImpl(pParam->m_MatchFilter2by2, pParam->s_lpBuffer, CSize(pParam->s_nFrameWidth, pParam->s_nFrameHeight), pBlob->s_sThreshold, pParam->GetRealScanPitch(), CPoint(pBlob->s_xMaxPeak, pBlob->s_yMaxPeak), pParam->s_RectConv, pParam->s_nThresholdSupress))
|
{
|
continue;
|
}
|
}
|
|
if(nCosmicThreshold && pBlob->s_DefectType == DEFTYPE_WHITE && IsCosmicRayDefect(pBlob, MosisBuffer, nCosmicThreshold))
|
{
|
bCosmicray= TRUE;
|
}
|
/*
|
CCropBuffer crop, crop2;
|
CNoiseStat noise1, noise2, noise;
|
CRect rect= pBlob->s_DefectRect;
|
CRect rect2= rect;
|
int sub;
|
double pitch;
|
if(pParam->m_ConvDir == ConvDir_Vert)
|
{
|
pitch= pParam->GetRealScanPitch();
|
sub= ((int)(pitch*16) & 15);
|
if(rect.bottom + pitch > pParam->s_RectConv.bottom)
|
{
|
pitch= -pitch;
|
sub= 15- sub;
|
}
|
rect2.OffsetRect(0, pitch);
|
}else
|
{
|
pitch= pParam->GetRealConvPitch();
|
sub= ((int)(pitch*16) & 15);
|
if(rect.bottom + pitch > pParam->s_RectConv.right)
|
{
|
pitch= -pitch;
|
sub= 15- sub;
|
}
|
rect2.OffsetRect(pitch, 0);
|
}
|
//rect2.right+= 2;
|
|
// crop.DoCrop(MosisBuffer, rect);
|
// crop2.DoCrop(MosisBuffer, rect2);
|
// CDiffBuff diff;
|
// diff.MakeDiffBuff(crop, crop2, 16- sub, sub, pParam->m_ConvDir == ConvDir_Vert);
|
// diff.GetStatic(noise1, noise2);
|
// diff.GetStatic(noise);
|
//
|
|
CCropBuffer crop, crop2;
|
CRect rect= pBlob->s_DefectRect;
|
CRect rect2;
|
int height= rect.Height();
|
height= height/2;
|
rect.bottom= rect.top+ height;
|
crop.DoCrop(MosisBuffer, rect);
|
rect2= rect;
|
rect2.OffsetRect(pParam->GetRealConvPitch(), 0);
|
rect2.right+= 2;
|
crop2.DoCrop(MosisBuffer, rect2);
|
//CShiftBuffer shift(MosisBuffer, rect.top, rect.bottom);
|
|
int sub= ((int)(pParam->GetRealConvPitch()*16) & 15);
|
|
CTightBuff<short> diff1, diff2;
|
reinspector1.MakeBuff(crop, crop2, diff1, 16- sub, sub);
|
float mean= reinspector1.GetMean(diff1);
|
reinspector1.GetStdDeviation(diff1, mean);
|
|
rect.OffsetRect(0, height);
|
rect2.OffsetRect(0, height);
|
crop.DoCrop(MosisBuffer, rect);
|
crop2.DoCrop(MosisBuffer, rect2);
|
|
reinspector2.MakeBuff(crop, crop2, diff2, 16- sub, sub);
|
mean= reinspector2.GetMean(diff2);
|
reinspector2.GetStdDeviation(diff2, mean);
|
|
// m_pDefect[m_nDefect].JudgeTFE(noise1.m_Mean, noise1.m_StdDeviation, noise2.m_Mean, noise2.m_StdDeviation, noise.m_Mean, noise.m_StdDeviation, noise.m_Rough);
|
// if(bDelGeneral && m_pDefect[m_nDefect].m_ReKind == CReDefect::Re_Other)
|
// continue;
|
*/
|
m_pDefect[m_nDefect].m_Defect= *pBlob;
|
|
m_nDefect++;
|
}
|
|
LeaveCriticalSection(&m_csDefect);
|
|
return m_nDefect;
|
}
|
|
|
BOOL CDefectStorage::IsCosmicRayDefect(CDefectBlob *pBlob, CMosisBuffer &fBuffer, int crFilterThreshold)
|
{
|
int maxX= pBlob->s_xLevelSrcMax;
|
int maxY= pBlob->s_yLevelSrcMax;
|
|
BYTE *pData= fBuffer.GetDataAddress();
|
double dMaxWhite = fBuffer.GetPixel(maxX, maxY);
|
double dTemp = 0.0;
|
|
for(int x= -1; x<= 1; x++)
|
{
|
dTemp = fBuffer.GetPixel(maxX+ x, maxY- 1);//*(pParam->m_lpBuffer + (maxY - 1) * fBuffer.GetWidth() + (maxX - 1));
|
if (dMaxWhite - dTemp < crFilterThreshold)
|
{
|
//g_pLog->DisplayMessage(TRUE, "CosmicRay Á¤»ó MaxWhite %3.0f, (%d, -1) Value %3.0f", dMaxWhite, dTemp, x);
|
return FALSE;
|
}
|
dTemp = fBuffer.GetPixel(maxX+ x, maxY+ 1);//*(pParam->m_lpBuffer + (maxY - 1) * fBuffer.GetWidth() + (maxX - 1));
|
if (dMaxWhite - dTemp < crFilterThreshold)
|
{
|
//g_pLog->DisplayMessage(TRUE, "CosmicRay Á¤»ó MaxWhite %3.0f, (%d, +1) Value %3.0f", dMaxWhite, dTemp, x);
|
return FALSE;
|
}
|
}
|
|
// ÁÂ/¿ì Çȼ¿ ºñ±³
|
if (pBlob->s_nDefectArea == 1)
|
{
|
dTemp = fBuffer.GetPixel(maxX- 1, maxY);//*(pParam->m_lpBuffer + (maxY) * fBuffer.GetWidth() + (maxX - 1));
|
if (dMaxWhite - dTemp < crFilterThreshold)
|
{
|
//g_pLog->DisplayMessage(TRUE, "CosmicRay Á¤»ó MaxWhite %3.0f, (-1, 0) Value %3.0f", dMaxWhite, dTemp);
|
return FALSE;
|
}
|
|
dTemp = fBuffer.GetPixel(maxX+ 1, maxY);//*(pParam->m_lpBuffer + (maxY) * fBuffer.GetWidth() + (maxX + 1));
|
if (dMaxWhite - dTemp < crFilterThreshold)
|
{
|
//g_pLog->DisplayMessage(TRUE, "CosmicRay Á¤»ó MaxWhite %3.0f, (1, 0) Value %3.0f", dMaxWhite, dTemp);
|
return FALSE;
|
}
|
}
|
|
// ¿ÞÂÊ µÎ Çȼ¿ ºñ±³
|
double dTemp2 = 0.0;
|
dTemp = fBuffer.GetPixel(maxX- 1, maxY);//*(pParam->m_lpBuffer + (maxY) * fBuffer.GetWidth() + (maxX - 1));
|
dTemp2 = fBuffer.GetPixel(maxX- 2, maxY);//*(pParam->m_lpBuffer + (maxY) * fBuffer.GetWidth() + (maxX - 2));
|
if (dTemp2 <= dTemp)
|
{
|
//g_pLog->DisplayMessage(TRUE, "CosmicRay Á¤»ó MaxWhite %3.0f, (¿ÞÂÊ) Value %3.0f", dMaxWhite, dTemp);
|
return FALSE;
|
}
|
|
// ¿À¸¥ÂÊ µÎ Çȼ¿ ºñ±³
|
dTemp = fBuffer.GetPixel(maxX+ 1, maxY);//*(pParam->m_lpBuffer + (maxY) * fBuffer.GetWidth() + (maxX + 1));
|
dTemp2 = fBuffer.GetPixel(maxX+ 2, maxY);//*(pParam->m_lpBuffer + (maxY) * fBuffer.GetWidth() + (maxX + 2));
|
if (dTemp2 <= dTemp)
|
{
|
//g_pLog->DisplayMessage(TRUE, "CosmicRay Á¤»ó MaxWhite %3.0f, (¿À¸¥ÂÊ) Value %3.0f", dMaxWhite, dTemp);
|
return FALSE;
|
}
|
|
// //g_pLog->DisplayMessage(TRUE, "CosmicRay °É·¯³¿ %d MaxWhite %3.0f", pDefect->m_nIndex, dMaxWhite);
|
return TRUE;
|
}
|
|
|
int CDefectStorage::StopInspection(CAssemControl *pAssemControl)
|
{
|
return 0;
|
}
|