#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 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; }