contrib/rpl/rgrl/rgrl_convergence_tester.cxx
Go to the documentation of this file.
00001 #include "rgrl_convergence_tester.h"
00002 #include <rgrl/rgrl_view.h>
00003 #include <rgrl/rgrl_converge_status.h>
00004 
00005 rgrl_convergence_tester::
00006 ~rgrl_convergence_tester()
00007 {
00008 }
00009 
00010 rgrl_converge_status_sptr
00011 rgrl_convergence_tester::
00012 compute_status( rgrl_converge_status_sptr               prev_status,
00013                 rgrl_view                        const& prev_view,
00014                 rgrl_view                        const& current_view,
00015                 rgrl_match_set_sptr                     current_match_set,
00016                 rgrl_scale_sptr                         current_scale,
00017                 bool                                    penalize_scaling )const
00018 {
00019   rgrl_set_of<rgrl_match_set_sptr> match_sets;
00020   match_sets.push_back( current_match_set );
00021   rgrl_set_of<rgrl_scale_sptr> scales;
00022   scales.push_back( current_scale );
00023   return compute_status( prev_status, prev_view, current_view,
00024                          match_sets, scales, penalize_scaling );
00025 }
00026 
00027 rgrl_converge_status_sptr
00028 rgrl_convergence_tester::
00029 compute_status( rgrl_converge_status_sptr               prev_status,
00030                 rgrl_transformation_sptr                xform_estimate,
00031                 rgrl_estimator_sptr                     xform_estimator,
00032                 rgrl_set_of<rgrl_match_set_sptr> const& current_match_sets,
00033                 rgrl_set_of<rgrl_scale_sptr>     const& current_scales,
00034                 bool                                    penalize_scaling )const
00035 {
00036   rgrl_mask_box   dummy_image_region(0);
00037   rgrl_mask_sptr  dummy_roi = new rgrl_mask_box( 0 );
00038   rgrl_view view( dummy_roi, dummy_roi,
00039                   dummy_image_region, dummy_image_region,
00040                   xform_estimator, xform_estimate, 0);
00041   return compute_status( prev_status, view, view,
00042                          current_match_sets, current_scales, penalize_scaling );
00043 }
00044 
00045 rgrl_converge_status_sptr
00046 rgrl_convergence_tester::
00047 compute_status( rgrl_converge_status_sptr               prev_status,
00048                 rgrl_transformation_sptr                xform_estimate,
00049                 rgrl_estimator_sptr                     xform_estimator,
00050                 rgrl_match_set_sptr                     current_match_set,
00051                 rgrl_scale_sptr                         current_scale,
00052                 bool                                    penalize_scaling )const
00053 {
00054   rgrl_set_of<rgrl_match_set_sptr> match_sets;
00055   match_sets.push_back( current_match_set );
00056   rgrl_set_of<rgrl_scale_sptr> scales;
00057   scales.push_back( current_scale );
00058   return compute_status( prev_status, xform_estimate, xform_estimator,
00059                          match_sets, scales, penalize_scaling );
00060 }
00061 
00062 
00063 rgrl_converge_status_sptr
00064 rgrl_convergence_tester::
00065 verify( rgrl_view                   const& view,
00066         rgrl_match_set_sptr         const& current_match_set,
00067         rgrl_scale_sptr             const& current_scale )const
00068 {
00069   rgrl_set_of<rgrl_match_set_sptr> match_sets;
00070   match_sets.push_back( current_match_set );
00071   rgrl_set_of<rgrl_scale_sptr> scales;
00072   scales.push_back( current_scale );
00073   return this->verify( view, match_sets, scales );
00074 }
00075 
00076 rgrl_converge_status_sptr
00077 rgrl_convergence_tester::
00078 verify( rgrl_view                        const& /*view*/,
00079         rgrl_set_of<rgrl_match_set_sptr> const& /*current_match_sets*/,
00080         rgrl_set_of<rgrl_scale_sptr>     const& /*current_scales*/ )const
00081 {
00082   vcl_cerr << "WARNING: should never call rgrl_convergence_tester::verify()\n";
00083   return new rgrl_converge_status( rgrl_converge_status::converged, rgrl_converge_status::good_and_terminate,
00084                                    -1.0, 0, -1.0 );
00085 }
00086 
00087 rgrl_converge_status_sptr
00088 rgrl_convergence_tester::
00089 initialize_status( rgrl_transformation_sptr                xform_estimate,
00090                    rgrl_estimator_sptr                     xform_estimator,
00091                    rgrl_scale_sptr                  const& prior_scale,
00092                    bool                                    penalize_scaling )const
00093 {
00094   rgrl_mask_box   dummy_image_region(0);
00095   rgrl_mask_sptr  dummy_roi = new rgrl_mask_box( 0 );
00096   rgrl_view view( dummy_roi, dummy_roi,
00097                   dummy_image_region, dummy_image_region,
00098                   xform_estimator, xform_estimate, 0);
00099   return this->init_status( view, prior_scale, penalize_scaling );
00100 }
00101 
00102 rgrl_converge_status_sptr
00103 rgrl_convergence_tester::
00104 initialize_status( rgrl_view       const& init_view,
00105                    rgrl_scale_sptr const& prior_scale,
00106                    bool                   penalize_scaling ) const
00107 {
00108   // call the real virtual function
00109   return this->init_status( init_view, prior_scale, penalize_scaling );
00110 }
00111 
00112 rgrl_converge_status_sptr
00113 rgrl_convergence_tester::
00114 init_status( rgrl_view       const& /*init_view*/,
00115              rgrl_scale_sptr const& /*prior_scale*/,
00116              bool                   /*penalize_scaling*/ ) const
00117 {
00118   // nothing to initialize
00119   return 0;
00120 }
00121 
00122 rgrl_converge_status_sptr
00123 rgrl_convergence_tester::
00124 compute_status_helper( double new_error,
00125                        bool good_enough,
00126                 rgrl_converge_status_sptr               prev_status,
00127                 rgrl_view                        const& prev_view,
00128                 rgrl_view                        const& current_view ) const
00129 {
00130   // Step3: First check if the regions in the view have converged. If yes,
00131   //        check the convergence of the transform estimate by comparing to
00132   //        the previous status. The oscillation count is incremented if the
00133   //        error_diff changes the sign.
00134   //
00135   bool converged;
00136   bool stagnated = false;
00137   unsigned int oscillation_count = 0;
00138   double error_diff = 0.0;
00139   if (new_error == 0.0 )
00140     converged = true;
00141   else if ( prev_status &&  current_view.regions_converged_to(prev_view) ) {
00142     double old_error = prev_status->error();
00143     error_diff = new_error-old_error;
00144     double diff = (new_error-old_error) / new_error ;
00145     converged = vcl_abs( diff ) < rel_tol_thres_;
00146 
00147     if ( !converged ) {
00148       // look for oscillation
00149       // There are two kinds of oscillation:
00150       // 1. the error increases and decreases in turn
00151       // 2. Once it is good enough, the error increases slightly
00152       //
00153 
00154       // first situation
00155       if ( !good_enough ) {
00156         if ( error_diff * prev_status->error_diff() < 0.0 ) {
00157           oscillation_count = prev_status->oscillation_count() + 1;
00158           DebugMacro_abv(1, "Oscillation. Count="<<oscillation_count<<'\n' );
00159 
00160         } else {
00161           if ( prev_status->oscillation_count() > 0 )
00162             oscillation_count = prev_status->oscillation_count() - 1;
00163         }
00164         if ( oscillation_count > 10 ) {
00165           stagnated = true;
00166         }
00167       } else {
00168 
00169         // second situation
00170         if ( error_diff > 0 )  { // error increases again
00171           oscillation_count = prev_status->oscillation_count() + 1;
00172           DebugMacro_abv(1, "Good Oscillation. Count="<<oscillation_count<<'\n' );
00173         }
00174 
00175         // check for oscillation, call convergence
00176         if ( oscillation_count > 3 )
00177           converged = true;
00178       }
00179     }
00180 
00181   } else {
00182     converged = false;
00183   }
00184 
00185   return new rgrl_converge_status( converged, stagnated, good_enough, false, new_error, oscillation_count, error_diff );
00186 }