// EdgeFind.cpp: implementation of the CEdgeFind class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "EdgeFind.h" #include "SISBuffer.h" #include "EdgeProc.h" #include #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CEdgeFind::CEdgeFind() { m_pHproj = NULL; m_pVproj = NULL; } CEdgeFind::~CEdgeFind() { if(m_pHproj != NULL) delete[] m_pHproj, m_pHproj=NULL; if(m_pVproj != NULL) delete[] m_pVproj, m_pVproj=NULL; } int CEdgeFind::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; 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++) { /* //2 by 1 org= pBuffer->GetPixel(x, y)+ pBuffer->GetPixel(x+ 1, y); tar= (int)(pBuffer->GetPixel(x+ iPitch, y)*pa+ pBuffer->GetPixel(x+iPitch+ 1, y)+ pBuffer->GetPixel(x+iPitch+ 2, y)*pb); */ //3 by 2 // org= pBuffer->GetPixel(x, y)+ pBuffer->GetPixel(x+ 1, y)+ pBuffer->GetPixel(x+ 2, y); // org+=pBuffer->GetPixel(x, y+1)+ pBuffer->GetPixel(x+ 1, y+1)+ pBuffer->GetPixel(x+ 2, y+1); // tar= (int)(pBuffer->GetPixel(x+ iPitch, y)*pa+ pBuffer->GetPixel(x+iPitch+ 1, y)+ pBuffer->GetPixel(x+iPitch+ 2, y)+ pBuffer->GetPixel(x+iPitch+ 3, y)*pb); // tar+=(int)(pBuffer->GetPixel(x+ iPitch, y+1)*pa+ pBuffer->GetPixel(x+iPitch+ 1, y+1)+ pBuffer->GetPixel(x+iPitch+ 2, y+1)+ pBuffer->GetPixel(x+iPitch+ 3, y+1)*pb); // if(abs(org- tar) > threshold) 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 CEdgeFind::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= 0; x< width; x++) { count= 0; for(y= 0; y< height; y++) { /* //2 by 1 org= pBuffer->GetPixel(x, y)+ pBuffer->GetPixel(x+ 1, y); tar= (int)(pBuffer->GetPixel(x+ iPitch, y)*pa+ pBuffer->GetPixel(x+iPitch+ 1, y)+ pBuffer->GetPixel(x+iPitch+ 2, y)*pb); */ //3 by 2 // org= pBuffer->GetPixel(x, y)+ pBuffer->GetPixel(x+ 1, y)+ pBuffer->GetPixel(x+ 2, y); // org+=pBuffer->GetPixel(x, y+1)+ pBuffer->GetPixel(x+ 1, y+1)+ pBuffer->GetPixel(x+ 2, y+1); // tar= (int)(pBuffer->GetPixel(x+ iPitch, y)*pa+ pBuffer->GetPixel(x+iPitch+ 1, y)+ pBuffer->GetPixel(x+iPitch+ 2, y)+ pBuffer->GetPixel(x+iPitch+ 3, y)*pb); // tar+=(int)(pBuffer->GetPixel(x+ iPitch, y+1)*pa+ pBuffer->GetPixel(x+iPitch+ 1, y+1)+ pBuffer->GetPixel(x+iPitch+ 2, y+1)+ pBuffer->GetPixel(x+iPitch+ 3, y+1)*pb); // if(abs(org- tar) > threshold) 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 CEdgeFind::Find_LeftCanny(CSISBuffer *pBuffer,int nThres) { LPBYTE pImg = pBuffer->GetDataAddress(); CSize szImg = CSize(pBuffer->GetWidth(),pBuffer->GetHeight()); if(pImg == NULL || szImg.cx <= 0 || szImg.cy <= 0) return -1; int nLeftLine = -1; const int nFindLineRatio = (int)((double)szImg.cy*0.5); LPBYTE pTgt = new BYTE[szImg.cx*szImg.cy]; ZeroMemory(pTgt,sizeof(BYTE)*szImg.cx*szImg.cy); CEdgeProc EdgeProc; CSISBuffer mosisEdge(pTgt,szImg.cx,szImg.cy); if(EdgeProc.CannyEdgeProcessing(pImg,CRect(0,0,szImg.cx,szImg.cy),GM_Sobel,nThres,mosisEdge) == FALSE) { delete[] pTgt, pTgt=NULL; return nLeftLine; } // CString str; // if(pImg != NULL) // { // CSISBuffer mosis(pImg,szImg.cx,szImg.cy); // str.Format("D:\\Image\\Org.bmp"); // CBufferAttach attach(str); // attach.AttachToFile(mosis); // } // // if(pTgt != NULL) // { // CSISBuffer mosis(pTgt,szImg.cx,szImg.cy); // str.Format("D:\\Image\\Edge.bmp"); // CBufferAttach attach(str); // attach.AttachToFile(mosis); // } int u,v,nCount; for(u=2;u= nFindLineRatio) { nLeftLine = u; break; } } delete[] pTgt, pTgt=NULL; return nLeftLine; } double CEdgeFind::FindLine_H(LPBYTE pImg,CSize szImg,CRect &rectIns,int nThres,EDGELINE_POLAR enDir,EdgeSignalType enSignalType,enEdgeFindType enFind) { if(pImg == NULL || szImg.cx <= 0) return -1; if(enFind == EDGE_PROJECTION) return FindGlassHorizontalLine(pImg,szImg,rectIns,nThres,TRUE); if(m_pHproj != NULL) delete[] m_pHproj, m_pHproj=NULL; m_pHproj = new IMPROJ[szImg.cx+1]; ZeroMemory(m_pHproj,sizeof(IMPROJ)*(szImg.cx+1)); CRect rect = rectIns; ULONG nProjMax,nProjMin; int nPos = -1; double dAvgPos = 0; AssertOnFrameRect(rect,szImg); if(FV_ProjGet(pImg,szImg,rect,PROJECTION_VERTICAL,m_pHproj,&nProjMax,&nProjMin) == TRUE) { switch(enFind) { case EDGE_MAXCONTRAST: nPos = FindMaxContrastEx(m_pHproj,rect.left,rect.right,szImg.cx,rect.Height(),enDir,nThres); break; case EDGE_FIRSTEDGE: nPos = FindFirstEdge(m_pHproj,rect.left,rect.right,szImg.cx,rect.Height(),enDir,nThres); break; default: { if(m_pHproj != NULL) delete[] m_pHproj, m_pHproj=NULL; return dAvgPos; } } if(nPos <= -1) { CSISBuffer buffer(pImg,szImg.cx,szImg.cy); int nMaxVal; nPos = FindMaxContrast(buffer,rect,TRUE,nMaxVal); if(nPos == -1) { if(m_pHproj != NULL) delete[] m_pHproj, m_pHproj=NULL; return dAvgPos; } } dAvgPos = (double)nPos; rect.left = nPos - 5; rect.right = nPos + 5; double dTmp = FindLineSubPixel(pImg,szImg,rect,nThres,-nThres,DIR_HORIZONTAL,SearchTypeIn2Out,enSignalType); if(dTmp != -1) dAvgPos = dTmp; //dAvgPos = GetSubPixelPos(pImg,nPos,szImg,rect,dRatio,bLeft,DIR_HORIZONTAL,nNumber); } if(m_pHproj != NULL) delete[] m_pHproj, m_pHproj=NULL; return dAvgPos; } BOOL CEdgeFind::FindGlssEdgeLine(int &nPos,CRect rect,LPIMPROJ pProj,BOOL bDir,PROJECTION_TYPE nType,int nThres,int nContiValue,int nDist) { if(pProj == NULL) return FALSE; int nThreshold = nThres * rect.Width(); int iX,nCountinueCount,nGab; nPos = -1; nCountinueCount = 0; switch(nType) { case PROJECTION_VERTICAL: { nThreshold = nThres * rect.Height(); if(bDir == TRUE) // Left -> Right { for(iX=rect.left;iX nThreshold) nCountinueCount++; else nCountinueCount = 0; if (nCountinueCount >= nContiValue) { nPos = pProj[iX+nDist].x-(nContiValue-1); return TRUE; } } } else // Right -> Left { for(iX=rect.right-1;iX>=rect.left+nDist;iX--) { nGab = abs(pProj[iX].f - pProj[iX-nDist].f); if (nGab > nThreshold) nCountinueCount++; else nCountinueCount = 0; if (nCountinueCount >= nContiValue) { nPos = pProj[iX-nDist].x+(nContiValue-1); return TRUE; } } } } break; case PROJECTION_HORIZONTAL: { nThreshold = nThres * rect.Width(); if(bDir == TRUE) // Top -> Bottom { for(iX=rect.top;iX nThreshold) nCountinueCount++; else nCountinueCount = 0; if (nCountinueCount >= nContiValue) { nPos = pProj[iX+nDist].x-(nContiValue-1); return TRUE; } } } else // Bottom -> Top { for(iX=rect.bottom-1;iX>=rect.top+nDist;iX--) { nGab = abs(pProj[iX].f - pProj[iX-nDist].f); if (nGab > nThreshold) nCountinueCount++; else nCountinueCount = 0; if (nCountinueCount >= nContiValue) { nPos = pProj[iX-nDist].x+(nContiValue-1); return TRUE; } } } } break; } return FALSE; } double CEdgeFind::FindGlassHorizontalLine(LPBYTE pImg,CSize szImg,CRect &rectIns,int nThres,BOOL bDir, int nDist) { if(pImg == NULL || szImg.cx <= 0) return -1; if(m_pHproj != NULL) delete[] m_pHproj, m_pHproj=NULL; m_pHproj = new IMPROJ[szImg.cx+1]; ZeroMemory(m_pHproj,sizeof(IMPROJ)*(szImg.cx+1)); CRect rect = rectIns; ULONG nProjMax,nProjMin; BOOL bRet = FALSE; int nPos = -1; const int nContinueCnt = 2; const int nLevelDist = nDist; double dAvgPos = 0; AssertOnFrameRect(rect,szImg); if(FV_ProjGet(pImg,szImg,rect,PROJECTION_VERTICAL,m_pHproj,&nProjMax,&nProjMin) == TRUE) { if(FindGlssEdgeLine(nPos,rect,m_pHproj,bDir,PROJECTION_VERTICAL,nThres,nContinueCnt,nLevelDist) == FALSE) { if(m_pHproj != NULL) delete[] m_pHproj, m_pHproj=NULL; return -1; } else { dAvgPos = nPos; /* CRect rectCon(nPos-2,rect.top,nPos+2,rect.bottom); CSISBuffer buffer(pImg,szImg.cx,szImg.cy); int nMaxVal; int nMaxCon = FindMaxContrast(buffer,rectCon,TRUE,nMaxVal); if(nMaxCon != -1) nPos = nMaxCon; double cPos; double dPosVal[3]; int nHorStart = nPos; int v; double dSumPos=0,dSumCnt=0; for(v=rect.top;v 0) dAvgPos = dSumPos/dSumCnt; dAvgPos += nPos; */ } } if(m_pHproj != NULL) delete[] m_pHproj, m_pHproj=NULL; return dAvgPos; } double CEdgeFind::FindGlassVerticalLine(LPBYTE pImg,CSize szImg,CRect &rectIns,int nThres,BOOL bDir,int nDist) { if(pImg == NULL || szImg.cy <= 0) return -1; if(m_pVproj != NULL) delete[] m_pVproj, m_pVproj=NULL; m_pVproj = new IMPROJ[szImg.cy+1]; ZeroMemory(m_pVproj,sizeof(IMPROJ)*(szImg.cy+1)); CRect rect = rectIns; ULONG nProjMax,nProjMin; BOOL bRet = FALSE; int nVertical = -1; const int nContinueCnt = 3; const int nLevelDist = nDist; double dAvgPos; AssertOnFrameRect(rect,szImg); if(FV_ProjGet(pImg,szImg,rect,PROJECTION_HORIZONTAL,m_pVproj,&nProjMax,&nProjMin) == TRUE) { if(FindGlssEdgeLine(nVertical,rect,m_pVproj,bDir,PROJECTION_HORIZONTAL,nThres,nContinueCnt,nLevelDist) == FALSE) { if(m_pVproj != NULL) delete[] m_pVproj, m_pVproj=NULL; return -1; } else { dAvgPos = nVertical; /* CRect rectCon(rect.left,nVertical-2,rect.right,nVertical+2); CSISBuffer buffer(pImg,szImg.cx,szImg.cy); int nMaxVal; int nMaxCon = FindMaxContrast(buffer,rectCon,FALSE,nMaxVal,bDir); if(nMaxCon != -1) nVertical = nMaxCon; double cPos; double dPosVal[3]; int nVertStart = nVertical; int u; double dSumPos=0,dSumCnt=0; for(u=rect.left;u 0) dAvgPos = dSumPos/dSumCnt; dAvgPos += nVertical; */ } } if(m_pVproj != NULL) delete[] m_pVproj, m_pVproj=NULL; return dAvgPos; } double CEdgeFind::FindLine_V(LPBYTE pImg,CSize szImg,CRect &rectIns,int nThres,EDGELINE_POLAR enDir,EdgeSignalType enSignalType,enEdgeFindType enFind,BOOL bTop) { if(pImg == NULL || szImg.cy <= 0) return -1; if(enFind == EDGE_PROJECTION) { return FindGlassVerticalLine(pImg,szImg,rectIns,nThres,bTop); } if(m_pVproj != NULL) delete[] m_pVproj, m_pVproj=NULL; m_pVproj = new IMPROJ[szImg.cy+1]; ZeroMemory(m_pVproj,sizeof(IMPROJ)*(szImg.cy+1)); CRect rect = rectIns; ULONG nProjMax,nProjMin; int nPos = -1; double dAvgPos = 0; AssertOnFrameRect(rect,szImg); if(FV_ProjGet(pImg,szImg,rect,PROJECTION_HORIZONTAL,m_pVproj,&nProjMax,&nProjMin) == TRUE) { switch(enFind) { case EDGE_MAXCONTRAST: nPos = FindMaxContrastEx(m_pVproj,rect.top,rect.bottom,szImg.cy,rect.Width(),enDir,nThres,bTop); break; case EDGE_FIRSTEDGE: nPos = FindFirstEdge(m_pVproj,rect.top,rect.bottom,szImg.cy,rect.Width(),enDir,nThres,bTop); break; default: { if(m_pVproj != NULL) delete[] m_pVproj, m_pVproj=NULL; return dAvgPos; } } if(nPos <= -1) { CSISBuffer buffer(pImg,szImg.cx,szImg.cy); int nMaxVal; nPos = FindMaxContrast(buffer,rect,FALSE,nMaxVal,bTop); if(nPos == -1) { if(m_pVproj != NULL) delete[] m_pVproj, m_pVproj=NULL; return dAvgPos; } } dAvgPos = (double)nPos; rect.top = nPos - 5; rect.bottom = nPos + 5; double dTmp = FindLineSubPixel(pImg,szImg,rect,nThres,-nThres,DIR_VERTICAL,SearchTypeIn2Out,enSignalType); if(dTmp != -1) dAvgPos = dTmp; //dAvgPos = GetSubPixelPos(pImg,nPos,szImg,rect,dRatio,bTop,DIR_VERTICAL,nNumber); } if(m_pVproj != NULL) delete[] m_pVproj, m_pVproj=NULL; return dAvgPos; } void CEdgeFind::AssertOnFrameRect(CRect &rect,CSize szImg) { if(szImg.cx <= 0 || szImg.cy <= 0) return; if(rect.left < 0) rect.left = 0; if(rect.left > szImg.cx) rect.left = szImg.cx-1; if(rect.right < 0) rect.right = 0; if(rect.right > szImg.cx) rect.right = szImg.cx-1; if(rect.left > rect.right) std::swap(rect.left,rect.right); if(rect.top < 0) rect.top = 0; if(rect.top > szImg.cy) rect.top = szImg.cy-1; if(rect.bottom < 0) rect.bottom = 0; if(rect.bottom > szImg.cy) rect.bottom = szImg.cy-1; if(rect.top > rect.bottom) std::swap(rect.top,rect.bottom); } // BOOL IMProjGet(IMAGE src, ROI roi, long type, IMPROJ* res, unsigned long* max, unsigned long* min) // * Get the projected data // * Parameters // - src : image // - rect : ROI // - type : direction // - res : projection data pointer // - max : maximum value // - min : minimum value //------------------------------------------------------------------------ BOOL CEdgeFind::FV_ProjGet(LPBYTE src,CSize szImg, CRect &rect, PROJECTION_TYPE type, IMPROJ* res, ULONG* max, ULONG* min) { if(res == NULL || src == NULL) return FALSE; long cu = szImg.cx, cv = szImg.cy; unsigned char *buf = src; long u, v, i; unsigned long sum, *mx = max, *mn = min; switch(type) { case PROJECTION_VERTICAL: ZeroMemory(res,sizeof(IMPROJ)*rect.Width()); *mx = 0; *mn = (rect.bottom-rect.top+1)*255; for(i=0, u=rect.left; u sum) *mn = sum; i++; } return TRUE; case PROJECTION_HORIZONTAL: ZeroMemory(res,sizeof(IMPROJ)*rect.Height()); *mx = 0; *mn = (rect.right-rect.left+1)*255; for(i=0, v=rect.top; v sum) *mn = sum; i++; } return TRUE; } return FALSE; } int CEdgeFind::FindMaxContrastEx(IMPROJ* src, int nStart,int nEnd, long Width, long Height, EDGELINE_POLAR enDir, long Thresh,BOOL bForward) { long i, j, k; long *fvalue; int ret = -1; long sum, max = 0, min = 0; long val; fvalue = new long[Width]; ZeroMemory(fvalue,sizeof(long)*Width); int filterWidth; int *mask; filterWidth = 2; mask = (int*)malloc( sizeof(int) * ((filterWidth*2)+1) ); for(i=0; i<(filterWidth*2)+1; i++) { if(i < filterWidth) { mask[i] = -1; } else if( i == filterWidth) { mask[i] = 0; } else { mask[i] = 1; } } for(i=nStart+filterWidth; i= Thresh) { if(fvalue[i] >= max) { max = fvalue[i]; ret = src[i].x; } } } else if(enDir == POLAR_WTOB) { val = fvalue[i]*-1; if(val >= Thresh) { if(val >= max) { max = val; ret = src[i].x; } } } else if(enDir == POLAR_ANY) { val = abs(fvalue[i]); if(val >= Thresh) { if(val >= max) { max = val; ret = src[i].x; } } } } } else { for(i=nEnd-1; i>=nStart; i--) { if(enDir == POLAR_BTOW) { if(fvalue[i] >= Thresh) { if(fvalue[i] >= max) { max = fvalue[i]; ret = src[i].x; } } } else if(enDir == POLAR_WTOB) { val = fvalue[i]*-1; if(val >= Thresh) { if(val >= max) { max = val; ret = src[i].x; } } } else if(enDir == POLAR_ANY) { val = abs(fvalue[i]); if(val >= Thresh) { if(val >= max) { max = val; ret = src[i].x; } } } } } delete[] fvalue; if(mask) free(mask); return ret; } int CEdgeFind::FindMaxContrast(CSISBuffer &bufferOrg,CRect rect,BOOL bHor,int &nMaxDiff,BOOL bForward) { int nPos = -1; int i,j,nCnt,iLoop; int *pVal = NULL; int nMaxVal = 0; int nDiff; nMaxDiff = 0; if(bHor == TRUE) { pVal = new int[rect.Width()+1]; nCnt = rect.Width()+1; ZeroMemory(pVal,sizeof(int)*nCnt); for(i=rect.top;i nMaxDiff) nMaxDiff = nDiff; } } for(i=0;i nMaxDiff) nMaxDiff = nDiff; } } for(i=0;i=rect.top+1;j--,iLoop++) { nDiff = abs(*bufferOrg.GetDataAddress(i,j)-*bufferOrg.GetDataAddress(i,j-1)); pVal[iLoop] += nDiff; if(nDiff > nMaxDiff) nMaxDiff = nDiff; } } for(i=0;i Thresh) { for(int j=0; j max) { max = fvalue[i+j]; max_index = j; } } ret = src[i].x + max_index; break; } } else if(enDir == POLAR_WTOB) { if(fvalue[i]*-1 > Thresh) { for(int j=0; j max) { max = fvalue[i+j]; max_index = j; } } ret = src[i].x + max_index; break; } } else if(enDir == POLAR_ANY) { if(abs(fvalue[i]) > Thresh) { for(int j=0; j max) { max = fvalue[i+j]; max_index = j; } } ret = src[i].x + max_index; break; } } } } else { for(i=nEnd - filterWidth-1; i>=nStart+filterWidth; i--) { sum = 0; for(j=0, k=filterWidth; j<(filterWidth*2)+1; j++, k--) { sum += src[i+k].f * mask[j]; } fvalue[i] = sum / ((Height+1)*filterWidth); } for(i=nEnd-1; i>=nStart; i--) { if(enDir == POLAR_BTOW) { if(fvalue[i] > Thresh) { for(int j=0; j max) { max = fvalue[i+j]; max_index = j; } } ret = src[i].x + max_index; break; } } else if(enDir == POLAR_WTOB) { if(fvalue[i]*-1 > Thresh) { for(int j=0; j max) { max = fvalue[i+j]; max_index = j; } } ret = src[i].x + max_index; break; } } else if(enDir == POLAR_ANY) { if(abs(fvalue[i]) > Thresh) { for(int j=0; j max) { max = fvalue[i+j]; max_index = j; } } ret = src[i].x + max_index; break; } } } } delete[] fvalue; if(mask) free(mask); return ret; } double CEdgeFind::FindLineSubPixel(LPBYTE pImg,CSize szImg,CRect &rectIns,int nPosiThres,int nNegaThres,EDGELINE_DIR enDir,EdgeSearchType enSearchType,EdgeSignalType enSignalType,int nKernelSize) { if(pImg == NULL) return -1; CRect rect = rectIns; double dAvgPos = -1; AssertOnFrameRect(rect,szImg); if(CalculateImageValue(enDir,pImg,szImg.cx,szImg.cy,rect,szImg.cx,m_vectorImageData) == FALSE) return dAvgPos; if(CalculateEdgeValue(m_vectorImageData,m_vectorEdgeData,m_vectorEdgeType,nPosiThres,nNegaThres,nKernelSize) == FALSE) return dAvgPos; CalculateEdgePosition(SubPixelQuadratic, nPosiThres, nNegaThres); // get left position double dLeftPos = 9999.0; if (!GetEdgeLeftPosition(enSignalType, enSearchType, 0, dLeftPos)) { return dAvgPos; } if(enDir == DIR_HORIZONTAL) dAvgPos = rect.left + dLeftPos; else dAvgPos = rect.top + dLeftPos; return dAvgPos; } BOOL CEdgeFind::CalculateImageValue(EDGELINE_DIR nDirection, BYTE *pImage, int nWidth, int nHeight, CRect &rect, int nStep, VectorDouble& vectorImageData) { vectorImageData.clear(); if (pImage==NULL) return FALSE; double dValue = 0.0; switch (nDirection) { case DIR_HORIZONTAL: for (int j=rect.left; j= dPositiveThres) { nType = EdgeTypePositive; } else if (dValue <= dNegativeThres ) { nType = EdgeTypeNegative; } vectorEdgeType.push_back(nType); vectorEdgeData.push_back(dValue); } break; case DIR_HORIZONTAL: for (int i=0; i= dPositiveThres) { nType = EdgeTypePositive; } else if (dValue <= dNegativeThres ) { nType = EdgeTypeNegative; } vectorEdgeData.push_back(dValue); vectorEdgeType.push_back(nType); } break; } return TRUE; } BOOL CEdgeFind::CalculateEdgeValue(const VectorDouble& vectorImageData, VectorDouble& vectorEdgeData, int nKernelSize) { if (nKernelSize<2 || (nKernelSize%2)!=0) return FALSE; if (vectorImageData.size()= dPositiveThres) { nType = EdgeTypePositive; } else if (dValue <= dNegativeThres ) { nType = EdgeTypeNegative; } vectorEdgeData.push_back(dValue); vectorEdgeType.push_back(nType); } // push last pitch for (UINT i=0; i= 0 && edgeResult.dPosition <= m_vectorEdgeType.size()-1) { m_vectorEdgeResult.push_back(edgeResult); nEdgeIndex++; } } } // end for } else { for (UINT i=1; i m_vectorEdgeData[j]) { nEdgePosition = j; dEdgeValue = m_vectorEdgeData[j]; } i = j; } } break; } // end switch if (nEdgeType==EdgeTypeNone) continue; CEdgeResult edgeResult(nEdgeIndex, nEdgeType, nEdgePosition, dEdgeValue); switch(nSubPixelType) { case SubPixelQuadratic: if (CalculateInterpolateQuadratic(edgeResult)) { m_vectorEdgeResult.push_back(edgeResult); nEdgeIndex++; } break; case SubPixelRegression: if (CalculateInterpolateRegression(edgeResult)) { m_vectorEdgeResult.push_back(edgeResult); nEdgeIndex++; } break; } // end switch } // end for } } BOOL CEdgeFind::CalculateInterpolateQuadratic(CEdgeResult& edgeResult) { if (m_vectorEdgeData.size()<1) return FALSE; UINT i = 0; for (i=edgeResult.nEdgePosition-1; i>0; i--) { if (m_vectorEdgeType[i]!=edgeResult.nSignal) break; edgeResult.nLeftPosition = i; } for (i=edgeResult.nEdgePosition+1; idCoef!=0.0) { switch(pCurrent->nDegree) { case 2: a = pCurrent->dCoef; break; case 1: b = pCurrent->dCoef; break; case 0: c = pCurrent->dCoef; break; } } } // PrintGraph(listPolynomial, edgeResult.nLeftPosition - edgeResult.nEdgePosition, edgeResult.nRightPosition - edgeResult.nEdgePosition); // remove polynomial RemovePolynomial(listPolynomial); // ¿ø·¡ À§Ä¡ º¹±Í. edgeResult.dPosition = (-1.0 * b) / (2.0 * a); edgeResult.dStrength = -1.0 * ( ( (b*b) - (4.0 * a * c) ) / (4.0 * a) ); return TRUE; } BOOL CEdgeFind::CalculateInterpolateRegression(CEdgeResult& edgeResult) { if (m_vectorEdgeData.size()<1) return FALSE; UINT i = 0; for (i=edgeResult.nEdgePosition-1; i>0; i--) { if (m_vectorEdgeType[i]!=edgeResult.nSignal) break; edgeResult.nLeftPosition = i; } for (i=edgeResult.nEdgePosition+1; idCoef!=0.0) { switch(pCurrent->nDegree) { case 1: a = pCurrent->dCoef; break; case 0: b = pCurrent->dCoef; break; } } } // remove polynomial RemovePolynomial(listPolynomial); if (edgeResult.nSignal==EdgeTypeNegative) { dEdgeThreshold *= -1.0; } edgeResult.dPosition = (dEdgeThreshold-b) / a; edgeResult.dStrength = dEdgeThreshold; return TRUE; } BOOL CEdgeFind::CalculateLagrange(VectorDouble& vectorX, VectorDouble& vectorY, ListPolynomial& listPolynomial) { if (vectorX.size()<2) return FALSE; if (vectorX.size()!=vectorY.size()) return FALSE; int n = int(vectorX.size()); int i, j; int sign; double coef, temp; for (i=0; inDegree == pNewPoly->nDegree) { // ÇöÀç ³ëµå¿Í Â÷¼ö °°À¸¸é ÇöÀç ³ëµå¿¡ °è¼ö¸¦ ´õÇϰí, »ý¼º³ëµå´Â »èÁ¦ÇÑ´Ù. pCurrent->dCoef += pNewPoly->dCoef; delete pNewPoly; bAdded = TRUE; break; } else if (pCurrent->nDegree < pNewPoly->nDegree) { // ÇöÀç ¾Õ¿¡ »ðÀÔÇÑ´Ù. listPolynomial.push_front(pNewPoly); bAdded = TRUE; break; } } // ¾Õ¿¡¼­ Ãß°¡°¡ ¾ÈµÇ¾úÀ¸¸é, ¸ÇµÚ¿¡ »ðÀÔÇÑ´Ù. if (!bAdded) { listPolynomial.push_back(pNewPoly); return; } } void CEdgeFind::RemovePolynomial(ListPolynomial& listPolynomial) { /* for(ListPolynomialIt it=listPolynomial.begin(); it!= listPolynomial.end(); it++) { CPolynomial *pNode = *it; //listPolynomial.erase(it); delete pNode; } listPolynomial.clear(); */ ListPolynomialIt it = listPolynomial.begin(); while (it != listPolynomial.end()) { CPolynomial *pNode = *it; delete pNode; listPolynomial.erase(it++); } listPolynomial.clear(); } double CEdgeFind::Combi(VectorDouble& vectorX, VectorDouble& vectorY, int n, int r) { int i; double result = 1; if (n<0 || r<0 || n0) ? x: -x; return init + x; } double CEdgeFind::Sum(double init, double x) { return init + x; } BOOL CEdgeFind::GetEdgeLeftPosition(int nEdgeType, int nSearchType, int nStartPos, double& dPosition) { if (m_vectorEdgeResult.size()<1) return FALSE; BOOL bReturn = FALSE; UINT nWidth = (UINT)m_vectorImageData.size(); double dValue = -9999.0; int nIndex = -1; UINT i = 0; switch(nSearchType) { case SearchTypeOut2In: dPosition = 9999.; for (i=0; i dPosition) { dValue = m_vectorEdgeResult[i].dStrength; dPosition = m_vectorEdgeResult[i].dPosition; bReturn = TRUE; nIndex = i; } } break; case SearchTypeMinMax: dValue = 0.; for (i=0; i dPosition) { dValue = m_vectorEdgeResult[i].dStrength; dPosition = m_vectorEdgeResult[i].dPosition; bReturn = TRUE; nIndex = i; } } break; case SearchTypeIn2Out: dPosition = 9999.; for (i=0; i