00001 #ifndef msm_aligner_h_ 00002 #define msm_aligner_h_ 00003 00004 //: 00005 // \file 00006 // \author Tim Cootes 00007 // \brief Base for functions which calculate and apply 2D transformations 00008 00009 #include <vcl_string.h> 00010 #include <vcl_memory.h> 00011 #include <vcl_iosfwd.h> 00012 #include <vsl/vsl_fwd.h> 00013 #include <vnl/vnl_fwd.h> 00014 #include <msm/msm_points.h> 00015 #include <msm/msm_wt_mat_2d.h> 00016 class mbl_read_props_type; 00017 00018 //: Base for functions which calculate and apply 2D transformations. 00019 // Derived classes represent transformations, eg translation, similarity, affine. 00020 // The parameters of the transformation are stored in a vector, arranged so 00021 // that the zero vector corresponds to the identity transformation. 00022 // Each class contains functions to apply the transformation, invert it 00023 // and to estimate the best transform parameters to map one set of points to 00024 // another. 00025 class msm_aligner 00026 { 00027 public: 00028 00029 virtual ~msm_aligner() {} 00030 00031 //: Return number of parameters defining the transformation 00032 virtual unsigned size() const=0; 00033 00034 //: Compute parameters for inverse transformation 00035 virtual vnl_vector<double> inverse(const vnl_vector<double>&) const = 0; 00036 00037 //: Apply the transformation to the given points 00038 virtual void apply_transform(const msm_points& points, 00039 const vnl_vector<double>& trans, 00040 msm_points& new_points) const = 0; 00041 00042 //: Return scaling applied by the transform with given parameters. 00043 virtual double scale(const vnl_vector<double>& trans) const = 0; 00044 00045 //: Estimate parameter which best map ref_points to points2 00046 // Minimises ||points2-T(ref_points)||^2. 00047 // Takes advantage of assumed properties of ref_points (eg CoG=origin, 00048 // unit size etc) to perform efficiently. 00049 // 00050 // When used with a shape model of form ref_points+Pb, where the modes P 00051 // have certain orthogonality properties with respect to the ref shape, 00052 // this can give the optimal transformation into a tangent plane, independent 00053 // of the current parameters. In this case a one-shot method can be used 00054 // to compute the optimal shape and pose parameters, rather than an iterative 00055 // method which is required where the orthogonality properties do not hold, 00056 // or where weights are considered. 00057 virtual void calc_transform_from_ref(const msm_points& ref_points, 00058 const msm_points& points2, 00059 vnl_vector<double>& trans) const =0; 00060 00061 //: Estimate parameter which best map points1 to points2 00062 // Minimises ||points2-T(points1)||^2 00063 virtual void calc_transform(const msm_points& points1, 00064 const msm_points& points2, 00065 vnl_vector<double>& trans) const =0; 00066 00067 //: Estimate parameters which map points1 to points2 allowing for weights 00068 // Minimises sum of weighted squares error in frame of pts2, 00069 // ie sum w_i * ||p2_i - T(p1_i)|| 00070 virtual void calc_transform_wt(const msm_points& points1, 00071 const msm_points& points2, 00072 const vnl_vector<double>& wts, 00073 vnl_vector<double>& trans) const =0; 00074 00075 //: Estimate parameters which map points allowing for anisotropic wts 00076 // Errors on point i are weighted by wt_mat[i] in pts2 frame. 00077 // ie error is sum (p2_i-T(p1_i)'*wt_mat[i]*(p2_i-T(p1_i) 00078 virtual void calc_transform_wt_mat(const msm_points& points1, 00079 const msm_points& points2, 00080 const vcl_vector<msm_wt_mat_2d>& wt_mat, 00081 vnl_vector<double>& trans) const =0; 00082 00083 //: Apply transform to weight matrices (ie ignore translation component) 00084 virtual void transform_wt_mat(const vcl_vector<msm_wt_mat_2d>& wt_mat, 00085 const vnl_vector<double>& trans, 00086 vcl_vector<msm_wt_mat_2d>& new_wt_mat) const = 0; 00087 00088 //: Returns params of pose such that pose(x) = pose1(pose2(x)) 00089 virtual vnl_vector<double> compose(const vnl_vector<double>& pose1, 00090 const vnl_vector<double>& pose2) const = 0; 00091 00092 //: Apply transform to generate points in some reference frame 00093 // For instance, depending on transform, may translate so the 00094 // centre of gravity is at the origin and scale to a unit size. 00095 virtual void normalise_shape(msm_points& points) const = 0; 00096 00097 //: Find poses which align a set of points 00098 // On exit ref_mean_shape is the mean shape in the reference 00099 // frame, pose_to_ref[i] maps points[i] into the reference 00100 // frame (ie pose is the mapping from the reference frame to 00101 // the target frames). 00102 // \param average_pose Some estimate of the average mapping 00103 virtual void align_set(const vcl_vector<msm_points>& points, 00104 msm_points& ref_mean_shape, 00105 vcl_vector<vnl_vector<double> >& pose_to_ref, 00106 vnl_vector<double>& average_pose) const =0; 00107 00108 //: Compute mean of points[i] after transforming with pose[i] 00109 void mean_of_transformed(const vcl_vector<msm_points>& points, 00110 const vcl_vector<vnl_vector<double> >& pose, 00111 msm_points& mean) const; 00112 00113 //: Name of the class 00114 virtual vcl_string is_a() const = 0; 00115 00116 //: Create a copy on the heap and return base class pointer 00117 virtual msm_aligner* clone() const = 0; 00118 00119 //: Print class to os 00120 virtual void print_summary(vcl_ostream& os) const; 00121 00122 //: Save class to binary file stream 00123 virtual void b_write(vsl_b_ostream& bfs) const; 00124 00125 //: Load class from binary file stream 00126 virtual void b_read(vsl_b_istream& bfs); 00127 00128 //: Create a concrete msm_aligner-derived object, from a text specification. 00129 static vcl_auto_ptr<msm_aligner> create_from_stream(vcl_istream &is); 00130 00131 //: Initialise from a text stream. 00132 // The default implementation is for attribute-less normalisers, 00133 // and throws if it finds any data in the stream. 00134 virtual void config_from_stream(vcl_istream &is); 00135 }; 00136 00137 //: Allows derived class to be loaded by base-class pointer 00138 // A loader object exists which is invoked by calls 00139 // of the form "vsl_b_read(bfs,base_ptr);". This loads derived class 00140 // objects from the disk, places them on the heap and 00141 // returns a base class pointer. 00142 // In order to work the loader object requires 00143 // an instance of each derived class that might be 00144 // found. This function gives the model class to 00145 // the appropriate loader. 00146 void vsl_add_to_binary_loader(const msm_aligner& b); 00147 00148 //: Binary file stream output operator for class reference 00149 void vsl_b_write(vsl_b_ostream& bfs, const msm_aligner& b); 00150 00151 //: Binary file stream input operator for class reference 00152 void vsl_b_read(vsl_b_istream& bfs, msm_aligner& b); 00153 00154 //: Stream output operator for class reference 00155 vcl_ostream& operator<<(vcl_ostream& os,const msm_aligner& b); 00156 00157 //: Stream output operator for class pointer 00158 vcl_ostream& operator<<(vcl_ostream& os,const msm_aligner* b); 00159 00160 //: Stream output operator for class reference 00161 void vsl_print_summary(vcl_ostream& os,const msm_aligner& b); 00162 00163 //: Stream output operator for class reference 00164 void vsl_print_summary(vcl_ostream& os,const msm_aligner* b); 00165 00166 #endif // msm_aligner_h_ 00167 00168