00001 /* 00002 Copyright (C) 2010 - 2014 Christoph Haenisch 00003 00004 Chair of Medical Engineering (mediTEC) 00005 RWTH Aachen University 00006 Pauwelsstr. 20 00007 52074 Aachen 00008 Germany 00009 00010 Version 0.1.1 (2011-08-05) 00011 */ 00012 00019 #ifndef ESTIMATE_TRANSFORMATION_2D_HPP_4376432766 00020 #define ESTIMATE_TRANSFORMATION_2D_HPP_4376432766 00021 00022 00023 #include <vector> 00024 00025 #include <Eigen/Core> 00026 #include <Eigen/StdVector> 00027 00028 #include "Coordinate.hpp" 00029 #include "ErrorObj.hpp" 00030 #include "EstimateTransformation.hpp" 00031 #include "Transform2D.hpp" 00032 00033 00034 namespace TRTK 00035 { 00036 00037 00052 template <class T> 00053 class EstimateTransformation2D : public EstimateTransformation<T> 00054 { 00055 private: 00056 00057 typedef EstimateTransformation<T> super; 00058 00059 public: 00060 00061 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00062 00063 typedef T value_type; 00064 00065 typedef typename super::ArrayXT ArrayXT; 00066 typedef typename super::MatrixXT MatrixXT; 00067 typedef typename super::VectorXT VectorXT; 00068 typedef typename super::Vector2T Vector2T; 00069 typedef typename super::Vector3T Vector3T; 00070 typedef typename super::Vector4T Vector4T; 00071 typedef typename super::RowVector2T RowVector2T; 00072 typedef typename super::RowVector3T RowVector3T; 00073 typedef typename super::Matrix2T Matrix2T; 00074 typedef typename super::Matrix3T Matrix3T; 00075 typedef typename super::Matrix4T Matrix4T; 00076 00077 using super::NOT_ENOUGH_POINTS; 00078 using super::UNEQUAL_NUMBER_OF_POINTS; 00079 using super::UNKNOWN_ERROR; 00080 using super::WRONG_POINT_SIZE; 00081 00082 EstimateTransformation2D(); 00083 virtual ~EstimateTransformation2D(); 00084 00085 virtual void compute() = 0; 00086 00087 virtual value_type getRMS() const; 00088 00089 virtual const Matrix3T & getTransformationMatrix() const; 00090 00091 void setSourcePoints(const std::vector<Coordinate<T> > &); 00092 void setSourcePoints(const std::vector<Vector2T, Eigen::aligned_allocator<Vector2T> > &); 00093 void setSourcePoints(const std::vector<Vector3T> &); 00094 00095 void setTargetPoints(const std::vector<Coordinate<T> > &); 00096 void setTargetPoints(const std::vector<Vector2T, Eigen::aligned_allocator<Vector2T> > &); 00097 void setTargetPoints(const std::vector<Vector3T> &); 00098 00099 protected: 00100 MatrixXT m_source_points; // each column contains a coordinate vector 00101 MatrixXT m_target_points; // each column contains a coordinate vector 00102 00103 Matrix3T m_transformation_matrix; 00104 }; 00105 00106 00112 template <class T> 00113 EstimateTransformation2D<T>::EstimateTransformation2D() 00114 { 00115 m_transformation_matrix.setIdentity(); 00116 } 00117 00118 00124 template <class T> 00125 EstimateTransformation2D<T>::~EstimateTransformation2D() 00126 { 00127 } 00128 00129 00147 template <class T> 00148 typename EstimateTransformation2D<T>::value_type EstimateTransformation2D<T>::getRMS() const 00149 { 00150 using std::sqrt; 00151 00152 if (m_source_points.size() != m_target_points.size()) 00153 { 00154 ErrorObj error; 00155 error.setClassName("EstimateTransformation2D<T>"); 00156 error.setFunctionName("getRMS"); 00157 error.setErrorMessage("Point sets must have the same cardinality."); 00158 error.setErrorCode(UNEQUAL_NUMBER_OF_POINTS); 00159 throw error; 00160 } 00161 00162 const int number_points = m_source_points.cols(); 00163 00164 if (number_points == 0) return 0; 00165 00166 Transform2D<T> transform = getTransformationMatrix(); 00167 00168 value_type RMS = 0; 00169 00170 for (int i = 0; i < number_points; ++i) 00171 { 00172 const Vector2T & source = m_source_points.block(0, i, 2, 1); 00173 const Vector2T & target = m_target_points.block(0, i, 2, 1); 00174 00175 RMS += (transform * source - target).squaredNorm(); 00176 } 00177 00178 RMS = sqrt(RMS / number_points); 00179 00180 return RMS; 00181 } 00182 00183 00193 template <class T> 00194 const typename EstimateTransformation2D<T>::Matrix3T & EstimateTransformation2D<T>::getTransformationMatrix() const 00195 { 00196 return m_transformation_matrix; 00197 } 00198 00199 00213 template <class T> 00214 void EstimateTransformation2D<T>::setSourcePoints(const std::vector<Coordinate<T> > & source_points) 00215 { 00216 const int m = 2; 00217 const int n = source_points.size(); 00218 00219 m_source_points.resize(m, n); 00220 00221 for (int i = 0; i < n; ++i) 00222 { 00223 if (!(source_points[i].size() == 2 || source_points[i].size() == 3)) 00224 { 00225 ErrorObj error; 00226 error.setClassName("EstimateTransformation2D<T>"); 00227 error.setFunctionName("setSourcePoints"); 00228 error.setErrorMessage("One or more source points are of wrong size."); 00229 error.setErrorCode(WRONG_POINT_SIZE); 00230 throw error; 00231 } 00232 00233 m_source_points.col(i) = source_points[i].toArray().head(2); 00234 } 00235 } 00236 00237 00245 template <class T> 00246 void EstimateTransformation2D<T>::setSourcePoints(const std::vector<Vector2T, Eigen::aligned_allocator<Vector2T> > & source_points) 00247 { 00248 const int m = 2; 00249 const int n = source_points.size(); 00250 // we use the fact that std::vector is contiguous; use a C cast instead of an 00251 // C++ cast (reinterpret_cast + const_cast) to make the line easier to read 00252 m_source_points = Eigen::Map<MatrixXT>((T *)(&source_points[0]), m, n); 00253 } 00254 00255 00263 template <class T> 00264 void EstimateTransformation2D<T>::setSourcePoints(const std::vector<Vector3T> & source_points) 00265 { 00266 const int m = 2; 00267 const int n = source_points.size(); 00268 00269 m_source_points.resize(m, n); 00270 00271 for (int i = 0; i < n; ++i) 00272 { 00273 m_source_points.col(i) = source_points[i].head(2); 00274 } 00275 } 00276 00277 00291 template <class T> 00292 void EstimateTransformation2D<T>::setTargetPoints(const std::vector<Coordinate<T> > & target_points) 00293 { 00294 const int m = 2; 00295 const int n = target_points.size(); 00296 00297 m_target_points.resize(m, n); 00298 00299 for (int i = 0; i < n; ++i) 00300 { 00301 if (!(target_points[i].size() == 2 || target_points[i].size() == 3)) 00302 { 00303 ErrorObj error; 00304 error.setClassName("EstimateTransformation2D<T>"); 00305 error.setFunctionName("setTargetPoints"); 00306 error.setErrorMessage("One or more source points are of wrong size."); 00307 error.setErrorCode(WRONG_POINT_SIZE); 00308 throw error; 00309 } 00310 00311 m_target_points.col(i) = target_points[i].toArray().head(2); 00312 } 00313 } 00314 00315 00323 template <class T> 00324 void EstimateTransformation2D<T>::setTargetPoints(const std::vector<Vector2T, Eigen::aligned_allocator<Vector2T> > & target_points) 00325 { 00326 const int m = 2; 00327 const int n = target_points.size(); 00328 // we use the fact that std::vector is contiguous; use a C cast instead of an 00329 // C++ cast (reinterpret_cast + const_cast) to make the line easier to read 00330 m_target_points = Eigen::Map<MatrixXT>((T *)(&target_points[0]), m, n); 00331 } 00332 00333 00341 template <class T> 00342 void EstimateTransformation2D<T>::setTargetPoints(const std::vector<Vector3T> & target_points) 00343 { 00344 const int m = 2; 00345 const int n = target_points.size(); 00346 00347 m_target_points.resize(m, n); 00348 00349 for (int i = 0; i < n; ++i) 00350 { 00351 m_target_points.col(i) = target_points[i].head(2); 00352 } 00353 } 00354 00355 00356 } // namespace TRTK 00357 00358 00359 #endif // ESTIMATE_TRANSFORMATION_2D_HPP_4376432766
Documentation generated by Doxygen