17#ifndef __image_filter_gradient_h__
18#define __image_filter_gradient_h__
26#include "filter/base.h"
27#include "filter/smooth.h"
48 template <
class HeaderType>
60 axes_[4].size = in.size(3);
67 }
else if (in.ndim() == 3) {
77 throw Exception(
"input image must be 3D or 4D");
80 DEBUG (
"creating gradient filter");
83 void compute_wrt_scanner (
bool do_wrt_scanner) {
92 template <
class InputImageType,
class OutputImageType>
93 void operator() (InputImageType& in, OutputImageType& out)
97 full_gradient.set_stdev (
stdev);
99 full_gradient.set_message (
message);
101 full_gradient (in, temp);
102 for (
auto l =
Loop (out)(out, temp); l; ++l) {
103 if (out.ndim() == 4) {
104 ssize_t tmp = out.index(3);
108 for (temp.index(3) = 0; temp.index(3) != 3; ++temp.index(3))
109 grad_sq += Math::pow2<float> (temp.value());
110 out.value() = std::sqrt (grad_sq);
117 smoother.set_message (
"applying smoothing prior to calculating gradient");
121 const size_t num_volumes = (in.ndim() == 3) ? 1 : in.size(3);
125 for (
size_t vol = 0; vol < num_volumes; ++vol) {
126 if (in.ndim() == 4) {
127 smoothed.index(3) = vol;
134 if (progress) ++(*progress);
136 gradient1D.set_axis (1);
138 if (progress) ++(*progress);
140 gradient1D.set_axis (2);
142 if (progress) ++(*progress);
146 for (
auto l =
Loop(0,3) (out); l; ++l)
147 out.row(3) = transform.
image2scanner.linear() * Eigen::Vector3d (out.row(3));
static constexpr uint8_t Float32
vector< default_type > stdev
static Image scratch(const Header &template_header, const std::string &label="scratch image")
implements a progress meter to provide feedback to the user
FORCE_INLINE LoopAlongAxes Loop()
void threaded_copy(InputImageType &source, OutputImageType &destination, const vector< size_t > &axes, size_t num_axes_in_thread=1)