TeGeometricTransformation Class Reference
[Geometric transformation.]

#include <TeGeometricTransformation.h>

Inheritance diagram for TeGeometricTransformation:

Te2ndDegPolinomialGT TeAffineGT TeProjectiveGT

Detailed Description

This is the base class to deal with a geometric trasformation direct and inverse mapping the tie-points TeCoordPair::pt1 space into TeCoordPair::pt2 space.
Author:
Emiliano F. Castejon <castejon@dpi.inpe.br>

Definition at line 48 of file TeGeometricTransformation.h.


Public Types

typedef TeSharedPtr
< TeGeometricTransformation
pointer
 Type definition for a TeGeometricTransformation instance pointer.

Public Member Functions

void directMap (const TeCoord2D &pt1, TeCoord2D &pt2) const
double getDirectMappingError (const TeCoordPair &tie_point) const
double getDirectMappingError () const
double getDMapRMSE () const
double getIMapRMSE () const
double getInverseMappingError (const TeCoordPair &tie_point) const
double getInverseMappingError () const
virtual unsigned int getMinRequiredTiePoints () const =0
const TeGTParamsgetParameters () const
void getParameters (TeGTParams &params) const
void inverseMap (const TeCoord2D &pt2, TeCoord2D &pt1) const
bool reset (const TeGTParams &newparams)
virtual ~TeGeometricTransformation ()

Static Public Member Functions

static
TeGeometricTransformation
DefaultObject (const TeGTParams &)

Protected Member Functions

virtual bool computeParameters (TeGTParams &params) const =0
virtual void directMap (const TeGTParams &params, const TeCoord2D &pt1, TeCoord2D &pt2) const =0
double getDirectMappingError (const TeCoordPair &tie_point, const TeGTParams &params) const
double getDirectMappingError (const TeGTParams &params) const
double getDMapRMSE (const TeGTParams &params) const
double getIMapRMSE (const TeGTParams &params) const
double getInverseMappingError (const TeCoordPair &tie_point, const TeGTParams &params) const
double getInverseMappingError (const TeGTParams &params) const
virtual void inverseMap (const TeGTParams &params, const TeCoord2D &pt2, TeCoord2D &pt1) const =0
virtual bool isTransDefined (const TeGTParams &params) const =0
 TeGeometricTransformation ()

Private Types

typedef unsigned int RansacItCounterT

Private Member Functions

bool exaustiveOutRemotion (TeGTParams &params, unsigned int threads_nmb)
double getPt1ConvexHullArea (const TeCoordPairVect &tiePoints) const
bool lWOutRemotion (TeGTParams &params)
bool normalizeTPWeights (std::vector< double > &tpWeights) const
const
TeGeometricTransformation
operator= (const TeGeometricTransformation &)
bool ransacRemotion (const TeGTParams &inputParams, TeGTParams &outputParams) const
void updateExcTPErrList (const TeGTParams &params, bool useTPWeights, std::list< ExcTPDataNode > &exc_tp_list) const
void updateTPErrVec (const TeGTParams &params, bool useTPWeights, std::vector< TPDataNode > &errvec) const

Static Private Member Functions

static bool eORThreadEntry (const TeThreadParameters &params)
static bool recombineSeed (std::vector< unsigned int > &seed, const unsigned int &seedpos, const unsigned int &elements_nmb)

Private Attributes

TeGTParams internal_params_

Data Structures

class  ExcTPDataNode
class  TPDataNode

Member Typedef Documentation

TeSharedPtr< TeGeometricTransformation > TeGeometricTransformation::pointer

Definition at line 74 of file TeGeometricTransformation.h.

typedef unsigned int TeGeometricTransformation::RansacItCounterT [private]

RANSAC iterations counter type.

Definition at line 337 of file TeGeometricTransformation.h.


Constructor & Destructor Documentation

TeGeometricTransformation::~TeGeometricTransformation (  )  [virtual]

Default Destructor

Definition at line 53 of file TeGeometricTransformation.cpp.

00054 {
00055 }

TeGeometricTransformation::TeGeometricTransformation (  )  [protected]

Default Constructor.

Definition at line 48 of file TeGeometricTransformation.cpp.

00049 {
00050 }


Member Function Documentation

virtual bool TeGeometricTransformation::computeParameters ( TeGTParams params  )  const [protected, pure virtual]

Calculate the transformation parameters following the new supplied tie-points.

Parameters:
params Transformation parameters.
Returns:
true if OK, false on errors.

Implemented in Te2ndDegPolinomialGT, TeAffineGT, and TeProjectiveGT.

Referenced by eORThreadEntry(), lWOutRemotion(), ransacRemotion(), and reset().

TeGeometricTransformation * TeGeometricTransformation::DefaultObject ( const TeGTParams  )  [static]

Returns a default object.

Returns:
A default object.

Definition at line 354 of file TeGeometricTransformation.cpp.

References TEAGN_LOG_AND_THROW.

00356 { 
00357   TEAGN_LOG_AND_THROW( "Trying to create an invalid "
00358     "TeGemetricTransformation instance" );
00359   
00360   return 0;
00361 }; 

virtual void TeGeometricTransformation::directMap ( const TeGTParams params,
const TeCoord2D pt1,
TeCoord2D pt2 
) const [protected, pure virtual]

Direct mapping ( from pt1 space into pt2 space ).

Parameters:
params Transformation parameters.
pt1 pt1 coordinate.
pt2 pt2 coordinate.

Implemented in Te2ndDegPolinomialGT, TeAffineGT, and TeProjectiveGT.

void TeGeometricTransformation::directMap ( const TeCoord2D pt1,
TeCoord2D pt2 
) const [inline]

Direct mapping ( from pt1 space into pt2 space ).

Parameters:
pt1 pt1 coordinate.
pt2 pt2 coordinate.

Definition at line 87 of file TeGeometricTransformation.h.

References TEAGN_DEBUG_CONDITION.

Referenced by getDirectMappingError().

00088       {
00089         TEAGN_DEBUG_CONDITION( isTransDefined( internal_params_ ),
00090           "Transformation not defined" )
00091         
00092         directMap( internal_params_, pt1, pt2 );
00093       };

bool TeGeometricTransformation::eORThreadEntry ( const TeThreadParameters params  )  [static, private]

Exaustive outliers remotion thread entry.

Parameters:
params Thread parameters.
Returns:
TRUE if OK, false on errors.

Definition at line 460 of file TeGeometricTransformation.cpp.

References computeParameters(), getDirectMappingError(), getInverseMappingError(), TeMutex::lock(), TeGTParams::max_dmap_error_, TeGTParams::max_imap_error_, recombineSeed(), TeMultiContainer< TeMultiContainerKeyT >::retrive(), TEAGN_TRUE_OR_THROW, TeGTParams::tiepoints_, and TeMutex::unLock().

Referenced by exaustiveOutRemotion().

