1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
/* Copyright (c) 2008-2022 the MRtrix3 contributors.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Covered Software is provided under this License on an "as is"
* basis, without warranty of any kind, either expressed, implied, or
* statutory, including, without limitation, warranties that the
* Covered Software is free of defects, merchantable, fit for a
* particular purpose or non-infringing.
* See the Mozilla Public License v. 2.0 for more details.
*
* For more details, see http://www.mrtrix.org/.
*/
#ifndef __image_adapter_gradient1D_h__
#define __image_adapter_gradient1D_h__
#include "adapter/base.h"
namespace MR
{
namespace Adapter
{
template <class ImageType>
class Gradient1D :
public Base<Gradient1D<ImageType>, ImageType>
{ MEMALIGN (Gradient1D<ImageType>)
public:
using base_type = Base<Gradient1D<ImageType>, ImageType>;
using value_type = typename ImageType::value_type;
using base_type::name;
using base_type::size;
using base_type::spacing;
using base_type::index;
Gradient1D (const ImageType& parent,
size_t axis = 0,
bool wrt_spacing = false) :
base_type (parent),
axis (axis),
wrt_spacing (wrt_spacing),
derivative_weights (3, 1.0),
half_derivative_weights (3, 0.5) {
if (wrt_spacing) {
for (size_t dim = 0; dim < 3; ++dim) {
derivative_weights[dim] /= spacing(dim);
half_derivative_weights[dim] /= spacing(dim);
}
}
}
void set_axis (size_t val)
{
axis = val;
}
/**
* @brief computes the image gradient at the current index along the dimension defined by set_axis();
* @return the image gradient
*/
value_type value ()
{
const ssize_t pos = index (axis);
result = 0.0;
if (pos == 0) {
result = base_type::value();
index (axis) = pos + 1;
result = derivative_weights[axis] * (base_type::value() - result);
} else if (pos == size(axis) - 1) {
result = base_type::value();
index (axis) = pos - 1;
result = derivative_weights[axis] * (result - base_type::value());
} else {
index (axis) = pos + 1;
result = base_type::value();
index (axis) = pos - 1;
result = half_derivative_weights[axis] * (result - base_type::value());
}
index (axis) = pos;
return result;
}
protected:
size_t axis;
value_type result;
const bool wrt_spacing;
vector<value_type> derivative_weights;
vector<value_type> half_derivative_weights;
};
}
}
#endif
|