1 #include "rgrl_convergence_tester.h"
2 #include <rgrl/rgrl_view.h>
3 #include <rgrl/rgrl_converge_status.h>
4
5 rgrl_convergence_tester::
6 ~rgrl_convergence_tester() = default;
7
8 rgrl_converge_status_sptr
9 rgrl_convergence_tester::
compute_status(const rgrl_converge_status_sptr & prev_status,rgrl_view const & prev_view,rgrl_view const & current_view,const rgrl_match_set_sptr & current_match_set,const rgrl_scale_sptr & current_scale,bool penalize_scaling) const10 compute_status( const rgrl_converge_status_sptr& prev_status,
11 rgrl_view const& prev_view,
12 rgrl_view const& current_view,
13 const rgrl_match_set_sptr& current_match_set,
14 const rgrl_scale_sptr& current_scale,
15 bool penalize_scaling )const
16 {
17 rgrl_set_of<rgrl_match_set_sptr> match_sets;
18 match_sets.push_back( current_match_set );
19 rgrl_set_of<rgrl_scale_sptr> scales;
20 scales.push_back( current_scale );
21 return compute_status( prev_status, prev_view, current_view,
22 match_sets, scales, penalize_scaling );
23 }
24
25 rgrl_converge_status_sptr
26 rgrl_convergence_tester::
compute_status(const rgrl_converge_status_sptr & prev_status,const rgrl_transformation_sptr & xform_estimate,const rgrl_estimator_sptr & xform_estimator,rgrl_set_of<rgrl_match_set_sptr> const & current_match_sets,rgrl_set_of<rgrl_scale_sptr> const & current_scales,bool penalize_scaling) const27 compute_status( const rgrl_converge_status_sptr& prev_status,
28 const rgrl_transformation_sptr& xform_estimate,
29 const rgrl_estimator_sptr& xform_estimator,
30 rgrl_set_of<rgrl_match_set_sptr> const& current_match_sets,
31 rgrl_set_of<rgrl_scale_sptr> const& current_scales,
32 bool penalize_scaling )const
33 {
34 rgrl_mask_box dummy_image_region(0);
35 rgrl_mask_sptr dummy_roi = new rgrl_mask_box( 0 );
36 rgrl_view view( dummy_roi, dummy_roi,
37 dummy_image_region, dummy_image_region,
38 xform_estimator, xform_estimate, 0);
39 return compute_status( prev_status, view, view,
40 current_match_sets, current_scales, penalize_scaling );
41 }
42
43 rgrl_converge_status_sptr
44 rgrl_convergence_tester::
compute_status(const rgrl_converge_status_sptr & prev_status,const rgrl_transformation_sptr & xform_estimate,const rgrl_estimator_sptr & xform_estimator,const rgrl_match_set_sptr & current_match_set,const rgrl_scale_sptr & current_scale,bool penalize_scaling) const45 compute_status( const rgrl_converge_status_sptr& prev_status,
46 const rgrl_transformation_sptr& xform_estimate,
47 const rgrl_estimator_sptr& xform_estimator,
48 const rgrl_match_set_sptr& current_match_set,
49 const rgrl_scale_sptr& current_scale,
50 bool penalize_scaling )const
51 {
52 rgrl_set_of<rgrl_match_set_sptr> match_sets;
53 match_sets.push_back( current_match_set );
54 rgrl_set_of<rgrl_scale_sptr> scales;
55 scales.push_back( current_scale );
56 return compute_status( prev_status, xform_estimate, xform_estimator,
57 match_sets, scales, penalize_scaling );
58 }
59
60
61 rgrl_converge_status_sptr
62 rgrl_convergence_tester::
verify(rgrl_view const & view,rgrl_match_set_sptr const & current_match_set,rgrl_scale_sptr const & current_scale) const63 verify( rgrl_view const& view,
64 rgrl_match_set_sptr const& current_match_set,
65 rgrl_scale_sptr const& current_scale )const
66 {
67 rgrl_set_of<rgrl_match_set_sptr> match_sets;
68 match_sets.push_back( current_match_set );
69 rgrl_set_of<rgrl_scale_sptr> scales;
70 scales.push_back( current_scale );
71 return this->verify( view, match_sets, scales );
72 }
73
74 rgrl_converge_status_sptr
75 rgrl_convergence_tester::
verify(rgrl_view const &,rgrl_set_of<rgrl_match_set_sptr> const &,rgrl_set_of<rgrl_scale_sptr> const &) const76 verify( rgrl_view const& /*view*/,
77 rgrl_set_of<rgrl_match_set_sptr> const& /*current_match_sets*/,
78 rgrl_set_of<rgrl_scale_sptr> const& /*current_scales*/ )const
79 {
80 std::cerr << "WARNING: should never call rgrl_convergence_tester::verify()\n";
81 return new rgrl_converge_status( rgrl_converge_status::converged, rgrl_converge_status::good_and_terminate,
82 -1.0, 0, -1.0 );
83 }
84
85 rgrl_converge_status_sptr
86 rgrl_convergence_tester::
initialize_status(const rgrl_transformation_sptr & xform_estimate,const rgrl_estimator_sptr & xform_estimator,rgrl_scale_sptr const & prior_scale,bool penalize_scaling) const87 initialize_status( const rgrl_transformation_sptr& xform_estimate,
88 const rgrl_estimator_sptr& xform_estimator,
89 rgrl_scale_sptr const& prior_scale,
90 bool penalize_scaling )const
91 {
92 rgrl_mask_box dummy_image_region(0);
93 rgrl_mask_sptr dummy_roi = new rgrl_mask_box( 0 );
94 rgrl_view view( dummy_roi, dummy_roi,
95 dummy_image_region, dummy_image_region,
96 xform_estimator, xform_estimate, 0);
97 return this->init_status( view, prior_scale, penalize_scaling );
98 }
99
100 rgrl_converge_status_sptr
101 rgrl_convergence_tester::
initialize_status(rgrl_view const & init_view,rgrl_scale_sptr const & prior_scale,bool penalize_scaling) const102 initialize_status( rgrl_view const& init_view,
103 rgrl_scale_sptr const& prior_scale,
104 bool penalize_scaling ) const
105 {
106 // call the real virtual function
107 return this->init_status( init_view, prior_scale, penalize_scaling );
108 }
109
110 rgrl_converge_status_sptr
111 rgrl_convergence_tester::
init_status(rgrl_view const &,rgrl_scale_sptr const &,bool) const112 init_status( rgrl_view const& /*init_view*/,
113 rgrl_scale_sptr const& /*prior_scale*/,
114 bool /*penalize_scaling*/ ) const
115 {
116 // nothing to initialize
117 return nullptr;
118 }
119
120 rgrl_converge_status_sptr
121 rgrl_convergence_tester::
compute_status_helper(double new_error,bool good_enough,rgrl_converge_status_sptr prev_status,rgrl_view const & prev_view,rgrl_view const & current_view) const122 compute_status_helper( double new_error,
123 bool good_enough,
124 rgrl_converge_status_sptr prev_status,
125 rgrl_view const& prev_view,
126 rgrl_view const& current_view ) const
127 {
128 // Step3: First check if the regions in the view have converged. If yes,
129 // check the convergence of the transform estimate by comparing to
130 // the previous status. The oscillation count is incremented if the
131 // error_diff changes the sign.
132 //
133 bool converged;
134 bool stagnated = false;
135 unsigned int oscillation_count = 0;
136 double error_diff = 0.0;
137 if (new_error == 0.0 )
138 converged = true;
139 else if ( prev_status && current_view.regions_converged_to(prev_view) ) {
140 double old_error = prev_status->error();
141 error_diff = new_error-old_error;
142 double diff = (new_error-old_error) / new_error ;
143 converged = std::abs( diff ) < rel_tol_thres_;
144
145 if ( !converged ) {
146 // look for oscillation
147 // There are two kinds of oscillation:
148 // 1. the error increases and decreases in turn
149 // 2. Once it is good enough, the error increases slightly
150 //
151
152 // first situation
153 if ( !good_enough ) {
154 if ( error_diff * prev_status->error_diff() < 0.0 ) {
155 oscillation_count = prev_status->oscillation_count() + 1;
156 DebugMacro_abv(1, "Oscillation. Count="<<oscillation_count<<'\n' );
157
158 } else {
159 if ( prev_status->oscillation_count() > 0 )
160 oscillation_count = prev_status->oscillation_count() - 1;
161 }
162 if ( oscillation_count > 10 ) {
163 stagnated = true;
164 }
165 } else {
166
167 // second situation
168 if ( error_diff > 0 ) { // error increases again
169 oscillation_count = prev_status->oscillation_count() + 1;
170 DebugMacro_abv(1, "Good Oscillation. Count="<<oscillation_count<<'\n' );
171 }
172
173 // check for oscillation, call convergence
174 if ( oscillation_count > 3 )
175 converged = true;
176 }
177 }
178
179 } else {
180 converged = false;
181 }
182
183 return new rgrl_converge_status( converged, stagnated, good_enough, false, new_error, oscillation_count, error_diff );
184 }
185