00462 {
00463   /* Extracting parameters */
00464   
00465   unsigned int req_tie_pts_nmb = 0;
00466   TEAGN_TRUE_OR_THROW( params.retrive( "req_tie_pts_nmb",
00467     req_tie_pts_nmb ), "Missing parameter" );
00468     
00469   TeGTParams const* init_trans_params_ptr = 0;
00470   TEAGN_TRUE_OR_THROW( params.retrive( "init_trans_params_ptr",
00471     init_trans_params_ptr ), "Missing parameter" );
00472   
00473   TeGTParams* best_trans_params_ptr = 0;
00474   TEAGN_TRUE_OR_THROW( params.retrive( "best_trans_params_ptr",
00475     best_trans_params_ptr ), "Missing parameter" );   
00476     
00477   double volatile* best_trans_dmap_error_ptr = 0;
00478   TEAGN_TRUE_OR_THROW( params.retrive( "best_trans_dmap_error_ptr",
00479     best_trans_dmap_error_ptr ), "Missing parameter" );     
00480     
00481   double volatile* best_trans_imap_error_ptr = 0;
00482   TEAGN_TRUE_OR_THROW( params.retrive( "best_trans_imap_error_ptr",
00483     best_trans_imap_error_ptr ), "Missing parameter" );     
00484 
00485   std::vector<unsigned int>* comb_seed_vec_ptr = 0;
00486   TEAGN_TRUE_OR_THROW( params.retrive( "comb_seed_vec_ptr",
00487     comb_seed_vec_ptr ), "Missing parameter" );
00488     
00489   TeMutex* trans_params_mutex_ptr = 0;
00490   TEAGN_TRUE_OR_THROW( params.retrive( "trans_params_mutex_ptr",
00491     trans_params_mutex_ptr ), "Missing parameter" ); 
00492 
00493   TeMutex* comb_seed_vec_mutex_ptr = 0;
00494   TEAGN_TRUE_OR_THROW( params.retrive( "comb_seed_vec_mutex_ptr",
00495     comb_seed_vec_mutex_ptr ), "Missing parameter" );  
00496     
00497   TeGeometricTransformation const* geo_trans_ptr = 0;
00498   TEAGN_TRUE_OR_THROW( params.retrive( "geo_trans_ptr",
00499     geo_trans_ptr ), "Missing parameter" ); 
00500   
00501   /* Optimized local variables based on the input parameters */
00502   
00503   std::vector<unsigned int>& comb_seed_vec =
00504     (*comb_seed_vec_ptr);  
00505     
00506   TeMutex& comb_seed_vec_mutex = (*comb_seed_vec_mutex_ptr); 
00507   
00508   const TeGeometricTransformation& geo_trans = (*geo_trans_ptr); 
00509   
00510   /* Copying some parameters to local variables to avoid
00511      mutex overhead */
00512      
00513   trans_params_mutex_ptr->lock();
00514      
00515   const TeGTParams initial_trans_params = (*init_trans_params_ptr);     
00516   const unsigned int initial_tiepoints_size = 
00517     initial_trans_params.tiepoints_.size();   
00518   
00519   trans_params_mutex_ptr->unLock();
00520         
00521   /* Trying to find the best tie-points by building 
00522     the transformation with the highest number of
00523     tie-points, but with an acceptable mapping error */
00524     
00525   TeGTParams local_best_params;
00526   double local_best_params_dmap_error = DBL_MAX;
00527   double local_best_params_imap_error = DBL_MAX;
00528   
00529   TeGTParams curr_params = initial_trans_params;
00530   double curr_params_dmap_error = DBL_MAX;
00531   double curr_params_imap_error = DBL_MAX; 
00532   
00533   TeGTParams cp_plus_new_point;
00534   double cp_plus_new_point_dmap_error = DBL_MAX;
00535   double cp_plus_new_point_imap_error = DBL_MAX;
00536   
00537   unsigned int tiepoints_index = 0;
00538   bool point_already_present = false;
00539   bool seed_recombined = true;
00540   unsigned int comb_seed_vec_index_2 = 0;
00541   unsigned int comb_seed_vec_index_3 = 0;
00542   
00543   while( seed_recombined ) {
00544     /* trying to recombine seed */
00545     
00546     comb_seed_vec_mutex.lock();
00547     seed_recombined = recombineSeed( comb_seed_vec, 0, 
00548       initial_tiepoints_size );
00549     comb_seed_vec_mutex.unLock();
00550       
00551     if( seed_recombined ) {
00552       /* Extracting tie-points from the original vector */
00553       
00554       curr_params.tiepoints_.clear();
00555       
00556       for( comb_seed_vec_index_2 = 0 ; 
00557         comb_seed_vec_index_2 < req_tie_pts_nmb ;
00558         ++comb_seed_vec_index_2 ) {
00559         
00560         curr_params.tiepoints_.push_back( 
00561           initial_trans_params.tiepoints_[ comb_seed_vec[ 
00562           comb_seed_vec_index_2 ] - 1 ] );
00563       }
00564       
00565       /* Trying to generate a valid transformation */
00566       
00567       if( geo_trans.computeParameters( curr_params ) ) {
00568         curr_params_dmap_error = geo_trans.getDirectMappingError( 
00569           curr_params );
00570         curr_params_imap_error = geo_trans.getInverseMappingError( 
00571           curr_params );
00572       
00573         if( ( initial_trans_params.max_dmap_error_ >= 
00574           curr_params_dmap_error ) &&
00575           ( initial_trans_params.max_imap_error_ >= 
00576           curr_params_imap_error ) ) {
00577         
00578           /* Trying to insert more tie-points into current 
00579               transformation */
00580           
00581           for( tiepoints_index = 0 ; tiepoints_index < 
00582             initial_tiepoints_size ; ++tiepoints_index ) {
00583             
00584             /* Verifying if the current tie-point is already 
00585                present */
00586             
00587             point_already_present = false;
00588             
00589             for( comb_seed_vec_index_3 = 0 ; 
00590               comb_seed_vec_index_3 < req_tie_pts_nmb ;
00591               ++comb_seed_vec_index_3 ) {
00592             
00593               if( tiepoints_index == ( 
00594                 comb_seed_vec[ comb_seed_vec_index_3 ] - 1 ) ) {
00595               
00596                 point_already_present = true;
00597                 break;
00598               }
00599             }
00600             
00601             if( ! point_already_present ) {
00602               cp_plus_new_point = curr_params;
00603               
00604               cp_plus_new_point.tiepoints_.push_back( 
00605                 initial_trans_params.tiepoints_[ tiepoints_index ] );
00606               
00607               /* Verifying if the new tie-point insertion does 
00608                 not generate an invalid transformation */
00609               
00610               if( geo_trans.computeParameters( cp_plus_new_point ) ) {
00611                 cp_plus_new_point_dmap_error =
00612                   geo_trans.getDirectMappingError( cp_plus_new_point );
00613                 cp_plus_new_point_imap_error =
00614                   geo_trans.getInverseMappingError( cp_plus_new_point );
00615                   
00616                 if( ( cp_plus_new_point_dmap_error <=
00617                   initial_trans_params.max_dmap_error_ ) &&
00618                   ( cp_plus_new_point_imap_error <=
00619                   initial_trans_params.max_imap_error_ ) ) {
00620                   
00621                   curr_params = cp_plus_new_point;
00622                   curr_params_dmap_error = 
00623                     cp_plus_new_point_dmap_error;
00624                   curr_params_imap_error =
00625                     cp_plus_new_point_imap_error;  
00626                 }
00627               }
00628             }
00629           }
00630           
00631           /* A valid transformation was generated, now 
00632             verifying 
00633             if the number of tie-poits is greater then the current 
00634             thread local best transformation.
00635           */            
00636           
00637           if( curr_params.tiepoints_.size() >= 
00638             local_best_params.tiepoints_.size() ) {
00639             
00640             if( ( curr_params_dmap_error < 
00641               local_best_params_dmap_error ) &&
00642               ( curr_params_imap_error <
00643                 local_best_params_imap_error ) ) {
00644             
00645               local_best_params = curr_params;
00646               local_best_params_dmap_error = curr_params_dmap_error;
00647               local_best_params_imap_error = curr_params_imap_error;
00648             }
00649           }           
00650         }
00651       } //if( geo_trans.computeParameters( curr_params ) )
00652     } //if( seed_recombined )
00653   } //while( seed_recombined )
00654   
00655   /* A valid local thread transformation was generated, now 
00656     verifying 
00657     if the error is smaller then the current 
00658     global transformation.
00659   */
00660 
00661   if( local_best_params.tiepoints_.size() >= req_tie_pts_nmb ) {
00662     trans_params_mutex_ptr->lock();
00663     
00664     if( local_best_params.tiepoints_.size() >=
00665       best_trans_params_ptr->tiepoints_.size() ) {
00666       
00667       if( ( local_best_params_dmap_error < 
00668         (*best_trans_dmap_error_ptr) ) &&
00669         ( local_best_params_imap_error < 
00670         (*best_trans_imap_error_ptr) ) ) {
00671       
00672         (*best_trans_params_ptr) = local_best_params;
00673         (*best_trans_dmap_error_ptr) = local_best_params_dmap_error;
00674         (*best_trans_imap_error_ptr) = local_best_params_imap_error;       
00675       }      
00676     }
00677     
00678     trans_params_mutex_ptr->unLock();
00679   }
00680   
00681   return true;
00682 }

bool TeGeometricTransformation::exaustiveOutRemotion ( TeGTParams params,
unsigned int  threads_nmb 
) [private]

Multi-thread exaustive outliers remotion strategy (All tie-points combinations will be tested).

Parameters:
params The current transformation parameters.
threads_nmb Threads number (not including the curent process).
Returns:
TRUE if OK, false on errors.

Definition at line 364 of file TeGeometricTransformation.cpp.

References eORThreadEntry(), TeGTParams::ExaustiveOutRemotion, getMinRequiredTiePoints(), TeGTParams::max_dmap_error_, TeGTParams::max_imap_error_, TeGTParams::out_rem_strat_, TeMultiContainer< TeMultiContainerKeyT >::store(), TEAGN_DEBUG_CONDITION, TEAGN_TRUE_OR_THROW, and TeGTParams::tiepoints_.

Referenced by reset().

00366 {
00367   TEAGN_DEBUG_CONDITION( ( params.out_rem_strat_ == 
00368     TeGTParams::ExaustiveOutRemotion ), 
00369     "Inconsistent outliers remotion strategy" )
00370   TEAGN_TRUE_OR_THROW( ( params.max_dmap_error_ >= 0 ),
00371     "Invalid maximum allowed direct mapping error" );
00372   TEAGN_TRUE_OR_THROW( ( params.max_imap_error_ >= 0 ),
00373     "Invalid maximum allowed inverse mapping error" );    
00374 
00375   /* Initiating seed */
00376   
00377   std::vector<unsigned int> comb_seed_vec;       
00378     
00379   unsigned int req_tie_pts_nmb = getMinRequiredTiePoints();
00380   
00381   for( unsigned int comb_seed_vec_index = 0 ; 
00382     comb_seed_vec_index < req_tie_pts_nmb ;
00383     ++comb_seed_vec_index ) {
00384     
00385     comb_seed_vec.push_back( 0 );
00386   }
00387   
00388   /* initializing mutexes */
00389   
00390   TeMutex comb_seed_vec_mutex;
00391   TeMutex trans_params_mutex;
00392   
00393   /* Initializing threads */
00394   
00395   TeGTParams best_trans_params;
00396   volatile double best_trans_dmap_error = DBL_MAX;
00397   volatile double best_trans_imap_error = DBL_MAX;
00398   
00399   std::vector< TeThreadFunctor::pointer > threads_vector;
00400   
00401   TeThreadParameters thread_params;
00402   
00403   thread_params.store( "req_tie_pts_nmb", req_tie_pts_nmb );  
00404   thread_params.store( "init_trans_params_ptr", 
00405     (TeGTParams const*)(&params) );
00406   thread_params.store( "best_trans_params_ptr", 
00407     &best_trans_params );    
00408   thread_params.store( "best_trans_dmap_error_ptr", 
00409     &best_trans_dmap_error );      
00410   thread_params.store( "best_trans_imap_error_ptr", 
00411     &best_trans_imap_error );     
00412   thread_params.store( "comb_seed_vec_ptr", &comb_seed_vec );
00413   thread_params.store( "trans_params_mutex_ptr", 
00414     &trans_params_mutex );
00415   thread_params.store( "comb_seed_vec_mutex_ptr", 
00416     &comb_seed_vec_mutex );  
00417   thread_params.store( "geo_trans_ptr", 
00418     (TeGeometricTransformation const*)this );        
00419     
00420   unsigned int thread_index = 0;
00421   
00422   for( thread_index = 0 ; thread_index < threads_nmb ; 
00423     ++thread_index ) {
00424     
00425     TeThreadFunctor::pointer aux_thread_ptr( 
00426       new TeThreadFunctor );
00427     aux_thread_ptr->setStartFunctPtr( eORThreadEntry );
00428     aux_thread_ptr->setParameters( thread_params );
00429     aux_thread_ptr->start();
00430   
00431     threads_vector.push_back( aux_thread_ptr );
00432   }
00433   
00434   bool my_return = eORThreadEntry( thread_params );
00435   bool threads_return = true;
00436   
00437   for( thread_index = 0 ; thread_index < threads_nmb ; 
00438     ++thread_index ) {
00439     
00440     threads_vector[ thread_index ]->waitToFinish();
00441     
00442     threads_return = threads_return & 
00443       threads_vector[ thread_index ]->getReturnValue();
00444   }  
00445   
00446   if( my_return & threads_return ) {
00447     if( best_trans_params.tiepoints_.size() >= req_tie_pts_nmb ) {
00448       params = best_trans_params;
00449       
00450       return true;
00451     } else {
00452       return false;
00453     }
00454   } else {
00455     return false;
00456   }
00457 }

double TeGeometricTransformation::getDirectMappingError ( const TeCoordPair tie_point,
const TeGTParams params 
) const [protected]

Calculates the direct mapping error for the supplied tie-point. ( from pt1 space into pt2 space ).

Parameters:
tie_point The tie-point.
params Transformation parameters.
Returns:
The current maximum direct mapping error.

Definition at line 266 of file TeGeometricTransformation.cpp.

References directMap(), isTransDefined(), TeCoordPair::pt1, TeCoordPair::pt2, TEAGN_DEBUG_CONDITION, TeCoord2D::x(), and TeCoord2D::y().

00268 {
00269   TEAGN_DEBUG_CONDITION( isTransDefined( params ),
00270     "Transformation not defined" )   
00271     
00272   TeCoord2D direct_mapped_point;
00273 
00274   directMap( params, tie_point.pt1, direct_mapped_point );
00275     
00276   double diff_x = tie_point.pt2.x() - direct_mapped_point.x();
00277   double diff_y = tie_point.pt2.y() - direct_mapped_point.y();
00278     
00279   return hypot( diff_x, diff_y );
00280 }

double TeGeometricTransformation::getDirectMappingError ( const TeGTParams params  )  const [protected]

Calculates maximum direct mapping error for the supplied parameters ( from pt1 space into pt2 space ).

Parameters:
params Transformation parameters.
Returns:
The maximum direct mapping error for the supplied parameters.

Definition at line 160 of file TeGeometricTransformation.cpp.

References getDirectMappingError(), isTransDefined(), TEAGN_DEBUG_CONDITION, and TeGTParams::tiepoints_.

00162 {
00163   TEAGN_DEBUG_CONDITION( isTransDefined( params ),
00164     "Transformation not defined" )   
00165     
00166   unsigned int tiepoints_size = params.tiepoints_.size();
00167   
00168   double max_error = 0;
00169   double current_error = 0;
00170   
00171   for( unsigned int tpindex = 0 ; tpindex < tiepoints_size ; ++tpindex ) {
00172     current_error = getDirectMappingError( params.tiepoints_[ tpindex ], 
00173       params );
00174     
00175     if( current_error > max_error ) {
00176       max_error = current_error;
00177     }
00178   }
00179   
00180   return max_error;
00181 }

double TeGeometricTransformation::getDirectMappingError ( const TeCoordPair tie_point  )  const [inline]

Calculates the direct mapping error for the supplied tie-point ( from pt1 space into pt2 space ).

Parameters:
tie_point The tie-point.
Returns:
The current direct mapping error.

Definition at line 196 of file TeGeometricTransformation.h.

References TEAGN_DEBUG_CONDITION.

00197       {
00198         TEAGN_DEBUG_CONDITION( isTransDefined( internal_params_ ),
00199           "Transformation not defined" )
00200       
00201         return getDirectMappingError( tie_point, internal_params_ );      
00202       };

double TeGeometricTransformation::getDirectMappingError (  )  const [inline]

Calculates the current transformation maximum direct mapping error ( from pt1 space into pt2 space ).

Returns:
The current maximum direct mapping error.

Definition at line 139 of file TeGeometricTransformation.h.

References TEAGN_DEBUG_CONDITION.

Referenced by eORThreadEntry(), getDirectMappingError(), getDMapRMSE(), lWOutRemotion(), ransacRemotion(), reset(), updateExcTPErrList(), and updateTPErrVec().

00140       {
00141         TEAGN_DEBUG_CONDITION( isTransDefined( internal_params_ ),
00142           "Transformation not defined" )
00143         
00144         return getDirectMappingError( internal_params_ );
00145       };

double TeGeometricTransformation::getDMapRMSE ( const TeGTParams params  )  const [protected]

Calculates root mean square direct mapping error for the supplied parameters ( from pt1 space into pt2 space ).

Parameters:
params Transformation parameters.
Returns:
The root mean square error.

Definition at line 208 of file TeGeometricTransformation.cpp.

References getDirectMappingError(), isTransDefined(), TEAGN_DEBUG_CONDITION, and TeGTParams::tiepoints_.

00210 {
00211   TEAGN_DEBUG_CONDITION( isTransDefined( params ),
00212     "Transformation not defined" )   
00213     
00214   unsigned int tiepoints_size = params.tiepoints_.size();
00215   
00216   if( tiepoints_size == 0 )
00217   {
00218     return 0;
00219   }
00220   else
00221   {
00222     double error2_sum = 0;
00223     double current_error = 0;
00224     
00225     for( unsigned int tpindex = 0 ; tpindex < tiepoints_size ; ++tpindex ) {
00226       current_error = getDirectMappingError( params.tiepoints_[ tpindex ], 
00227         params );
00228         
00229       error2_sum += ( current_error * current_error );
00230     }
00231     
00232     return sqrt( error2_sum / ( (double)tiepoints_size ) );
00233   }
00234 }

double TeGeometricTransformation::getDMapRMSE (  )  const [inline]

Calculates root mean square direct mapping error ( from pt1 space into pt2 space ).

Returns:
The root mean square error.

Definition at line 167 of file TeGeometricTransformation.h.

References TEAGN_DEBUG_CONDITION.

Referenced by lWOutRemotion().

00168       {
00169         TEAGN_DEBUG_CONDITION( isTransDefined( internal_params_ ),
00170           "Transformation not defined" )
00171         
00172         return getDMapRMSE( internal_params_ );
00173       };        

double TeGeometricTransformation::getIMapRMSE ( const TeGTParams params  )  const [protected]

Calculates root mean square inverse mapping error for the supplied parameters ( from pt2 space into pt1 space ).

Parameters:
params Transformation parameters.
Returns:
The root mean square error.

Definition at line 237 of file TeGeometricTransformation.cpp.

References getInverseMappingError(), isTransDefined(), TEAGN_DEBUG_CONDITION, and TeGTParams::tiepoints_.

00239 {
00240   TEAGN_DEBUG_CONDITION( isTransDefined( params ),
00241     "Transformation not defined" )   
00242     
00243   unsigned int tiepoints_size = params.tiepoints_.size();
00244   
00245   if( tiepoints_size == 0 )
00246   {
00247     return 0;
00248   }
00249   else
00250   {
00251     double error2_sum = 0;
00252     double current_error = 0;
00253     
00254     for( unsigned int tpindex = 0 ; tpindex < tiepoints_size ; ++tpindex ) {
00255       current_error = getInverseMappingError( params.tiepoints_[ tpindex ], 
00256         params );
00257         
00258       error2_sum += ( current_error * current_error );
00259     }
00260     
00261     return sqrt( error2_sum / ( (double)tiepoints_size ) );
00262   }  
00263 }

double TeGeometricTransformation::getIMapRMSE (  )  const [inline]

Calculates root mean square inverse mapping error ( from pt2 space into pt1 space ).

Returns:
The root mean square error.

Definition at line 181 of file TeGeometricTransformation.h.

References TEAGN_DEBUG_CONDITION.

Referenced by lWOutRemotion().

00182       {
00183         TEAGN_DEBUG_CONDITION( isTransDefined( internal_params_ ),
00184           "Transformation not defined" )
00185         
00186         return getIMapRMSE( internal_params_ );
00187       };

double TeGeometricTransformation::getInverseMappingError ( const TeCoordPair tie_point,
const TeGTParams params 
) const [protected]

Calculates the inverse mapping error for the supplied tie-point. ( from pt2 space into pt1 space ).

Parameters:
tie_point The tie-point.
params Transformation parameters.
Returns:
The current maximum inverse mapping error.

Definition at line 283 of file TeGeometricTransformation.cpp.

References inverseMap(), isTransDefined(), TeCoordPair::pt1, TeCoordPair::pt2, TEAGN_DEBUG_CONDITION, TeCoord2D::x(), and TeCoord2D::y().

00285 {
00286   TEAGN_DEBUG_CONDITION( isTransDefined( params ),
00287     "Transformation not defined" )   
00288     
00289   TeCoord2D inverse_mapped_point;
00290 
00291   inverseMap( params, tie_point.pt2, inverse_mapped_point );
00292     
00293   double diff_x = tie_point.pt1.x() - inverse_mapped_point.x();
00294   double diff_y = tie_point.pt1.y() - inverse_mapped_point.y();
00295     
00296   return hypot( diff_x, diff_y );
00297 }

double TeGeometricTransformation::getInverseMappingError ( const TeGTParams params  )  const [protected]

Calculates maximum inverse mapping error for the supplied parameters ( from pt2 space into pt1 space ).

Parameters:
params Transformation parameters.
Returns:
The maximum inverse mapping error for the supplied parameters.

Definition at line 184 of file TeGeometricTransformation.cpp.

References getInverseMappingError(), isTransDefined(), TEAGN_DEBUG_CONDITION, and TeGTParams::tiepoints_.

00186 {
00187   TEAGN_DEBUG_CONDITION( isTransDefined( params ),
00188     "Transformation not defined" )  
00189     
00190   unsigned int tiepoints_size = params.tiepoints_.size();
00191   
00192   double max_error = 0;
00193   double current_error = 0;
00194   
00195   for( unsigned int tpindex = 0 ; tpindex < tiepoints_size ; ++tpindex ) {
00196     current_error = getInverseMappingError( params.tiepoints_[ tpindex ], 
00197       params );
00198     
00199     if( current_error > max_error ) {
00200       max_error = current_error;
00201     }
00202   }
00203   
00204   return max_error;
00205 }

double TeGeometricTransformation::getInverseMappingError ( const TeCoordPair tie_point  )  const [inline]

Calculates the inverse mapping error for the supplied tie-point ( from pt2 space into pt1 space ).

Parameters:
tie_point The tie-point.
Returns:
The current inverse mapping error.

Definition at line 211 of file TeGeometricTransformation.h.

References TEAGN_DEBUG_CONDITION.

00212       {
00213         TEAGN_DEBUG_CONDITION( isTransDefined( internal_params_ ),
00214           "Transformation not defined" )
00215       
00216         return getInverseMappingError( tie_point, internal_params_ );      
00217       };      

double TeGeometricTransformation::getInverseMappingError (  )  const [inline]

Calculates the current transformation maximum inverse mapping error ( from pt2 space into pt1 space ).

Returns:
The current maximum inverse mapping error.

Definition at line 153 of file TeGeometricTransformation.h.

References TEAGN_DEBUG_CONDITION.

Referenced by eORThreadEntry(), getIMapRMSE(), getInverseMappingError(), lWOutRemotion(), ransacRemotion(), reset(), updateExcTPErrList(), and updateTPErrVec().

00154       {
00155         TEAGN_DEBUG_CONDITION( isTransDefined( internal_params_ ),
00156           "Transformation not defined" )
00157         
00158         return getInverseMappingError( internal_params_ );
00159       };     

virtual unsigned int TeGeometricTransformation::getMinRequiredTiePoints (  )  const [pure virtual]

Returns the minimum number of required tie-points for the current transformation.

Returns:
The minimum number of required tie-points for the current transformation.

Implemented in Te2ndDegPolinomialGT, TeAffineGT, and TeProjectiveGT.

Referenced by exaustiveOutRemotion(), lWOutRemotion(), ransacRemotion(), and reset().

const TeGTParams & TeGeometricTransformation::getParameters (  )  const

Returns a reference of the current internal transformation parameters.

Returns:
A reference of the current internal transformation parameters..

Definition at line 63 of file TeGeometricTransformation.cpp.

References internal_params_.

00064 {
00065   return internal_params_;
00066 }

void TeGeometricTransformation::getParameters ( TeGTParams params  )  const

Returns a copy of the current internal transformation parameters.

Parameters:
params The internal parameters copy.

Definition at line 58 of file TeGeometricTransformation.cpp.

References internal_params_.

00059 {
00060   params = internal_params_;
00061 }

double TeGeometricTransformation::getPt1ConvexHullArea ( const TeCoordPairVect tiePoints  )  const [private]

Definition at line 1838 of file TeGeometricTransformation.cpp.

References TeConvexHull(), and TeGeometryArea().

Referenced by ransacRemotion().

01840 {
01841   const unsigned int tiePointsSize = (unsigned int)tiePoints.size();
01842   
01843   std::vector< TeCoord2D > coords;
01844   coords.resize( tiePointsSize );
01845   
01846   for( unsigned int tpIdx = 0 ; tpIdx < tiePointsSize ; ++tpIdx )
01847   {
01848     coords[ tpIdx ] = tiePoints[ tpIdx ].pt1;
01849   }
01850   
01851   return TeGeometryArea( TeConvexHull( coords ) );
01852 }

virtual void TeGeometricTransformation::inverseMap ( const TeGTParams params,
const TeCoord2D pt2,
TeCoord2D pt1 
) const [protected, pure virtual]

Inverse mapping ( from pt2 space into pt1 space ).

Parameters:
params Transformation parameters.
pt2 pt2 coordinate.
pt1 pt1 coordinate.

Implemented in Te2ndDegPolinomialGT, TeAffineGT, and TeProjectiveGT.

void TeGeometricTransformation::inverseMap ( const TeCoord2D pt2,
TeCoord2D pt1 
) const [inline]

