17#ifndef __adapter_reslice_h__
18#define __adapter_reslice_h__
39 template <
typename value_type>
43 return ((sum*norm) >= 0.5) ? true :
false;
47 template <
typename value_type>
54 template <
typename value_type>
109 template <
template <
class ImageType>
class Interpolator,
class ImageType>
111 public ImageBase<Reslice<Interpolator,ImageType>,typename ImageType::value_type>
118 template <
class HeaderType>
119 Reslice (
const ImageType& original,
120 const HeaderType& reference,
124 interp (original, value_when_out_of_bounds),
126 dim { reference.size(0), reference.size(1), reference.size(2) },
127 vox { reference.spacing(0), reference.spacing(1), reference.spacing(2) },
128 transform_ (reference.transform()),
129 direct_transform (
Transform(original).scanner2voxel * transform *
Transform(reference).voxel2scanner) {
130 using namespace Eigen;
131 assert (ndim() >= 3);
133 const bool is_nearest = std::is_same<typename Interp::Nearest<ImageType>,
decltype(interp)>::value;
135 if (oversample.size()) {
136 assert (oversample.size() == 3);
137 if (oversample[0] < 1 || oversample[1] < 1 || oversample[2] < 1)
138 throw Exception (
"oversample factors must be greater than zero");
139 if (is_nearest && (oversample[0] != 1 || oversample[1] != 1 || oversample[2] != 1)) {
140 WARN(
"oversampling factors ignored for nearest neighbour interpolation");
141 OS[0] = OS[1] = OS[2] = 1;
144 OS[0] = oversample[0]; OS[1] = oversample[1]; OS[2] = oversample[2];
149 OS[0] = OS[1] = OS[2] = 1;
152 Vector3d y = direct_transform * Vector3d (0.0, 0.0, 0.0);
153 Vector3d x0 = direct_transform * Vector3d (1.0, 0.0, 0.0);
154 OS[0] =
std::ceil ((1.0-std::numeric_limits<default_type>::epsilon()) * (y-x0).norm());
155 x0 = direct_transform * Vector3d (0.0, 1.0, 0.0);
156 OS[1] =
std::ceil ((1.0-std::numeric_limits<default_type>::epsilon()) * (y-x0).norm());
157 x0 = direct_transform * Vector3d (0.0, 0.0, 1.0);
158 OS[2] =
std::ceil ((1.0-std::numeric_limits<default_type>::epsilon()) * (y-x0).norm());
162 if (OS[0] * OS[1] * OS[2] > 1) {
163 INFO (
"using oversampling factors [ " +
str (OS[0]) +
" " +
str (OS[1]) +
" " +
str (OS[2]) +
" ]");
166 for (
size_t i = 0; i < 3; ++i) {
168 from[i] = 0.5* (inc[i]-1.0);
173 else oversampling =
false;
177 size_t ndim ()
const {
return interp.ndim(); }
178 bool valid ()
const {
return interp.valid(); }
179 int size (
size_t axis)
const {
return axis < 3 ? dim[
axis]: interp.size (
axis); }
182 const std::string& name ()
const {
return interp.name(); }
184 ssize_t stride (
size_t axis)
const {
185 return interp.stride (
axis);
189 x[0] = x[1] = x[2] = 0;
190 for (
size_t n = 3; n < interp.ndim(); ++n)
195 using namespace Eigen;
197 Vector3d d (x[0]+from[0], x[1]+from[1], x[2]+from[2]);
200 for (uint32_t z = 0; z < OS[2]; ++z) {
201 s[2] = d[2] + z*inc[2];
202 for (uint32_t y = 0; y < OS[1]; ++y) {
203 s[1] = d[1] + y*inc[1];
204 for (uint32_t x = 0; x < OS[0]; ++x) {
205 s[0] = d[0] + x*inc[0];
206 if (interp.voxel (direct_transform * s))
207 sum += interp.value();
211 return normalise<value_type> (sum, norm);
213 interp.voxel (direct_transform * Vector3d (x[0], x[1], x[2]));
214 return interp.value();
217 ssize_t get_index (
size_t axis)
const {
return axis < 3 ? x[
axis] : interp.index(
axis); }
218 void move_index (
size_t axis, ssize_t increment) {
220 else interp.index(
axis) += increment;
224 Interpolator<ImageType> interp;
226 const ssize_t dim[3];
an Image providing interpolated values from another Image
This class defines the interface for classes that perform image interpolation.
constexpr I ceil(const T x)
template function with cast to different type
constexpr I round(const T x)
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
const vector< uint32_t > AutoOverSample
const transform_type NoTransform
MR::default_type value_type
double default_type
the default type used throughout MRtrix
std::string str(const T &value, int precision=0)
Eigen::Transform< default_type, 3, Eigen::AffineCompact > transform_type
the type for the affine transform of an image: