17#ifndef __filter_optimal_threshold_h__
18#define __filter_optimal_threshold_h__
25#include "filter/base.h"
39 MeanStdFunctor (
double& overall_sum,
double& overall_sum_sqr,
size_t& overall_count) :
40 overall_sum (overall_sum), overall_sum_sqr (overall_sum_sqr), overall_count (overall_count),
41 sum (0.0), sum_sqr (0.0), count (0) { }
44 std::lock_guard<std::mutex> lock (mutex);
46 overall_sum_sqr += sum_sqr;
47 overall_count += count;
50 template <
class ImageType,
class MaskType>
51 void operator() (ImageType& vox, MaskType& mask) {
53 double in = vox.value();
54 if (std::isfinite(in)) {
62 template <
class ImageType>
63 void operator() (ImageType& vox) {
64 double in = vox.value();
65 if (std::isfinite(in)) {
73 double& overall_sum_sqr;
74 size_t& overall_count;
78 static std::mutex mutex;
80 std::mutex MeanStdFunctor::mutex;
84 CorrelationFunctor (
double threshold,
double& overall_sum,
double& overall_mean_xy) :
85 threshold (threshold), overall_sum (overall_sum), overall_mean_xy (overall_mean_xy),
86 sum (0), mean_xy (0.0) { }
88 ~CorrelationFunctor () {
89 std::lock_guard<std::mutex> lock (mutex);
91 overall_mean_xy += mean_xy;
94 template <
class ImageType>
95 void operator() (ImageType& vox) {
96 double in = vox.value();
97 if (std::isfinite(in)) {
105 template <
class ImageType,
class MaskType>
106 void operator() (ImageType& vox, MaskType& mask) {
108 double in = vox.value();
109 if (std::isfinite(in)) {
110 if (in > threshold) {
118 const double threshold;
120 double& overall_mean_xy;
124 static std::mutex mutex;
126 std::mutex CorrelationFunctor::mutex;
132 template <
class ImageType,
class MaskType>
143 double sum_sqr = 0.0, sum = 0.0;
148 ThreadedLoop (input).run (MeanStdFunctor (sum, sum_sqr, count), input, replicated_mask);
151 ThreadedLoop (input).run (MeanStdFunctor (sum, sum_sqr, count), input);
154 input_image_mean = sum / count;
155 input_image_stdev = sqrt ((sum_sqr - sum * input_image_mean) / count);
160 double mean_xy = 0.0;
164 ThreadedLoop (input).run (CorrelationFunctor (threshold, sum, mean_xy), input, replicated_mask);
167 ThreadedLoop (input).run (CorrelationFunctor (threshold, sum, mean_xy), input);
170 double covariance = mean_xy - (sum / count) * input_image_mean;
171 double mask_stdev = sqrt ((sum -
double (sum * sum) / count) / count);
173 return -covariance / (input_image_stdev * mask_stdev);
180 double input_image_mean;
181 double input_image_stdev;
185 template <
class ImageType,
class MaskType>
190 input_value_type min, max;
192 min_max (input, mask, min, max);
196 input_value_type optimal_threshold = 0.0;
200 min + 0.001*(max-min), 0.5*(min+max), max-0.001*(max-min));
203 return optimal_threshold;
209 template <
class ImageType>
247 template <
class InputImageType,
class OutputImageType>
248 void operator() (InputImageType& input, OutputImageType& output)
251 operator() (input, output, mask);
255 template <
class InputImageType,
class OutputImageType,
class MaskType>
256 void operator() (InputImageType& input, OutputImageType& output, MaskType& mask)
262 auto f = [&](
decltype(input) in,
decltype(output) out) {
263 input_value_type val = in.value();
264 out.value() = ( std::isfinite (val) && val > optimal_threshold ) ? 1 : 0;
266 ThreadedLoop (
"thresholding", input) .run (f, input, output);
static constexpr uint8_t Bit
typename ImageType::value_type value_type
ImageCorrelationCostFunction(ImageType &input, MaskType &mask)
typename MaskType::value_type mask_value_type
value_type operator()(value_type threshold) const
a filter to compute the optimal threshold to mask a DataSet.
ValueType golden_section_search(FunctionType &function, const std::string &message, ValueType min_bound, ValueType init_estimate, ValueType max_bound, ValueType tolerance=0.01)
Computes the minimum of a 1D function using a golden section search.
constexpr T pow2(const T &v)
ImageType::value_type estimate_optimal_threshold(ImageType &input, MaskType &mask)
MR::default_type value_type
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.
void min_max(ImageType &in, typename ImageType::value_type &min, typename ImageType::value_type &max, size_t from_axis=0, size_t to_axis=std::numeric_limits< size_t >::max())