Inverse mapping ( from pt2 space into pt1 space ).

Parameters:
pt2 pt2 coordinate.
pt1 pt1 coordinate.

Definition at line 101 of file TeGeometricTransformation.h.

References TEAGN_DEBUG_CONDITION.

Referenced by getInverseMappingError().

00103       {
00104         TEAGN_DEBUG_CONDITION( isTransDefined( internal_params_ ),
00105           "Transformation not defined" )         
00106       
00107         inverseMap( internal_params_, pt2, pt1 );
00108       };

virtual bool TeGeometricTransformation::isTransDefined ( const TeGTParams params  )  const [protected, pure virtual]

Verifies if the supplied parameters already has a defined transformation.

Parameters:
params Transformation parameters.
Returns:
true if a transformation is already defined, false otherwise.

Implemented in Te2ndDegPolinomialGT, TeAffineGT, and TeProjectiveGT.

Referenced by getDirectMappingError(), getDMapRMSE(), getIMapRMSE(), getInverseMappingError(), and reset().

bool TeGeometricTransformation::lWOutRemotion ( TeGTParams params  )  [private]

Leave-worse-out outliers remotion strategy (On each iteration the worse tie-point will be removed).

Parameters:
params The current transformation parameters.
Returns:
TRUE if OK, false on errors.

Definition at line 685 of file TeGeometricTransformation.cpp.

References TeMatrix::Clear(), computeParameters(), TeGTParams::direct_parameters_, TeGeometricTransformation::ExcTPDataNode::dmap_error_, getDirectMappingError(), getDMapRMSE(), getIMapRMSE(), getInverseMappingError(), getMinRequiredTiePoints(), TeGeometricTransformation::ExcTPDataNode::imap_error_, TeGTParams::inverse_parameters_, TeGTParams::LWOutRemotion, TeGTParams::max_dmap_error_, TeGTParams::max_dmap_rmse_, TeGTParams::max_imap_error_, TeGTParams::max_imap_rmse_, normalizeTPWeights(), TeGTParams::out_rem_strat_, TEAGN_DEBUG_CONDITION, TEAGN_TRUE_OR_THROW, TeGTParams::tiepoints_, TeGTParams::tiePointsWeights_, TeGeometricTransformation::ExcTPDataNode::tp_, TeGeometricTransformation::ExcTPDataNode::tp_weight_, updateExcTPErrList(), and updateTPErrVec().

Referenced by reset().

00687 {
00688   TEAGN_DEBUG_CONDITION( ( external_params.out_rem_strat_ == 
00689     TeGTParams::LWOutRemotion ), 
00690     "Inconsistent outliers remotion strategy" )
00691   TEAGN_TRUE_OR_THROW( ( external_params.tiePointsWeights_.size() ?
00692     ( external_params.tiePointsWeights_.size() ==
00693     external_params.tiepoints_.size() ) : true ),
00694     "The tie-points vector size do not match the tie-points "
00695     "weights vector size" )
00696   TEAGN_TRUE_OR_THROW( ( external_params.max_dmap_error_ >= 0 ),
00697     "Invalid maximum allowed direct mapping error" );
00698   TEAGN_TRUE_OR_THROW( ( external_params.max_imap_error_ >= 0 ),
00699     "Invalid maximum allowed inverse mapping error" );
00700   TEAGN_TRUE_OR_THROW( ( external_params.max_dmap_rmse_ >= 0 ),
00701     "Invalid maximum allowed direct mapping RMSE" );
00702   TEAGN_TRUE_OR_THROW( ( external_params.max_imap_rmse_ >= 0 ),
00703     "Invalid maximum allowed inverse mapping RMSE" );        
00704     
00705   const unsigned int req_tie_pts_nmb = getMinRequiredTiePoints();
00706   
00707   // Normalizing tie-points weights
00708     
00709   const bool useTPWeights = ( external_params.tiePointsWeights_.size() ) ?
00710     true : false;
00711   TEAGN_TRUE_OR_THROW( normalizeTPWeights( 
00712      external_params.tiePointsWeights_ ),
00713      "Error normalizing tie-points weights" );
00714   
00715   if( external_params.tiepoints_.size() == req_tie_pts_nmb ) {
00716     return computeParameters( external_params );
00717   } else if( external_params.tiepoints_.size() > req_tie_pts_nmb ) {
00718     /* Global vars */
00719     
00720     const double max_dmap_error = 
00721       external_params.max_dmap_error_;
00722     const double max_imap_error = 
00723       external_params.max_imap_error_;
00724     const double max_dmap_rmse = 
00725       external_params.max_dmap_rmse_;
00726     const double max_imap_rmse = 
00727       external_params.max_imap_rmse_;
00728           
00729     /* Computing the initial global transformation */
00730     
00731     if( ! computeParameters( external_params ) ) {
00732       return false;
00733     }    
00734     
00735     if( ( getDirectMappingError( external_params ) 
00736       <= max_dmap_error ) && 
00737       ( getInverseMappingError( external_params ) 
00738       <= max_imap_error ) &&
00739       ( getDMapRMSE( external_params ) 
00740       <= max_dmap_rmse ) && 
00741       ( getIMapRMSE( external_params ) 
00742       <= max_imap_rmse ) ) {
00743     
00744       /* This transformation has no outliers */
00745       
00746       return true;
00747     }    
00748     
00749     /* Iterating over the current transformation tie-points */
00750     
00751     TeGTParams best_params;
00752     double best_params_dmap_rmse = DBL_MAX;
00753     double best_params_imap_rmse = DBL_MAX;
00754     double best_params_dmap_error = DBL_MAX;
00755     double best_params_imap_error = DBL_MAX;
00756     
00757     bool transformation_not_updated = false;
00758     unsigned int iterations_remainning = (unsigned int)
00759       external_params.tiepoints_.size();
00760     std::vector< TPDataNode > norm_err_vec;     
00761     std::list< ExcTPDataNode > exc_tp_list;
00762     TeGTParams iteration_params = external_params;
00763     TeCoordPair excluded_tp;
00764     double excluded_tp_weight = 0;
00765     ExcTPDataNode dummy_exctpdata;
00766   
00767     while( ( iteration_params.tiepoints_.size() > 
00768       req_tie_pts_nmb ) && iterations_remainning )
00769     {
00770       unsigned int iter_tps_nmb = (unsigned int)
00771         iteration_params.tiepoints_.size();
00772       transformation_not_updated = true;
00773       
00774       /* Updating the normalized error map */
00775       
00776       updateTPErrVec( iteration_params, useTPWeights, norm_err_vec );
00777       
00778       /* Generating all possible transformations without 
00779          each tie-point, starting with the worse point */
00780       
00781       for( int norm_err_vec_idx = ((int)norm_err_vec.size()) - 1 ;
00782         ( norm_err_vec_idx > ( -1 ) ) ; --norm_err_vec_idx )
00783       {
00784         const unsigned int& cur_candtp_idx = 
00785           norm_err_vec[ norm_err_vec_idx ].tpindex_;
00786           
00787         TEAGN_DEBUG_CONDITION( ( cur_candtp_idx < 
00788           iteration_params.tiepoints_.size() ), "Invalid index" )
00789 
00790         /* Generating a transformation parameters without the
00791           current tie-point (bigger error)*/
00792             
00793         TeGTParams new_iteration_params = iteration_params;
00794         new_iteration_params.tiepoints_.clear();
00795         new_iteration_params.tiePointsWeights_.clear();
00796         new_iteration_params.direct_parameters_.Clear();
00797         new_iteration_params.inverse_parameters_.Clear();
00798             
00799         for( unsigned int tpindex2 = 0 ; tpindex2 < iter_tps_nmb ; 
00800           ++tpindex2 ) 
00801         {
00802           if( cur_candtp_idx != tpindex2 ) 
00803           {
00804             new_iteration_params.tiepoints_.push_back( 
00805               iteration_params.tiepoints_[ tpindex2 ] );
00806               
00807             if( useTPWeights )
00808             {
00809               new_iteration_params.tiePointsWeights_.push_back( 
00810                 iteration_params.tiePointsWeights_[ tpindex2 ] );
00811             }
00812           }
00813         }            
00814       
00815         /* Trying to generate a transformation without the current
00816             candidate tie-point for exclusion */      
00817         
00818         if( computeParameters( new_iteration_params ) ) 
00819         {
00820           double new_it_dmap_rmse = 
00821             getDMapRMSE( new_iteration_params );
00822           double new_it_imap_rmse = 
00823             getIMapRMSE( new_iteration_params );
00824           
00825           if( ( best_params_dmap_rmse > new_it_dmap_rmse ) && 
00826             ( best_params_imap_rmse > new_it_imap_rmse ) ) 
00827           {
00828             double new_it_dmap_error = 
00829               getDirectMappingError( new_iteration_params );
00830             double new_it_imap_error = 
00831               getInverseMappingError( new_iteration_params );
00832                         
00833             excluded_tp = iteration_params.tiepoints_[ cur_candtp_idx ];
00834             if( useTPWeights )
00835             {
00836               excluded_tp_weight = iteration_params.tiePointsWeights_[ 
00837                 cur_candtp_idx ];
00838             }
00839               
00840             /* Trying to insert back other tie-points excluded
00841                before */
00842             
00843             if( exc_tp_list.size() > 0 )
00844             {
00845               /* Updating the excluded tie points errors map */
00846               
00847               updateExcTPErrList( new_iteration_params, useTPWeights,
00848                 exc_tp_list );
00849                 
00850               /* Iterating over the excluded tps */
00851               
00852               std::list< ExcTPDataNode >::iterator 
00853                 exc_tps_list_it = exc_tp_list.begin();
00854               std::list< ExcTPDataNode >::iterator 
00855                 exc_tps_list_it_end = exc_tp_list.end();
00856                 
00857               while( exc_tps_list_it != exc_tps_list_it_end )
00858               {
00859                 const ExcTPDataNode& curr_exc_tp_data = 
00860                   *exc_tps_list_it;
00861 
00862                 /* Does this tp has direct and inverse errors 
00863                    smaller than the current new_iteration_params ?? */
00864                         
00865                 if( ( curr_exc_tp_data.dmap_error_ <= 
00866                   new_it_dmap_error ) && 
00867                   ( curr_exc_tp_data.imap_error_ <= 
00868                   new_it_imap_error ) )
00869                 {
00870                   /* Trying to generate a trasformation with
00871                      this point */
00872                      
00873                   TeGTParams new_iteration_params_plus1tp = 
00874                     new_iteration_params;
00875                   new_iteration_params.tiepoints_.push_back(
00876                     curr_exc_tp_data.tp_ );
00877                   if( useTPWeights )
00878                   {  
00879                     new_iteration_params.tiePointsWeights_.push_back(
00880                       curr_exc_tp_data.tp_weight_ );
00881                   }
00882                     
00883                   if( computeParameters( 
00884                     new_iteration_params_plus1tp ) ) 
00885                   {
00886                     double newp1tp_dmap_rmse = getDMapRMSE( 
00887                       new_iteration_params_plus1tp );
00888                     double newp1tp_imap_rmse = getIMapRMSE( 
00889                       new_iteration_params_plus1tp );
00890                     
00891                     if( ( new_it_dmap_rmse >= newp1tp_dmap_rmse ) && 
00892                       ( new_it_imap_rmse >= newp1tp_imap_rmse ) ) 
00893                     {
00894                       new_iteration_params = 
00895                         new_iteration_params_plus1tp;
00896                       new_it_dmap_error = getDirectMappingError( 
00897                         new_iteration_params_plus1tp );
00898                       new_it_imap_error = getInverseMappingError( 
00899                         new_iteration_params_plus1tp ); 
00900                       new_it_dmap_rmse = newp1tp_dmap_rmse;
00901                       new_it_imap_rmse = newp1tp_imap_rmse;
00902                         
00903                       exc_tp_list.erase( exc_tps_list_it );
00904                         
00905                       updateExcTPErrList( new_iteration_params, 
00906                         useTPWeights, exc_tp_list );   
00907                         
00908                       exc_tps_list_it = exc_tp_list.begin();
00909                       exc_tps_list_it_end = exc_tp_list.end();                    
00910                     }
00911                     else
00912                     {
00913                       ++exc_tps_list_it;
00914                     }
00915                   } 
00916                   else
00917                   {
00918                     ++exc_tps_list_it;
00919                   }                   
00920                 }
00921                 else
00922                 {  
00923                   ++exc_tps_list_it;
00924                 }
00925               }
00926             }
00927             
00928             /* Updating the best transformation parameters */
00929             
00930             best_params_dmap_error = new_it_dmap_error;
00931             best_params_imap_error = new_it_imap_error;
00932             best_params_dmap_rmse = new_it_dmap_rmse;
00933             best_params_imap_rmse = new_it_imap_rmse;
00934             best_params = new_iteration_params;
00935             
00936             /* Updating the next iteration parameters */
00937             
00938             iteration_params = new_iteration_params;
00939             
00940             transformation_not_updated = false;
00941             
00942             /* Putting the excluded tie-point into the 
00943                excluded tie-points map */
00944                
00945             dummy_exctpdata.tp_ = excluded_tp;
00946             if( useTPWeights )
00947             {
00948               dummy_exctpdata.tp_weight_ = excluded_tp_weight;
00949             }
00950             exc_tp_list.push_back( dummy_exctpdata );
00951             
00952             /* break the current tie-points loop */
00953             
00954             break;
00955           } //if( ( best_params_dmap_error > new_it_dmap_error ) && 
00956         } //if( computeParameters( new_iteration_params ) ) {    
00957       }
00958       
00959       if( transformation_not_updated ) {
00960         /* There is no way to improve the current transformation
00961            since all tie-points were tested */
00962         
00963         break; /* break the iterations loop */
00964       } else {
00965         if( ( max_dmap_error >= best_params_dmap_error ) && 
00966             ( max_imap_error >= best_params_imap_error ) &&
00967             ( max_dmap_rmse >= best_params_dmap_rmse ) && 
00968             ( max_imap_rmse >= best_params_imap_rmse ) ) {
00969             
00970           /* A valid transformation was found */
00971           break;
00972         }
00973       }
00974       
00975       --iterations_remainning;
00976     }//while( params.tiepoints_.size() > req_tie_pts_nmb ) {
00977     
00978     if( ( best_params.tiepoints_.size() >= req_tie_pts_nmb ) &&
00979         ( max_dmap_error >= best_params_dmap_error ) && 
00980         ( max_imap_error >= best_params_imap_error ) &&
00981         ( max_dmap_rmse >= best_params_dmap_rmse ) && 
00982         ( max_imap_rmse >= best_params_imap_rmse ) ) {
00983         
00984       external_params = best_params;
00985       
00986       return true;
00987     } else {
00988       return false;
00989     }    
00990   }
00991   
00992   return false;
00993 }

