comparison median.h @ 4:d90abfa9585a

* Adaptive method
author Chris Cannam
date Fri, 11 Jun 2010 15:38:44 +0100
parents
children 45bcfa3d5da7
comparison
equal deleted inserted replaced
3:8b79175c9f02 4:d90abfa9585a
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 #ifndef _MEDIAN_H_
4 #define _MEDIAN_H_
5
6 #include <algorithm>
7 #include <cassert>
8
9 template <typename T>
10 class MedianFilter
11 {
12 public:
13 MedianFilter(int size, float percentile = 50.f) :
14 m_size(size),
15 m_frame(new T[size]),
16 m_sorted(new T[size]),
17 m_sortend(m_sorted + size - 1) {
18 setPercentile(percentile);
19 reset();
20 }
21
22 ~MedianFilter() {
23 delete[] m_frame;
24 delete[] m_sorted;
25 }
26
27 void setPercentile(float p) {
28 m_index = int((m_size * p) / 100.f);
29 if (m_index >= m_size) m_index = m_size-1;
30 if (m_index < 0) m_index = 0;
31 }
32
33 void push(T value) {
34 drop(m_frame[0]);
35 const int sz1 = m_size-1;
36 for (int i = 0; i < sz1; ++i) m_frame[i] = m_frame[i+1];
37 m_frame[m_size-1] = value;
38 put(value);
39 }
40
41 T get() const {
42 return m_sorted[m_index];
43 }
44
45 T getAt(float percentile) {
46 int ix = int((m_size * percentile) / 100.f);
47 if (ix >= m_size) ix = m_size-1;
48 if (ix < 0) ix = 0;
49 return m_sorted[ix];
50 }
51
52 void reset() {
53 for (int i = 0; i < m_size; ++i) m_frame[i] = 0;
54 for (int i = 0; i < m_size; ++i) m_sorted[i] = 0;
55 }
56
57 private:
58 const int m_size;
59 T *const m_frame;
60 T *const m_sorted;
61 T *const m_sortend;
62 int m_index;
63
64 void put(T value) {
65 // precondition: m_sorted contains m_size-1 values, packed at start
66 // postcondition: m_sorted contains m_size values, one of which is value
67 T *point = std::lower_bound(m_sorted, m_sortend, value);
68 const int n = m_sortend - point;
69 for (int i = n; i > 0; --i) point[i] = point[i-1];
70 *point = value;
71 }
72
73 void drop(T value) {
74 // precondition: m_sorted contains m_size values, one of which is value
75 // postcondition: m_sorted contains m_size-1 values, packed at start
76 T *point = std::lower_bound(m_sorted, m_sortend + 1, value);
77 if (*point != value) {
78 std::cerr << "WARNING: MedianFilter::drop: *point is " << *point
79 << ", expected " << value << std::endl;
80 }
81 const int n = m_sortend - point;
82 for (int i = 0; i < n; ++i) point[i] = point[i+1];
83 *m_sortend = T(0);
84 }
85 };
86
87 #endif
88