contour.cpp
Go to the documentation of this file.
00001 
00010 #include "tuw_utils/contour.h"
00011 #include <iostream>
00012 #include <stack>
00013 #include <cstdio>
00014 #include "opencv/highgui.h"
00015 
00016 namespace tuw {
00017 
00018 const int Contour::ANGLE_8U = 8;
00019 const int Contour::ANGLE_32F = 32;
00020 const int Contour::ANGLE_64F = 64;
00021 
00022 
00023 const int Contour::MODE_SIMPLE = 1;
00024 const int Contour::MODE_CONTOUR = 2;
00025 const int Contour::MODE_GRAIDENT = 3;
00026 const int Contour::MODE_COMPLEX = 4;
00027 
00028 const float Contour::fPi  = 3.1415926535897932384626433832795;
00029 const double Contour::dPi = 3.1415926535897932384626433832795;
00030 
00031 const int Contour::pppDirectionWeightsField[4][3][3] = {
00032     {   {2,1,2}, // 0 0 0
00033         {4,0,4}, // 1 1 1
00034         {2,1,2}  // 0 0 0
00035     },
00036     {   {1,2,4}, // 0 0 1
00037         {2,0,2}, // 0 1 0
00038         {4,2,1}  // 1 0 0
00039     },
00040     {   {2,4,2}, // 0 1 0
00041         {1,0,1}, // 0 1 0
00042         {2,4,4}  // 0 1 0
00043     },
00044     {   {4,2,1}, // 1 0 0
00045         {2,0,2}, // 0 1 0
00046         {1,2,4}  // 0 0 1
00047     }
00048 };
00049 
00050 const int Contour::ppGradientWeightsField[4][9] = {
00051     {3, 5, 6, 8, 2, 0, 7, 1, 4},
00052     {2, 6, 1, 3, 7, 5, 0, 8, 4},
00053     {1, 7, 0, 6, 8, 2, 3, 5, 4},
00054     {0, 8, 1, 7, 5, 3, 2, 6, 4}
00055 };
00056 
00057 const int Contour::pppCommingFromEdgeWeightsField[9][3][3] = {
00058     {   {0,1,2}, // 1 0 0
00059         {1,0,3}, // 0 0 0
00060         {2,3,4}  // 0 0 0
00061     },
00062     {   {1,0,1}, // 0 1 0
00063         {2,0,2}, // 0 0 0
00064         {3,4,3}  // 0 0 0
00065     },
00066     {   {2,1,0}, // 0 0 1
00067         {3,0,1}, // 0 0 0
00068         {4,3,2}  // 0 0 0
00069     },
00070     {   {1,2,3}, // 0 0 0
00071         {0,0,4}, // 1 0 0
00072         {1,2,3}  // 0 0 0
00073     },
00074     {   {0,0,0}, // 0 0 0
00075         {0,0,0}, // 0 1 0
00076         {0,0,0}  // 0 0 0
00077     },
00078     {   {3,2,1}, // 0 0 0
00079         {4,0,0}, // 0 0 1
00080         {3,2,1}  // 0 0 0
00081     },
00082     {   {2,3,4}, // 0 0 0
00083         {1,0,3}, // 0 0 0
00084         {0,1,2}  // 1 0 0
00085     },
00086     {   {3,4,3}, // 0 0 0
00087         {2,0,2}, // 0 0 0
00088         {1,0,1}  // 0 1 0
00089     },
00090     {   {4,3,2}, // 0 0 0
00091         {3,0,1}, // 0 0 0
00092         {2,1,0}  // 0 0 1
00093     }
00094 };
00095 
00096 const int Contour::ppContourWeightsField[9][9] = {
00097     {8, 7, 5, 6, 2, 3, 1, 0, 4},
00098     {7, 6, 8, 3, 5, 0, 2, 1, 4},
00099     {6, 7, 3, 8, 0, 5, 1, 2, 4},
00100     {5, 2, 8, 1, 7, 0, 6, 3, 4},
00101     {0, 0, 0, 0, 0, 0, 0, 0, 0},
00102     {3, 6, 0, 7, 1, 8, 2, 5, 4},
00103     {2, 1, 5, 0, 8, 3, 7, 6, 4},
00104     {1, 2, 0, 3, 5, 6, 8, 7, 4},
00105     {0, 1, 3, 2, 6, 5, 7, 8, 4}
00106 };
00107 
00108 Contour::Contour() :
00109     mpImgEdge ( NULL ),
00110     mpImgEdgeDirection ( NULL ),
00111     mdImgEdgeDirectionType ( 0 ),
00112     mdefEdgeLinkMode ( 0 ),
00113     mImgWidth ( 0 ),
00114     mImgHeight ( 0 ),
00115     mbAllowToModifyTheSources ( false ),
00116 //            mpEdges ( NULL ),
00117     mNrOfEdges ( 0 ) {}
00118 
00119 Contour::~Contour() {
00120     Contour::RelaseMemory();
00121 }
00122 
00123 void Contour::AllocateMemory() {
00124     RelaseMemory();
00125     if ( mbAllowToModifyTheSources == false ) {
00126         mpImgEdge = ( unsigned char* ) malloc ( sizeof ( unsigned char ) * mImgWidth * mImgHeight );
00127     }
00128     //mpEdges = ( CvPoint* ) malloc ( sizeof ( CvPoint ) * mImgWidth * mImgHeight );
00129     mEdges.resize ( mImgWidth * mImgHeight );
00130     mAngle8Bit.resize ( mImgWidth * mImgHeight );
00131 }
00132 
00133 void Contour::RelaseMemory() {
00134     if ( mbAllowToModifyTheSources ) {
00135         if ( mpImgEdge != NULL ) {
00136             free ( mpImgEdge );
00137             mpImgEdge = NULL;
00138         }
00139         /*
00140         if ( mpEdges != NULL ) {
00141         free ( mpEdges );
00142         mpEdges = NULL;
00143         }
00144         */
00145     }
00146 }
00147 
00148 int Contour::getContours( std::vector<std::vector<cv::Point> > &contours, unsigned int min_length) {
00149     contours.clear();
00150     std::vector<cv::Range> idx = getSegmentIndexes () ;
00151     for ( unsigned int i = 0; i < idx.size(); i++ ) {
00152         int length = idx[i].end - idx[i].start;
00153         if (length > min_length) {
00154             contours.push_back(std::vector<cv::Point>());
00155             for ( int index = idx[i].start; index < idx[i].end; index++ ) {
00156               CvPoint &edge = (mEdges)[index];
00157                 contours.back().push_back( edge);
00158             }
00159         }
00160     }
00161     return contours.size();
00162 }
00163 
00164 void Contour::Draw( unsigned char* pImgRGB ) {
00165     unsigned char *pDes;
00166     std::vector<cv::Range> idx = getSegmentIndexes () ;
00167     for ( unsigned int i = 0; i < idx.size(); i++ ) {
00168         unsigned char pColor[] = {rand() / ( RAND_MAX/0xFF ), rand() / ( RAND_MAX/0xFF ), rand() / ( RAND_MAX/0xFF ) };
00169         for ( int index = idx[i].start; index < idx[i].end; index++ ) {
00170             CvPoint edge = (mEdges)[index];
00171             pDes = pImgRGB + ( 3 * ( mImgWidth * edge.y + edge.x ) );
00172             for ( int j  = 0; j < 3; j++ ) {
00173                 pDes[j] = pColor[j];
00174             }
00175         }
00176     }
00177 }
00178 
00179 void Contour::Init ( unsigned int iImgWidth, unsigned int iImgHeight, bool bAllowToModifyTheSources, unsigned char iEdgeToProcess, unsigned char iEdgeInProcess, unsigned char iEdgeProcessed, unsigned char iEdgeStrengthRemoved ) {
00180     if((iImgWidth != mImgWidth) || (mImgHeight != iImgHeight)  ||
00181             (mbAllowToModifyTheSources != bAllowToModifyTheSources) || (mEdgeToProcess != iEdgeToProcess) ||
00182             (mEdgeInProcess != iEdgeInProcess) || (mEdgeProcessed != iEdgeProcessed)) {
00183         RelaseMemory();
00184         mImgWidth = iImgWidth;
00185         mImgHeight = iImgHeight;
00186         mbAllowToModifyTheSources = bAllowToModifyTheSources;
00187         mEdgeToProcess = iEdgeToProcess;
00188         mEdgeInProcess = iEdgeInProcess;
00189         mEdgeProcessed = iEdgeProcessed;
00190         AllocateMemory();
00191     }
00192 }
00193 
00194 int Contour::GetImgDirectionIndex ( CvPoint tPoint ) {
00195     /* Direction of the change
00196     1   0   3
00197      *  *  *
00198       * * *
00199     2*******2
00200       * * *
00201      *  *  *
00202     3   0   1
00203     */
00204     int iIndex = 0;
00205     unsigned char i8BitAngle;
00206     float fAngle;
00207     double dAngle;
00208     switch ( mdImgEdgeDirectionType ) {
00209     case ANGLE_8U:
00210         i8BitAngle = ( ( unsigned char* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
00211         if ( i8BitAngle > 128 ) {
00212             i8BitAngle -= 128;
00213         }
00214         i8BitAngle = i8BitAngle + 16;
00215         iIndex = i8BitAngle / 32;
00216         break;
00217     case ANGLE_32F:
00218         fAngle = ( ( float* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
00219         if ( fAngle < 0 ) {
00220             fAngle += fPi;
00221         }
00222         iIndex = ( int ) ( ( fAngle + fPi/8 ) * 3/fPi );
00223         break;
00224     case ANGLE_64F:
00225         dAngle = ( ( double* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
00226 
00227         if ( dAngle < 0 ) {
00228             dAngle += dPi;
00229         }
00230         iIndex = ( int ) ( ( dAngle + dPi/8 ) * 3/dPi );
00231         break;
00232     }
00233     return iIndex;
00234 }
00235 
00236 void Contour::Perform ( unsigned char* pImgEdgeStrength, int defEdgeLinkMode, void* pImgEdgeDirection, int dImgEdgeDirectionType ) {
00237     mNrOfEdges = 0;
00238     mSegments.clear();
00239     mSegments.reserve ( 100 );
00240     mdefEdgeLinkMode = defEdgeLinkMode;
00241     mpImgEdgeDirection = pImgEdgeDirection;
00242     mdImgEdgeDirectionType = dImgEdgeDirectionType;
00243     if ( mbAllowToModifyTheSources ) {
00244         mpImgEdge = pImgEdgeStrength;
00245     } else {
00246         memcpy ( mpImgEdge, pImgEdgeStrength, mImgWidth * mImgHeight );
00247     }
00248 
00249     switch ( mdefEdgeLinkMode ) {
00250     case MODE_SIMPLE:
00251         Linking_Simple();
00252         break;
00253     case MODE_CONTOUR:
00254         Linking_Contour();
00255         break;
00256     case MODE_GRAIDENT:
00257         if ( pImgEdgeDirection == NULL ) {
00258             printf ( "The linker mode requires an edge direction image!\n" );
00259         }
00260         Linking_Gradient();
00261         break;
00262     case MODE_COMPLEX:
00263         if ( pImgEdgeDirection == NULL ) {
00264             printf ( "The linker mode requires an edge direction image!\n" );
00265         }
00266         Linking_Complex();
00267         break;
00268     }
00269 }
00270 
00271 
00272 void Contour::Linking_Simple() {
00273     CvPoint tPoint = {0,0};
00274     cv::Range range(0,0);
00275     for ( tPoint.y = 1; tPoint.y < mImgHeight-1; tPoint.y++ ) {
00276         tPoint.x = 1;
00277         unsigned char *pCurrent = getImgEdge ( tPoint );
00278         for ( ; tPoint.x < mImgWidth-1; tPoint.x++ ) {
00279             if ( *pCurrent >= mEdgeToProcess ) {
00280                 range.start = mNrOfEdges;
00281                 Trace_Simple ( tPoint, &range.end );
00282                 mSegments.push_back ( range );
00283                 //*pCurrent = 0;
00284             }
00285             pCurrent++;
00286         }
00287     }
00288 }
00289 
00290 // void Contour::Trace_Simple ( CvPoint tPoint, int *pEnd ) {
00291 //     if (isInImage(tPoint)) {
00292 //         CvPoint tCurrent;
00293 //         CvPoint tNext = {0,0};
00294 //         unsigned char *pNeighbor;
00295 //         bool bRemove = false;
00296 //         for ( tCurrent.y = tPoint.y - 1; tCurrent.y <= tPoint.y+1; tCurrent.y++ ) {
00297 //             tCurrent.x = tPoint.x - 1;
00298 //             pNeighbor = getImgEdge ( tCurrent );
00299 //             for ( ; tCurrent.x <= tPoint.x+1; tCurrent.x++ ) {
00300 //                 if ( *pNeighbor >= mEdgeToProcess ) {
00301 //                     if ( ( tCurrent.x == tPoint.x ) && ( tCurrent.y == tPoint.y ) ) {
00302 //                         *pNeighbor = mEdgeProcessed;
00303 //                         mEdges[mNrOfEdges] = tPoint;
00304 //                         *pEnd = mNrOfEdges;
00305 //                         mNrOfEdges++;
00306 //                     } else {
00307 //                         if ( bRemove ) {
00308 //                             *pNeighbor = mEdgeProcessed;
00309 //                         } else {
00310 //                             bRemove = true;
00311 //                             tNext = tCurrent;
00312 //                         }
00313 //                     }
00314 //                 }
00315 //                 pNeighbor++;
00316 //             }
00317 //         }
00318 //         if ( bRemove ) {
00319 //             Trace_Simple ( tNext, pEnd );
00320 //         }
00321 //     }
00322 // }
00323 
00324 void Contour::Trace_Simple ( CvPoint tPoint, int *pEnd ) {
00325     /*
00326       IplImage *pImgSimple = cvCreateImage(cvSize(mImgWidth, mImgHeight),8,3);
00327       cvZero(pImgSimple);
00328       cvNamedWindow ( "ImgSimple", 1 );
00329       for(int i = 0; i < mImgWidth * mImgHeight; i++){
00330         pImgSimple->imageData[i*3] = mpImgEdge[i];
00331       }
00332       cvShowImage ( "ImgSimple", pImgSimple );
00333       cvWaitKey(100);
00334       */
00335     if (isInImage(tPoint)) {
00336         unsigned char *pPix = getImgEdge ( tPoint );
00337         CvPoint tCurrent = tPoint;
00338         bool bEnd = false;
00339         bool bStart = false;
00340         std::stack<CvPoint> trace_to_start;
00341         std::stack<CvPoint> trace_to_end;
00342         std::stack<CvPoint> *pEdgeStack = &trace_to_start;
00343         while (bEnd == false) {
00344             /*
00345                     if(bStart == false) pImgSimple->imageData[( tCurrent.y * mImgWidth + tCurrent.x )*3+1] = 0xFF;
00346                     else pImgSimple->imageData[( tCurrent.y * mImgWidth + tCurrent.x )*3+2] = 0xFF;
00347                       cvShowImage ( "ImgSimple", pImgSimple );
00348                       cvWaitKey(10);
00349                     */
00350             *pPix = mEdgeProcessed;
00351             pEdgeStack->push(tCurrent);
00352             if (pPix[-mImgWidth-1] >= mEdgeToProcess) {
00353                 pPix = pPix-mImgWidth-1;
00354                 tCurrent.x--, tCurrent.y--;
00355             } else if (pPix[-mImgWidth] >= mEdgeToProcess) {
00356                 pPix = pPix-mImgWidth;
00357                 tCurrent.y--;
00358             } else if ( pPix[-mImgWidth+1] >= mEdgeToProcess) {
00359                 pPix = pPix-mImgWidth+1;
00360                 tCurrent.x++, tCurrent.y--;
00361             } else if (pPix[-1] >= mEdgeToProcess) {
00362                 pPix = pPix-1;
00363                 tCurrent.x--;
00364             } else if (pPix[+1] >= mEdgeToProcess) {
00365                 pPix = pPix+1;
00366                 tCurrent.x++;
00367             } else if (pPix[mImgWidth-1] >= mEdgeToProcess) {
00368                 pPix = pPix + mImgWidth-1;
00369                 tCurrent.x--, tCurrent.y++;
00370             } else if (pPix[mImgWidth] >= mEdgeToProcess) {
00371                 pPix = pPix + mImgWidth;
00372                 tCurrent.y++;
00373             } else if (pPix[mImgWidth+1] >= mEdgeToProcess) {
00374                 pPix = pPix + mImgWidth + 1;
00375                 tCurrent.x++, tCurrent.y++;
00376             } else {
00377                 if (bStart == false) {
00378                     bStart = true;
00379                     while (!trace_to_start.empty()) {
00380                         trace_to_end.push(trace_to_start.top());
00381                         trace_to_start.pop();
00382                     }
00383                     pEdgeStack = &trace_to_end;
00384                     tCurrent = pEdgeStack->top();
00385                     pEdgeStack->pop();
00386                     pPix = getImgEdge ( tCurrent );
00387                 } else {
00388                     bEnd = true;
00389                 }
00390             }
00391         }
00392         while (!pEdgeStack->empty()) {
00393             CvPoint p = pEdgeStack->top();
00394             mEdges[mNrOfEdges++] = p;
00395             pEdgeStack->pop();
00396         }
00397 
00398         *pEnd = (mNrOfEdges-1);
00399     }
00400 }
00401 
00402 void Contour::Linking_Contour() {
00403     CvPoint tPoint = {0,0};
00404     cv::Range range(0,0);
00405     for ( tPoint.y = 1; tPoint.y < ( int ) mImgHeight-1; tPoint.y++ ) {
00406         tPoint.x = 1;
00407         unsigned char *pCurrent = getImgEdge ( tPoint );
00408         for ( ; tPoint.x < ( int ) mImgWidth-1; tPoint.x++ ) {
00409             if ( *pCurrent >= mEdgeToProcess ) {
00410                 range.start = mNrOfEdges;
00411                 Trace_Contour ( tPoint, &range.end, 0 );
00412                 mSegments.push_back ( range );
00413                 //*pCurrent = 0;
00414             }
00415             pCurrent++;
00416         }
00417     }
00418 }
00419 
00420 void Contour::Trace_Contour ( CvPoint tPoint, int *pEnd, unsigned int iCommingFromEdge ) {
00421     /*
00422       IplImage *pImgSimple = cvCreateImage(cvSize(mImgWidth, mImgHeight),8,3);
00423       cvZero(pImgSimple);
00424       cvNamedWindow ( "ImgSimple", 1 );
00425       for(int i = 0; i < mImgWidth * mImgHeight; i++){
00426         pImgSimple->imageData[i*3] = mpImgEdge[i];
00427       }
00428       */
00429     if (isInImage(tPoint)) {
00430         unsigned char *pPix = getImgEdge ( tPoint );
00431         CvPoint tCurrent = tPoint;
00432         bool bEnd = false;
00433         bool bStart = false;
00434         std::stack<CvPoint> trace_to_start;
00435         std::stack<CvPoint> trace_to_end;
00436         std::stack<CvPoint> *pEdgeStack = &trace_to_start;
00437         while (bEnd == false) {
00438             *pPix = mEdgeProcessed;
00439             pEdgeStack->push(tCurrent);
00440             if (pPix[-mImgWidth-1] >= mEdgeToProcess) {
00441                 pPix = pPix-mImgWidth-1;
00442                 tCurrent.x--, tCurrent.y--;
00443             } else if (pPix[-mImgWidth] >= mEdgeToProcess) {
00444                 pPix = pPix-mImgWidth;
00445                 tCurrent.y--;
00446             } else if ( pPix[-mImgWidth+1] >= mEdgeToProcess) {
00447                 pPix = pPix-mImgWidth+1;
00448                 tCurrent.x++, tCurrent.y--;
00449             } else if (pPix[-1] >= mEdgeToProcess) {
00450                 pPix = pPix-1;
00451                 tCurrent.x--;
00452             } else if (pPix[+1] >= mEdgeToProcess) {
00453                 pPix = pPix+1;
00454                 tCurrent.x++;
00455             } else if (pPix[mImgWidth-1] >= mEdgeToProcess) {
00456                 pPix = pPix + mImgWidth-1;
00457                 tCurrent.x--, tCurrent.y++;
00458             } else if (pPix[mImgWidth] >= mEdgeToProcess) {
00459                 pPix = pPix + mImgWidth;
00460                 tCurrent.y++;
00461             } else if (pPix[mImgWidth+1] >= mEdgeToProcess) {
00462                 pPix = pPix + mImgWidth + 1;
00463                 tCurrent.x++, tCurrent.y++;
00464             } else {
00465                 if (bStart == false) {
00466                     bStart = true;
00467                     while (!trace_to_start.empty()) {
00468                         trace_to_end.push(trace_to_start.top());
00469                         trace_to_start.pop();
00470                     }
00471                     pEdgeStack = &trace_to_end;
00472                     tCurrent = pEdgeStack->top();
00473                     pPix = getImgEdge ( tCurrent );
00474                 } else {
00475                     bEnd = true;
00476                 }
00477             }
00478         }
00479         while (!pEdgeStack->empty()) {
00480             mEdges[mNrOfEdges++] = pEdgeStack->top();
00481             pEdgeStack->pop();
00482         }
00483         *pEnd = mNrOfEdges;
00484     }
00485 }
00486 
00487 
00488 void Contour::Linking_Gradient() {
00489     CvPoint tPoint = {0,0};
00490     cv::Range range(0,0);
00491     for ( tPoint.y = 1; tPoint.y < ( int ) mImgHeight-1; tPoint.y++ ) {
00492         tPoint.x = 1;
00493         unsigned char *pCurrent = getImgEdge ( tPoint );
00494         for ( ; tPoint.x < ( int ) mImgWidth-1; tPoint.x++ ) {
00495             if ( *pCurrent >= mEdgeToProcess ) {
00496                 range.start = mNrOfEdges;
00497                 Trace_Gradient ( tPoint, &range.end );
00498                 mSegments.push_back ( range );
00499                 //*pCurrent = 0;
00500             }
00501             pCurrent++;
00502         }
00503     }
00504 }
00505 
00506 void Contour::Trace_Gradient ( CvPoint tPoint, int *pEnd ) {
00507     if (isInImage(tPoint)) {
00508         CvPoint tCurrent = {0,0};
00509         CvPoint tNext = {0,0};
00510         bool bRemove = false;
00511         unsigned char *pNeighbor;
00512         int iEdgeDirection;
00513         if ( mdImgEdgeDirectionType == ANGLE_8U) {
00514             mAngle8Bit[mNrOfEdges] = ( ( unsigned char* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
00515         }
00516         iEdgeDirection = GetImgDirectionIndex ( tPoint );
00517         int *pIndex = ( int* ) ppGradientWeightsField[iEdgeDirection];
00518         for ( int i = 0; i < 9; i++ ) {
00519             tCurrent = GetNeighborPoint ( tPoint, pIndex[i] );
00520             pNeighbor = getImgEdge ( tCurrent );
00521             if ( *pNeighbor >= mEdgeToProcess ) {
00522                 if ( pIndex[i] == 4 ) {
00523                     //Center
00524                     *pNeighbor = mEdgeProcessed;
00525                     mEdges[mNrOfEdges] = tPoint;
00526                     *pEnd = mNrOfEdges;
00527                     mNrOfEdges++;
00528                 } else {
00529                     if ( bRemove ) {
00530                         *pNeighbor = mEdgeProcessed;
00531                     } else {
00532                         bRemove = true;
00533                         tNext = tCurrent;
00534                     }
00535                 }
00536             }
00537         }
00538         if ( bRemove ) {
00539             Trace_Gradient ( tNext, pEnd );
00540         }
00541     }
00542 }
00543 
00544 
00545 void Contour::Linking_Complex() {
00546     CvPoint tPoint = {0,0};
00547     cv::Range range(0,0);
00548     for ( tPoint.y = 1; tPoint.y < ( int ) mImgHeight-1; tPoint.y++ ) {
00549         tPoint.x = 1;
00550         unsigned char *pCurrent = getImgEdge ( tPoint );
00551         for ( ; tPoint.x < ( int ) mImgWidth-1; tPoint.x++ ) {
00552             if ( *pCurrent >= mEdgeToProcess ) {
00553                 range.start = mNrOfEdges;
00554                 Trace_Complex ( tPoint, &range.end, 0 );
00555                 mSegments.push_back ( range );
00556                 //*pCurrent = 0;
00557             }
00558             pCurrent++;
00559         }
00560     }
00561 }
00562 
00563 void Contour::Trace_Complex ( CvPoint tPoint, int *pEnd, unsigned int iCommingFromEdge ) {
00564     if (isInImage(tPoint)) {
00565         CvPoint tCurrent;
00566         CvPoint tNext = {0,0};;
00567         bool bRemove = false;
00568         unsigned char *pNeighbor = NULL;
00569         unsigned int iGointToEdge = 0;
00570         int pSum[9];
00571         int pIndex[9];
00572         int iEdgeDirection;
00573         if ( mdImgEdgeDirectionType == ANGLE_8U) {
00574             mAngle8Bit[mNrOfEdges] = ( ( unsigned char* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
00575         }
00576         iEdgeDirection = GetImgDirectionIndex ( tPoint );
00577         SumArrayMatrix (  ( int * ) pppDirectionWeightsField[iEdgeDirection],
00578                           ( int * ) pppCommingFromEdgeWeightsField[iCommingFromEdge],
00579                           ( int * ) pSum, 9 );
00580         SortArrayIndexes ( pSum, pIndex, 9 );
00581         for ( int i = 0; i < 9; i++ ) {
00582             tCurrent = GetNeighborPoint ( tPoint, pIndex[i] );
00583             pNeighbor = getImgEdge ( tCurrent );
00584             if ( *pNeighbor >= mEdgeToProcess ) {
00585                 if ( pIndex[i] == 4 ) {
00586                     //Center
00587                     *pNeighbor = mEdgeProcessed;
00588                     mEdges[mNrOfEdges] = tPoint;
00589                     *pEnd = mNrOfEdges;
00590                     mNrOfEdges++;
00591                 } else {
00592                     if ( bRemove ) {
00593                         *pNeighbor = mEdgeProcessed;
00594                     } else {
00595                         bRemove = true;
00596                         tNext = tCurrent;
00597                         iGointToEdge = 8-pIndex[i];
00598                     }
00599                 }
00600             }
00601         }
00602         if ( bRemove ) {
00603             Trace_Complex ( tNext, pEnd, iGointToEdge );
00604         }
00605     }
00606 }
00607 
00608 const CvPoint Contour::GetNeighborPoint ( CvPoint tPoint, int iNeighborIndex ) {
00609     switch ( iNeighborIndex ) {
00610     case 0:
00611         tPoint.x += -1;
00612         tPoint.y += -1;
00613         break;
00614     case 1:
00615         tPoint.x +=  0;
00616         tPoint.y += -1;
00617         break;
00618     case 2:
00619         tPoint.x += +1;
00620         tPoint.y += -1;
00621         break;
00622     case 3:
00623         tPoint.x += -1;
00624         tPoint.y +=  0;
00625         break;
00626     case 4:
00627         tPoint.x +=  0;
00628         tPoint.y +=  0;
00629         break;
00630     case 5:
00631         tPoint.x += +1;
00632         tPoint.y +=  0;
00633         break;
00634     case 6:
00635         tPoint.x += -1;
00636         tPoint.y += +1;
00637         break;
00638     case 7:
00639         tPoint.x +=  0;
00640         tPoint.y += +1;
00641         break;
00642     case 8:
00643         tPoint.x += +1;
00644         tPoint.y += +1;
00645         break;
00646     }
00647     return tPoint;
00648 }
00649 int Contour::GetEdgeListSplittedXY (std::vector<cv::Point_<int> > &rEdges, std::vector<unsigned char> **ppAngle8Bit) {
00650 
00651     rEdges.resize ( mEdges.size() );
00652     for (unsigned int i = 0; i < mEdges.size(); i++) {
00653         rEdges[i] = mEdges[i];
00654     }
00655     if (ppAngle8Bit != NULL) {
00656         *ppAngle8Bit = &mAngle8Bit;
00657     }
00658     return mEdges.size();
00659 }
00660 
00661 const void Contour::SortArrayIndexes ( int *pArray, int *pIndexes, const int iSize ) {
00662     int iMax = -1;
00663     int iMin = iMax;
00664     int iMaxIndex = 0;
00665     for ( int j = 0; j < iSize; j++ ) {
00666         for ( int i = 0; i < iSize; i++ ) {
00667             if ( pArray[i] > iMax ) {
00668                 iMax = pArray[i];
00669                 iMaxIndex = i;
00670             }
00671             if ( pArray[i] < iMin ) {
00672                 iMin = pArray[i];
00673             }
00674         }
00675         pIndexes[j] = iMaxIndex;
00676         pArray[iMaxIndex] = iMin;
00677         iMax = iMin;
00678     }
00679 }
00680 
00681 void  Contour::GetAbnormitiesInEdgesImage ( IplImage *ptImgEdge, std::vector<CvPoint> *pAbnormities, uchar iEdgeStrength ) {
00682     pAbnormities->clear();
00683     bool bAbnormities;
00684     CvPoint tPoint;
00685     for ( tPoint.y = 1; tPoint.y < ptImgEdge->height-1; tPoint.y++ ) {
00686         unsigned char *pRow0 = ( unsigned char * ) ptImgEdge->imageData + ptImgEdge->width* ( tPoint.y-1 );
00687         unsigned char *pRow1 = pRow0 + ptImgEdge->width;
00688         unsigned char *pRow2 = pRow1 + ptImgEdge->width;
00689         for ( tPoint.x = 1; tPoint.x < ptImgEdge->width-1; tPoint.x++ ) {
00690             bAbnormities = false;
00691             if ( pRow1[1] > iEdgeStrength ) {
00692                 int iNoOfNeighbors = 0;
00693                 if ( pRow0[0] > iEdgeStrength ) {
00694                     iNoOfNeighbors++;
00695                     if ( ( pRow0[1] > iEdgeStrength ) || ( pRow1[0] > iEdgeStrength ) ) {
00696                         bAbnormities = true;
00697                     }
00698                 }
00699                 if ( pRow0[1] > iEdgeStrength ) {
00700                     iNoOfNeighbors++;
00701                     if ( ( pRow0[0] > iEdgeStrength ) || ( pRow0[2] > iEdgeStrength ) ) {
00702                         bAbnormities = true;
00703                     }
00704                 }
00705                 if ( pRow0[2] > iEdgeStrength ) {
00706                     iNoOfNeighbors++;
00707                     if ( ( pRow0[1] > iEdgeStrength ) || ( pRow1[2] > iEdgeStrength ) ) {
00708                         bAbnormities = true;
00709                     }
00710                 }
00711                 if ( pRow1[0] > iEdgeStrength ) {
00712                     iNoOfNeighbors++;
00713                     if ( ( pRow0[0] > iEdgeStrength ) || ( pRow2[0] > iEdgeStrength ) ) {
00714                         bAbnormities = true;
00715                     }
00716                 }
00717                 if ( pRow1[2] > iEdgeStrength ) {
00718                     iNoOfNeighbors++;
00719                     if ( ( pRow0[2] > iEdgeStrength ) || ( pRow2[2] > iEdgeStrength ) ) {
00720                         bAbnormities = true;
00721                     }
00722                 }
00723                 if ( pRow2[0] > iEdgeStrength ) {
00724                     iNoOfNeighbors++;
00725                     if ( ( pRow1[0] > iEdgeStrength ) || ( pRow2[1] > iEdgeStrength ) ) {
00726                         bAbnormities = true;
00727                     }
00728                 }
00729                 if ( pRow2[1] > iEdgeStrength ) {
00730                     iNoOfNeighbors++;
00731                     if ( ( pRow2[0] > iEdgeStrength ) || ( pRow2[2] > iEdgeStrength ) ) {
00732                         bAbnormities = true;
00733                     }
00734                 }
00735                 if ( pRow2[2] > iEdgeStrength ) {
00736                     iNoOfNeighbors++;
00737                     if ( ( pRow2[1] > iEdgeStrength ) || ( pRow1[2] > iEdgeStrength ) ) {
00738                         bAbnormities = true;
00739                     }
00740                 }
00741                 if ( bAbnormities ) {
00742                     pAbnormities->push_back ( tPoint );
00743                 }
00744             }
00745             pRow0++;
00746             pRow1++;
00747             pRow2++;
00748         }
00749     }
00750 
00751 }
00752 
00753 std::vector<cv::Range> Contour::getSegmentIndexes() {
00754     return mSegments;
00755 }
00756 
00757 } //namespace V4R


tuw_ellipses
Author(s):
autogenerated on Sun May 29 2016 02:50:24