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 "BlobResult.h"
00015 #include "BlobExtraction.h"
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
00089 CBlobResult::CBlobResult(IplImage *source, IplImage *mask, int threshold, bool findmoments)
00090 {
00091 bool success;
00092
00093 try
00094 {
00095
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
00135 m_blobs = blob_vector( source.GetNumBlobs() );
00136
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
00143
00144
00145 *pBlobsDst = new CBlob(**pBlobsSrc);
00146 pBlobsSrc++;
00147 pBlobsDst++;
00148 }
00149 }
00150
00151
00152
00174 CBlobResult::~CBlobResult()
00175 {
00176 ClearBlobs();
00177 }
00178
00179
00180
00181
00182
00183
00206 CBlobResult& CBlobResult::operator=(const CBlobResult& source)
00207 {
00208
00209 if (this != &source)
00210 {
00211
00212 for( int i = 0; i < GetNumBlobs(); i++ )
00213 {
00214 delete m_blobs[i];
00215 }
00216 m_blobs.clear();
00217
00218 m_blobs = blob_vector( source.GetNumBlobs() );
00219
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
00226
00227
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
00265 CBlobResult resultat( *this );
00266
00267
00268 resultat.m_blobs.resize( resultat.GetNumBlobs() + source.GetNumBlobs() );
00269
00270
00271 blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
00272 blob_vector::iterator pBlobsDst = resultat.m_blobs.end();
00273
00274
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
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
00344 double_vector result = double_vector( GetNumBlobs() );
00345
00346 double_vector::iterator itResult = result.GetIterator();
00347 blob_vector::const_iterator itBlobs = m_blobs.begin();
00348
00349
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
00394 double_stl_vector result = double_stl_vector( GetNumBlobs() );
00395
00396 double_stl_vector::iterator itResult = result.begin();
00397 blob_vector::const_iterator itBlobs = m_blobs.begin();
00398
00399
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 )
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
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
00607
00608 if( &dst == this )
00609 {
00610
00611
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
00636
00637
00638
00639
00640
00641
00642
00643
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
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 void CBlobResult::GetNthBlob( funcio_calculBlob *criteri, int nBlob, CBlob &dst ) const
00691 {
00692
00693 if( nBlob < 0 || nBlob >= GetNumBlobs() )
00694 {
00695
00696 dst = CBlob();
00697 return;
00698 }
00699
00700 double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat;
00701 double valorEnessim;
00702
00703
00704 avaluacioBlobs = GetSTLResult(criteri);
00705
00706 avaluacioBlobsOrdenat = double_stl_vector( GetNumBlobs() );
00707
00708
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
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
00747
00748
00749
00750
00751
00752
00753
00754
00755 void CBlobResult::ClearBlobs()
00756 {
00757
00758
00759
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
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 void CBlobResult::RaiseError(const int errorCode) const
00798 {
00799
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
00823
00824
00825
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 void CBlobResult::PrintBlobs( char *nom_fitxer ) const
00850 {
00851 double_stl_vector area, exterior, mitjana, compacitat, longitud,
00852 externPerimeter, perimetreConvex;
00853 double_vector perimetre;
00854 int i;
00855 FILE *fitxer_sortida;
00856
00857 area = GetSTLResult( CBlobGetArea());
00858
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 }