20 #ifndef MIRTK_UnaryVoxelFunction_H 21 #define MIRTK_UnaryVoxelFunction_H 23 #include "mirtk/VoxelFunction.h" 25 #include "mirtk/Assert.h" 26 #include "mirtk/Voxel.h" 27 #include "mirtk/VoxelCast.h" 28 #include "mirtk/BaseImage.h" 29 #include "mirtk/GenericImage.h" 30 #include "mirtk/Math.h" 37 class InterpolateImageFunction;
56 namespace UnaryVoxelFunction {
69 void Reset() { _Min = voxel_limits<double>::max(); }
75 void join (
const GetMin &rhs) {
if (rhs._Min < _Min) _Min = rhs._Min; }
77 template <
class TImage,
class T>
78 void operator ()(
const TImage&,
int,
const T *p)
80 if (static_cast<double>(*p) < _Min) _Min =
static_cast<double>(*p);
84 void operator ()(
int,
int,
int,
int,
const T *p)
86 if (static_cast<double>(*p) < _Min) _Min =
static_cast<double>(*p);
89 double GetMinAsDouble()
const 91 if (_Min == voxel_limits<double>::max()) {
92 return numeric_limits<double>::quiet_NaN();
107 void Reset() { _Max = voxel_limits<double>::min(); }
113 void join (
const GetMax &rhs) {
if (rhs._Max < _Max) _Max = rhs._Max; }
115 template <
class TImage,
class T>
116 void operator ()(
const TImage&,
int,
const T *p)
118 if (static_cast<double>(*p) > _Max) _Max =
static_cast<double>(*p);
122 void operator ()(
int,
int,
int,
int,
const T *p)
124 if (static_cast<double>(*p) > _Max) _Max =
static_cast<double>(*p);
127 double GetMaxAsDouble()
const 129 if (_Max == voxel_limits<double>::min()) {
130 return numeric_limits<double>::quiet_NaN();
147 _Min = voxel_limits<double>::max();
148 _Max = voxel_limits<double>::min();
162 if (rhs._Min < _Min) _Min = rhs._Min;
163 if (rhs._Max > _Max) _Max = rhs._Max;
166 template <
class TImage,
class T>
167 void operator ()(
const TImage&,
int,
const T *p)
169 if (static_cast<double>(*p) < _Min) _Min =
static_cast<double>(*p);
170 if (static_cast<double>(*p) > _Max) _Max =
static_cast<double>(*p);
174 void operator ()(
int,
int,
int,
int,
const T *p)
176 if (static_cast<double>(*p) < _Min) _Min =
static_cast<double>(*p);
177 if (static_cast<double>(*p) > _Max) _Max =
static_cast<double>(*p);
180 double GetMinAsDouble()
const 182 if (_Min == voxel_limits<double>::max()) {
183 return numeric_limits<double>::quiet_NaN();
188 double GetMaxAsDouble()
const 190 if (_Max == voxel_limits<double>::min()) {
191 return numeric_limits<double>::quiet_NaN();
215 if (*p < _LowerThreshold) *p = _LowerThreshold;
218 void operator ()(
int,
int,
int,
int, T *p)
220 if (*p < _LowerThreshold) *p = _LowerThreshold;
237 if (*p > _UpperThreshold) *p = _UpperThreshold;
240 void operator ()(
int,
int,
int,
int, T *p)
242 if (*p > _UpperThreshold) *p = _UpperThreshold;
255 Clamp(T min, T max) : _LowerThreshold(min), _UpperThreshold(max) {}
259 if (*p < _LowerThreshold) *p = _LowerThreshold;
260 else if (*p > _UpperThreshold) *p = _UpperThreshold;
263 void operator ()(
int,
int,
int,
int, T *p)
265 if (*p < _LowerThreshold) *p = _LowerThreshold;
266 else if (*p > _UpperThreshold) *p = _UpperThreshold;
283 template <
class TImage,
class T>
284 void operator ()(
const TImage&,
int, T *p)
286 *p =
static_cast<T
>(sqrt(static_cast<double>(*p)));
290 void operator ()(
int,
int,
int,
int,
const T *p)
292 *p =
static_cast<T
>(sqrt(static_cast<double>(*p)));
304 template <
class TImage,
class T>
305 void operator ()(
const TImage &,
int, T *v)
307 *v =
static_cast<GreyPixel
>(*v);
317 template <
class TInterpolator = InterpolateImageFunction>
321 const TInterpolator *_Interpolator;
326 _Input (input->Input()),
327 _Interpolator(input),
330 mirtkAssert(input->Input()->T() == 1 || input->Input()->GetTSize() != .0,
331 "Input image is not a multi-channel image");
336 _Input (other._Input),
337 _Interpolator(other._Interpolator),
338 _Output (other._Output)
346 double x = i, y = j, z = k, t = l;
354 _Interpolator->Evaluate(v, x, y, z, t);
355 (*o) = voxel_cast<T>(v);
361 template <
class TInterpolator = InterpolateImageFunction>
365 const TInterpolator *_Interpolator;
370 _Input (input->Input()),
371 _Interpolator(input),
374 mirtkAssert(input->Input()->N() == 1,
"Input image has scalar data type");
379 _Input (other._Input),
380 _Interpolator(other._Interpolator),
381 _Output (other._Output)
389 double x = i, y = j, z = k, t = l;
396 (*o) = voxel_cast<T>(_Interpolator->Evaluate(x, y, z, t));
402 template <
class TInterpolator = InterpolateImageFunction>
406 const TInterpolator *_Interpolator;
412 _Input (input->Input()),
413 _Interpolator (input),
417 mirtkAssert(input->Input() != NULL,
"Interpolator is initialized");
418 mirtkAssert(output->
T() == input->Input()->T(),
419 "Input and output images have same number of channels");
424 _Input (other._Input),
425 _Interpolator (other._Interpolator),
426 _Output (other._Output),
427 _NumberOfVoxels(other._NumberOfVoxels)
435 double x = i, y = j, z = k;
440 double *v =
new double[_Output->
T()];
441 _Interpolator->Evaluate(v, x, y, z);
442 for (
int l = 0; l < _Output->
T(); ++l, o += _NumberOfVoxels) {
443 (*o) = voxel_cast<T>(v[l]);
452 double x = i, y = j, z = k;
457 _Interpolator->Evaluate(o, x, y, z, _NumberOfVoxels);
466 template <
class TVoxel>
474 : _Input(input), _Offset((input->
GetX() % m) / 2), _Factor(m)
478 void operator ()(
int i,
int j,
int k,
int l, T *out)
480 *out = _Input->
Get(_Offset + i * _Factor, j, k, l);
485 template <
class TVoxel>
493 : _Input(input), _Offset((input->
GetY() % m) / 2), _Factor(m)
497 void operator ()(
int i,
int j,
int k,
int l, T *out)
499 *out = _Input->
Get(i, _Offset + j * _Factor, k, l);
504 template <
class TVoxel>
512 : _Input(input), _Offset((input->
GetZ() % m) / 2), _Factor(m)
516 void operator ()(
int i,
int j,
int k,
int l, T *out)
518 *out = _Input->
Get(i, j, _Offset + k * _Factor, l);
525 #endif // MIRTK_UnaryVoxelFunction_H void operator()(int i, int j, int k, int l, T *o)
Interpolate scalar at (i, j, k, l)
Dummy type used to distinguish split constructor from copy constructor.
void operator()(int i, int j, int k, int, double *o)
Interpolate all channels at (i, j, k) at once.
void WorldToImage(double &, double &) const
World to image coordinate conversion with two doubles.
T _UpperThreshold
Upper threshold value.
Casts intensities to grey values.
Interpolate scalar or vector image.
T _LowerThreshold
Lower threshold value.
void operator()(int i, int j, int k, int, T *o)
Interpolate all channels at (i, j, k) at once.
void operator()(int i, int j, int k, int l, T *o)
Interpolate scalar/vector image.
T _UpperThreshold
Upper threshold value.
int GetX() const
Returns the number of voxels in the x-direction.
void ImageToWorld(double &, double &) const
Image to world coordinate conversion with two doubles.
double TimeToImage(double) const
Time to image coordinate conversion.
int GetY() const
Returns the number of voxels in the y-direction.
double ImageToTime(double) const
Image to time coordinate conversion.
Interpolate scalar image.
T _LowerThreshold
Lower threshold value.
int T() const
Returns the number of voxels in the t-direction.
VoxelType Get(int) const
Function for pixel get access.
Interpolate multi-channel image (3D+c)
int GetZ() const
Returns the number of voxels in the z-direction.
int NumberOfSpatialVoxels() const
Returns the total number of spatial voxels.