00001 #include "msm_shape_instance.h"
00002
00003
00004
00005
00006
00007 #include <msm/msm_shape_model.h>
00008 #include <vcl_iostream.h>
00009 #include <vsl/vsl_indent.h>
00010 #include <vsl/vsl_binary_io.h>
00011 #include <vnl/io/vnl_io_vector.h>
00012 #include <vnl/algo/vnl_cholesky.h>
00013 #include <vnl/algo/vnl_svd.h>
00014
00015 #include <vcl_cstdlib.h>
00016 #include <vcl_cassert.h>
00017
00018
00019
00020
00021
00022 msm_shape_instance::msm_shape_instance()
00023 : model_(0)
00024 {
00025 }
00026
00027
00028 msm_shape_instance::msm_shape_instance(const msm_shape_model& model)
00029 {
00030 set_shape_model(model);
00031 }
00032
00033
00034
00035
00036
00037 msm_shape_instance::~msm_shape_instance()
00038 {
00039 }
00040
00041
00042 void msm_shape_instance::set_shape_model(const msm_shape_model& model)
00043 {
00044 model_=&model;
00045 ref_shape_.set_shape_model(model);
00046 pose_ = model.default_pose();
00047
00048 points_valid_=false;
00049 }
00050
00051
00052 void msm_shape_instance::set_pose(const vnl_vector<double>& pose)
00053 {
00054 assert(pose.size()==pose_.size());
00055 pose_=pose;
00056 points_valid_=false;
00057 }
00058
00059
00060 void msm_shape_instance::set_params(const vnl_vector<double>& b)
00061 {
00062 assert(b.size()<=model().n_modes());
00063 ref_shape_.set_params(b);
00064 points_valid_=false;
00065 }
00066
00067
00068 void msm_shape_instance::set_to_mean()
00069 {
00070 ref_shape_.set_to_mean();
00071 points_valid_=false;
00072 }
00073
00074
00075
00076 const msm_points& msm_shape_instance::points()
00077 {
00078 if (points_valid_) return points_;
00079
00080
00081 model().aligner().apply_transform(model_points(),pose_,points_);
00082
00083 points_valid_=true;
00084 return points_;
00085 }
00086
00087
00088
00089 double msm_shape_instance::approx_points_scale() const
00090 {
00091 double s = model().aligner().scale(pose_);
00092 return model().ref_mean_points_scale() * s;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102 void msm_shape_instance::fit_to_points(const msm_points& pts,
00103 double res_var)
00104 {
00105
00106 if (&pts == &points_) return;
00107
00108 #if 0 // commented out
00109
00110
00111
00112
00113 model().aligner().calc_transform_from_ref(
00114 ref_shape_.model().mean_points(),pts,pose_);
00115
00116 vnl_vector<double> pose_inv = model().aligner().inverse(pose_);
00117 model().aligner().apply_transform(pts,pose_inv,tmp_points_);
00118
00119 double s = model().aligner().scale(pose_);
00120 double rv=res_var/(s*s);
00121
00122 ref_shape_.fit_to_points(tmp_points_,rv);
00123 points_valid_=false;
00124 #endif // 0
00125 vnl_vector<double> pose0 = pose_;
00126
00127
00128 model().aligner().calc_transform(model_points(),pts,pose_);
00129
00130 double dp=1.0;
00131 int n_its=0;
00132 while (dp>1e-6 && n_its<10)
00133 {
00134
00135 vnl_vector<double> pose_inv = model().aligner().inverse(pose_);
00136 model().aligner().apply_transform(pts,pose_inv,tmp_points_);
00137
00138 double s = model().aligner().scale(pose_);
00139 double rv=res_var/(s*s);
00140
00141 ref_shape_.fit_to_points(tmp_points_,rv);
00142 points_valid_=false;
00143
00144
00145 pose0 = pose_;
00146 model().aligner().calc_transform(model_points(),pts,pose_);
00147 dp = (pose_-pose0).magnitude();
00148
00149 n_its++;
00150 }
00151 }
00152
00153
00154
00155 void msm_shape_instance::fit_to_points_wt(const msm_points& pts,
00156 const vnl_vector<double>& wts)
00157 {
00158
00159 if (&pts == &points_) return;
00160
00161 vnl_vector<double> pose0 = pose_;
00162 vnl_vector<double> ref_wts;
00163
00164
00165 model().aligner().calc_transform_wt(model_points(),pts,wts,pose_);
00166
00167 double dp=1.0;
00168 int n_its=0;
00169 while (dp>1e-6 && n_its<10)
00170 {
00171
00172 vnl_vector<double> pose_inv = model().aligner().inverse(pose_);
00173 model().aligner().apply_transform(pts,pose_inv,tmp_points_);
00174
00175 if (ref_shape_.use_prior())
00176 {
00177
00178 double s = model().aligner().scale(pose_);
00179 ref_wts=wts/(s*s);
00180 ref_shape_.fit_to_points_wt(tmp_points_,ref_wts);
00181 }
00182 else
00183 {
00184
00185
00186 ref_shape_.fit_to_points_wt(tmp_points_,wts);
00187 }
00188
00189 points_valid_=false;
00190
00191
00192 pose0 = pose_;
00193 model().aligner().calc_transform_wt(model_points(),pts,wts,pose_);
00194 dp = (pose_-pose0).magnitude();
00195
00196 n_its++;
00197 }
00198 }
00199
00200
00201
00202 void msm_shape_instance::fit_to_points_wt_mat(const msm_points& pts,
00203 const vcl_vector<msm_wt_mat_2d>& wt_mat)
00204 {
00205
00206 if (&pts == &points_) return;
00207
00208 unsigned n=model().size();
00209 assert(wt_mat.size()==n);
00210
00211 vnl_vector<double> pose0 = pose_;
00212
00213
00214 model().aligner().calc_transform_wt_mat(model_points(),pts,
00215 wt_mat,pose_);
00216
00217 double dp=1.0;
00218 int n_its=0;
00219 while (dp>1e-6 && n_its<10)
00220 {
00221
00222 vnl_vector<double> pose_inv = model().aligner().inverse(pose_);
00223 model().aligner().apply_transform(pts,pose_inv,tmp_points_);
00224
00225
00226
00227
00228
00229 vcl_vector<msm_wt_mat_2d> wt_mat2(n);
00230 model().aligner().transform_wt_mat(wt_mat,pose_inv,wt_mat2);
00231
00232 ref_shape_.fit_to_points_wt_mat(tmp_points_,wt_mat2);
00233 points_valid_=false;
00234
00235
00236 pose0 = pose_;
00237 model().aligner().calc_transform_wt_mat(model_points(),pts,
00238 wt_mat,pose_);
00239 dp = (pose_-pose0).magnitude();
00240 n_its++;
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249 short msm_shape_instance::version_no() const
00250 {
00251 return 1;
00252 }
00253
00254
00255
00256
00257
00258 vcl_string msm_shape_instance::is_a() const
00259 {
00260 return vcl_string("msm_shape_instance");
00261 }
00262
00263
00264
00265
00266
00267
00268 void msm_shape_instance::print_summary(vcl_ostream& ) const
00269 {
00270 }
00271
00272
00273
00274
00275
00276
00277 void msm_shape_instance::b_write(vsl_b_ostream& bfs) const
00278 {
00279 vsl_b_write(bfs,version_no());
00280 vsl_b_write(bfs,ref_shape_);
00281 vsl_b_write(bfs,pose_);
00282 }
00283
00284
00285
00286
00287
00288
00289 void msm_shape_instance::b_read(vsl_b_istream& bfs)
00290 {
00291 short version;
00292 vsl_b_read(bfs,version);
00293 switch (version)
00294 {
00295 case (1):
00296 vsl_b_read(bfs,ref_shape_);
00297 vsl_b_read(bfs,pose_);
00298 break;
00299 default:
00300 vcl_cerr << "msm_shape_instance::b_read() :\n"
00301 << "Unexpected version number " << version << vcl_endl;
00302 bfs.is().clear(vcl_ios::badbit);
00303 return;
00304 }
00305
00306 points_valid_=false;
00307 }
00308
00309
00310
00311
00312
00313
00314 void vsl_b_write(vsl_b_ostream& bfs, const msm_shape_instance& b)
00315 {
00316 b.b_write(bfs);
00317 }
00318
00319
00320
00321
00322
00323 void vsl_b_read(vsl_b_istream& bfs, msm_shape_instance& b)
00324 {
00325 b.b_read(bfs);
00326 }
00327
00328
00329
00330
00331
00332 vcl_ostream& operator<<(vcl_ostream& os,const msm_shape_instance& b)
00333 {
00334 os << b.is_a() << ": ";
00335 vsl_indent_inc(os);
00336 b.print_summary(os);
00337 vsl_indent_dec(os);
00338 return os;
00339 }
00340
00341
00342 void vsl_print_summary(vcl_ostream& os,const msm_shape_instance& b)
00343 {
00344 os << b;
00345 }