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