차근차근/OpenCV

몰라요..매칭률검색하다가 나옴

예쁜꽃이피었으면 2014. 8. 6. 17:25

뭔진 모르지만 좋아보임..나중에 한번 봐야지..


http://read.pudn.com/downloads113/sourcecode/graph/text_recognize/474247/2/%E8%8D%A4%E5%A4%AF%20-%20LswVisionMouse/MouthFeature.cpp__.htm




  • #include "StdAfx.h"   
  • #include "MouthFeature.h"   
  •    
  • CMouthFeature::CMouthFeature()   
  • {   
  •     m_boundaryMin = m_boundaryMax = cvPoint( 1, 1 );      
  •     threshold= 130;   
  •     m_pPrevBuffer = new unsigned char[ TRACK_CAMERA_WIDTH*TRACK_CAMERA_HEIGHT ];   
  •     memset( m_pPrevBuffer, 0, TRACK_CAMERA_WIDTH*TRACK_CAMERA_HEIGHT );   
  •     m_count = 0;   
  •     m_projScale = 10;   
  •    
  •     m_switch1 = 0;   
  •     m_switch2 = 0;   
  •     m_switch3 = 0;   
  •     m_switch4 = 0;   
  •     m_switch5 = 0;   
  •     m_segmentCountX=0;   
  •     m_segmentCountY=0;   
  •     m_bIsActive = false;   
  •     m_mouthHeightOffset = 0;   
  •    
  •     m_threshImage = cvCreateImage( cvSize( TRACK_CAMERA_WIDTH, TRACK_CAMERA_HEIGHT ), 8, 1 );   
  • }   
  •    
  • CMouthFeature::~CMouthFeature()   
  • {   
  •     delete [] m_pPrevBuffer;   
  • }   
  •    
  • // image에 모든 points를 그린다   
  • void CMouthFeature::drawBoundary( CvArr* image )   
  • {   
  •     cvRectangle( image, m_boundaryMin, m_boundaryMax, CV_RGB(255,0,0) );   
  • }   
  •    
  • void CMouthFeature::removeNoise( IplImage* greyImage )   
  • {   
  •     int i;   
  •     int size = TRACK_CAMERA_WIDTH*TRACK_CAMERA_HEIGHT;   
  •     int thresh = 12; //18; //13;   
  •     for( i=0; i<size; i++ ) {   
  •         if( abs( greyImage->imageData[ i ] - m_pPrevBuffer[ i ] ) < thresh ) {   
  •             greyImage->imageData[ i ] = m_pPrevBuffer[ i ];   
  •         }   
  •         m_pPrevBuffer[ i ] = greyImage->imageData[ i ];   
  •     }   
  • }   
  •    
  • #include "highgui.h"   
  • void CMouthFeature::updateStep1( IplImage* greyImage, IplImage* rgbFrame )   
  • {   
  •     //#################################################################   
  •     // 이미지 변환   
  •     switch( m_switch1 ) {   
  •         case 0:   
  •             break;   
  •         case 1:   
  •             // HSV의 H채널을 사용   
  •             cvCvtColor( rgbFrame , rgbFrame, CV_RGB2HSV);   
  •             cvSetImageCOI(rgbFrame,1);   
  •             cvCopy(rgbFrame,greyImage);   
  •             cvSetImageCOI(rgbFrame,0);   
  •             cvCvtColor( rgbFrame, rgbFrame, CV_HSV2RGB);   
  •             break;   
  •         case 2:   
  •             // RGB의 R채널을 사용   
  •             IplImage* tempB = cvCreateImage( cvSize( TRACK_CAMERA_WIDTH, TRACK_CAMERA_HEIGHT ), 8, 1 );   
  •             IplImage* tempG = cvCreateImage( cvSize( TRACK_CAMERA_WIDTH, TRACK_CAMERA_HEIGHT ), 8, 1 );   
  •             cvCvtPixToPlane( rgbFrame, tempB, tempG, greyImage, NULL);   
  •             cvReleaseImage( &tempB );   
  •             cvReleaseImage( &tempG );   
  •             break;   
  •     }   
  •    
  •     //ljs   
  •     cvCopy(greyImage,m_threshImage);   
  •     cvThreshold(m_threshImage,m_threshImage,threshold,255,CV_THRESH_BINARY_INV);   
  •     adjustThreshold();   
  •     //cvShowImage("sub1",m_threshImage);   
  • }   
  •    
  • void CMouthFeature::updateStep2( IplImage* greyImage )   
  • {   
  •     // 잡음제거   
  •     if( m_switch2 > 0 )   
  •         removeNoise( greyImage );   
  • }   
  •    
  • void CMouthFeature::updateStep3( IplImage* greyImage )   
  • {   
  •     // 모폴로지 적용     
  •     if( m_switch3 > 0 ) {   
  •         cvSmooth( greyImage, greyImage );   
  •         cvDilate( greyImage, greyImage, NULL, 1 );   
  •         cvErode( greyImage, greyImage, NULL, 3 );   
  •     }   
  • }   
  •    
  • void CMouthFeature::updateStep4( IplImage* greyImage )   
  • {      
  •     // 이진화   
  •     // threshold_type=CV_THRESH_TOZERO_INV:   
  •     // dst(x,y) = 0, if src(x,y)>threshold   
  •     //   src(x,y), otherwise   
  •     switch( m_switch4 ) {   
  •     case 0:   
  •         cvThreshold( greyImage, greyImage, threshold, 0, CV_THRESH_TOZERO_INV );   
  •         /*  
  •         if(threshold<3) threshold=3;  
  •         if(threshold%2==0) threshold++;  
  •         cvAdaptiveThreshold(greyImage,greyImage,255,CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY_INV,threshold,5);  
  •         */   
  •         break;   
  •     case 1:   
  •         cvThreshold( greyImage, greyImage, threshold, 0, CV_THRESH_TOZERO );       
  •         break;   
  •     case 2:   
  •         cvThreshold( greyImage, greyImage, threshold, 255, CV_THRESH_BINARY_INV );     
  •         break;   
  •     }   
  •     //cvThreshold( greyImage, grey, threshold, 255, CV_THRESH_BINARY_INV );    
  • }   
  •    
  • void CMouthFeature::updateStep5( IplImage* greyImage, IplImage* rgbFrame, bool isFaceThere )   
  • {   
  •     // 그레이로 바꾼 영상을 다시 컬러로 출력하기 위해!!   
  •     bool projectInv = false;   
  •     if( m_switch5 > 0 )    
  •         projectInv = true;   
  •     cvCvtColor( greyImage, rgbFrame, CV_GRAY2RGB );   
  •     if( isFaceThere ) {   
  •         calcProjection( rgbFrame, greyImage, projectInv );   
  •     }   
  •     drawBoundary( rgbFrame );   
  • }   
  •    
  • void CMouthFeature::updateStep6()   
  • {   
  •     /*  
  •     // 템플릿 매칭  
  •     if( mouthROI != NULL ) {          
  •         double min, max;  
  •         CvPoint left_top;         
  •         double bestMax = 0.0;  
  •         int bestIndex = -1;  
  •         CvPoint best_left_top;  
  •   
  •         DWORD dwStart = timeGetTime();  
  •         for( int i=0; i<4; i++ ) {  
  •             cvMatchTemplate( mouthROI, mouthTmp[i], coeffFrame, CV_TM_CCOEFF_NORMED );  
  •             cvMinMaxLoc( coeffFrame, &min, &max, NULL, &left_top); // 상관계수가 최대값을 갖는 위치 찾기  
  •             if( max > bestMax ) {  
  •                 bestMax = max;  
  •                 best_left_top = left_top;  
  •                 bestIndex = i;  
  •             }  
  •         }  
  •         DWORD dwEnd = timeGetTime();  
  •         TRACE( "best index: %d, max: %f, time: %d\n", bestIndex, bestMax, dwEnd - dwStart );  
  •                   
  •         left_top.x += minPt.x;  
  •         left_top.y += minPt.y;  
  •         cvRectangle( rgbFrame, left_top, cvPoint( left_top.x + mouthTmp[0]->width, left_top.y + mouthTmp[0]->height), CV_RGB(0,255,0));  
  •     }  
  •     */   
  • }   
  •    
  • void CMouthFeature::updateFrame( IplImage* greyImage, IplImage* rgbFrame, bool isFaceThere )   
  • {   
  •     //#################################################################   
  •     // 이미지 변환   
  •     updateStep1( greyImage, rgbFrame );   
  •    
  •     // LSW_070405 테스트   
  • //  cvSaveImage( "c:\\TImage_1)이미지변환.bmp", greyImage );   
  •    
  •     //#################################################################   
  •     // 잡음제거   
  •     updateStep2( greyImage );   
  •    
  •     // LSW_070405 테스트   
  • //  cvSaveImage( "c:\\TImage_2)잡음제거.bmp", greyImage );   
  •    
  •     //#################################################################   
  •     // 모폴로지 적용   
  •     updateStep3( greyImage );   
  •    
  •     // LSW_070405 테스트   
  • //  cvSaveImage( "c:\\TImage_3)모폴로지적용.bmp", greyImage );   
  •    
  •     //#################################################################   
  •     // 이진화   
  •     updateStep4( greyImage );   
  •    
  •     // LSW_070405 테스트   
  • //  cvSaveImage( "c:\\TImage_4)이진화.bmp", greyImage );   
  •    
  •     //#################################################################   
  •     // 그레이로 바꾼 영상을 다시 컬러로 출력하기 위해!!   
  •     updateStep5( greyImage, rgbFrame, isFaceThere );   
  •    
  •     // LSW_070405 테스트   
  • //  cvSaveImage( "c:\\TImage_5)다시컬러.bmp", greyImage );   
  •        
  •     //#################################################################   
  •     // 템플릿 매칭   
  •     updateStep6();             
  •    
  •     //#################################################################   
  •     // 자동 Threshold 계산    
  •     adjustThreshold();   
  •        
  • }   
  •    
  • void CMouthFeature::calcProjectionHori(  IplImage* image, IplImage* grey, bool projectInv )   
  • {   
  •     int yy;   
  •     float maxHistoHori, minHistoHori;   
  •     int maxPos;   
  •    
  •     m_hMin1 = m_hMin2 = maxPos = 0;   
  •     maxHistoHori = 0;   
  •     minHistoHori = 999;   
  •    
  •     int upCount=0;   
  •     int downCount=0;   
  •     int prevSum=0;   
  •    
  •     int dx = m_boundaryMax.x - m_boundaryMin.x;   
  •     int dy = m_boundaryMax.y - m_boundaryMin.y;   
  •    
  •     // Horizontal Projection   
  •     int boundaryWidth = m_boundaryMax.x - m_boundaryMin.x;   
  •     //for( yy=m_boundaryMin.y; yy<m_boundaryMax.y; yy++ ) {   
  •     for( yy=m_boundaryMin.y; yy<m_boundaryMin.y+dy/2; yy++ ) {   
  •         float sumX = 0;   
  •         forint xx=m_boundaryMin.x; xx<m_boundaryMax.x; xx++ ) {   
  •    
  •             ////   
  •             ////   
  •             ////   
  •             ////   
  •             unsigned char pixel = grey->imageData[ yy*grey->width+xx ];   
  •             if( projectInv ) pixel = 255 - pixel;   
  •             sumX += pixel * m_projScale;   
  •             ////   
  •             ////   
  •             ////   
  •             ////   
  •                
  •         }   
  •         sumX /= boundaryWidth;   
  •         m_histoBuf[ yy ] = sumX;   
  •         if( sumX > maxHistoHori ) {   
  •             maxHistoHori = sumX;   
  •             maxPos = yy;   
  •         }   
  •            
  •         prevSum = sumX;   
  •         cvLine( image, cvPoint( m_boundaryMax.x+1, yy ), cvPoint( m_boundaryMax.x+sumX, yy ), CV_RGB(0,0,255),1 );   
  •     }   
  •     int startX = m_boundaryMin.x;   
  •     int endX = m_boundaryMax.x;   
  •     for( yy=m_boundaryMin.y+dy/2; yy<m_boundaryMax.y; yy++ ) {   
  •         float sumX = 0;   
  •         forint xx=startX; xx<endX; xx++ ) {   
  •    
  •             ////   
  •             ////   
  •             ////   
  •             ////   
  •             unsigned char pixel = grey->imageData[ yy*grey->width+xx ];   
  •             if( projectInv ) pixel = 255 - pixel;   
  •             sumX += pixel * m_projScale;   
  •             ////   
  •             ////   
  •             ////   
  •             ////   
  •                
  •         }   
  •         startX++;   
  •         endX--;   
  •         sumX /= boundaryWidth;   
  •         m_histoBuf[ yy ] = sumX;   
  •         if( sumX > maxHistoHori ) {   
  •             maxHistoHori = sumX;   
  •             maxPos = yy;   
  •         }   
  •            
  •         prevSum = sumX;   
  •         cvLine( image, cvPoint( m_boundaryMax.x+1, yy ), cvPoint( m_boundaryMax.x+sumX, yy ), CV_RGB(0,0,255),1 );   
  •     }   
  •     // 최대값 출력   
  •     cvLine( image, cvPoint( m_boundaryMax.x+1, maxPos ), cvPoint( m_boundaryMax.x+maxHistoHori, maxPos ), CV_RGB(255,255,255),1 );   
  •    
  •     // 최대값의 20%를 threshold값으로 하고 다시 탐색한다.   
  •     minHistoHori = maxHistoHori * 0.2f;   
  •     // 최대값 위치에서 위로 올라오면서 threshold보다 낮아지면 입 윗부분이 끝나는 걸로 간주   
  •     for( yy=maxPos-1; yy>=m_boundaryMin.y; yy-- ) {   
  •         if( m_histoBuf[ yy ] < minHistoHori ) {   
  •             cvLine( image, cvPoint( m_boundaryMax.x+1, yy ), cvPoint( m_boundaryMax.x+minHistoHori, yy ), CV_RGB(255,255,255),1 );   
  •             break;   
  •         }   
  •         if( yy == m_boundaryMin.y) // 없으면 바운딩박스 가장자리에 그린다.   
  •             cvLine( image, cvPoint( m_boundaryMax.x+1, yy ), cvPoint( m_boundaryMax.x+minHistoHori, yy ), CV_RGB(255,255,255),1 );   
  •     }   
  •     m_hMin1 = yy; // 위쪽 최소값 위치   
  •    
  •     // 최대값 다음부터 탐색하면서 threshold보다 낮아지면 입 아랫부분이 끝나는 걸로 간주   
  •     for( yy=maxPos+1; yy<m_boundaryMax.y; yy++ ) {   
  •         if( m_histoBuf[ yy ] < minHistoHori ) {   
  •             cvLine( image, cvPoint( m_boundaryMax.x+1, yy ), cvPoint( m_boundaryMax.x+minHistoHori, yy ), CV_RGB(255,255,255),1 );   
  •             break;   
  •         }   
  •         if( yy == m_boundaryMax.y-1 )    
  •             cvLine( image, cvPoint( m_boundaryMax.x+1, yy ), cvPoint( m_boundaryMax.x+minHistoHori, yy ), CV_RGB(255,255,255),1 );   
  •     }   
  •     m_hMin2 = yy; // 아래쪽 최소값 위치   
  •    
  •     if( m_hMin1 < 0 )    
  •         m_hMin1 = 0;   
  •    
  • //  if( m_bIsActive ) {   
  • //      if( m_hMin1 == m_boundaryMin.y ) {   
  • //          m_mouthHeightOffset--;   
  • //      }   
  • //      int heightThresh = m_boundaryMin.y + dy*0.66f;   
  • //      if( (m_hMin2+m_hMin1)/2 > heightThresh ){   
  • //          m_mouthHeightOffset--;   
  • //      }   
  • //    
  • //  }   
  • }   
  •    
  • void CMouthFeature::calcProjectionVerti(  IplImage* image, IplImage* grey, bool projectInv )   
  • {   
  •     int xx;   
  •     float maxHistoVerti, minHistoVerti;   
  •     int maxPos;   
  •    
  •     m_vMin1 = m_vMin2 = maxPos = 0;   
  •     maxHistoVerti = 0;   
  •     minHistoVerti = 999;   
  •    
  •     // Vertical Projection   
  •     int boundaryHeight = m_boundaryMax.y - m_boundaryMin.y;   
  •     for( xx=m_boundaryMin.x; xx<m_boundaryMax.x; xx++ ) {   
  •         long sumY = 0;   
  •         //for( int yy=m_boundaryMin.y; yy<m_boundaryMax.y; yy++ ) {   
  •         forint yy=m_hMin1; yy<m_hMin2; yy++ ) {   
  •             ////   
  •             ////   
  •             ////   
  •             ////   
  •             unsigned char pixel = grey->imageData[ yy*grey->width+xx ];   
  •             if( projectInv ) pixel = 255 - pixel;   
  •             sumY += pixel * m_projScale;   
  •             ////   
  •             ////   
  •             ////   
  •             ////   
  •         }   
  •         sumY /= boundaryHeight;   
  •         m_histoBuf[ xx ] = sumY;   
  •         if( sumY > maxHistoVerti ) {   
  •             maxHistoVerti = sumY;   
  •             maxPos = xx;   
  •         }   
  •         cvLine( image, cvPoint( xx, m_boundaryMin.y-1 ), cvPoint( xx, m_boundaryMin.y-sumY ), CV_RGB(0,255,0),1 );   
  •     }   
  •     // 최대값 출력   
  •     cvLine( image, cvPoint( maxPos, m_boundaryMin.y-1 ), cvPoint( maxPos, m_boundaryMin.y-maxHistoVerti ), CV_RGB(255,255,255),1 );   
  •        
  •     // 최대값의 20%를 threshold값으로 하고 다시 탐색한다.   
  •     minHistoVerti = maxHistoVerti * 0.2f;   
  •     // 우측으로 가면서 threshold보다 높아지면 입이 시작하는 걸로 간주   
  •     for( xx=m_boundaryMin.x; xx<m_boundaryMax.x; xx++ ) {   
  •         if( m_histoBuf[ xx ] > minHistoVerti ) {   
  •             cvLine( image, cvPoint( xx, m_boundaryMin.y-1 ), cvPoint( xx, m_boundaryMin.y-minHistoVerti ), CV_RGB(255,255,255),1 );   
  •             break;   
  •         }   
  •         if( xx == m_boundaryMax.x-1 ) // 없으면 바운딩박스 가장자리에 그린다.   
  •             cvLine( image, cvPoint( xx, m_boundaryMin.y-1 ), cvPoint( xx, m_boundaryMin.y-minHistoVerti ), CV_RGB(255,255,255),1 );   
  •     }   
  •     m_vMin1 = xx; // 좌측 최소값 위치   
  •     // 좌측으로 오면서 threshold보다 높아지면 입이 끝나는 걸로 간주   
  •     for( xx=m_boundaryMax.x-1; xx>=m_boundaryMin.x; xx-- ) {   
  •         if( m_histoBuf[ xx ] > minHistoVerti ) {   
  •             cvLine( image, cvPoint( xx, m_boundaryMin.y-1 ), cvPoint( xx, m_boundaryMin.y-minHistoVerti ), CV_RGB(255,255,255),1 );   
  •             break;   
  •         }   
  •         if( xx == m_boundaryMin.x )    
  •             cvLine( image, cvPoint( xx, m_boundaryMin.y-1 ), cvPoint( xx, m_boundaryMin.y-minHistoVerti ), CV_RGB(255,255,255),1 );   
  •     }   
  •     m_vMin2 = xx; // 우측 최소값 위치   
  •    
  • }   
  •    
  • // boundary영역에서 projection을 보여준다.   
  • void CMouthFeature::calcProjection( IplImage* image, IplImage* grey, bool projectInv )   
  • {   
  •     calcProjectionHori( image, grey, projectInv );   
  •     calcProjectionVerti( image, grey, projectInv );   
  •    
  • }   
  •    
  • // 포인트 개수 리턴   
  • int CMouthFeature::getCount()   
  • {   
  •     return m_count;   
  • }   
  •    
  • void CMouthFeature::setCount( int num )   
  • {   
  •     m_count = num;   
  • }   
  •    
  •    
  • void CMouthFeature::setMinBoundary( CvPoint minPt )   
  • {   
  •     m_boundaryMin = minPt;   
  •     m_boundaryMin.x = max( m_boundaryMin.x, 0 );   
  •     m_boundaryMin.y = max( m_boundaryMin.y, 0 );   
  •     m_boundaryMin.y += m_mouthHeightOffset;   
  • }   
  • void CMouthFeature::getMinBoundary( CvPoint& minPt )   
  • {   
  •     minPt = m_boundaryMin;   
  • }   
  • void CMouthFeature::setMaxBoundary( CvPoint maxPt )   
  • {   
  •     m_boundaryMax = maxPt;   
  •     // 히스토그램 버퍼의 최대크기는 800이므로 바운딩박스가 800x800보다 크면 조정해준다.   
  •     if( TRACK_CAMERA_WIDTH-1 < m_boundaryMax.x - m_boundaryMin.x )   
  •         m_boundaryMax.x = m_boundaryMin.x + 799;   
  •     if( TRACK_CAMERA_WIDTH-1 < m_boundaryMax.y - m_boundaryMin.y )   
  •         m_boundaryMax.y = m_boundaryMin.y + 799;   
  •    
  •     m_boundaryMax.x = max( m_boundaryMax.x, 1 );   
  •     m_boundaryMax.y = max( m_boundaryMax.y, 1 );   
  •     m_boundaryMax.y += m_mouthHeightOffset;   
  • }   
  • void CMouthFeature::getMaxBoundary( CvPoint& maxPt )   
  • {   
  •     maxPt = m_boundaryMax;   
  • }   
  •    
  • int CMouthFeature::getVerMin1()   
  • {   
  •     return m_vMin1;   
  • }   
  •    
  • int CMouthFeature::getVerMin2()   
  • {   
  •     return m_vMin2;   
  • }   
  •    
  • int CMouthFeature::getHorMin1()   
  • {   
  •     return m_hMin1;   
  • }   
  •    
  • int CMouthFeature::getHorMin2()   
  • {   
  •     return m_hMin2;   
  • }   
  •    
  • void CMouthFeature::setNormalWidth()   
  • {   
  •     float width = m_boundaryMax.x - m_boundaryMin.x;   
  •     m_normalWidth = (float)(m_vMin2-m_vMin1)/width;   
  • }   
  •    
  • void CMouthFeature::setNormalHeight()   
  • {   
  •     float height = m_boundaryMax.x - m_boundaryMin.x;   
  •     m_normalHeight = (float)(m_hMin2-m_hMin1)/height;   
  • }   
  •    
  • float CMouthFeature::getNormalWidth()   
  • {   
  •     setNormalWidth();   
  •     return m_normalWidth;   
  • }   
  • float CMouthFeature::getNormalHeight()   
  • {   
  •     setNormalHeight();   
  •     return m_normalHeight;   
  • }   
  •    
  • void CMouthFeature::resetThreshold()   
  • {   
  •     threshold = 140;   
  • }   
  •    
  • void CMouthFeature::setStaticThreshold( int thresh )   
  • {   
  •     threshold = thresh;   
  • }   
  •    
  • void CMouthFeature::adjustThreshold()   
  • {   
  •     int x,y,i;   
  •     int pX = m_boundaryMax.x - m_boundaryMin.x;   
  •     int pY = m_boundaryMax.y - m_boundaryMin.y;   
  •    
  •     int interval=5;   
  •     int x1 = m_vMin1-interval;   
  •     int x2 = m_vMin2+interval;   
  •     int y1 = m_hMin1-interval;   
  •     int y2 = m_hMin2+interval;   
  •     if( x1<m_boundaryMin.x ) x1=m_boundaryMin.x;   
  •     if( y1<m_boundaryMin.y ) y1=m_boundaryMin.y;   
  •     if( x2>m_boundaryMax.x ) x2=m_boundaryMax.x;   
  •     if( y2>m_boundaryMax.y ) y2=m_boundaryMax.y;   
  •    
  •     bool black;   
  •     int whiteCount;   
  •     int blackCount=0;   
  •     int state=0;   
  •     int startX=0, lastX=0;   
  •     int yThresh = m_boundaryMin.y + pY*0.66f; // 2/3지점 이후로 시작되는 black은 무시   
  •     for( x=x1; x<x2; x++ )   
  •     {   
  •         black=false;   
  •         for( y=y1; y<y2; y++ )   
  •         {   
  •             i = y*TRACK_CAMERA_WIDTH+x;   
  •             if( (unsigned char)m_threshImage->imageData[i]==0 )   
  •             {   
  •                 black=true;   
  •                 break;   
  •             }   
  •         }   
  •         if( black )   
  •         {   
  •             blackCount++;   
  •         }   
  •    
  •         switch(state)   
  •         {   
  •         case 0:   
  •             if( black )   
  •             {   
  •                 state++;   
  •                 whiteCount=0;   
  •             }   
  •             break;   
  •         case 1:   
  •             if( !black )   
  •             {   
  •                 if( ++whiteCount>=2 )   
  •                     state++;   
  •             }   
  •             break;   
  •         case 2:   
  •             if( black )   
  •             {   
  •                 m_segmentCountX++; //검은색 절단 검출   
  •                 whiteCount=0;   
  •                 state=1;   
  •             }   
  •             break;   
  •         }   
  •     }   
  •    
  •     if( m_segmentCountX>=1 || blackCount==0 )   
  •     {   
  •         threshold--;   
  •         m_segmentCountX=0;   
  •     }   
  •    
  •    
  • /*  
  •     int maxVal[3];  
  •     int minVal[3];  
  •     maxVal[0]=maxVal[1]=maxVal[2]=INT_MIN;  
  •     minVal[0]=minVal[1]=minVal[2]=INT_MAX;  
  •     int count;  
  •     for( y=y1; y<y2; y++ )   
  •     {  
  •         count=0;  
  •         for( x=x1; x<x2; x++ )  
  •         {  
  •             i = y*CAMERA_WIDTH+x;  
  •             if( (byte)m_threshImage->imageData[i]==0 )  
  •             {  
  •                 count++;  
  •             }  
  •         }  
  •         if( count==0 ) continue;  
  •   
  •         if( count > maxVal[0] )  
  •         {  
  •             maxVal[1] = maxVal[0];  
  •             maxVal[0] = count;  
  •         }  
  •         else if( count > maxVal[1] )  
  •         {  
  •             maxVal[2] = maxVal[1];  
  •             maxVal[1] = count;  
  •         }  
  •         else if( count > maxVal[2] ) maxVal[2] = count;  
  •   
  •         if( count < minVal[0] )  
  •         {  
  •             minVal[1] = minVal[0];  
  •             minVal[0] = count;  
  •         }  
  •         else if( count < minVal[1] )  
  •         {  
  •             minVal[2] = minVal[1];  
  •             minVal[1] = count;  
  •         }  
  •         else if( count < minVal[2] ) minVal[2] = count;  
  •     }  
  •   
  •     int distance = (maxVal[0]+maxVal[1]+maxVal[2]) - (minVal[0]+minVal[1]+minVal[2]) ;  
  •     if( distance>=50 )  
  •         m_segmentCountY++;  
  •       
  •     if( m_segmentCountY>=10 )  
  •     {  
  •         threshold++;  
  •         m_segmentCountY=0;  
  •     }  
  • */   
  •    
  •    
  •     state=0;   
  •     blackCount=0;   
  •     for( y=y1; y<y2; y++ )   
  •     {   
  •         black=false;   
  •         for( x=x1; x<x2; x++ )   
  •         {   
  •             i = y*TRACK_CAMERA_WIDTH+x;   
  •             if( (unsigned char)m_threshImage->imageData[i]==0 )   
  •             {   
  •                 black=true;   
  •                 break;   
  •             }   
  •         }   
  •         if( black ) blackCount++;   
  •    
  •         switch(state)   
  •         {   
  •         case 0:   
  •             if( black )   
  •             {   
  •                 state++;   
  •                 whiteCount=0;   
  •             }   
  •             break;   
  •         case 1:   
  •             if( !black )   
  •             {   
  •                 if( ++whiteCount>=2 )   
  •                     state++;   
  •             }   
  •             break;   
  •         case 2:   
  •             if( black )   
  •             {   
  •                 m_segmentCountY++; //검은색 절단 검출   
  •                 whiteCount=0;   
  •                 state=1;   
  •             }   
  •             break;   
  •         }   
  •     }   
  •    
  •     if( m_segmentCountY>=1 )   
  •     {   
  •         threshold++;   
  •         m_segmentCountY=0;   
  •     }   
  •        
  • }   

  • 반응형