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 "hrl_cvblobslib/BlobResult.h"
00015 
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 
00094 CBlobResult::CBlobResult(IplImage *source, IplImage *mask, uchar backgroundColor )
00095 {
00096         bool success;
00097 
00098         try
00099         {
00100                 success = ComponentLabeling( source, mask, backgroundColor, m_blobs );
00101         }
00102         catch(...)
00103         {
00104                 success = false;
00105         }
00106 
00107         if( !success ) throw EXCEPCIO_CALCUL_BLOBS;
00108 }
00109 
00134 CBlobResult::CBlobResult( const CBlobResult &source )
00135 {
00136         m_blobs = Blob_vector( source.GetNumBlobs() );
00137         
00138         // creem el nou a partir del passat com a paràmetre
00139         m_blobs = Blob_vector( source.GetNumBlobs() );
00140         // copiem els blobs de l'origen a l'actual
00141         Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
00142         Blob_vector::iterator pBlobsDst = m_blobs.begin();
00143 
00144         while( pBlobsSrc != source.m_blobs.end() )
00145         {
00146                 // no podem cridar a l'operador = ja que Blob_vector és un 
00147                 // vector de CBlob*. Per tant, creem un blob nou a partir del
00148                 // blob original
00149                 *pBlobsDst = new CBlob(**pBlobsSrc);
00150                 pBlobsSrc++;
00151                 pBlobsDst++;
00152         }
00153 }
00154 
00155 
00156 
00178 CBlobResult::~CBlobResult()
00179 {
00180         ClearBlobs();
00181 }
00182 
00183 /**************************************************************************
00184                 Operadors / Operators
00185 **************************************************************************/
00186 
00187 
00210 CBlobResult& CBlobResult::operator=(const CBlobResult& source)
00211 {
00212         // si ja són el mateix, no cal fer res
00213         if (this != &source)
00214         {
00215                 // alliberem el conjunt de blobs antic
00216                 for( int i = 0; i < GetNumBlobs(); i++ )
00217                 {
00218                         delete m_blobs[i];
00219                 }
00220                 m_blobs.clear();
00221                 // creem el nou a partir del passat com a paràmetre
00222                 m_blobs = Blob_vector( source.GetNumBlobs() );
00223                 // copiem els blobs de l'origen a l'actual
00224                 Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
00225                 Blob_vector::iterator pBlobsDst = m_blobs.begin();
00226 
00227                 while( pBlobsSrc != source.m_blobs.end() )
00228                 {
00229                         // no podem cridar a l'operador = ja que Blob_vector és un 
00230                         // vector de CBlob*. Per tant, creem un blob nou a partir del
00231                         // blob original
00232                         *pBlobsDst = new CBlob(**pBlobsSrc);
00233                         pBlobsSrc++;
00234                         pBlobsDst++;
00235                 }
00236         }
00237         return *this;
00238 }
00239 
00240 
00266 CBlobResult CBlobResult::operator+( const CBlobResult& source ) const
00267 {       
00268         //creem el resultat a partir dels blobs actuals
00269         CBlobResult resultat( *this );
00270         
00271         // reservem memòria per als nous blobs
00272         resultat.m_blobs.resize( resultat.GetNumBlobs() + source.GetNumBlobs() );
00273 
00274         // declarem els iterador per recòrrer els blobs d'origen i desti
00275         Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
00276         Blob_vector::iterator pBlobsDst = resultat.m_blobs.end();
00277 
00278         // insertem els blobs de l'origen a l'actual
00279         while( pBlobsSrc != source.m_blobs.end() )
00280         {
00281                 pBlobsDst--;
00282                 *pBlobsDst = new CBlob(**pBlobsSrc);
00283                 pBlobsSrc++;
00284         }
00285         
00286         return resultat;
00287 }
00288 
00289 /**************************************************************************
00290                 Operacions / Operations
00291 **************************************************************************/
00292 
00305 void CBlobResult::AddBlob( CBlob *blob )
00306 {
00307         if( blob != NULL )
00308                 m_blobs.push_back( new CBlob( blob ) );
00309 }
00310 
00311 
00312 #ifdef MATRIXCV_ACTIU
00313 
00340 double_vector CBlobResult::GetResult( funcio_calculBlob *evaluador ) const
00341 {
00342         if( GetNumBlobs() <= 0 )
00343         {
00344                 return double_vector();
00345         }
00346 
00347         // definim el resultat
00348         double_vector result = double_vector( GetNumBlobs() );
00349         // i iteradors sobre els blobs i el resultat
00350         double_vector::iterator itResult = result.GetIterator();
00351         Blob_vector::const_iterator itBlobs = m_blobs.begin();
00352 
00353         // avaluem la funció en tots els blobs
00354         while( itBlobs != m_blobs.end() )
00355         {
00356                 *itResult = (*evaluador)(**itBlobs);
00357                 itBlobs++;
00358                 itResult++;
00359         }
00360         return result;
00361 }
00362 #endif
00363 
00390 double_stl_vector CBlobResult::GetSTLResult( funcio_calculBlob *evaluador ) const
00391 {
00392         if( GetNumBlobs() <= 0 )
00393         {
00394                 return double_stl_vector();
00395         }
00396 
00397         // definim el resultat
00398         double_stl_vector result = double_stl_vector( GetNumBlobs() );
00399         // i iteradors sobre els blobs i el resultat
00400         double_stl_vector::iterator itResult = result.begin();
00401         Blob_vector::const_iterator itBlobs = m_blobs.begin();
00402 
00403         // avaluem la funció en tots els blobs
00404         while( itBlobs != m_blobs.end() )
00405         {
00406                 *itResult = (*evaluador)(**itBlobs);
00407                 itBlobs++;
00408                 itResult++;
00409         }
00410         return result;
00411 }
00412 
00439 double CBlobResult::GetNumber( int indexBlob, funcio_calculBlob *evaluador ) const
00440 {
00441         if( indexBlob < 0 || indexBlob >= GetNumBlobs() )
00442                 RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
00443         return (*evaluador)( *m_blobs[indexBlob] );
00444 }
00445 
00447 
00499 void CBlobResult::Filter(CBlobResult &dst, 
00500                                                  int filterAction, 
00501                                                  funcio_calculBlob *evaluador, 
00502                                                  int condition, 
00503                                                  double lowLimit, double highLimit /*=0*/) const
00504                                                         
00505 {
00506         // do the job
00507         DoFilter(dst, filterAction, evaluador, condition, lowLimit, highLimit );
00508 }
00509 
00561 void CBlobResult::Filter(CBlobResult &dst, 
00562                                                  int filterAction, 
00563                                                  funcio_calculBlob *evaluador, 
00564                                                  int condition, 
00565                                                  double lowLimit, double highLimit /*=0*/)
00566                                                         
00567 {
00568         int numBlobs = GetNumBlobs();
00569 
00570         // do the job
00571         DoFilter(dst, filterAction, evaluador, condition, lowLimit, highLimit );
00572 
00573         // inline operation: remove previous blobs
00574         if( &dst == this ) 
00575         {
00576                 // esborrem els primers blobs ( que són els originals )
00577                 // ja que els tindrem replicats al final si passen el filtre
00578                 Blob_vector::iterator itBlobs = m_blobs.begin();
00579                 for( int i = 0; i < numBlobs; i++ )
00580                 {
00581                         delete *itBlobs;
00582                         itBlobs++;
00583                 }
00584                 m_blobs.erase( m_blobs.begin(), itBlobs );
00585         }
00586 }
00587 
00588 
00590 void CBlobResult::DoFilter(CBlobResult &dst, int filterAction, funcio_calculBlob *evaluador, 
00591                                                    int condition, double lowLimit, double highLimit/* = 0*/) const
00592 {
00593         int i, numBlobs;
00594         bool resultavaluacio;
00595         double_stl_vector avaluacioBlobs;
00596         double_stl_vector::iterator itavaluacioBlobs;
00597 
00598         if( GetNumBlobs() <= 0 ) return;
00599         if( !evaluador ) return;
00600         //avaluem els blobs amb la funció pertinent     
00601         avaluacioBlobs = GetSTLResult(evaluador);
00602         itavaluacioBlobs = avaluacioBlobs.begin();
00603         numBlobs = GetNumBlobs();
00604         switch(condition)
00605         {
00606                 case B_EQUAL:
00607                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00608                         {
00609                                 resultavaluacio= *itavaluacioBlobs == lowLimit;
00610                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00611                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00612                                 {
00613                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00614                                 }                               
00615                         }
00616                         break;
00617                 case B_NOT_EQUAL:
00618                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00619                         {
00620                                 resultavaluacio = *itavaluacioBlobs != lowLimit;
00621                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00622                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00623                                 {
00624                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00625                                 }
00626                         }
00627                         break;
00628                 case B_GREATER:
00629                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00630                         {
00631                                 resultavaluacio= *itavaluacioBlobs > lowLimit;
00632                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00633                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00634                                 {
00635                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00636                                 }
00637                         }
00638                         break;
00639                 case B_LESS:
00640                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00641                         {
00642                                 resultavaluacio= *itavaluacioBlobs < lowLimit;
00643                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00644                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00645                                 {
00646                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00647                                 }
00648                         }
00649                         break;
00650                 case B_GREATER_OR_EQUAL:
00651                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00652                         {
00653                                 resultavaluacio= *itavaluacioBlobs>= lowLimit;
00654                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00655                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00656                                 {
00657                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00658                                 }
00659                         }
00660                         break;
00661                 case B_LESS_OR_EQUAL:
00662                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00663                         {
00664                                 resultavaluacio= *itavaluacioBlobs <= lowLimit;
00665                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00666                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00667                                 {
00668                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00669                                 }
00670                         }
00671                         break;
00672                 case B_INSIDE:
00673                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00674                         {
00675                                 resultavaluacio=( *itavaluacioBlobs >= lowLimit) && ( *itavaluacioBlobs <= highLimit); 
00676                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00677                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00678                                 {
00679                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00680                                 }
00681                         }
00682                         break;
00683                 case B_OUTSIDE:
00684                         for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
00685                         {
00686                                 resultavaluacio=( *itavaluacioBlobs < lowLimit) || ( *itavaluacioBlobs > highLimit); 
00687                                 if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
00688                                         ( !resultavaluacio && filterAction == B_EXCLUDE ))
00689                                 {
00690                                         dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
00691                                 }
00692                         }
00693                         break;
00694         }
00695 }
00707 /*
00708 - FUNCTION: GetBlob
00709 - FUNCTIONALITY: Gets the n-th blob (without ordering the blobs)
00710 - PARAMETERS:
00711         - indexblob: index in the blob array
00712 - RESULT:
00713 - RESTRICTIONS:
00714 - AUTHOR: Ricard Borràs
00715 - CREATION DATE: 25-05-2005.
00716 - MODIFICATION: Date. Author. Description.
00717 */
00718 CBlob CBlobResult::GetBlob(int indexblob) const
00719 {       
00720         if( indexblob < 0 || indexblob >= GetNumBlobs() )
00721                 RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
00722 
00723         return *m_blobs[indexblob];
00724 }
00725 CBlob *CBlobResult::GetBlob(int indexblob)
00726 {       
00727         if( indexblob < 0 || indexblob >= GetNumBlobs() )
00728                 RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
00729 
00730         return m_blobs[indexblob];
00731 }
00732 
00750 /*
00751 - FUNCTION: GetNthBlob
00752 - FUNCTIONALITY: Gets the n-th blob ordering first the blobs with some criteria
00753 - PARAMETERS:
00754         - criteri: criteria to order the blob array
00755         - nBlob: index of the returned blob in the ordered blob array
00756         - dst: where to store the result
00757 - RESULT:
00758 - RESTRICTIONS:
00759 - AUTHOR: Ricard Borràs
00760 - CREATION DATE: 25-05-2005.
00761 - MODIFICATION: Date. Author. Description.
00762 */
00763 void CBlobResult::GetNthBlob( funcio_calculBlob *criteri, int nBlob, CBlob &dst ) const
00764 {
00765         // verifiquem que no estem accedint fora el vector de blobs
00766         if( nBlob < 0 || nBlob >= GetNumBlobs() )
00767         {
00768                 //RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
00769                 dst = CBlob();
00770                 return;
00771         }
00772 
00773         double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat;
00774         double valorEnessim;
00775 
00776         //avaluem els blobs amb la funció pertinent     
00777         avaluacioBlobs = GetSTLResult(criteri);
00778 
00779         avaluacioBlobsOrdenat = double_stl_vector( GetNumBlobs() );
00780 
00781         // obtenim els nBlob primers resultats (en ordre descendent)
00782         std::partial_sort_copy( avaluacioBlobs.begin(), 
00783                                                     avaluacioBlobs.end(),
00784                                                     avaluacioBlobsOrdenat.begin(), 
00785                                                     avaluacioBlobsOrdenat.end(),
00786                                                     std::greater<double>() );
00787 
00788         valorEnessim = avaluacioBlobsOrdenat[nBlob];
00789 
00790         // busquem el primer blob que té el valor n-ssim
00791         double_stl_vector::const_iterator itAvaluacio = avaluacioBlobs.begin();
00792 
00793         bool trobatBlob = false;
00794         int indexBlob = 0;
00795         while( itAvaluacio != avaluacioBlobs.end() && !trobatBlob )
00796         {
00797                 if( *itAvaluacio == valorEnessim )
00798                 {
00799                         trobatBlob = true;
00800                         dst = CBlob( GetBlob(indexBlob));
00801                 }
00802                 itAvaluacio++;
00803                 indexBlob++;
00804         }
00805 }
00806 
00818 /*
00819 - FUNCTION: ClearBlobs
00820 - FUNCTIONALITY: Clears all the blobs from the object and releases all its memory
00821 - PARAMETERS:
00822 - RESULT:
00823 - RESTRICTIONS:
00824 - AUTHOR: Ricard Borràs
00825 - CREATION DATE: 25-05-2005.
00826 - MODIFICATION: Date. Author. Description.
00827 */
00828 void CBlobResult::ClearBlobs()
00829 {
00830         /*for( int i = 0; i < GetNumBlobs(); i++ )
00831         {
00832                 delete m_blobs[i];
00833         }*/
00834         Blob_vector::iterator itBlobs = m_blobs.begin();
00835         while( itBlobs != m_blobs.end() )
00836         {
00837                 delete *itBlobs;
00838                 itBlobs++;
00839         }
00840 
00841         m_blobs.clear();
00842 }
00843 
00857 /*
00858 - FUNCTION: RaiseError
00859 - FUNCTIONALITY: Error handling function
00860 - PARAMETERS:
00861         - errorCode: reason of the error
00862 - RESULT:
00863         - in _DEBUG version, shows a message box with the error. In release is silent.
00864           In both cases throws an exception with the error.
00865 - RESTRICTIONS:
00866 - AUTHOR: Ricard Borràs
00867 - CREATION DATE: 25-05-2005.
00868 - MODIFICATION: Date. Author. Description.
00869 */
00870 void CBlobResult::RaiseError(const int errorCode) const
00871 {
00872         // estem en mode debug?
00873 #ifdef _DEBUG
00874         CString msg, format = "Error en CBlobResult: %s";
00875 
00876         switch (errorCode)
00877         {
00878         case EXCEPTION_BLOB_OUT_OF_BOUNDS:
00879                 msg.Format(format, "Intentant accedir a un blob no existent");
00880                 break;
00881         default:
00882                 msg.Format(format, "Codi d'error desconegut");
00883                 break;
00884         }
00885 
00886         AfxMessageBox(msg);
00887 
00888 #endif
00889         throw errorCode;
00890 }
00891 
00892 
00893 
00894 /**************************************************************************
00895                 Auxiliars / Auxiliary functions
00896 **************************************************************************/
00897 
00898 
00911 /*
00912 - FUNCTION: PrintBlobs
00913 - FUNCTIONALITY: Prints some blob features in an ASCII file
00914 - PARAMETERS:
00915         - nom_fitxer: full path + filename to generate
00916 - RESULT:
00917 - RESTRICTIONS:
00918 - AUTHOR: Ricard Borràs
00919 - CREATION DATE: 25-05-2005.
00920 - MODIFICATION: Date. Author. Description.
00921 */
00922 void CBlobResult::PrintBlobs( char *nom_fitxer ) const
00923 {
00924         double_stl_vector area, /*perimetre,*/ exterior, compacitat, longitud, 
00925                                           externPerimeter, perimetreConvex, perimetre;
00926         int i;
00927         FILE *fitxer_sortida;
00928 
00929         area      = GetSTLResult( CBlobGetArea());
00930         perimetre = GetSTLResult( CBlobGetPerimeter());
00931         exterior  = GetSTLResult( CBlobGetExterior());
00932         compacitat = GetSTLResult(CBlobGetCompactness());
00933         longitud  = GetSTLResult( CBlobGetLength());
00934         externPerimeter = GetSTLResult( CBlobGetExternPerimeter());
00935         perimetreConvex = GetSTLResult( CBlobGetHullPerimeter());
00936 
00937         fitxer_sortida = fopen( nom_fitxer, "w" );
00938 
00939         for(i=0; i<GetNumBlobs(); i++)
00940         {
00941                 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",
00942                                  i, area[i], perimetre[i], externPerimeter[i], perimetreConvex[i], exterior[i], compacitat[i], longitud[i] );
00943         }
00944         fclose( fitxer_sortida );
00945 
00946 }


hrl_cvblobslib
Author(s): kelsey
autogenerated on Wed Nov 27 2013 11:32:58