bool TeGeometricTransformation::normalizeTPWeights ( std::vector< double > &  tpWeights  )  const [private]

Normalize the tie-points weights in such a way that the sum of all of then is 1.

Parameters:
tpWeights The tie-points weights.
Returns:
true if OK, false on errors.

Definition at line 1809 of file TeGeometricTransformation.cpp.

Referenced by lWOutRemotion().

01811 {
01812   const unsigned int size = (unsigned int)tpWeights.size();
01813   
01814   if( size )
01815   {
01816     double wSum = 0;
01817     unsigned int idx = 0;
01818     
01819     for( ; idx < size ; ++idx )
01820     {
01821       if( tpWeights[ idx ] < 0.0 ) return false;
01822 
01823       wSum += tpWeights[ idx ];
01824     }
01825     
01826     if( wSum > 0.0 )
01827     {
01828       for( idx = 0 ; idx < size ; ++idx )
01829       {
01830         tpWeights[ idx ] /= wSum;
01831       }
01832     }
01833   }
01834 
01835   return true;
01836 }

const TeGeometricTransformation& TeGeometricTransformation::operator= ( const TeGeometricTransformation  )  [inline, private]

Operator= overload.

Parameters:
external External instance reference.
Returns:
The external instance reference.

Definition at line 436 of file TeGeometricTransformation.h.

00437                                            { return *this; };

bool TeGeometricTransformation::ransacRemotion ( const TeGTParams inputParams,
TeGTParams outputParams 
) const [private]

Random Sample Consensus based outliers remotion.

Parameters:
inputParams The current transformation parameters.
outputParams The output transformation parameters.
Returns:
TRUE if OK, false on errors.

Definition at line 1450 of file TeGeometricTransformation.cpp.

References ABS, computeParameters(), getDirectMappingError(), getInverseMappingError(), getMinRequiredTiePoints(), getPt1ConvexHullArea(), TeGTParams::max_dmap_error_, TeGTParams::max_dmap_rmse_, TeGTParams::max_imap_error_, TeGTParams::max_imap_rmse_, MIN, TeGTParams::out_rem_strat_, TeGTParams::RANSACRemotion, TEAGN_DEBUG_CONDITION, TEAGN_TRUE_OR_THROW, TeGTParams::tiepoints_, TeGTParams::tiePointsWeights_, and TeGTParams::transformation_name_.

Referenced by reset().

