00001
00002
00003
00004
00005
00006
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>
00018 #include <afxwin.h>
00019 #endif
00020
00021
00022
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
00139 m_blobs = Blob_vector( source.GetNumBlobs() );
00140
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
00147
00148
00149 *pBlobsDst = new CBlob(**pBlobsSrc);
00150 pBlobsSrc++;
00151 pBlobsDst++;
00152 }
00153 }
00154
00155
00156
00178 CBlobResult::~CBlobResult()
00179 {
00180 ClearBlobs();
00181 }
00182
00183
00184
00185
00186
00187
00210 CBlobResult& CBlobResult::operator=(const CBlobResult& source)
00211 {
00212
00213 if (this != &source)
00214 {
00215
00216 for( int i = 0; i < GetNumBlobs(); i++ )
00217 {
00218 delete m_blobs[i];
00219 }
00220 m_blobs.clear();
00221
00222 m_blobs = Blob_vector( source.GetNumBlobs() );
00223
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
00230
00231
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
00269 CBlobResult resultat( *this );
00270
00271
00272 resultat.m_blobs.resize( resultat.GetNumBlobs() + source.GetNumBlobs() );
00273
00274
00275 Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
00276 Blob_vector::iterator pBlobsDst = resultat.m_blobs.end();
00277
00278
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
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
00348 double_vector result = double_vector( GetNumBlobs() );
00349
00350 double_vector::iterator itResult = result.GetIterator();
00351 Blob_vector::const_iterator itBlobs = m_blobs.begin();
00352
00353
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
00398 double_stl_vector result = double_stl_vector( GetNumBlobs() );
00399
00400 double_stl_vector::iterator itResult = result.begin();
00401 Blob_vector::const_iterator itBlobs = m_blobs.begin();
00402
00403
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 ) const
00504
00505 {
00506
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 )
00566
00567 {
00568 int numBlobs = GetNumBlobs();
00569
00570
00571 DoFilter(dst, filterAction, evaluador, condition, lowLimit, highLimit );
00572
00573
00574 if( &dst == this )
00575 {
00576
00577
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) 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
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
00709
00710
00711
00712
00713
00714
00715
00716
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
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 void CBlobResult::GetNthBlob( funcio_calculBlob *criteri, int nBlob, CBlob &dst ) const
00764 {
00765
00766 if( nBlob < 0 || nBlob >= GetNumBlobs() )
00767 {
00768
00769 dst = CBlob();
00770 return;
00771 }
00772
00773 double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat;
00774 double valorEnessim;
00775
00776
00777 avaluacioBlobs = GetSTLResult(criteri);
00778
00779 avaluacioBlobsOrdenat = double_stl_vector( GetNumBlobs() );
00780
00781
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
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
00820
00821
00822
00823
00824
00825
00826
00827
00828 void CBlobResult::ClearBlobs()
00829 {
00830
00831
00832
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
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 void CBlobResult::RaiseError(const int errorCode) const
00871 {
00872
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
00896
00897
00898
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 void CBlobResult::PrintBlobs( char *nom_fitxer ) const
00923 {
00924 double_stl_vector area, 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 }