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