WPILibC++ 2024.3.2
MedianFilter.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <algorithm>
8#include <vector>
9
10#include <wpi/Algorithm.h>
11#include <wpi/circular_buffer.h>
12
13namespace frc {
14/**
15 * A class that implements a moving-window median filter. Useful for reducing
16 * measurement noise, especially with processes that generate occasional,
17 * extreme outliers (such as values from vision processing, LIDAR, or ultrasonic
18 * sensors).
19 */
20template <class T>
22 public:
23 /**
24 * Creates a new MedianFilter.
25 *
26 * @param size The number of samples in the moving window.
27 */
28 explicit MedianFilter(size_t size) : m_valueBuffer(size), m_size{size} {}
29
30 /**
31 * Calculates the moving-window median for the next value of the input stream.
32 *
33 * @param next The next input value.
34 * @return The median of the moving window, updated to include the next value.
35 */
36 T Calculate(T next) {
37 // Insert next value at proper point in sorted array
38 wpi::insert_sorted(m_orderedValues, next);
39
40 size_t curSize = m_orderedValues.size();
41
42 // If buffer is at max size, pop element off of end of circular buffer
43 // and remove from ordered list
44 if (curSize > m_size) {
45 m_orderedValues.erase(std::find(m_orderedValues.begin(),
46 m_orderedValues.end(),
47 m_valueBuffer.pop_back()));
48 --curSize;
49 }
50
51 // Add next value to circular buffer
52 m_valueBuffer.push_front(next);
53
54 if (curSize % 2 != 0) {
55 // If size is odd, return middle element of sorted list
56 return m_orderedValues[curSize / 2];
57 } else {
58 // If size is even, return average of middle elements
59 return (m_orderedValues[curSize / 2 - 1] + m_orderedValues[curSize / 2]) /
60 2.0;
61 }
62 }
63
64 /**
65 * Returns the last value calculated by the MedianFilter.
66 *
67 * @return The last value.
68 */
69 T LastValue() const { return m_valueBuffer.front(); }
70
71 /**
72 * Resets the filter, clearing the window of all elements.
73 */
74 void Reset() {
75 m_orderedValues.clear();
76 m_valueBuffer.reset();
77 }
78
79 private:
80 wpi::circular_buffer<T> m_valueBuffer;
81 std::vector<T> m_orderedValues;
82 size_t m_size;
83};
84} // namespace frc
A class that implements a moving-window median filter.
Definition: MedianFilter.h:21
MedianFilter(size_t size)
Creates a new MedianFilter.
Definition: MedianFilter.h:28
T Calculate(T next)
Calculates the moving-window median for the next value of the input stream.
Definition: MedianFilter.h:36
T LastValue() const
Returns the last value calculated by the MedianFilter.
Definition: MedianFilter.h:69
void Reset()
Resets the filter, clearing the window of all elements.
Definition: MedianFilter.h:74
This is a simple circular buffer so we don't need to "bucket brigade" copy old values.
Definition: circular_buffer.h:20
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2120
Definition: AprilTagPoseEstimator.h:15
std::vector< T >::iterator insert_sorted(std::vector< T > &vec, T const &item)
Definition: Algorithm.h:16