FastLED 3.9.15
Loading...
Searching...
No Matches
median_filter_impl.h
Go to the documentation of this file.
1#pragma once
2
4#include "fl/log/log.h"
5#include "fl/stl/algorithm.h"
6#include "fl/stl/span.h"
7#include "fl/stl/noexcept.h"
9
10namespace fl {
11namespace detail {
12
13template <typename T, fl::size N = 0>
15 FL_STATIC_ASSERT(N == 0 || (N % 2 == 1),
16 "MedianFilter: N must be odd for an unambiguous median");
17 public:
19 explicit MedianFilterImpl(fl::size capacity)
21 mSortedCount(0), mLastMedian(T(0)) {
22 if (capacity % 2 == 0) {
23 FL_ERROR("MedianFilter: capacity should be odd, adding 1");
26 }
27 }
28
30 if (values.size() == 0) return mLastMedian;
31 for (fl::size i = 0; i < values.size(); ++i) {
32 mRing.push_back(values[i]);
33 }
34 // Rebuild sorted array from ring contents
35 mSortedCount = mRing.size();
36 for (fl::size i = 0; i < mSortedCount; ++i) {
37 mSorted[i] = mRing[i];
38 }
41 return mLastMedian;
42 }
43
44 T update(T input) {
45 if (!mRing.full()) {
46 T* base = &mSorted[0];
47 T* pos = fl::lower_bound(base, base + mSortedCount, input);
48 fl::size idx = static_cast<fl::size>(pos - base);
49 for (fl::size i = mSortedCount; i > idx; --i) {
50 mSorted[i] = mSorted[i - 1];
51 }
52 mSorted[idx] = input;
54 } else {
55 T oldest = mRing.front();
56 T* base = &mSorted[0];
57 T* rm_pos = fl::lower_bound(base, base + mSortedCount, oldest);
58 fl::size rm = static_cast<fl::size>(rm_pos - base);
59 for (fl::size i = rm; i + 1 < mSortedCount; ++i) {
60 mSorted[i] = mSorted[i + 1];
61 }
62 T* ins_pos =
63 fl::lower_bound(base, base + mSortedCount - 1, input);
64 fl::size idx = static_cast<fl::size>(ins_pos - base);
65 for (fl::size i = mSortedCount - 1; i > idx; --i) {
66 mSorted[i] = mSorted[i - 1];
67 }
68 mSorted[idx] = input;
69 }
70
71 mRing.push_back(input);
73 return mLastMedian;
74 }
75
76 T value() const { return mLastMedian; }
77
78 void reset() {
79 mRing.clear();
80 mSortedCount = 0;
81 mLastMedian = T(0);
82 }
83
84 fl::size size() const { return mRing.size(); }
85 fl::size capacity() const { return mRing.capacity(); }
86
87 void resize(fl::size new_capacity) {
88 if (new_capacity % 2 == 0) {
89 FL_ERROR("MedianFilter: capacity should be odd, adding 1");
90 new_capacity += 1;
91 }
92 mRing = circular_buffer<T, N>(new_capacity);
93 mSorted = circular_buffer<T, N>(new_capacity);
94 mSortedCount = 0;
95 mLastMedian = T(0);
96 }
97
98 private:
101 fl::size mSortedCount;
103};
104
105} // namespace detail
106} // namespace fl
uint8_t pos
Definition Blur.ino:11
T update(fl::span< const T > values)
void resize(fl::size new_capacity)
circular_buffer< T, N > mSorted
MedianFilterImpl(fl::size capacity)
FL_STATIC_ASSERT(N==0||(N % 2==1), "MedianFilter: N must be odd for an unambiguous median")
circular_buffer< T, N > mRing
constexpr fl::size size() const FL_NOEXCEPT
Definition span.h:458
#define FL_ERROR(X)
Definition log.h:219
Centralized logging categories for FastLED hardware interfaces and subsystems.
Compile-time linker keep-alive hook for a single fl::Bus.
Definition bus_traits.h:48
void sort(Iterator first, Iterator last, Compare comp) FL_NOEXCEPT
Definition algorithm.h:564
Iterator lower_bound(Iterator first, Iterator last, const T &value, Compare comp) FL_NOEXCEPT
Definition algorithm.h:551
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT
Portable compile-time assertion wrapper.