// ChamferInspect.cpp : implementation file // #include "stdafx.h" #include "ChamferInspect.h" #include #include #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:\\RCutProject_Data\\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 &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 &vecBlob, int nMergePixel) { int i,j; //µðÆå·ºÆ®·Î ¸ÓÁö CChipBlob Blob; CChipBlob BlobNext; int nSize = (int)vecBlob.size(); for(i=0; i 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::vectorvecTemp; for(i=0; i &vecBlob, int nMergePixel) { int i,j; //µðÆå·ºÆ®·Î ¸ÓÁö CChipBlob Blob; CChipBlob BlobNext; int nSize = (int)vecBlob.size(); for(i=0; i 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::vectorvecTemp; for(i=0; i 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(dRScale + 0.5); } void CChamferInspect::ReleaseBuffer() { if(m_pGlassEdgeLine != NULL && m_nGlassEdgeLineCnt > 0) { for(int i=0;i 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 arrU; nPos = rectIns.top+1; for(v=1;v 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 0 && m_pGlassEdgeLine[v].pPos != NULL) { for(u=0;u vecPos; std::vector::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= 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= 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 = 10; dRightLine = -1; nSumLine = nSumCnt = 0; for(v=0;v= 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(nforecast_S+nRightOffset > dRightLine || nSumCnt < pBuffer.GetHeight() *0.5) dRightLine = nforecast_S; if(nSumCnt > 0) { dRightLine = (double)nSumLine/(double)nSumCnt; } 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= nContinCnt) { nWCnt = 0; for(int u1=u+1; u1 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 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 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 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 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 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 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 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 nChipThres_white = insParam.nChipThres_White; int nChipDiffThres = insParam.nChipDiffThres; int nMinSize = insParam.nChipMinSize; int nSideFilterSize = insParam.nChipSideFilterSize; nChipThres = (nChipThres <= 0) ? 0 : (255 <= nChipThres ) ? 255 : nChipThres; nChipThres_white = (nChipThres_white <= 0) ? 0 : (255 <= nChipThres_white ) ? 255 : nChipThres_white; 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, nChipThres_white, 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 &vecBlob,int nBaseLeft,int nBaseRight,int nDetMargin,int nImgBurrMargin) { std::vector vecTmp; std::vector::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 &vecBlob) { std::vector vecTmp; std::vector::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= CannyImg.GetWidth()) { uE=CannyImg.GetWidth()-1; uS = uE-2; } for(v=1;v 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= 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= 0 && (int)dLeftEdge < dispbuf.GetWidth() && (int)dRightEdge >= 0 && (int)dRightEdge < dispbuf.GetWidth()) { int i; for(i=0;i= 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;inPixelCount > 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 &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 &vecBlob,std::vector &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 &vecBlob) { std::vector vecTmp; std::vector::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 vecPair; std::vector 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::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::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 vecPair; std::vector 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(stuPoly.nSL) * cos(stuPoly.dTheta) - static_cast(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::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* 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 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(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(nIdx, cv::CC_STAT_AREA); int left = matStats.at(nIdx, cv::CC_STAT_LEFT); int top = matStats.at(nIdx, cv::CC_STAT_TOP); int width = matStats.at(nIdx, cv::CC_STAT_WIDTH); int height = matStats.at(nIdx, cv::CC_STAT_HEIGHT); int x = (int)matCentrois.at(nIdx, 0); int y = (int)matCentrois.at(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 blobTmp; LPBYTE pImg = BufferIns.GetDataAddress(); int x,y,iLoop; for(iLoop=0;iLoop 0) { std::vector::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 &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 &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 &vecBlob,ChipResionType emSide,int nBaseLine,int nDetMargin) { std::vector vecTmp; std::vector::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 &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 vecPair; std::vector blobRight,blobLeft; std::vector 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::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; iGetHeight(); 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; iGetHeight(); 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); IplImage* pBinImage_OR = cvCreateImage(cvSize(pBinImage->GetWidth(), pBinImage->GetHeight()), 8, 1); cvZero(pBinImage_Low); cvZero(pBinImage_Hight); cvZero(pBinImage_OR); if(nThresholdLow >= 0 && nThresholdLow <= 255) { cvThreshold(pOriginImage, pBinImage_Low, (double) nThresholdLow, 255.0, CV_THRESH_BINARY_INV); } if(nThresholdHigh >= 0 && nThresholdHigh <= 255) { cvThreshold(pOriginImage, pBinImage_Hight, (double) nThresholdHigh, 255.0, CV_THRESH_BINARY); } cvOr(pBinImage_Low, pBinImage_Hight, pBinImage_OR); CopyMemory(pBinImage->GetDataAddress(),pBinImage_OR->imageData,sizeof(BYTE)*pBinImage_OR->width*pBinImage_OR->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(&pBinImage_OR); cvReleaseImage(&pOriginImage); return TRUE; }