D:/users/ricard/src/utilitats/cpp/cvblobslib/BlobResult.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002                         BlobResult.cpp
00003                         
00004 FUNCIONALITAT: Implementaciķ de la classe CBlobResult
00005 AUTOR: Inspecta S.L.
00006 MODIFICACIONS (Modificaciķ, Autor, Data):
00007  
00008 **************************************************************************/
00009 
00010 #include <limits.h>
00011 #include <stdio.h>
00012 #include <functional>
00013 #include <algorithm>
00014 #include "BlobResult.h"
00015 #include "BlobExtraction.h"
00016 #ifdef _DEBUG
00017         #include <afx.h>                        //suport per a CStrings
00018         #include <afxwin.h>                     //suport per a AfxMessageBox
00019 #endif
00020 
00021 /**************************************************************************
00022                 Constructors / Destructors
00023 **************************************************************************/
00024 
00025 
00048 CBlobResult::CBlobResult()
00049 {
00050         m_blobs = blob_vector();
00051 }
00052 
00089 CBlobResult::CBlobResult(IplImage *source, IplImage *mask, int threshold, bool findmoments)
00090 {
00091         bool success;
00092 
00093         try
00094         {
00095                 // cridem la funciķ amb el marc a true=1=blanc (així no unirā els blobs externs)
00096                 success = BlobAnalysis(source,(uchar)threshold,mask,true,findmoments, m_blobs );
00097         }
00098         catch(...)
00099         {
00100                 success = false;
00101         }
00102 
00103         if( !success ) throw EXCEPCIO_CALCUL_BLOBS;
00104 }
00105 
00130 CBlobResult::CBlobResult( const CBlobResult &source )
00131 {
00132         m_blobs = blob_vector( source.GetNumBlobs() );
00133         
00134         // creem el nou a partir del passat com a parāmetre
00135         m_blobs = blob_vector( source.GetNumBlobs() );
00136         // copiem els blobs de l'origen a l'actual
00137         blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
00138         blob_vector::iterator pBlobsDst = m_blobs.begin();
00139 
00140         while( pBlobsSrc != source.m_blobs.end() )
00141         {
00142                 // no podem cridar a l'operador = ja que blob_vector és un 
00143                 // vector de CBlob*. Per tant, creem un blob nou a partir del
00144                 // blob original
00145                 *pBlobsDst = new CBlob(**pBlobsSrc);
00146                 pBlobsSrc++;
00147                 pBlobsDst++;
00148         }
00149 }
00150 
00151 
00152 
00174 CBlobResult::~CBlobResult()
00175 {
00176         ClearBlobs();
00177 }
00178 
00179 /**************************************************************************
00180                 Operadors / Operators
00181 **************************************************************************/
00182 
00183 
00206 CBlobResult& CBlobResult::operator=(const CBlobResult& source)
00207 {
00208         // si ja sķn el mateix, no cal fer res
00209         if (this != &source)
00210         {
00211                 // alliberem el conjunt de blobs antic
00212                 for( int i = 0; i < GetNumBlobs(); i++ )
00213                 {
00214                         delete m_blobs[i];
00215                 }
00216                 m_blobs.clear();
00217                 // creem el nou a partir del passat com a parāmetre
00218                 m_blobs = blob_vector( source.GetNumBlobs() );
00219                 // copiem els blobs de l'origen a l'actual
00220                 blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
00221                 blob_vector::iterator pBlobsDst = m_blobs.begin();
00222 
00223                 while( pBlobsSrc != source.m_blobs.end() )
00224                 {
00225                         // no podem cridar a l'operador = ja que blob_vector és un 
00226                         // vector de CBlob*. Per tant, creem un blob nou a partir del
00227                         // blob original
00228                         *pBlobsDst = new CBlob(**pBlobsSrc);
00229                         pBlobsSrc++;
00230                         pBlobsDst++;
00231                 }
00232         }
00233         return *this;
00234 }
00235 
00236 
00262 CBlobResult CBlobResult::operator+( const CBlobResult& source )
00263 {       
00264         //creem el resultat a partir dels blobs actuals
00265         CBlobResult resultat( *this );
00266         
00267         // reservem memōria per als nous blobs
00268         resultat.m_blobs.resize( resultat.GetNumBlobs() + source.GetNumBlobs() );
00269 
00270         // declarem els iterador per recōrrer els blobs d'origen i desti
00271         blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
00272         blob_vector::iterator pBlobsDst = resultat.m_blobs.end();
00273 
00274         // insertem els blobs de l'origen a l'actual
00275         while( pBlobsSrc != source.m_blobs.end() )
00276         {
00277                 pBlobsDst--;
00278                 *pBlobsDst = new CBlob(**pBlobsSrc);
00279                 pBlobsSrc++;
00280         }
00281         
00282         return resultat;
00283 }
00284 
00285 /**************************************************************************
00286                 Operacions / Operations
00287 **************************************************************************/
00288 
00301 void CBlobResult::AddBlob( CBlob *blob )
00302 {
00303         if( blob != NULL )
00304                 m_blobs.push_back( new CBlob( blob ) );
00305 }
00306 
00307 
00308 #ifdef MATRIXCV_ACTIU
00309 
00336 double_vector CBlobResult::GetResult( funcio_calculBlob *evaluador ) const
00337 {
00338         if( GetNumBlobs() <= 0 )
00339         {
00340                 return double_vector();
00341         }
00342 
00343         // definim el resultat
00344         double_vector result = double_vector( GetNumBlobs() );
00345         // i iteradors sobre els blobs i el resultat
00346         double_vector::iterator itResult = result.GetIterator();
00347         blob_vector::const_iterator itBlobs = m_blobs.begin();
00348 
00349         // avaluem la funciķ en tots els blobs
00350         while( itBlobs != m_blobs.end() )
00351         {
00352                 *itResult = (*evaluador)(**itBlobs);
00353                 itBlobs++;
00354                 itResult++;
00355         }
00356         return result;
00357 }
00358 #endif
00359 
00386 double_stl_vector CBlobResult::GetSTLResult( funcio_calculBlob *evaluador ) const
00387 {
00388         if( GetNumBlobs() <= 0 )
00389         {
00390                 return double_stl_vector();
00391         }
00392 
00393         // definim el resultat
00394         double_stl_vector result = double_stl_vector( GetNumBlobs() );
00395         // i iteradors sobre els blobs i el resultat
00396         double_stl_vector::iterator itResult = result.begin();
00397         blob_vector::const_iterator itBlobs = m_blobs.begin();
00398 
00399         // avaluem la funciķ en tots els blobs
00400         while( itBlobs != m_blobs.end() )
00401         {
00402                 *itResult = (*evaluador)(**itBlobs);
00403                 itBlobs++;
00404                 itResult++;
00405         }
00406         return result;
00407 }
00408 
00435 double CBlobResult::GetNumber( int indexBlob, funcio_calculBlob *evaluador ) const
00436 {
00437         if( indexBlob < 0 || indexBlob >= GetNumBlobs() )
00438                 RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
00439         return (*evaluador)( *m_blobs[indexBlob] );
00440 }
00441 
00443 
00495 void CBlobResult::Filter(CBlobResult &dst, 
00496                                                  int filterAction, 
00497                                                  funcio_calculBlob *evaluador, 
00498                                                  int condition, 
00499                                                  double lowLimit, double highLimit /*=0*/)
00500                                                         
00501 {
00502         int i, numBlobs;
00503         bool resultavaluacio;
00504         double_stl_vector avaluacioBlobs;
00505         double_stl_vector::iterator itavaluacioBlobs;
00506 
00507         if( GetNumBlobs() <= 0 ) return;
00508         if( !evaluador ) return;
00509         //avaluem els blobs amb la funciķ pertinent     
00510         avaluacioBlobs = GetSTLResult(evaluador);
00511         itavaluacioBlobs = avaluacioBlobs.begin();
00512         numBlobs = GetNumBlobs();
00513         switch(condition)
00514         {
00515                 case B_EQUAL:
00516                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00517                         {
00518                                 resultavaluacio= *itavaluacioBlobs == lowLimit;
00519                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00520                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00521                                 {
00522                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00523                                 }                               
00524                         }
00525                         break;
00526                 case B_NOT_EQUAL:
00527                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00528                         {
00529                                 resultavaluacio = *itavaluacioBlobs != lowLimit;
00530                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00531                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00532                                 {
00533                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00534                                 }
00535                         }
00536                         break;
00537                 case B_GREATER:
00538                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00539                         {
00540                                 resultavaluacio= *itavaluacioBlobs > lowLimit;
00541                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00542                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00543                                 {
00544                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00545                                 }
00546                         }
00547                         break;
00548                 case B_LESS:
00549                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00550                         {
00551                                 resultavaluacio= *itavaluacioBlobs < lowLimit;
00552                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00553                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00554                                 {
00555                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00556                                 }
00557                         }
00558                         break;
00559                 case B_GREATER_OR_EQUAL:
00560                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00561                         {
00562                                 resultavaluacio= *itavaluacioBlobs>= lowLimit;
00563                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00564                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00565                                 {
00566                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00567                                 }
00568                         }
00569                         break;
00570                 case B_LESS_OR_EQUAL:
00571                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00572                         {
00573                                 resultavaluacio= *itavaluacioBlobs <= lowLimit;
00574                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00575                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00576                                 {
00577                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00578                                 }
00579                         }
00580                         break;
00581                 case B_INSIDE:
00582                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00583                         {
00584                                 resultavaluacio=( *itavaluacioBlobs >= lowLimit) && ( *itavaluacioBlobs <= highLimit); 
00585                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00586                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00587                                 {
00588                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00589                                 }
00590                         }
00591                         break;
00592                 case B_OUTSIDE:
00593                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00594                         {
00595                                 resultavaluacio=( *itavaluacioBlobs < lowLimit) || ( *itavaluacioBlobs > highLimit); 
00596                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00597                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00598                                 {
00599                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00600                                 }
00601                         }
00602                         break;
00603         }
00604 
00605 
00606         // en cas de voler filtrar un CBlobResult i deixar-ho en el mateix CBlobResult
00607         // ( operacio inline )
00608         if( &dst == this ) 
00609         {
00610                 // esborrem els primers blobs ( que sķn els originals )
00611                 // ja que els tindrem replicats al final si passen el filtre
00612                 blob_vector::iterator itBlobs = m_blobs.begin();
00613                 for( int i = 0; i < numBlobs; i++ )
00614                 {
00615                         delete *itBlobs;
00616                         itBlobs++;
00617                 }
00618                 m_blobs.erase( m_blobs.begin(), itBlobs );
00619         }
00620 }
00621 
00622 
00634 /*
00635 - FUNCTION: GetBlob
00636 - FUNCTIONALITY: Gets the n-th blob (without ordering the blobs)
00637 - PARAMETERS:
00638         - indexblob: index in the blob array
00639 - RESULT:
00640 - RESTRICTIONS:
00641 - AUTHOR: Ricard Borrās
00642 - CREATION DATE: 25-05-2005.
00643 - MODIFICATION: Date. Author. Description.
00644 */
00645 CBlob CBlobResult::GetBlob(int indexblob) const
00646 {       
00647         if( indexblob < 0 || indexblob >= GetNumBlobs() )
00648                 RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
00649 
00650         return *m_blobs[indexblob];
00651 }
00652 CBlob *CBlobResult::GetBlob(int indexblob)
00653 {       
00654         if( indexblob < 0 || indexblob >= GetNumBlobs() )
00655                 RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
00656 
00657         return m_blobs[indexblob];
00658 }
00659 
00677 /*
00678 - FUNCTION: GetNthBlob
00679 - FUNCTIONALITY: Gets the n-th blob ordering first the blobs with some criteria
00680 - PARAMETERS:
00681         - criteri: criteria to order the blob array
00682         - nBlob: index of the returned blob in the ordered blob array
00683         - dst: where to store the result
00684 - RESULT:
00685 - RESTRICTIONS:
00686 - AUTHOR: Ricard Borrās
00687 - CREATION DATE: 25-05-2005.
00688 - MODIFICATION: Date. Author. Description.
00689 */
00690 void CBlobResult::GetNthBlob( funcio_calculBlob *criteri, int nBlob, CBlob &dst ) const
00691 {
00692         // verifiquem que no estem accedint fora el vector de blobs
00693         if( nBlob < 0 || nBlob >= GetNumBlobs() )
00694         {
00695                 //RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
00696                 dst = CBlob();
00697                 return;
00698         }
00699 
00700         double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat;
00701         double valorEnessim;
00702 
00703         //avaluem els blobs amb la funciķ pertinent     
00704         avaluacioBlobs = GetSTLResult(criteri);
00705 
00706         avaluacioBlobsOrdenat = double_stl_vector( GetNumBlobs() );
00707 
00708         // obtenim els nBlob primers resultats (en ordre descendent)
00709         std::partial_sort_copy( avaluacioBlobs.begin(), 
00710                                                     avaluacioBlobs.end(),
00711                                                     avaluacioBlobsOrdenat.begin(), 
00712                                                     avaluacioBlobsOrdenat.end(),
00713                                                     std::greater<double>() );
00714 
00715         valorEnessim = avaluacioBlobsOrdenat[nBlob];
00716 
00717         // busquem el primer blob que té el valor n-ssim
00718         double_stl_vector::const_iterator itAvaluacio = avaluacioBlobs.begin();
00719 
00720         bool trobatBlob = false;
00721         int indexBlob = 0;
00722         while( itAvaluacio != avaluacioBlobs.end() && !trobatBlob )
00723         {
00724                 if( *itAvaluacio == valorEnessim )
00725                 {
00726                         trobatBlob = true;
00727                         dst = CBlob( GetBlob(indexBlob));
00728                 }
00729                 itAvaluacio++;
00730                 indexBlob++;
00731         }
00732 }
00733 
00745 /*
00746 - FUNCTION: ClearBlobs
00747 - FUNCTIONALITY: Clears all the blobs from the object and releases all its memory
00748 - PARAMETERS:
00749 - RESULT:
00750 - RESTRICTIONS:
00751 - AUTHOR: Ricard Borrās
00752 - CREATION DATE: 25-05-2005.
00753 - MODIFICATION: Date. Author. Description.
00754 */
00755 void CBlobResult::ClearBlobs()
00756 {
00757         /*for( int i = 0; i < GetNumBlobs(); i++ )
00758         {
00759                 delete m_blobs[i];
00760         }*/
00761         blob_vector::iterator itBlobs = m_blobs.begin();
00762         while( itBlobs != m_blobs.end() )
00763         {
00764                 delete *itBlobs;
00765                 itBlobs++;
00766         }
00767 
00768         m_blobs.clear();
00769 }
00770 
00784 /*
00785 - FUNCTION: RaiseError
00786 - FUNCTIONALITY: Error handling function
00787 - PARAMETERS:
00788         - errorCode: reason of the error
00789 - RESULT:
00790         - in _DEBUG version, shows a message box with the error. In release is silent.
00791           In both cases throws an exception with the error.
00792 - RESTRICTIONS:
00793 - AUTHOR: Ricard Borrās
00794 - CREATION DATE: 25-05-2005.
00795 - MODIFICATION: Date. Author. Description.
00796 */
00797 void CBlobResult::RaiseError(const int errorCode) const
00798 {
00799         // estem en mode debug?
00800 #ifdef _DEBUG
00801         CString msg, format = "Error en CBlobResult: %s";
00802 
00803         switch (errorCode)
00804         {
00805         case EXCEPTION_BLOB_OUT_OF_BOUNDS:
00806                 msg.Format(format, "Intentant accedir a un blob no existent");
00807                 break;
00808         default:
00809                 msg.Format(format, "Codi d'error desconegut");
00810                 break;
00811         }
00812 
00813         AfxMessageBox(msg);
00814 
00815 #endif
00816         throw errorCode;
00817 }
00818 
00819 
00820 
00821 /**************************************************************************
00822                 Auxiliars / Auxiliary functions
00823 **************************************************************************/
00824 
00825 
00838 /*
00839 - FUNCTION: PrintBlobs
00840 - FUNCTIONALITY: Prints some blob features in an ASCII file
00841 - PARAMETERS:
00842         - nom_fitxer: full path + filename to generate
00843 - RESULT:
00844 - RESTRICTIONS:
00845 - AUTHOR: Ricard Borrās
00846 - CREATION DATE: 25-05-2005.
00847 - MODIFICATION: Date. Author. Description.
00848 */
00849 void CBlobResult::PrintBlobs( char *nom_fitxer ) const
00850 {
00851         double_stl_vector area, /*perimetre,*/ exterior, mitjana, compacitat, longitud, 
00852                                           externPerimeter, perimetreConvex;
00853         double_vector perimetre;
00854         int i;
00855         FILE *fitxer_sortida;
00856 
00857         area      = GetSTLResult( CBlobGetArea());
00858         //perimetre = GetSTLResult( CBlobGetPerimeter());
00859         perimetre = GetResult( CBlobGetPerimeter());
00860         exterior  = GetSTLResult( CBlobGetExterior());
00861         mitjana   = GetSTLResult( CBlobGetMean());
00862         compacitat = GetSTLResult(CBlobGetCompactness());
00863         longitud  = GetSTLResult( CBlobGetLength());
00864         externPerimeter = GetSTLResult( CBlobGetExternPerimeter());
00865         perimetreConvex = GetSTLResult( CBlobGetHullPerimeter());
00866 
00867         fitxer_sortida = fopen( nom_fitxer, "w" );
00868 
00869         for(i=0; i<GetNumBlobs(); i++)
00870         {
00871                 fprintf( fitxer_sortida, "blob %d ->\t a=%7.0f\t p=%8.2f (%8.2f extern)\t pconvex=%8.2f\t ext=%.0f\t m=%7.2f\t c=%3.2f\t l=%8.2f\n",
00872                                  i, area[i], perimetre(i), externPerimeter[i], perimetreConvex[i], exterior[i], mitjana[i], compacitat[i], longitud[i] );
00873         }
00874         fclose( fitxer_sortida );
00875 
00876 }

Generated on Mon Nov 13 13:32:49 2006 for cvBlobsLib by  doxygen 1.5.1-p1