17#ifndef __registration_transform_reorient_h__
18#define __registration_transform_reorient_h__
28 namespace Registration
40 return delta_matrix.transpose();
47 if (mcsettings.size() != 0) {
48 for (
const auto & mc : mcsettings) {
49 if (mc.do_reorientation && mc.lmax > 0) {
50 start_nvols.emplace_back(std::initializer_list<ssize_t>{(ssize_t) mc.start, (ssize_t) mc.nvols});
51 max_n_SH = std::max (mc.nvols, max_n_SH);
55 assert (max_n_SH > 1);
56 assert (start_nvols.size());
60 template <
class FODImageType>
67 const Eigen::MatrixXd& directions,
73 Eigen::MatrixXd transformed_directions = linear_transform.linear().inverse() * directions;
76 Eigen::VectorXd modulation_factors = transformed_directions.colwise().norm() / linear_transform.linear().inverse().determinant();
77 transformed_directions.colwise().normalize();
81 transformed_directions.colwise().normalize();
87 void operator() (FODImageType& in, FODImageType& out) {
92 if (
fod[sn[0]] > 0.0) {
93 fod.segment(sn[0],sn[1]) =
transform.block(0,0,sn[1],sn[1]) *
fod.segment(sn[0],sn[1]);
104 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
transform;
109 template <
class FODImageType>
115 const Eigen::MatrixXd& directions,
116 const bool modulate) :
fod (n_SH)
118 Eigen::MatrixXd transformed_directions = linear_transform.linear().inverse() * directions;
121 Eigen::VectorXd modulation_factors = transformed_directions.colwise().norm() / linear_transform.linear().inverse().determinant();
122 transformed_directions.colwise().normalize();
126 transformed_directions.colwise().normalize();
132 void operator() (FODImageType& in, FODImageType& out)
135 if (in.value() > 0.0) {
144 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
transform;
152 template <
class FODImageType>
154 FODImageType& output_fod_image,
156 const Eigen::MatrixXd& directions,
157 bool modulate =
false,
160 assert (directions.cols() > directions.rows());
163 if (multi_contrast_settings.size())
166 if (start_nvols.size()) {
167 assert (max_n_SH > 1);
170 input_fod_image, output_fod_image);
174 input_fod_image, output_fod_image);
183 template <
class FODImageType>
185 FODImageType& input_fod_image,
186 FODImageType& output_fod_image,
188 const Eigen::MatrixXd& directions,
189 bool modulate =
false,
192 assert (directions.cols() > directions.rows());
195 if (multi_contrast_settings.size())
198 if (start_nvols.size()) {
199 assert (max_n_SH > 1);
202 input_fod_image, output_fod_image);
206 input_fod_image, output_fod_image);
210 template <
class FODImageType>
229 void operator() (FODImageType& image) {
233 image.index(3) = sn[0];
234 if (image.value() > 0.0) {
244 for (
size_t dim = 0; dim < 3; ++dim)
246 Eigen::MatrixXd jacobian =
jacobian_adapter.value().inverse().template cast<default_type>();
247 Eigen::MatrixXd transformed_directions = jacobian *
directions;
250 modulation_factors = transformed_directions.colwise().norm() / jacobian.determinant();
252 transformed_directions.colwise().normalize();
256 for (ssize_t i = 0; i <
n_dirs; ++i)
268 if (
fod[sn[0]] > 0.0)
269 fod.segment(sn[0],sn[1]) =
transform.block(0,0,sn[1],sn[1]) *
fod.segment(sn[0],sn[1]);
289 template <
class FODImageType>
302 void operator() (FODImageType& image) {
304 if (image.value() > 0) {
305 for (
size_t dim = 0; dim < 3; ++dim)
307 Eigen::MatrixXd jacobian =
jacobian_adapter.value().inverse().template cast<default_type>();
308 Eigen::MatrixXd transformed_directions = jacobian *
directions;
311 Eigen::MatrixXd modulation_factors = transformed_directions.colwise().norm() / jacobian.determinant();
312 transformed_directions.colwise().normalize();
315 for (ssize_t i = 0; i < temp.cols(); ++i)
316 temp.col(i) = temp.col(i) * modulation_factors(0,i);
320 transformed_directions.colwise().normalize();
339 template <
class FODImageType>
341 FODImageType& fod_image,
343 const Eigen::MatrixXd& directions,
344 const bool modulate =
false,
347 assert (directions.cols() > directions.rows());
348 check_dimensions (fod_image,
warp, 0, 3);
351 if (multi_contrast_settings.size())
353 if (start_nvols.size()) {
354 DEBUG (
"reorienting warp using MultiContrast NonLinearKernel");
358 DEBUG (
"reorienting warp using NonLinearKernel");
364 template <
class FODImageType>
367 const Eigen::MatrixXd& directions,
368 const bool modulate =
false,
371 assert (directions.cols() > directions.rows());
372 check_dimensions (fod_image,
warp, 0, 3);
375 if (multi_contrast_settings.size())
378 if (start_nvols.size()) {
379 DEBUG (
"reorienting warp using MultiContrast NonLinearKernel");
383 DEBUG (
"reorienting warp using NonLinearKernel");
a class to hold the coefficients for an apodised point-spread function.
Eigen::Matrix< typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic > pinv(const MatrixType &M)
return Moore-Penrose pseudo-inverse of M
size_t LforN(int N)
returns the largest lmax given N parameters
Eigen::Matrix< typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic > init_transform_cart(const MatrixType &dirs, const int lmax)
form the SH->amplitudes matrix
MatrixType1 & sconv_mat(MatrixType1 &sh, const VectorType2 &RH)
perform spherical convolution, in place
void warp(ImageTypeSource &source, ImageTypeDestination &destination, WarpType &warp, const typename ImageTypeDestination::value_type value_when_out_of_bounds=Interpolator< ImageTypeSource >::default_out_of_bounds_value(), const vector< uint32_t > oversample=Adapter::AutoOverSample, const bool jacobian_modulate=false)
convenience function to warp one image onto another
Eigen::Transform< default_type, 3, Eigen::AffineCompact > transform_type
the type for the affine transform of an image:
ThreadedLoopRunOuter< decltype(Loop(vector< size_t >()))> ThreadedLoop(const HeaderType &source, const vector< size_t > &outer_axes, const vector< size_t > &inner_axes)
Multi-threaded loop object.