01452 {
01453   TEAGN_DEBUG_CONDITION( ( inputParams.out_rem_strat_ == 
01454     TeGTParams::RANSACRemotion ), 
01455     "Inconsistent outliers remotion strategy" )
01456   TEAGN_TRUE_OR_THROW( ( inputParams.max_dmap_error_ >= 0 ),
01457     "Invalid maximum allowed direct mapping error" );
01458   TEAGN_TRUE_OR_THROW( ( inputParams.max_imap_error_ >= 0 ),
01459     "Invalid maximum allowed inverse mapping error" );
01460   TEAGN_TRUE_OR_THROW( ( inputParams.max_dmap_rmse_ >= 0 ),
01461     "Invalid maximum allowed direct mapping RMSE" );
01462   TEAGN_TRUE_OR_THROW( ( inputParams.max_imap_rmse_ >= 0 ),
01463     "Invalid maximum allowed inverse mapping RMSE" );   
01464          
01465   TEAGN_TRUE_OR_THROW( ( inputParams.tiePointsWeights_.size() ?
01466     ( inputParams.tiePointsWeights_.size() ==
01467     inputParams.tiepoints_.size() ) : true ),
01468     "The tie-points vector size do not match the tie-points "
01469     "weights vector size" )
01470         
01471   // Checking the number of required tie-points
01472     
01473   const unsigned int reqTPsNmb = getMinRequiredTiePoints();
01474   const unsigned int inputTPNmb = (unsigned int)inputParams.tiepoints_.size();
01475   
01476   if( inputTPNmb < reqTPsNmb )
01477   {
01478     return false;  
01479   }
01480   else
01481   {
01482     // generating the tie-points accumulated probabilities map
01483           // with positive values up to RAND_MAX + 1
01484     std::map< double, TeCoordPair > tpsMap;
01485     {
01486       if( inputParams.tiePointsWeights_.size() > 0 )
01487       {
01488         // finding normalization factors
01489 
01490         double originalWSum = 0.0;
01491         unsigned int tpIdx = 0;
01492 
01493         for( tpIdx = 0 ; tpIdx < inputTPNmb ; ++tpIdx )
01494         {
01495           originalWSum += inputParams.tiePointsWeights_[ tpIdx ];
01496         }
01497 
01498         TEAGN_TRUE_OR_THROW( originalWSum > 0.0, 
01499           "Invalid tie-points weighs sum" );
01500 
01501         // map fill 
01502         
01503         double newWSum = 0.0;
01504         double newW = 0.0;
01505         
01506         for( tpIdx = 0 ; tpIdx < inputTPNmb ; ++tpIdx )
01507         {
01508           newW = inputParams.tiePointsWeights_[ tpIdx ];
01509           newW /= originalWSum;
01510           newW *= ((double)RAND_MAX) + 1.0;
01511 
01512           newWSum += newW;
01513 
01514           tpsMap[ newWSum ] = inputParams.tiepoints_[ tpIdx ];
01515         }
01516       }
01517       else
01518       {
01519         double wSum = 0;
01520         const double increment = ( ((double)RAND_MAX) + 1.0 ) / 
01521           ((double)inputParams.tiepoints_.size());
01522         
01523         for( unsigned int tpIdx = 0 ; tpIdx < inputTPNmb ; ++tpIdx )
01524         {
01525           wSum += increment;
01526           tpsMap[ wSum ] = inputParams.tiepoints_[ tpIdx ];
01527         }
01528       }
01529 
01530 /*
01531       std::map< double, TeCoordPair >::const_iterator mapIt =
01532         tpsMap.begin();
01533       while( mapIt != tpsMap.end() )
01534       {
01535         std::cout << " [" << mapIt->first 
01536           << "," << mapIt->second.pt1.x_
01537           << "," << mapIt->second.pt1.y_
01538           << "," << mapIt->second.pt2.x_
01539           << "," << mapIt->second.pt2.y_
01540           << "]";
01541         ++mapIt;
01542       }
01543 */
01544     }
01545     
01546     // The Maximum Number of iterations
01547     
01548     const RansacItCounterT maxIterations = std::numeric_limits< RansacItCounterT >::max();
01549       
01550     // Transformation maximum errors
01551     
01552     const double maxDMapErr = inputParams.max_dmap_error_;
01553     const double maxIMapErr = inputParams.max_imap_error_;
01554     const double maxDRMSE = inputParams.max_dmap_rmse_;
01555     const double maxIRMSE = inputParams.max_imap_rmse_;
01556       
01557     // This is the maximum number of allowed consecutive invalid
01558     // consensus sets (no transformation generated)
01559     const RansacItCounterT maxConsecutiveInvalidBaseSets = ( 
01560       ((RansacItCounterT)inputTPNmb) * 
01561       ((RansacItCounterT)reqTPsNmb) * ((RansacItCounterT)reqTPsNmb) * 
01562       ((RansacItCounterT)reqTPsNmb) );
01563       
01564     // This is the minimum number of consecutive valid
01565     // consensus sets (with the same number of tie-points)
01566     const RansacItCounterT minConsecutiveValidBaseSets = 
01567       ( ((RansacItCounterT)inputTPNmb) * ((RansacItCounterT)reqTPsNmb) );
01568       
01569     // If the difference between consecutive valid sets RMSE drops
01570     // below this value the process is stoped.
01571     const double consecValidBaseSetsDRMSEThr = MIN( maxDMapErr / 2.0,
01572       maxDRMSE );
01573     const double consecValidBaseSetsIRMSEThr = MIN( maxIMapErr / 2.0,
01574       maxIRMSE );
01575     
01576     TeGTParams bestParams;
01577     bestParams.transformation_name_ = inputParams.transformation_name_;
01578     
01579     double bestParamsMaxDMapErr = maxDMapErr;
01580     double bestParamsMaxIMapErr = maxIMapErr;
01581     double bestParamsDRMSE = maxDRMSE;
01582     double bestParamsIRMSE = maxIRMSE;
01583     double bestParamsConvexHullArea = -1.0;
01584 
01585     TeGTParams consensusSetParams;
01586     consensusSetParams.transformation_name_ = inputParams.transformation_name_;
01587     
01588     double consensusSetMaxDMapErr = 0;
01589     double consensusSetMaxIMapErr = 0;
01590     double consensusSetDRMSE = 0;
01591     double consensusSetIRMSE = 0;
01592     double consensusSetIRMSEDiff = 0; // diff against bestParamsIRMSE
01593     double consensusSetDRMSEDiff = 0; // diff against bestParamsDRMSE
01594     unsigned int consensusSetSize = 0;
01595     double consensusSetConvexHullArea = 0.0;
01596     std::vector< TeCoord2D > consensusSetPt1ConvexHullPoits;
01597     unsigned int consensusSetIdx = 0;
01598     
01599     double tiePointDMapErr = 0;
01600     double tiePointIMapErr = 0;    
01601     
01602     std::map< double, TeCoordPair >::const_iterator tpsMapIt;
01603     unsigned int inputTpIdx = 0;
01604       
01605     RansacItCounterT selectedTpsCounter = 0;
01606     std::vector< TeCoordPair* > selectedTpsPtrsVec;
01607     selectedTpsPtrsVec.resize( reqTPsNmb, 0 );
01608     unsigned int selectedTpsPtrsVecIdx = 0;
01609     bool selectedTpsNotSelectedBefore = false;
01610       
01611     // RANSAC main loop
01612     
01613     RansacItCounterT consecutiveInvalidBaseSetsLeft = 
01614       maxConsecutiveInvalidBaseSets;  
01615     RansacItCounterT iterationsLeft = maxIterations;       
01616     RansacItCounterT consecutiveValidBaseSets = 0;
01617       
01618     while( iterationsLeft )
01619     {
01620       // Trying to find a valid base consensus set
01621       // with the minimum number of required tie-points
01622       // Random selecting n distinc tpoints from the original set
01623 
01624       consensusSetParams.tiepoints_.clear();
01625       selectedTpsCounter = 0;
01626 
01627       while( selectedTpsCounter < reqTPsNmb )
01628       {
01629         tpsMapIt = tpsMap.upper_bound( (double)rand() );
01630         TEAGN_DEBUG_CONDITION( tpsMapIt != tpsMap.end(),
01631           "Tie-point random selection error" );
01632           
01633         // Checking if this TP was already selected before
01634         
01635         selectedTpsNotSelectedBefore = true;
01636         
01637         for( selectedTpsPtrsVecIdx = 0 ; selectedTpsPtrsVecIdx <
01638           selectedTpsCounter ; ++selectedTpsPtrsVecIdx )
01639         {
01640           if( selectedTpsPtrsVec[ selectedTpsPtrsVecIdx ] ==
01641             &(tpsMapIt->second) )
01642           {
01643             selectedTpsNotSelectedBefore = false;
01644             break;
01645           }
01646         }
01647         
01648         if( selectedTpsNotSelectedBefore )
01649         {
01650           consensusSetParams.tiepoints_.push_back( tpsMapIt->second );
01651         }
01652         
01653         ++selectedTpsCounter;
01654       }
01655 
01656       /* Trying to generate a valid base consensus transformation with the 
01657       selected points */      
01658       
01659       if( computeParameters( consensusSetParams ) ) 
01660       {
01661 //        consecutiveInvalidBaseSetsLeft = maxConsecutiveInvalidBaseSets;
01662         
01663         // finding those tie-points in agreement with the generated
01664         // consensus basic transformation
01665 
01666         consensusSetParams.tiepoints_.clear();
01667         consensusSetDRMSE = 0;
01668         consensusSetIRMSE = 0;
01669         consensusSetMaxDMapErr = 0;
01670         consensusSetMaxIMapErr = 0;
01671 
01672         for( inputTpIdx = 0 ; inputTpIdx < inputTPNmb ; ++inputTpIdx )
01673         {
01674           const TeCoordPair& curTP = inputParams.tiepoints_[ inputTpIdx ];
01675           
01676           tiePointDMapErr = getDirectMappingError( curTP, consensusSetParams );
01677           tiePointIMapErr = getInverseMappingError( curTP, consensusSetParams );
01678 
01679           if( ( tiePointDMapErr < maxDMapErr ) && 
01680             ( tiePointIMapErr < maxIMapErr ) )
01681           {
01682             consensusSetParams.tiepoints_.push_back( curTP );
01683             consensusSetDRMSE += ( tiePointDMapErr * tiePointDMapErr );
01684             consensusSetIRMSE += ( tiePointIMapErr * tiePointIMapErr );
01685             if( tiePointDMapErr > consensusSetMaxDMapErr )
01686               consensusSetMaxDMapErr = tiePointDMapErr;
01687             if( tiePointIMapErr > consensusSetMaxIMapErr )
01688               consensusSetMaxIMapErr = tiePointIMapErr;              
01689           }
01690         }
01691         
01692         consensusSetSize = (unsigned int)consensusSetParams.tiepoints_.size();
01693         
01694         consensusSetDRMSE = sqrt( consensusSetDRMSE );
01695         consensusSetIRMSE = sqrt( consensusSetIRMSE );
01696         
01697         consensusSetIRMSEDiff = ABS( bestParamsIRMSE - consensusSetIRMSE );
01698         consensusSetDRMSEDiff = ABS( bestParamsDRMSE - consensusSetDRMSE );
01699 
01700         /* Is this an acceptable consensus set ?? */      
01701         
01702         if( ( consensusSetDRMSE < maxDRMSE ) &&
01703             ( consensusSetIRMSE < maxIRMSE ) &&
01704             ( consensusSetMaxDMapErr < maxDMapErr ) &&
01705             ( consensusSetMaxIMapErr < maxIMapErr ) )
01706         {
01707           // Is this consensus set better than the current better one ??
01708           // (by using the number of tie-points as parameter
01709           // since we are interested in consensus sets with
01710           // the higher number of tie-points
01711         
01712           if( consensusSetSize > bestParams.tiepoints_.size() )
01713           {
01714             bestParams = consensusSetParams;
01715             bestParamsDRMSE = consensusSetDRMSE;
01716             bestParamsIRMSE = consensusSetIRMSE;
01717             bestParamsMaxDMapErr = consensusSetMaxDMapErr;
01718             bestParamsMaxIMapErr = consensusSetMaxIMapErr;
01719             bestParamsConvexHullArea = -1.0;
01720             
01721             consecutiveValidBaseSets = 0;
01722             
01723             consecutiveInvalidBaseSetsLeft = maxConsecutiveInvalidBaseSets;
01724           }
01725           else if( consensusSetSize == bestParams.tiepoints_.size() )
01726           {
01727             // Calculating the best consensus set convexhull area , if needed
01728             
01729             if( bestParamsConvexHullArea < 0.0 )
01730             {
01731               bestParamsConvexHullArea = getPt1ConvexHullArea( 
01732                 bestParams.tiepoints_ );
01733             }
01734             
01735             // Calculating the convexhull area covered by the tie-points (PT1 space)
01736             
01737             consensusSetConvexHullArea = getPt1ConvexHullArea( 
01738               consensusSetParams.tiepoints_ );
01739               
01740             if( consensusSetConvexHullArea > bestParamsConvexHullArea )
01741             {
01742               bestParams = consensusSetParams;
01743               bestParamsDRMSE = consensusSetDRMSE;
01744               bestParamsIRMSE = consensusSetIRMSE;
01745               bestParamsMaxDMapErr = consensusSetMaxDMapErr;
01746               bestParamsMaxIMapErr = consensusSetMaxIMapErr;
01747               bestParamsConvexHullArea = consensusSetConvexHullArea;
01748               
01749               ++consecutiveValidBaseSets;
01750             
01751               consecutiveInvalidBaseSetsLeft = maxConsecutiveInvalidBaseSets;            
01752             }
01753             else
01754             {
01755               // This consensus set isn't good enough
01756               
01757               --consecutiveInvalidBaseSetsLeft;
01758             }
01759           }
01760           else
01761           {
01762             // This consensus set isn't good enough
01763                         
01764             --consecutiveInvalidBaseSetsLeft;
01765           }
01766         }
01767         else
01768         {
01769           /* This isn't an acceptable consensus */           
01770 
01771           --consecutiveInvalidBaseSetsLeft;
01772         }
01773       } 
01774       else
01775       {
01776         // decrement the number of remaining consecutive
01777         // invalid base sets left
01778                     
01779         --consecutiveInvalidBaseSetsLeft;
01780 
01781       }
01782       
01783                         
01784       if( consecutiveInvalidBaseSetsLeft  == 0 ) break;
01785       
01786       if( ( consecutiveValidBaseSets > minConsecutiveValidBaseSets ) &&
01787         ( consensusSetDRMSEDiff < consecValidBaseSetsDRMSEThr ) &&
01788         ( consensusSetIRMSEDiff < consecValidBaseSetsIRMSEThr ) )
01789       {
01790         break;
01791       }
01792       
01793       --iterationsLeft;
01794     }
01795     
01796     if( bestParams.tiepoints_.size() >= reqTPsNmb )
01797     {
01798       outputParams = bestParams;
01799       
01800       return true;
01801     }
01802     else
01803     {
01804       return false;
01805     }
01806   }
01807 }

bool TeGeometricTransformation::recombineSeed ( std::vector< unsigned int > &  seed,
const unsigned int &  seedpos,
const unsigned int &  elements_nmb 
) [static, private]

