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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#ifndef THRESHOLDTOOLS_H
#define THRESHOLDTOOLS_H
#include <vector>
#include <cmath>
#include <complex>
#include "../structures/image2d.h"
#include "../structures/mask2d.h"
namespace algorithms {
class ThresholdTools {
public:
static void MeanAndStdDev(const Image2D* image, const Mask2D* mask,
num_t& mean, num_t& stddev);
static numl_t Sum(const Image2D* image, const Mask2D* mask);
static numl_t RMS(const Image2D* image, const Mask2D* mask);
static num_t Mode(const Image2D* input, const Mask2D* mask);
static num_t WinsorizedMode(const Image2D* image, const Mask2D* mask);
static num_t WinsorizedMode(const Image2D* image, const Mask2D* maskA,
const Mask2D* maskB);
static num_t WinsorizedMode(const Image2D* image);
template <typename T>
static void TrimmedMeanAndStdDev(const std::vector<T>& input, T& mean,
T& stddev);
template <typename T>
static void WinsorizedMeanAndStdDev(const std::vector<T>& input, T& mean,
T& stddev);
static void WinsorizedMeanAndStdDev(const Image2D* image, const Mask2D* mask,
num_t& mean, num_t& stddev);
static void WinsorizedMeanAndStdDev(const Image2D* image, const Mask2D* maskA,
const Mask2D* maskB, num_t& mean,
num_t& stddev);
static void WinsorizedMeanAndStdDev(const Image2D* image, num_t& mean,
num_t& stddev);
template <typename T>
static double WinsorizedRMS(const std::vector<std::complex<T>>& input);
static num_t MinValue(const Image2D* image, const Mask2D* mask);
static num_t MaxValue(const Image2D* image, const Mask2D* mask);
static void SetFlaggedValuesToZero(Image2D* dest, const Mask2D* mask);
static void CountMaskLengths(const Mask2D* mask, int* lengths,
size_t lengthsSize);
static void FilterConnectedSamples(Mask2D* mask,
size_t minConnectedSampleArea,
bool eightConnected = true);
static void FilterConnectedSample(Mask2D* mask, size_t x, size_t y,
size_t minConnectedSampleArea,
bool eightConnected = true);
static void UnrollPhase(Image2D* image);
static Image2DPtr ShrinkHorizontally(size_t factor, const Image2D* input,
const Mask2D* mask);
static Image2DPtr ShrinkVertically(size_t factor, const Image2D* input,
const Mask2D* mask);
static Image2DPtr FrequencyRectangularConvolution(const Image2D* source,
size_t convolutionSize) {
Image2DPtr image(new Image2D(*source));
const size_t upperWindowHalf = (convolutionSize + 1) / 2;
for (size_t x = 0; x < image->Width(); ++x) {
num_t sum = 0.0;
for (size_t y = 0; y < upperWindowHalf; ++y) sum += image->Value(x, y);
for (size_t y = upperWindowHalf; y < convolutionSize; ++y) {
image->SetValue(x, y - upperWindowHalf, sum / (num_t)y);
sum += image->Value(x, y);
}
size_t count = convolutionSize;
for (size_t y = convolutionSize; y != image->Height(); ++y) {
image->SetValue(x, y - upperWindowHalf, sum / (num_t)count);
sum += image->Value(x, y) - image->Value(x, y - convolutionSize);
}
for (size_t y = image->Height(); y != image->Height() + upperWindowHalf;
++y) {
image->SetValue(x, y - upperWindowHalf, sum / (num_t)count);
sum -= image->Value(x, y - convolutionSize);
--count;
}
}
return image;
}
static Mask2DPtr Threshold(const Image2D* image, num_t threshold) {
Mask2DPtr mask =
Mask2D::CreateUnsetMaskPtr(image->Width(), image->Height());
for (size_t y = 0; y < image->Height(); ++y) {
for (size_t x = 0; x < image->Width(); ++x) {
mask->SetValue(x, y, image->Value(x, y) >= threshold);
}
}
return mask;
}
private:
ThresholdTools() {}
// We need this less than operator, because the normal operator
// does not enforce a strictly ordered set, because a<b != !(b<a) in the case
// of nans/infs.
static bool numLessThanOperator(const num_t& a, const num_t& b) {
if (std::isfinite(a)) {
if (std::isfinite(b))
return a < b;
else
return true;
}
return false;
}
template <typename T>
static bool complexLessThanOperator(const std::complex<T>& a,
const std::complex<T>& b) {
if (std::isfinite(a.real()) && std::isfinite(a.imag())) {
if (std::isfinite(b.real()) && std::isfinite(b.imag()))
return (a * std::conj(a)).real() < (b * std::conj(b)).real();
else
return true;
}
return false;
}
};
} // namespace algorithms
#endif
|