17#ifndef __registration_transform_base_h__
18#define __registration_transform_base_h__
21#include <unsupported/Eigen/MatrixFunctions>
23#include <Eigen/Geometry>
30 namespace Registration
34 template <
class ValueType>
35 inline void param_mat2vec (
const Eigen::Matrix<ValueType, 3, 4, Eigen::RowMajor>& transformation_matrix,
36 Eigen::Matrix<ValueType, Eigen::Dynamic, 1>& param_vector) {
37 assert(param_vector.size() == 12);
38 param_vector = Eigen::Map<Eigen::MatrixXd> (transformation_matrix.data(), 12, 1);
40 template <
class ValueType>
41 inline void param_mat2vec (
const Eigen::Matrix<ValueType, 4, 4, Eigen::RowMajor>& transformation_matrix,
42 Eigen::Matrix<ValueType, Eigen::Dynamic, 1>& param_vector) {
43 assert(param_vector.size() == 12);
44 param_vector = Eigen::Map<Eigen::MatrixXd> ((transformation_matrix.template block<3,4>(0,0)).data(), 12, 1);
46 template <
class ValueType>
47 inline void param_mat2vec (
const Eigen::Matrix<ValueType, 3, 4, Eigen::ColMajor>& transformation_matrix,
48 Eigen::Matrix<ValueType, Eigen::Dynamic, 1>& param_vector) {
49 assert(param_vector.size() == 12);
51 param_vector = Eigen::Map<Eigen::Matrix<ValueType, 12, 1>> (
52 (Eigen::Matrix<default_type, 3, 4, Eigen::RowMajor>(transformation_matrix)).data() );
54 template <
class ValueType>
55 inline void param_mat2vec (
const Eigen::Matrix<ValueType, 4, 4, Eigen::ColMajor>& transformation_matrix,
56 Eigen::Matrix<ValueType, Eigen::Dynamic, 1>& param_vector) {
57 assert(param_vector.size() == 12);
59 param_vector = Eigen::Map<Eigen::Matrix<ValueType, 12, 1>> (
60 (Eigen::Matrix<default_type, 3, 4, Eigen::RowMajor>((transformation_matrix.template block<3,4>(0,0)))).data() );
62 template <
class Derived,
class ValueType>
63 inline void param_vec2mat (
const Eigen::MatrixBase<Derived>& param_vector,
64 Eigen::Matrix<ValueType, 3, 4>& transformation_matrix) {
65 assert(param_vector.size() == 12);
66 transformation_matrix = Eigen::Map<const Eigen::Matrix<ValueType, 3, 4, Eigen::RowMajor> >(¶m_vector(0));
68 template <
class Derived,
class ValueType>
69 inline void param_vec2mat (
const Eigen::MatrixBase<Derived>& param_vector,
70 Eigen::Matrix<ValueType, 4, 4>& transformation_matrix) {
71 assert(param_vector.size() == 12);
72 transformation_matrix.template block<3,4>(0,0) = Eigen::Map<const Eigen::Matrix<ValueType, 3, 4, Eigen::RowMajor> >(¶m_vector(0));
73 transformation_matrix.row(3) << 0.0, 0.0, 0.0, 1.0;
95 trafo.matrix().setIdentity();
102 template <
class OutPo
intType,
class InPo
intType>
103 inline void transform (OutPointType& out,
const InPointType& in)
const {
104 out.noalias() =
trafo * in;
107 template <
class OutPo
intType,
class InPo
intType>
108 inline void transform_half (OutPointType& out,
const InPointType& in)
const {
112 template <
class OutPo
intType,
class InPo
intType>
113 inline void transform_half_inverse (OutPointType& out,
const InPointType& in)
const {
117 size_t size()
const {
121 Eigen::Matrix<default_type, 4, 1> get_jacobian_vector_wrt_params (
const Eigen::Vector3d& p)
const {
122 throw Exception (
"FIXME: get_jacobian_vector_wrt_params not implemented for this metric");
123 Eigen::Matrix<default_type, 4, 1> jac;
127 Eigen::Transform<ParameterType, 3, Eigen::AffineCompact> get_transform ()
const {
128 Eigen::Transform<ParameterType, 3, Eigen::AffineCompact> transform;
129 transform.matrix() =
trafo.matrix();
133 Eigen::Transform<ParameterType, 3, Eigen::AffineCompact> get_transform_half ()
const {
137 Eigen::Transform<ParameterType, 3, Eigen::AffineCompact> get_transform_half_inverse ()
const {
141 template <
class TrafoType>
142 void set_transform (
const TrafoType& transform) {
143 trafo.matrix().template block<3,4>(0,0) = transform.matrix().template block<3,4>(0,0);
148 void set_matrix_const_translation (
const Eigen::Matrix<ParameterType, 3, 3>& mat) {
149 trafo.linear() = mat;
166 const Eigen::Matrix<ParameterType, 3, 3> get_matrix ()
const {
167 return trafo.linear();
170 void set_translation (
const Eigen::Matrix<ParameterType, 1, 3>& trans) {
171 trafo.translation() = trans;
176 const Eigen::Vector3d get_translation()
const {
177 return trafo.translation();
180 void set_centre_without_transform_update (
const Eigen::Vector3d& centre_in) {
185 void set_centre (
const Eigen::Vector3d& centre_in) {
192 const Eigen::Vector3d get_centre()
const {
197 void set_optimiser_weights (Eigen::VectorXd& weights) {
202 Eigen::VectorXd get_optimiser_weights ()
const {
207 bool is_symmetric ()
const {
211 void use_nonsymmetric (
const bool asym) {
215 void set_offset (
const Eigen::Vector3d& offset_in) {
216 trafo.translation() = offset_in;
220 std::string info () {
221 Eigen::IOFormat fmt(Eigen::FullPrecision, 0,
", ",
"\n",
"",
"",
"",
"");
222 INFO (
"transformation:\n"+
str(
trafo.matrix().format(fmt)));
225 return "centre: "+
str(
centre.transpose(),12);
228 std::string debug () {
229 Eigen::IOFormat fmt(Eigen::FullPrecision, 0,
", ",
"\n",
"",
"",
"",
"");
231 CONSOLE (
"trafo_inverse:\n"+
str(
trafo.inverse().matrix().format(fmt)));
238 template <
class ParamType,
class VectorType>
239 bool robust_estimate (VectorType& gradient,
241 const ParamType& params,
242 const VectorType& parameter_vector,
244 const size_t& weiszfeld_iterations,
246 DEBUG (
"robust estimator is not implemented for this metric");
247 for (
auto& grad_estimate : grad_estimates) {
248 gradient += grad_estimate;
260 Eigen::Matrix<ParameterType, 4, 4> tmp;
262 tmp.template block<3,4>(0,0) =
trafo.matrix();
263 assert ((tmp.template block<3,3>(0,0).isApprox (
trafo.linear())));
264 assert (tmp.determinant() > 0);
266 trafo_half.matrix() = tmp.template block<3,4>(0,0);
268 assert (
trafo.matrix().isApprox (
trafo.matrix()));
270 tmp = tmp.sqrt().eval();
271 trafo_half.matrix() = tmp.template block<3,4>(0,0);
280 Eigen::Transform<ParameterType, 3, Eigen::AffineCompact>
trafo;
281 Eigen::Transform<ParameterType, 3, Eigen::AffineCompact>
trafo_half;
T eval(const double *coef, const int order, const T lower, const T upper, const T x)
double default_type
the default type used throughout MRtrix
std::string str(const T &value, int precision=0)