00001 #include "rgrl_trans_similarity.h"
00002
00003
00004
00005
00006
00007 #include <vcl_cassert.h>
00008 #include <vnl/vnl_fastops.h>
00009 #include <vnl/algo/vnl_svd.h>
00010 #include <rgrl/rgrl_util.h>
00011
00012 rgrl_trans_similarity::
00013 rgrl_trans_similarity( unsigned int dimension )
00014 : A_( vnl_matrix<double>( dimension, dimension, vnl_matrix_identity ) ),
00015 trans_( vnl_vector<double>( dimension, 0.0 ) ),
00016 from_centre_( dimension, 0.0 )
00017 {
00018 }
00019
00020 rgrl_trans_similarity::
00021 rgrl_trans_similarity( vnl_matrix<double> const& rot_and_scale,
00022 vnl_vector<double> const& in_trans )
00023 : A_( rot_and_scale ),
00024 trans_( in_trans ),
00025 from_centre_( in_trans.size(), 0.0 )
00026 {
00027 assert ( A_.rows() == A_.cols() );
00028 assert ( A_.rows() == trans_.size() );
00029
00030
00031 }
00032
00033 rgrl_trans_similarity::
00034 rgrl_trans_similarity( vnl_matrix<double> const& rot_and_scale,
00035 vnl_vector<double> const& in_trans,
00036 vnl_matrix<double> const& in_covar )
00037 : rgrl_transformation( in_covar ),
00038 A_( rot_and_scale ),
00039 trans_( in_trans ),
00040 from_centre_( in_trans.size(), 0.0 )
00041 {
00042 assert ( A_.rows() == A_.cols() );
00043 assert ( A_.rows() == trans_.size() );
00044 if ( is_covar_set() ) {
00045 assert ( covar_.rows() == covar_.cols() );
00046 assert ( ( A_.rows() != 2 || covar_.rows() == 4 ) );
00047 assert ( ( A_.rows() != 3 || covar_.rows() == 7 ) );
00048 }
00049 }
00050
00051 rgrl_trans_similarity::
00052 rgrl_trans_similarity( vnl_matrix<double> const& in_A,
00053 vnl_vector<double> const& in_trans,
00054 vnl_matrix<double> const& in_covar,
00055 vnl_vector<double> const& in_from_centre,
00056 vnl_vector<double> const& in_to_centre )
00057 : rgrl_transformation( in_covar ),
00058 A_( in_A ),
00059 trans_( in_trans + in_to_centre ),
00060 from_centre_( in_from_centre )
00061 {
00062 assert ( A_.rows() == A_.cols() );
00063 assert ( A_.rows() == trans_.size() );
00064 assert ( from_centre_.size() == trans_.size() );
00065 if ( is_covar_set() ) {
00066 assert ( covar_.rows() == covar_.cols() );
00067 assert ( ( A_.rows() != 2 || covar_.rows() == 4 ) );
00068 assert ( ( A_.rows() != 3 || covar_.rows() == 7 ) );
00069 }
00070 }
00071
00072 void
00073 rgrl_trans_similarity::
00074 map_loc( vnl_vector<double> const& from,
00075 vnl_vector<double> & to ) const
00076 {
00077 assert ( from.size() == A_.rows() );
00078
00079
00080
00081 vnl_fastops::Ab( to, A_, from-from_centre_ );
00082 to += trans_;
00083 }
00084
00085 void
00086 rgrl_trans_similarity::
00087 map_dir( vnl_vector<double> const& from_loc,
00088 vnl_vector<double> const& from_dir,
00089 vnl_vector<double> & to_dir ) const
00090 {
00091 assert ( from_loc.size() == A_.cols() );
00092 assert ( from_dir.size() == A_.cols() );
00093 to_dir = A_ * from_dir;
00094 to_dir.normalize();
00095 }
00096
00097 vnl_matrix<double>
00098 rgrl_trans_similarity::
00099 transfer_error_covar( vnl_vector<double> const& p ) const
00100 {
00101 assert ( is_covar_set() );
00102 assert ( p.size() == 2);
00103 assert ( A_.rows() == 2);
00104
00105 vnl_matrix<double> temp( 2, 4, 0.0 );
00106 temp(0,0) = p[0]-from_centre_[0];
00107 temp(0,1) = from_centre_[1] - p[1];
00108 temp(0,2) = 1;
00109 temp(1,0) = p[1]-from_centre_[1];
00110 temp(1,1) = p[0] - from_centre_[0];
00111 temp(1,3) = 1;
00112
00113 return temp * covar_ * temp.transpose();
00114 }
00115
00116 vnl_matrix<double> const&
00117 rgrl_trans_similarity::
00118 A() const
00119 {
00120 return A_;
00121 }
00122
00123 double
00124 rgrl_trans_similarity::
00125 scaling() const
00126 {
00127 assert( A_.rows() && A_.cols() );
00128 vnl_vector<double> tmp = A_.get_column(0);
00129 return tmp.magnitude();
00130 }
00131
00132 vnl_vector<double>
00133 rgrl_trans_similarity::
00134 t() const
00135 {
00136 return trans_ - A_ * from_centre_;
00137 }
00138
00139 void
00140 rgrl_trans_similarity::
00141 inv_map( const vnl_vector<double>& to,
00142 bool initialize_next,
00143 const vnl_vector<double>& to_delta,
00144 vnl_vector<double>& from,
00145 vnl_vector<double>& from_next_est) const
00146 {
00147 const double epsilon = 0.01;
00148 vnl_vector<double> to_est = this->map_location(from);
00149
00150
00151 vnl_svd<double> svd( A_ );
00152 vnl_matrix<double> J_inv = svd.inverse();
00153
00154
00155 if (vnl_vector_ssd(to, to_est) > epsilon*epsilon) {
00156 from += J_inv * (to - to_est);
00157 }
00158 if ( initialize_next ) {
00159 from_next_est = from + (J_inv * to_delta);
00160 }
00161 }
00162
00163 void
00164 rgrl_trans_similarity::
00165 inv_map( const vnl_vector<double>& to,
00166 vnl_vector<double>& from ) const
00167 {
00168 vnl_svd<double> svd( A_ );
00169 from = svd.inverse()*to - svd.inverse()*trans_ + from_centre_;
00170 }
00171
00172 rgrl_transformation_sptr
00173 rgrl_trans_similarity::
00174 inverse_transform( ) const
00175 {
00176 vnl_svd<double> svd( A() );
00177 vnl_matrix<double> invA = svd.inverse();
00178 rgrl_transformation_sptr result = new rgrl_trans_similarity( invA, -invA * t() );
00179
00180 const unsigned m = scaling_factors_.size();
00181 if ( m > 0 ) {
00182 vnl_vector<double> scaling( m );
00183 for ( unsigned int i=0; i<m; ++i )
00184 scaling[i] = 1.0 / scaling_factors_[i];
00185 result->set_scaling_factors( scaling );
00186 }
00187
00188 return result;
00189 }
00190
00191
00192 void
00193 rgrl_trans_similarity::
00194 jacobian_wrt_loc( vnl_matrix<double>& jac, vnl_vector<double> const& ) const
00195 {
00196 jac = A_;
00197 }
00198
00199 rgrl_transformation_sptr
00200 rgrl_trans_similarity::
00201 scale_by( double scale ) const
00202 {
00203 rgrl_transformation_sptr xform
00204 = new rgrl_trans_similarity( A_, trans_ * scale,
00205 covar_, from_centre_ * scale,
00206 vnl_vector<double>(from_centre_.size(), 0.0) );
00207 xform->set_scaling_factors( this->scaling_factors() );
00208 return xform;
00209 }
00210
00211 void
00212 rgrl_trans_similarity::
00213 write( vcl_ostream& os ) const
00214 {
00215
00216 os << "SIMILARITY\n"
00217
00218 << t().size() << vcl_endl
00219 << A_ << trans_ << ' ' << from_centre_ << vcl_endl;
00220
00221
00222 rgrl_transformation::write( os );
00223 }
00224
00225 bool
00226 rgrl_trans_similarity::
00227 read( vcl_istream& is )
00228 {
00229 int dim;
00230
00231
00232 rgrl_util_skip_empty_lines( is );
00233
00234 vcl_string str;
00235 vcl_getline( is, str );
00236
00237
00238 if ( str.find( "SIMILARITY" ) != 0 ) {
00239 WarningMacro( "The tag is not SIMILARITY. reading is aborted.\n" );
00240 return false;
00241 }
00242
00243
00244 dim=-1;
00245 is >> dim;
00246 if ( dim > 0 ) {
00247 A_.set_size( dim, dim );
00248 trans_.set_size( dim );
00249 from_centre_.set_size( dim );
00250 is >> A_ >> trans_ >> from_centre_;
00251 }
00252
00253
00254 return is.good() && rgrl_transformation::read( is );
00255 }
00256
00257
00258 rgrl_transformation_sptr
00259 rgrl_trans_similarity::
00260 clone() const
00261 {
00262 return new rgrl_trans_similarity( *this );
00263 }