Recombine a seed vector without repetition (the number of combined elements on each iteration will follow the vectors size.

Parameters:
seed Seed vector.
elements_nmb Number of elements to be permutated
seedpos Location inside the seed vector where to begin the permutation.
Returns:
TRUE if a permutation was made, FALSE if no more permutation are left to made.
Note:
All initial fields must be set to value 0 for the initial seed.

Definition at line 300 of file TeGeometricTransformation.cpp.

Referenced by eORThreadEntry().

00302 {
00303   unsigned int seed_size = seed.size();
00304   
00305   if( seedpos >= seed_size ) {
00306     return false;
00307   }
00308 
00309   if( seed[ seedpos ]  >= ( elements_nmb - seed_size + seedpos + 1 ) ) {
00310     if( seedpos == seed_size - 1 ) {
00311       return false;
00312     } else if( seedpos == 0 ) {
00313       return recombineSeed( seed, seedpos + 1, elements_nmb ) ;
00314     } else {
00315       return recombineSeed( seed, seedpos + 1, elements_nmb ) ;
00316     };
00317   } else if( seed[ seedpos ]  == 0 ) {
00318     if( seedpos == 0 ) {
00319       seed[ seedpos ] = 1 ;
00320       return recombineSeed( seed, seedpos + 1, elements_nmb );
00321     } else if( seedpos == seed_size - 1 ) {
00322       seed[ seedpos ] = seed[ seedpos - 1 ] + 1;
00323       return true;
00324     } else {
00325       seed[ seedpos ] = seed[ seedpos - 1 ] + 1;
00326       seed[ seedpos + 1 ] = 0;
00327       return recombineSeed( seed, seedpos + 1, elements_nmb );
00328     }
00329   } else {
00330     if( seedpos == seed_size - 1 ) {
00331       seed[ seedpos ] = seed[ seedpos ] + 1;
00332       return true;
00333     } else if( seedpos == 0 ) {
00334       if( recombineSeed( seed, seedpos + 1, elements_nmb ) ) {
00335         return true;
00336       } else {
00337         seed[ seedpos ] = seed[ seedpos ] + 1;
00338         seed[ seedpos + 1 ] = 0;
00339         return recombineSeed( seed, seedpos + 1, elements_nmb );
00340       }
00341     } else {
00342       if( recombineSeed( seed, seedpos + 1, elements_nmb ) ) {
00343         return true;
00344       } else {
00345         seed[ seedpos ] = seed[ seedpos ] + 1;
00346         seed[ seedpos + 1 ] = 0;
00347         return recombineSeed( seed, seedpos + 1, elements_nmb );
00348       }
00349     }
00350   }
00351 }

bool TeGeometricTransformation::reset ( const TeGTParams newparams  ) 

Reset the current transformation following the new supplied parameters.

Parameters:
newparams The new parameters.
Returns:
true if OK, false on errors.

Definition at line 68 of file TeGeometricTransformation.cpp.

References computeParameters(), TeGTParams::enable_multi_thread_, exaustiveOutRemotion(), TeGTParams::ExaustiveOutRemotion, getDirectMappingError(), getInverseMappingError(), getMinRequiredTiePoints(), internal_params_, isTransDefined(), lWOutRemotion(), TeGTParams::LWOutRemotion, TeGTParams::max_dmap_error_, TeGTParams::max_imap_error_, TeGTParams::NoOutRemotion, TeGTParams::out_rem_strat_, ransacRemotion(), TeGTParams::RANSACRemotion, TeGTParams::reset(), TEAGN_LOG_AND_THROW, TeGetPhysProcNumber(), and TeGTParams::tiepoints_.

00069 {
00070   /* If previous calculated parameters were supplied, no need to do calcules */
00071 
00072   if( isTransDefined( newparams ) ) 
00073   {
00074     internal_params_ = newparams;
00075     return true;
00076   } else {
00077     /* No previous parameters given - Need to calculate the new transformation
00078        parameters */
00079        
00080     const unsigned int req_tie_pts_nmb = getMinRequiredTiePoints();
00081 
00082     if( newparams.tiepoints_.size() < req_tie_pts_nmb ) 
00083     {
00084       return false;
00085     } 
00086     else if( newparams.tiepoints_.size() == req_tie_pts_nmb ) 
00087     {
00088       internal_params_ = newparams;
00089       return computeParameters( internal_params_ );
00090     }
00091     else 
00092     {
00093       internal_params_ = newparams;
00094       
00095       switch( newparams.out_rem_strat_ ) {
00096         case TeGTParams::NoOutRemotion :
00097         {
00098           if( computeParameters( internal_params_ ) ) {
00099             
00100             if( ( newparams.max_dmap_error_ >= 
00101               getDirectMappingError( internal_params_ ) ) &&
00102               ( newparams.max_imap_error_ >= 
00103               getInverseMappingError( internal_params_ ) ) ) {
00104               
00105               return true;
00106             }
00107           }   
00108         
00109           break;
00110         }
00111         case TeGTParams::ExaustiveOutRemotion :
00112         {
00113           if( internal_params_.enable_multi_thread_ ) {
00114             if( exaustiveOutRemotion( internal_params_,
00115               TeGetPhysProcNumber() - 1 ) ) {
00116               
00117               return true;
00118             }          
00119           } else {
00120             if( exaustiveOutRemotion( internal_params_, 0 ) ) {
00121               return true;
00122             }
00123           }
00124         
00125           break;
00126         }
00127         case TeGTParams::LWOutRemotion :
00128         {
00129           if( lWOutRemotion( internal_params_ ) ) {
00130             return true;
00131           }
00132                   
00133           break;
00134         }    
00135         case TeGTParams::RANSACRemotion :
00136         {
00137           if( ransacRemotion( newparams, internal_params_ ) ) {
00138             return true;
00139           }
00140                   
00141           break;
00142         }            
00143         default : 
00144         {
00145           TEAGN_LOG_AND_THROW( 
00146             "Invalid outliers remotion strategy" )
00147           break;
00148         }
00149       
00150       }
00151     }
00152   }
00153   
00154   internal_params_.reset();
00155   
00156   return false;
00157 }

void TeGeometricTransformation::updateExcTPErrList ( const TeGTParams params,
bool  useTPWeights,
std::list< ExcTPDataNode > &  exc_tp_list 
) const [private]

Update the excluded tie-points errors following the supplied transformation parameters.

Parameters:
params The current transformation parameters.
useTPWeights Use the tie-points error vector.
exc_tp_list The excluded tie-points list (the first element has the lower normalized error.

Definition at line 997 of file TeGeometricTransformation.cpp.

References TeGeometricTransformation::ExcTPDataNode::dmap_error_, getDirectMappingError(), getInverseMappingError(), TeGeometricTransformation::ExcTPDataNode::imap_error_, TEAGN_DEBUG_CONDITION, TeGTParams::tiepoints_, TeGTParams::tiePointsWeights_, and TeGeometricTransformation::ExcTPDataNode::tp_.

Referenced by lWOutRemotion().

01002 {
01003   if( exc_tp_list.size() > 0 )
01004   {
01005     TEAGN_DEBUG_CONDITION( ( useTPWeights ?
01006       ( params.tiePointsWeights_.size() == 
01007       params.tiepoints_.size() ) : true ),
01008       "The tie-points vector size do not match the tie-points "
01009       "weights vector size" )
01010       
01011     /* Updating the new direct and inverse mapping errors */
01012      
01013     std::list< ExcTPDataNode >::iterator tp_list_it = 
01014       exc_tp_list.begin();
01015     std::list< ExcTPDataNode >::iterator tp_list_it_end = 
01016       exc_tp_list.end();
01017       
01018     double dmap_err_min =  DBL_MAX;
01019     double dmap_err_max =  (-1.0) * DBL_MAX;
01020     double imap_err_min =  DBL_MAX;  
01021     double imap_err_max =  (-1.0) * DBL_MAX;
01022     
01023     while( tp_list_it != tp_list_it_end )
01024     {
01025       ExcTPDataNode& curr_node = *tp_list_it;
01026       
01027       const TeCoordPair& cur_ex_tp = curr_node.tp_;
01028       
01029       curr_node.dmap_error_ = getDirectMappingError( cur_ex_tp, 
01030         params );
01031       curr_node.imap_error_ = getInverseMappingError( cur_ex_tp, 
01032         params );        
01033         
01034       if( dmap_err_min > curr_node.dmap_error_ ) {
01035         dmap_err_min = curr_node.dmap_error_;
01036       }
01037       if( dmap_err_max < curr_node.dmap_error_ ) {
01038         dmap_err_max = curr_node.dmap_error_;
01039       }        
01040         
01041       if( imap_err_min > curr_node.imap_error_ ) {
01042         imap_err_min = curr_node.imap_error_;
01043       }
01044       if( imap_err_max < curr_node.imap_error_ ) {
01045         imap_err_max = curr_node.imap_error_;
01046       }            
01047       
01048       ++tp_list_it;
01049     }
01050     
01051     double dmap_err_range = dmap_err_max - dmap_err_min;
01052     double imap_err_range = imap_err_max - imap_err_min;
01053     
01054     /* Updating the normalized error */
01055     
01056     tp_list_it = exc_tp_list.begin();
01057     
01058     if( ( dmap_err_range == 0.0 ) &&
01059       ( imap_err_range == 0.0 ) )
01060     {
01061       while( tp_list_it != tp_list_it_end )
01062       {
01063         tp_list_it->tp_error_ = 0.0;
01064         
01065         ++tp_list_it;
01066       }
01067     }
01068     else if( dmap_err_range == 0.0 ) 
01069     {
01070       if( useTPWeights )
01071       {       
01072         while( tp_list_it != tp_list_it_end )
01073         {
01074           TEAGN_DEBUG_CONDITION( tp_list_it->tp_weight_ > 0.0,
01075             "Invalid tie-point weight" )
01076           TEAGN_DEBUG_CONDITION( tp_list_it->tp_weight_ <= 1.0,
01077             "Invalid tie-point weight" )            
01078                     
01079           tp_list_it->tp_error_ =
01080             ( 
01081               (  
01082                 tp_list_it->imap_error_ - imap_err_min              
01083               ) 
01084               / ( imap_err_range * tp_list_it->tp_weight_  )
01085             );
01086 
01087           ++tp_list_it;
01088         }
01089       }
01090       else
01091       {
01092         while( tp_list_it != tp_list_it_end )
01093         {
01094           tp_list_it->tp_error_ =
01095             ( 
01096               (  
01097                 tp_list_it->imap_error_ - imap_err_min              
01098               ) 
01099               / imap_err_range 
01100             );
01101           
01102           ++tp_list_it;
01103         }
01104       }
01105     }
01106     else if( imap_err_range == 0.0 ) 
01107     {
01108       if( useTPWeights )
01109       {     
01110         while( tp_list_it != tp_list_it_end )
01111         {
01112           TEAGN_DEBUG_CONDITION( tp_list_it->tp_weight_ > 0.0,
01113             "Invalid tie-point weight" )
01114           TEAGN_DEBUG_CONDITION( tp_list_it->tp_weight_ <= 1.0,
01115             "Invalid tie-point weight" )            
01116                     
01117           tp_list_it->tp_error_ =
01118             ( 
01119               ( 
01120                 tp_list_it->dmap_error_ - dmap_err_min
01121               ) 
01122               / ( dmap_err_range * tp_list_it->tp_weight_ )
01123             );
01124 
01125           ++tp_list_it;
01126         }
01127       }
01128       else
01129       {
01130         while( tp_list_it != tp_list_it_end )
01131         {
01132           tp_list_it->tp_error_ =
01133             ( 
01134               ( 
01135                 tp_list_it->dmap_error_ - dmap_err_min
01136               ) 
01137               / dmap_err_range 
01138             );
01139           
01140           ++tp_list_it;
01141         }
01142       }
01143     }
01144     else
01145     {
01146       if( useTPWeights )
01147       {    
01148         while( tp_list_it != tp_list_it_end )
01149         {
01150           TEAGN_DEBUG_CONDITION( tp_list_it->tp_weight_ > 0.0,
01151             "Invalid tie-point weight" )
01152           TEAGN_DEBUG_CONDITION( tp_list_it->tp_weight_ <= 1.0,
01153             "Invalid tie-point weight" )            
01154                     
01155           tp_list_it->tp_error_ =
01156             (
01157               ( 
01158                 ( 
01159                   tp_list_it->dmap_error_ - dmap_err_min
01160                 ) 
01161                 / dmap_err_range 
01162               ) 
01163               + 
01164               ( 
01165                 (  
01166                   tp_list_it->imap_error_ - imap_err_min              
01167                 ) 
01168                 / imap_err_range 
01169               ) 
01170             ) / ( 2.0 * tp_list_it->tp_weight_ );
01171 
01172           ++tp_list_it;
01173         }
01174       }
01175       else
01176       {
01177         while( tp_list_it != tp_list_it_end )
01178         {
01179           tp_list_it->tp_error_ =
01180             ( 
01181               ( 
01182                 ( 
01183                   tp_list_it->dmap_error_ - dmap_err_min
01184                 ) 
01185                 / dmap_err_range 
01186               ) 
01187               + 
01188               ( 
01189                 (  
01190                   tp_list_it->imap_error_ - imap_err_min              
01191                 ) 
01192                 / imap_err_range 
01193               ) 
01194             );
01195           
01196           ++tp_list_it;
01197         }
01198       }
01199     }
01200     
01201     /* Sorting list */
01202     
01203     exc_tp_list.sort();
01204     
01205     /* printing */
01206 /*  
01207     tp_list_it = exc_tp_list.begin();
01208     tp_list_it_end = exc_tp_list.end();
01209     std::cout << std::endl << "Excluded Tie points list" << std::endl;
01210     while( tp_list_it != tp_list_it_end )
01211     {
01212       const ExcTPDataNode& node = *tp_list_it;
01213       
01214       std::cout << node.norm_error_ << " " <<
01215        " [" + Te2String( node.tp_.pt1.x(),2 ) + "," +
01216        Te2String( node.tp_.pt1.y(),2 ) + "-" +
01217        Te2String( node.tp_.pt2.x(),2 ) + "," +
01218        Te2String( node.tp_.pt2.y(),2 ) + "]"
01219        << std::endl;      
01220       
01221       ++tp_list_it;
01222     }    
01223     std::cout << std::endl;
01224 */ 
01225   }
01226 }

void TeGeometricTransformation::updateTPErrVec ( const TeGTParams params,
bool  useTPWeights,
std::vector< TPDataNode > &  errvec 
) const [private]

Recalc the tie-points errors vector the supplied transformation parameters.

Parameters:
params The current transformation parameters.
useTPWeights Use the tie-points error vector.
errvec The tie-points vector (the first element has the lower normalized error).

Definition at line 1229 of file TeGeometricTransformation.cpp.

References TeGeometricTransformation::TPDataNode::dmap_error_, getDirectMappingError(), getInverseMappingError(), TeGeometricTransformation::TPDataNode::imap_error_, TEAGN_DEBUG_CONDITION, TeGTParams::tiepoints_, TeGTParams::tiePointsWeights_, TeGeometricTransformation::TPDataNode::tp_error_, and TeGeometricTransformation::TPDataNode::tpindex_.

Referenced by lWOutRemotion().

01232 {
01233   TEAGN_DEBUG_CONDITION( ( useTPWeights ?
01234     ( params.tiePointsWeights_.size() == 
01235     params.tiepoints_.size() ) : true ),
01236     "The tie-points vector size do not match the tie-points "
01237     "weights vector size" )
01238     
01239   /* Calculating the two mapping errors */
01240   
01241   const unsigned int iter_tps_nmb = (unsigned int)
01242     params.tiepoints_.size();  
01243     
01244   errvec.clear();
01245 
01246   double dmap_err_vec_min = DBL_MAX;
01247   double dmap_err_vec_max = ( -1.0 ) * dmap_err_vec_min;
01248   double imap_err_vec_min = DBL_MAX;
01249   double imap_err_vec_max = ( -1.0 ) * imap_err_vec_min;      
01250   const TPDataNode dummy_struct;
01251   
01252   for( unsigned int par_tps_vec_idx = 0 ; par_tps_vec_idx < iter_tps_nmb ; 
01253     ++par_tps_vec_idx ) 
01254   {
01255     const TeCoordPair& cur_tp = params.tiepoints_[ 
01256       par_tps_vec_idx ];
01257       
01258     errvec.push_back( dummy_struct );
01259     TPDataNode& newNode = errvec[ errvec.size() - 1 ];
01260       
01261     newNode.tpindex_ = par_tps_vec_idx;
01262     newNode.dmap_error_ = getDirectMappingError( cur_tp, 
01263       params );
01264     newNode.imap_error_ = getInverseMappingError( cur_tp, 
01265       params );
01266     
01267     if( dmap_err_vec_min > newNode.dmap_error_ ) {
01268       dmap_err_vec_min = newNode.dmap_error_;
01269     }
01270     if( dmap_err_vec_max < newNode.dmap_error_ ) {
01271       dmap_err_vec_max = newNode.dmap_error_;
01272     }        
01273     
01274     if( imap_err_vec_min > newNode.imap_error_ ) {
01275       imap_err_vec_min = newNode.imap_error_;
01276     }
01277     if( imap_err_vec_max < newNode.imap_error_ ) {
01278       imap_err_vec_max = newNode.imap_error_;
01279     }            
01280   }
01281   
01282   const double dmap_err_vec_range = 
01283     dmap_err_vec_max - dmap_err_vec_min;
01284   const double imap_err_vec_range = 
01285     imap_err_vec_max - imap_err_vec_min;
01286   TEAGN_DEBUG_CONDITION( dmap_err_vec_range >= 0, "Invalid range" )
01287   TEAGN_DEBUG_CONDITION( imap_err_vec_range >= 0, "Invalid range" )
01288 
01289   const std::vector< double >& tpwVec = params.tiePointsWeights_;
01290     
01291     /* Updating normalized mapping errors */
01292     
01293   if( ( dmap_err_vec_range == 0.0 ) && ( imap_err_vec_range == 0.0 ) )
01294   {
01295     for( unsigned int errvec_idx = 0 ; errvec_idx < iter_tps_nmb ; 
01296       ++errvec_idx ) 
01297     {
01298       errvec[ errvec_idx ].tp_error_ = 0;
01299     }
01300   }
01301   else if( dmap_err_vec_range == 0.0 )
01302   {
01303     for( unsigned int errvec_idx = 0 ; errvec_idx < iter_tps_nmb ; 
01304       ++errvec_idx ) 
01305     {
01306       TPDataNode& curr_elem = errvec[ errvec_idx ];
01307       
01308       if( useTPWeights )
01309       {
01310         TEAGN_DEBUG_CONDITION( tpwVec[ errvec_idx ] > 0.0,
01311           "Invalid tie-point weight" )
01312         TEAGN_DEBUG_CONDITION( tpwVec[ errvec_idx ] <= 1.0,
01313           "Invalid tie-point weight" )            
01314                 
01315         curr_elem.tp_error_ = 
01316           ( 
01317             (  
01318               curr_elem.imap_error_ - 
01319               imap_err_vec_min              
01320             ) 
01321             / ( imap_err_vec_range * tpwVec[ errvec_idx ] )
01322           );
01323       }
01324       else
01325       {
01326         curr_elem.tp_error_ = 
01327           ( 
01328             (  
01329               curr_elem.imap_error_ - 
01330               imap_err_vec_min              
01331             ) 
01332             / imap_err_vec_range 
01333           );
01334       }
01335     }
01336   }
01337   else if( imap_err_vec_range == 0.0 )
01338   {
01339     for( unsigned int errvec_idx = 0 ; errvec_idx < iter_tps_nmb ; 
01340       ++errvec_idx ) 
01341     {
01342       TPDataNode& curr_elem = errvec[ errvec_idx ];
01343       
01344       if( useTPWeights )
01345       {        
01346         TEAGN_DEBUG_CONDITION( tpwVec[ errvec_idx ] > 0.0,
01347           "Invalid tie-point weight" )
01348         TEAGN_DEBUG_CONDITION( tpwVec[ errvec_idx ] <= 1.0,
01349           "Invalid tie-point weight" )            
01350                   
01351         curr_elem.tp_error_ = 
01352           ( 
01353             ( 
01354               curr_elem.dmap_error_ - 
01355               dmap_err_vec_min
01356             ) 
01357             / ( dmap_err_vec_range * tpwVec[ errvec_idx ] )
01358           );
01359       }
01360       else
01361       {
01362         curr_elem.tp_error_ = 
01363           ( 
01364             ( 
01365               curr_elem.dmap_error_ - 
01366               dmap_err_vec_min
01367             ) 
01368             / dmap_err_vec_range 
01369           );
01370       }
01371     }
01372   }
01373   else
01374   {
01375     for( unsigned int errvec_idx = 0 ; errvec_idx < iter_tps_nmb ; 
01376       ++errvec_idx ) 
01377     {
01378       TPDataNode& curr_elem = errvec[ errvec_idx ];
01379       
01380       if( useTPWeights )
01381       { 
01382         TEAGN_DEBUG_CONDITION( tpwVec[ errvec_idx ] > 0.0,
01383           "Invalid tie-point weight" )
01384         TEAGN_DEBUG_CONDITION( tpwVec[ errvec_idx ] <= 1.0,
01385           "Invalid tie-point weight" )            
01386                   
01387         curr_elem.tp_error_ = 
01388           (
01389             ( 
01390               ( 
01391                 curr_elem.dmap_error_ - 
01392                 dmap_err_vec_min
01393               ) 
01394               / dmap_err_vec_range 
01395             ) 
01396             + 
01397             ( 
01398               (  
01399                 curr_elem.imap_error_ - 
01400                 imap_err_vec_min              
01401               ) 
01402               / imap_err_vec_range 
01403             )
01404           ) / ( 2.0 * tpwVec[ errvec_idx ] );
01405       }
01406       else
01407       {
01408         curr_elem.tp_error_ = 
01409           ( 
01410             ( 
01411               curr_elem.dmap_error_ - 
01412               dmap_err_vec_min
01413             ) 
01414             / dmap_err_vec_range 
01415           ) 
01416           + 
01417           ( 
01418             (  
01419               curr_elem.imap_error_ - 
01420               imap_err_vec_min              
01421             ) 
01422             / imap_err_vec_range 
01423           );
01424       }
01425     }
01426   }
01427 
01428   sort( errvec.begin(), errvec.end() );
01429 
01430     /* printing */
01431 /*
01432   std::cout << std::endl << "Tie points error vector" << std::endl;
01433   for( unsigned int errvec_idx = 0 ; errvec_idx < iter_tps_nmb ; 
01434     ++errvec_idx ) 
01435   {
01436     const unsigned int& tp_pars_vec_idx = errvec[ errvec_idx ].tpindex_;
01437     const TeCoordPair& currtp = params.tiepoints_[ 
01438     tp_pars_vec_idx ];
01439     
01440     std::cout << errvec[ errvec_idx ].norm_error_ << " " <<
01441       " [" + Te2String( currtp.pt1.x(),2 ) + "," +
01442       Te2String( currtp.pt1.y(),2 ) + "-" +
01443       Te2String( currtp.pt2.x(),2 ) + "," +
01444       Te2String( currtp.pt2.y(),2 ) + "]"
01445       << std::endl;
01446   }    
01447 */   
01448 }


Field Documentation

TeGTParams TeGeometricTransformation::internal_params_ [private]

The current internal parameters.

Definition at line 54 of file TeGeometricTransformation.h.

Referenced by getParameters(), and reset().


The documentation for this class was generated from the following files:
Generated on Sun Jul 29 04:06:21 2012 for TerraLib - Development Source by  doxygen 1.5.3