Krita Source Code Documentation
Loading...
Searching...
No Matches
KisFilteredRollingMean Class Reference

#include <KisFilteredRollingMean.h>

Public Member Functions

void addValue (qreal value)
 
qreal filteredMean () const
 
bool isEmpty () const
 
 KisFilteredRollingMean (int windowSize, qreal effectivePortion)
 

Private Attributes

std::vector< qreal > m_cutOffBuffer
 
qreal m_effectivePortion
 
qreal m_rollingSum
 
boost::circular_buffer< qreal > m_values
 

Detailed Description

A special class that calculates a rolling mean of the values stream, but filtering out random extreme deviations.

On each step the algorithm sorts the entire sampling window and drops a small portion of the lowest and the highest values. The rest of the values are used to calculate the mean of the window.

Basically, it takes the median and a few surrounding values to calculate the mean.

PS: The actually implementation does a few optimizations. For example, it doesn't sort the entire range. But the idea is the same.

Definition at line 33 of file KisFilteredRollingMean.h.

Constructor & Destructor Documentation

◆ KisFilteredRollingMean()

KisFilteredRollingMean::KisFilteredRollingMean ( int windowSize,
qreal effectivePortion )

Creates a mean accumulator

windowSize is the size of the samples window effectivePortion the portion of the samples window that is used for actual mean calculation. On each side of the sorted range (0.5 * (1.0 - effectivePortion) * windowSize) values are dropped and are not counted for the mean calculation.

Definition at line 16 of file KisFilteredRollingMean.cpp.

17 : m_values(windowSize),
18 m_rollingSum(0.0),
19 m_effectivePortion(effectivePortion),
20 m_cutOffBuffer(qCeil(0.5 * (qCeil(windowSize * (1.0 - effectivePortion)))))
21{
22}
boost::circular_buffer< qreal > m_values
std::vector< qreal > m_cutOffBuffer

Member Function Documentation

◆ addValue()

void KisFilteredRollingMean::addValue ( qreal value)

Adds a value for the rolling mean calculation. The complexity of the call is O(1).

Definition at line 24 of file KisFilteredRollingMean.cpp.

25{
26 if (m_values.full()) {
27 m_rollingSum -= m_values.front();
28 }
29
30 m_values.push_back(value);
32}
float value(const T *src, size_t ch)

References m_rollingSum, m_values, and value().

◆ filteredMean()

qreal KisFilteredRollingMean::filteredMean ( ) const

Calculates the filtered mean value of the current range. The function is slow, its complexity is O(N) + O(N*log(M)), where N is the size of the rolling window, M is the number of elements dropped from the window (1.0 - effectivePortion) * windowSize).

Definition at line 34 of file KisFilteredRollingMean.cpp.

35{
37
38 const int usefulElements = qMax(1, qRound(m_effectivePortion * m_values.size()));
39
40 qreal sum = 0.0;
41 int num = 0;
42
43 const int cutOffTotal = m_values.size() - usefulElements;
44
45 if (cutOffTotal > 0) {
46 const std::vector<double>::size_type cutMin = qRound(0.5 * cutOffTotal);
47 const std::vector<double>::size_type cutMax = cutOffTotal - cutMin;
48
49 KIS_SAFE_ASSERT_RECOVER(cutMin <= m_cutOffBuffer.size()) {
50 m_cutOffBuffer.resize(cutMin);
51 }
52 KIS_SAFE_ASSERT_RECOVER(cutMax <= m_cutOffBuffer.size()) {
53 m_cutOffBuffer.resize(cutMax);
54 }
55
56 sum = m_rollingSum;
57 num = usefulElements;
58
59 std::partial_sort_copy(m_values.begin(),
60 m_values.end(),
61 m_cutOffBuffer.begin(),
62 m_cutOffBuffer.begin() + cutMin);
63
64 sum -= std::accumulate(m_cutOffBuffer.begin(),
65 m_cutOffBuffer.begin() + cutMin,
66 0.0);
67
68 std::partial_sort_copy(m_values.begin(),
69 m_values.end(),
70 m_cutOffBuffer.begin(),
71 m_cutOffBuffer.begin() + cutMax,
72 std::greater<qreal>());
73
74 sum -= std::accumulate(m_cutOffBuffer.begin(),
75 m_cutOffBuffer.begin() + cutMax,
76 0.0);
77 } else {
78 sum = m_rollingSum;
79 num = m_values.size();
80 }
81
83
84 return sum / num;
85}
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References KIS_SAFE_ASSERT_RECOVER, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, m_cutOffBuffer, m_effectivePortion, m_rollingSum, and m_values.

◆ isEmpty()

bool KisFilteredRollingMean::isEmpty ( ) const

Returns true if the accumulator has at least some value

Definition at line 87 of file KisFilteredRollingMean.cpp.

88{
89 return m_values.empty();
90}

References m_values.

Member Data Documentation

◆ m_cutOffBuffer

std::vector<qreal> KisFilteredRollingMean::m_cutOffBuffer
mutableprivate

Definition at line 72 of file KisFilteredRollingMean.h.

◆ m_effectivePortion

qreal KisFilteredRollingMean::m_effectivePortion
private

Definition at line 71 of file KisFilteredRollingMean.h.

◆ m_rollingSum

qreal KisFilteredRollingMean::m_rollingSum
private

Definition at line 70 of file KisFilteredRollingMean.h.

◆ m_values

boost::circular_buffer<qreal> KisFilteredRollingMean::m_values
private

Definition at line 69 of file KisFilteredRollingMean.h.


The documentation for this class was generated from the following files: