// EdgeFind.cpp: implementation of the CSISEdgeFind class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "SISEdgeFind.h" #include "SISBuffer.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CSISEdgeFind::CSISEdgeFind() { m_Buffer= NULL; } CSISEdgeFind::~CSISEdgeFind() { } int CSISEdgeFind::Find_LeftEdge(CSISBuffer *pBuffer, double pitch, int threshold, double rDefect, int nContinue) { if(!pBuffer->IsValidBuffer()) return -1; int x, y; int width, height; int iPitch= (int)(pitch); width= pBuffer->GetWidth()- iPitch- 6; height= pBuffer->GetHeight()- 5; double pa, pb; pb= pitch- iPitch; pa= 1- pb; threshold*= 6; int cContinue= 0; int count; // int org, tar; int nDefect= (int)(height*rDefect); for(x= width- 1; x>= 0; x--) { count= 0; for(y= 0; y< height; y++) { if(abs(pBuffer->GetDiff32(x, y, pitch)) > threshold) { count++; } } if(count >= nDefect) { cContinue++; if(cContinue >= nContinue) return x+ nContinue; } else { cContinue= 0; } } return -1; } int CSISEdgeFind::Find_RightEdge(CSISBuffer *pBuffer, double pitch, int threshold, double rDefect, int nContinue) { if(!pBuffer->IsValidBuffer()) return -1; int x, y; int width, height; int iPitch= (int)(pitch); width= pBuffer->GetWidth()- iPitch- 6; height= pBuffer->GetHeight()- 5; threshold*= 6; int cContinue= 0; int count; int nDefect= (int)(height*rDefect); for(x= 0; x< width; x++) { count= 0; for(y= 0; y< height; y++) { if(abs(pBuffer->GetDiff32(x, y, pitch)) > threshold) { count++; } } if(count >= nDefect) { cContinue++; if(cContinue >= nContinue) return x+ 2+ iPitch- nContinue; } else { cContinue= 0; } } return -1; } int CSISEdgeFind::Find_TopEdge(CSISBuffer *pBuffer, double pitch, int threshold, double rDefect, int nContinue) { if(!pBuffer->IsValidBuffer()) return -1; int x, y; int width, height; int iPitch= (int)(pitch); width= pBuffer->GetWidth()- 5; height= pBuffer->GetHeight()- iPitch- 6; double pa, pb; pb= pitch- iPitch; pa= 1- pb; threshold*= 6; int cContinue= 0; int count; // int org, tar; int nDefect= (int)(width*rDefect); for(y= height- 1; y>= 0; y--) { count= 0; for(x= 0; x< width; x++) { /* //2 by 1 org= pBuffer->GetPixel(x, y)+ pBuffer->GetPixel(x, y+ 1); tar= (int)(pBuffer->GetPixel(x, y+ iPitch)*pa+ pBuffer->GetPixel(x, y+iPitch+ 1)+ pBuffer->GetPixel(x, y+iPitch+ 2)*pb); */ //2 by 3 // org= pBuffer->GetPixel(x, y)+ pBuffer->GetPixel(x, y+ 1)+ pBuffer->GetPixel(x, y+ 2); // org+=pBuffer->GetPixel(x+1, y)+ pBuffer->GetPixel(x+1, y+ 1)+ pBuffer->GetPixel(x+1, y+ 2); // tar= (int)(pBuffer->GetPixel(x, y+ iPitch)*pa+ pBuffer->GetPixel(x, y+iPitch+ 1)+ pBuffer->GetPixel(x, y+iPitch+ 2)+ pBuffer->GetPixel(x, y+iPitch+ 3)*pb); // tar+=(int)(pBuffer->GetPixel(x+1, y+ iPitch)*pa+ pBuffer->GetPixel(x+1, y+iPitch+ 1)+ pBuffer->GetPixel(x+1, y+iPitch+ 2)+ pBuffer->GetPixel(x+1, y+iPitch+ 3)*pb); //if(abs(org- tar) > threshold) if(abs(pBuffer->GetDiff23(x, y, pitch)) > threshold) { count++; } } if(count >= nDefect) { cContinue++; if(cContinue >= nContinue) return y+ nContinue; } else { cContinue= 0; } } return -1; } #include int CSISEdgeFind::Find_GlassStart(CSISBuffer *pBuffer, double pitch) { if(!pBuffer->IsValidBuffer()) return -1; /* for(y= height- 1; y>= 0; y--) { unsigned int nResult = 0; for(x= 0; x< width; x++) { // org= pBuffer->GetPixel(x, y)+ pBuffer->GetPixel(x, y+ 1); // tar= (int)(pBuffer->GetPixel(x, y+ iPitch)*pa+ pBuffer->GetPixel(x, y+iPitch+ 1)+ pBuffer->GetPixel(x, y+iPitch+ 2)*pb); org= pBuffer->GetPixel(x, y); tar= (int)(pBuffer->GetPixel(x, y+ iPitch)*pa+ pBuffer->GetPixel(x, y+iPitch+ 1)*pb); nResult += abs(org- tar); // if(abs(org- tar) < 50) // { // // } } nResult = nResult/ width; if(nResult > 50) { return -1; } } */ /*TRACE("HEIGHT..[%d] WIDTH..[%d]",height,width); for(y= height- 1; y>= 0; y--) { for(x= 0; x< width; x++) { org= pBuffer->GetPixel(x, y)+ pBuffer->GetPixel(x, y+ 1); tar= (int)(pBuffer->GetPixel(x, y+ iPitch)*pa+ pBuffer->GetPixel(x, y+iPitch+ 1)+ pBuffer->GetPixel(x, y+iPitch+ 2)*pb); if(abs(org- tar) > 20) { g_pLog->DisplayMessage(TRUE, "Start Line difference : %d",abs(org- tar)); return abs(org- tar); } } }*/ const int width = pBuffer->GetWidth(); const int height = pBuffer->GetHeight(); int diffSum = 0; const int Pitch = 2; for(int i=0; iGetPixel(i, height) - pBuffer->GetPixel(i+Pitch, height); diffSum += (int)sqrt(diff*diff); } double per = diffSum / double(width*255); return (per < 0.1); } void CSISEdgeFind::GetCount_XROI(CSISBuffer *pBuffer, double pitch, int threshold, CCutoffFind &find,int nOffset,CRect rtROI) { if(!pBuffer->IsValidBuffer()) return ; if(rtROI.right >= pBuffer->GetWidth()) return; int x, y; int nx, ny; int org, tar; int iPitch= (int)(pitch); nx= (rtROI.Width()-nOffset)- iPitch- 1; ny= rtROI.Height() - 1; find.SetSize(rtROI.Width()); find.m_maxCount= ny; double pa, pb; pb= pitch- iPitch; pa= 1- pb; //threshold*= 2; int count; int ipos = 0; for(x= rtROI.left; x< rtROI.left+nx; x++,ipos++) { count= 0; for(y= rtROI.top; y< rtROI.bottom; y++) { org= pBuffer->GetPixel(x, y); tar= (int)(pBuffer->GetPixel(x+ iPitch, y)*pa+ pBuffer->GetPixel(x+iPitch+ 1, y)*pb); if(abs(org- tar) > threshold) { // pBuffer->SetPixel(x, y, 0); count++; } } find.SetCountData(ipos, count); } } void CSISEdgeFind::GetCount_X(CSISBuffer *pBuffer, double pitch, int threshold, CCutoffFind &find,int nOffset) { if(!pBuffer->IsValidBuffer()) return ; if(nOffset >= pBuffer->GetWidth()) return; int x, y; int nx, ny; int org, tar; int iPitch= (int)(pitch); nx= (pBuffer->GetWidth()-nOffset)- iPitch- 1; ny= pBuffer->GetHeight() - 1; find.SetSize(pBuffer->GetWidth()); find.m_maxCount= ny; double pa, pb; pb= pitch- iPitch; pa= 1- pb; //threshold*= 2; int count; for(x= nOffset; x< nOffset+nx; x++) { count= 0; for(y= 0; y< ny; y++) { org= pBuffer->GetPixel(x, y); tar= (int)(pBuffer->GetPixel(x+ iPitch, y)*pa+ pBuffer->GetPixel(x+iPitch+ 1, y)*pb); if(abs(org- tar) > threshold) { // pBuffer->SetPixel(x, y, 0); count++; } } find.SetCountData(x, count); } } void CSISEdgeFind::GetCount_Y(CSISBuffer *pBuffer, double pitch, int threshold, CCutoffFind &find) { if(!pBuffer->IsValidBuffer()) return ; int x, y; int nx, ny; int org, tar; int iPitch= (int)(pitch); nx= pBuffer->GetWidth()- 1; ny= pBuffer->GetHeight()- iPitch- 1; find.SetSize(ny); find.m_maxCount= nx; double pa, pb; pb= pitch- iPitch; pa= 1- pb; //threshold*= 2; int count; for(y= 0; y< ny; y++) { count= 0; for(x= 0; x< nx; x++) { org= pBuffer->GetPixel(x, y); tar= (int)(pBuffer->GetPixel(x, y+ iPitch)*pa+ pBuffer->GetPixel(x, y+iPitch+ 1)*pb); if(abs(org- tar) > threshold) { // pBuffer->SetPixel(x, y, 0); count++; } } find.SetCountData(y, count); } } BOOL CSISEdgeFind::FindEdge_ToTop(CSISBuffer *pBuffer, int &offset, double pitch, int threshold, double rDefect) { CCutoffFind find; GetCount_Y(pBuffer, pitch, threshold, find); return find.FindCutoff_Continuous(FALSE, int(find.m_maxCount*rDefect), 3, offset); } BOOL CSISEdgeFind::FindEdge_ToBottom(CSISBuffer *pBuffer, int &offset, double pitch, int threshold, double rDefect) { CCutoffFind find; GetCount_Y(pBuffer, pitch, threshold, find); int diff= 0; BOOL bRet= find.FindCutoff_Continuous(TRUE, int(find.m_maxCount*rDefect), 3, diff); if(bRet) offset= diff+ (int)(pitch); return bRet; } BOOL CSISEdgeFind::FindEdge_ToLeft(CSISBuffer *pBuffer, int &offset, double pitch, int threshold, double rDefect,int nOffset) { CCutoffFind find; GetCount_X(pBuffer, pitch, threshold, find,nOffset); return find.FindCutoff_Continuous(FALSE, int(find.m_maxCount*rDefect), 5, offset,nOffset); } BOOL CSISEdgeFind::FindEdge_ToRight(CSISBuffer *pBuffer, int &offset, double pitch, int threshold, double rDefect,int nOffset) { CCutoffFind find; GetCount_X(pBuffer, pitch, threshold, find,nOffset); int diff= 0; BOOL bRet= find.FindCutoff_Continuous(TRUE, int(find.m_maxCount*rDefect), 3, diff,nOffset); if(bRet) offset= diff+ (int)(pitch); return bRet; } BOOL CSISEdgeFind::FindEdge_ToRightROI(CSISBuffer *pBuffer, int &offset, double pitch, int threshold, double rDefect,int nOffset,CRect rtROI) { CCutoffFind find; GetCount_XROI(pBuffer, pitch, threshold, find,nOffset,rtROI); int diff= 0; BOOL bRet= find.FindCutoff_Continuous(TRUE, int(find.m_maxCount*rDefect), 3, diff,nOffset); if(bRet) offset= diff+ (int)(pitch) + rtROI.left; return bRet; } int CSISEdgeFind::ImageProjection(BYTE* pBuff, int nWidth, int nHeight, CRect ROI, int nThres, int nDist, int nContinue) { //¿¹¿Üó¸® if(pBuff == NULL || nWidth <= 0 || nHeight <= 0) return -1; int nSumLength = ROI.Height(); int nProjectionLength = ROI.Width(); int nSumStart = ROI.top; int nProjectionStart = ROI.left; int nProjectionEnd = nProjectionStart + nProjectionLength; if(nProjectionLength < 0 || nSumLength < 0) return -1; if(nWidth < ROI.Width() || nHeight < ROI.Height()) return -1; int* pnSum = new int[nWidth + nDist]; nThres *= nSumLength; ZeroMemory(pnSum, sizeof(int) * (nWidth + nDist)); int nSumLine, nProjectionLine; int nGab; int nContinueCount = 0; int nLine = 0; for (nProjectionLine = nProjectionStart; nProjectionLine < nProjectionEnd; nProjectionLine++) { for (nSumLine = nSumStart; nSumLine < nSumStart + nSumLength; nSumLine++) { pnSum[nProjectionLine] += *(pBuff + nProjectionLine + nSumLine * nWidth); } if (nProjectionLine - nProjectionStart >= nDist) { nGab = pnSum[nProjectionLine - nDist] - pnSum[nProjectionLine]; if (nGab < 0) nGab *= -1; if (nGab > nThres) nContinueCount++; else nContinueCount = 0; //¿¬¼ÓÀ¸·Î nContinue ÀÌ»ó ³ª¿À¸é if (nContinueCount >= nContinue) { delete [] pnSum; return nProjectionLine - (nContinue - 1); } } } delete [] pnSum; return -1; } int CSISEdgeFind::ImageProjection_R(BYTE* pBuff, int nWidth, int nHeight, CRect ROI, int nThres, int nDist, int nContinue) { //¿¹¿Üó¸® if(pBuff == NULL || nWidth <= 0 || nHeight <= 0) return -1; int nSumLength = ROI.Height(); int nProjectionLength = ROI.Width(); int nSumStart = ROI.top; int nProjectionStart = ROI.right; int nProjectionEnd = nProjectionStart - nProjectionLength; if(nProjectionLength < 0 || nSumLength < 0) return -1; if(nWidth < ROI.Width() || nHeight < ROI.Height()) return -1; int* pnSum = new int[nWidth + nDist]; nThres *= nSumLength; ZeroMemory(pnSum, sizeof(int) * (nWidth + nDist)); int nSumLine, nProjectionLine; int nGab; int nContinueCount = 0; int nLine = 0; for (nProjectionLine = nProjectionStart - 1; nProjectionLine >= nProjectionEnd; nProjectionLine--) { for (nSumLine = nSumStart; nSumLine < nSumStart + nSumLength; nSumLine++) { pnSum[nProjectionLine] += *(pBuff + nProjectionLine + nSumLine * nWidth); } if (nProjectionLine <= nProjectionStart - 1 - nDist) { nGab = pnSum[nProjectionLine + nDist] - pnSum[nProjectionLine]; if (nGab < 0) nGab *= -1; if (nGab > nThres) nContinueCount++; else nContinueCount = 0; //¿¬¼ÓÀ¸·Î nContinue ÀÌ»ó ³ª¿À¸é if (nContinueCount >= nContinue) { delete [] pnSum; return nProjectionLine + (nContinue - 1); } } } delete [] pnSum; return -1; } int CSISEdgeFind::ImageProjection_Vert(BYTE* pBuff, int nWidth, int nHeight, CRect ROI, int nThres, int nDist, int nContinue) { //¿¹¿Üó¸® if(pBuff == NULL || nWidth <= 0 || nHeight <= 0) return -1; int nSumLength = ROI.Width(); int nProjectionLength = ROI.Height(); int nSumStart = ROI.left; int nProjectionStart = ROI.top; int nProjectionEnd = nProjectionStart + nProjectionLength; if(nProjectionLength < 0 || nSumLength < 0) return -1; if(nWidth < ROI.Width() || nHeight < ROI.Height()) return -1; int* pnSum = new int[nHeight + nDist]; nThres *= nSumLength; ZeroMemory(pnSum, sizeof(int) * (nHeight + nDist)); int nSumLine, nProjectionLine; int nGab; int nContinueCount = 0; int nLine = 0; for (nProjectionLine = nProjectionStart; nProjectionLine < nProjectionEnd; nProjectionLine++) { for (nSumLine = nSumStart; nSumLine < nSumStart + nSumLength; nSumLine++) { pnSum[nProjectionLine] += *(pBuff + nSumLine + nProjectionLine * nWidth); } if (nProjectionLine - nProjectionStart >= nDist) { nGab = pnSum[nProjectionLine - nDist] - pnSum[nProjectionLine]; if (nGab < 0) nGab *= -1; if (nGab > nThres) nContinueCount++; else nContinueCount = 0; //¿¬¼ÓÀ¸·Î nContinue ÀÌ»ó ³ª¿À¸é if (nContinueCount >= nContinue) { delete [] pnSum; return nProjectionLine - (nContinue - 1); } } } delete [] pnSum; return -1; } int CSISEdgeFind::ImageProjection_Vert_R(BYTE* pBuff, int nWidth, int nHeight, CRect ROI, int nThres, int nDist, int nContinue) { //¿¹¿Üó¸® if(pBuff == NULL || nWidth <= 0 || nHeight <= 0) return -1; int nSumLength = ROI.Width(); int nProjectionLength = ROI.Height(); int nSumStart = ROI.left; int nProjectionStart = ROI.bottom; int nProjectionEnd = nProjectionStart - nProjectionLength; if(nProjectionLength < 0 || nSumLength < 0) return -1; if(nWidth < ROI.Width() || nHeight < ROI.Height()) return -1; int* pnSum = new int[nHeight + nDist]; nThres *= nSumLength; ZeroMemory(pnSum, sizeof(int) * (nHeight + nDist)); int nSumLine, nProjectionLine; int nGab; int nContinueCount = 0; int nLine = 0; for (nProjectionLine = nProjectionStart - 1; nProjectionLine >= nProjectionEnd; nProjectionLine--) { for (nSumLine = nSumStart; nSumLine < nSumStart + nSumLength; nSumLine++) { pnSum[nProjectionLine] += *(pBuff + nSumLine + nProjectionLine * nWidth); } if (nProjectionLine <= nProjectionStart - 1 - nDist) { nGab = pnSum[nProjectionLine + nDist] - pnSum[nProjectionLine]; if (nGab < 0) nGab *= -1; if (nGab > nThres) nContinueCount++; else nContinueCount = 0; //¿¬¼ÓÀ¸·Î nContinue ÀÌ»ó ³ª¿À¸é if (nContinueCount >= nContinue) { delete [] pnSum; return nProjectionLine + (nContinue - 1); } } } delete [] pnSum; return -1; } void CSISEdgeFind::ResetEdge() { m_nTopEdge = INT_MAX; m_nBottomEdge = INT_MIN; m_mapLeftEdge.clear(); m_mapRightEdge.clear(); } int CSISEdgeFind::GetEdgeResult(SISEdgePos eEP, int iFrame, BOOL bNearResult) { switch(eEP) { case eEP_LEFT: case eEP_RIGHT: { mapEdgeResult* pMapEdge = &m_mapLeftEdge; if(eEP == eEP_RIGHT) pMapEdge = &m_mapRightEdge; mapEdgeResultIt it = pMapEdge->find(iFrame); //iFrame º¸´Ù ÀÛÀº°ÍÁß¿¡ °¡Àå Å«°Å if(bNearResult) it = pMapEdge->lower_bound(iFrame); if(it == pMapEdge->end()) return -1; stEdgeLRResult stResult = it->second; if(stResult.iFrame != iFrame) return -1; return stResult.nPos; } case eEP_TOP: return m_nTopEdge; case eEP_BOTTOM: return m_nBottomEdge; } return -1; } BOOL CSISEdgeFind::IsFindEdge(SISEdgePos eEP, int iFrame) { switch(eEP) { case eEP_LEFT: case eEP_RIGHT: { mapEdgeResult* pMapEdge = &m_mapLeftEdge; if(eEP == eEP_RIGHT) pMapEdge = &m_mapRightEdge; mapEdgeResultIt it = pMapEdge->find(iFrame); if(it == pMapEdge->end()) return FALSE; stEdgeLRResult stResult = it->second; if(stResult.iFrame != iFrame) return FALSE; return TRUE; } case eEP_TOP: return m_nTopEdge != INT_MAX; case eEP_BOTTOM: return m_nBottomEdge != INT_MIN; } return FALSE; } //3Æ÷ÀÎÆ®Áß¿¡¼­ °¡Àå ÃֿܰûÀ» ¿§Áö·Î ÀÎÁ¤ //±Û¶ó½º¿¡¼­ °ø¿µ¿ªÀ¸·Î ã´Â´Ù. #define FIND_EDGE_COUNT 3 #define PROJECTION_SIZE 100 int CSISEdgeFind::FindEdge(CSISBuffer framebuffer, SISEdgePos eEP, CRect rtROI, int nThres) { if((int)eEP % 2 == 1) return FindEdgeVert(framebuffer, eEP, rtROI, nThres); int i; int nResult = (eEP == eEP_RIGHT) ? INT_MIN : INT_MAX; int nProjectionResult = 0; int nDivide = PROJECTION_SIZE; for(i = 0; i < FIND_EDGE_COUNT; i++) { rtROI.top = framebuffer.GetHeight()/3 * i; rtROI.bottom = rtROI.top + nDivide; if (eEP == eEP_RIGHT) nProjectionResult = ImageProjection(framebuffer.GetDataAddress(0,0), framebuffer.GetWidth(), framebuffer.GetHeight(), rtROI, nThres); else nProjectionResult = ImageProjection_R(framebuffer.GetDataAddress(0,0), framebuffer.GetWidth(), framebuffer.GetHeight(), rtROI, nThres); if (nProjectionResult != -1) nResult = (eEP == eEP_RIGHT) ? max(nResult, nProjectionResult) : min(nResult, nProjectionResult); } if(nResult == INT_MAX || nResult == INT_MIN) { return -1; } else { return nResult; } } int CSISEdgeFind::FindEdgeVert(CSISBuffer framebuffer, SISEdgePos eEP, CRect rtROI, int nThres) { int i; int nResult = (eEP == eEP_BOTTOM) ? INT_MIN : INT_MAX; int nProjectionResult; int nDivide = PROJECTION_SIZE; int nEndRight = rtROI.right; int nEndBottom = rtROI.bottom; int nWidth = rtROI.Width(); int nHeight = rtROI.Height(); //(FIND_EDGE_COUNT - 1)°³ ¿µ¿ª¸¸ ¸ÕÀú ¿§Áö¸¦ ã°í... for(i = 0; i < FIND_EDGE_COUNT; i++) { rtROI.left = nWidth/FIND_EDGE_COUNT * i + nWidth/FIND_EDGE_COUNT/2; rtROI.right = rtROI.left + nDivide; if(eEP == eEP_BOTTOM) nProjectionResult = ImageProjection_Vert(framebuffer.GetDataAddress(0,0), framebuffer.GetWidth(), framebuffer.GetHeight(), rtROI, nThres); else nProjectionResult = ImageProjection_Vert_R(framebuffer.GetDataAddress(0,0), framebuffer.GetWidth(), framebuffer.GetHeight(), rtROI, nThres); if (nProjectionResult != -1) nResult = (eEP == eEP_BOTTOM) ? max(nResult, nProjectionResult) : min(nResult, nProjectionResult); } if(nResult == INT_MAX || nResult == INT_MIN) { return -1; } return nResult; }