Mercurial > hg > devuvuzelator
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 |