annotate median.h @ 7:5adad2ca3188

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