1 | // ArchTOIPipe (C) CEA/DAPNIA/SPP IN2P3/LAL
|
---|
2 | // Eric Aubourg
|
---|
3 | // Christophe Magneville
|
---|
4 | // Reza Ansari
|
---|
5 | // $Id: toimedfilter.cc,v 1.4 2002-11-28 15:49:21 aubourg Exp $
|
---|
6 |
|
---|
7 | #include <algorithm>
|
---|
8 | #include <set>
|
---|
9 | #include "toimedfilter.h"
|
---|
10 |
|
---|
11 | TOIMedFilter::TOIMedFilter(int width)
|
---|
12 | : w((width/2)*2+1)
|
---|
13 | {}
|
---|
14 |
|
---|
15 | void TOIMedFilter::init() {
|
---|
16 | declareInput("signal");
|
---|
17 | declareOutput("out");
|
---|
18 | name="medianfilter";
|
---|
19 | upExtra = w/2;
|
---|
20 | lowExtra = w/2;
|
---|
21 | setNeededHistory(w+1);
|
---|
22 | }
|
---|
23 |
|
---|
24 | void TOIMedFilter::run_raw() {
|
---|
25 | int snb = getMinOut()-w/2;
|
---|
26 | int sne = getMaxOut()+w/2;
|
---|
27 |
|
---|
28 | const int window = (w>200) ? 5*w : 1000;
|
---|
29 | double* data = new double[window];
|
---|
30 | double* filter = new double[w];
|
---|
31 |
|
---|
32 | for (int i=snb; i<=sne; i += window-w+1) {
|
---|
33 | int j = i+window-1;
|
---|
34 | if (j>=sne) j = sne;
|
---|
35 | // cout << "median: fetching " << i << " -> " << j << endl;
|
---|
36 | getData(0, i, j-i+1, data);
|
---|
37 | for (int ii=i+w/2; ii<=j-w/2; ii++) {
|
---|
38 | // cout << "median: computing " << ii << endl;
|
---|
39 | copy(data+(ii-i-w/2), data+(ii-i+w/2)+1, filter);
|
---|
40 | sort(filter, filter+w);
|
---|
41 | // if (ii == snb+w/2 || (ii%100 == 0))
|
---|
42 | // cout << ii << " -> " << filter[w/2] << endl;
|
---|
43 | putData(0, ii, filter[w/2]);
|
---|
44 | }
|
---|
45 | }
|
---|
46 |
|
---|
47 | delete[] filter;
|
---|
48 | delete[] data;
|
---|
49 | }
|
---|
50 |
|
---|
51 | void TOIMedFilter::run() {
|
---|
52 | cout << "TOIMedFilter in : " << getMinIn() << " - " << getMaxIn()
|
---|
53 | << " out : " << getMinOut() << " - " << getMaxOut() << endl;
|
---|
54 | multiset<double> low; // w/2
|
---|
55 | multiset<double> high; // w/2
|
---|
56 | double mid;
|
---|
57 |
|
---|
58 | int snb = getMinOut()-w/2;
|
---|
59 | int sne = getMaxOut()+w/2;
|
---|
60 |
|
---|
61 | // init structures
|
---|
62 | {for (int i=0; i<w; i++) {
|
---|
63 | double data = getData(0, snb+i);
|
---|
64 | low.insert(data);
|
---|
65 | }}
|
---|
66 |
|
---|
67 | multiset<double>::iterator ii = low.begin();
|
---|
68 | {for (int i=0; i<w/2; i++, ii++);}
|
---|
69 | mid = *ii;
|
---|
70 | ii++; high.insert(ii, low.end());
|
---|
71 | ii--; low.erase(ii, low.end());
|
---|
72 |
|
---|
73 | putData(0, snb+w/2, mid);
|
---|
74 | cout << snb+w/2<< " -> " << mid << endl;
|
---|
75 |
|
---|
76 | {for (int i=snb+w; i<=sne; i ++) {
|
---|
77 | double b = getData(0, i);
|
---|
78 | double a = getData(0, i-w);
|
---|
79 | if (a < mid && b <= mid) {
|
---|
80 | low.erase(low.find(a));
|
---|
81 | low.insert(b);
|
---|
82 | } else if (a > mid && b >= mid) {
|
---|
83 | high.erase(high.find(a));
|
---|
84 | high.insert(b);
|
---|
85 | } else if (a == mid) {
|
---|
86 | if ( b <= *high.begin() && b >= *low.rbegin()) {
|
---|
87 | mid = b;
|
---|
88 | } else if (b > *high.begin()) {
|
---|
89 | mid = *high.begin();
|
---|
90 | high.erase(high.begin());
|
---|
91 | high.insert(b);
|
---|
92 | } else {
|
---|
93 | mid = *low.rbegin();
|
---|
94 | multiset<double>::iterator i = low.end(); i--;
|
---|
95 | low.erase(i);
|
---|
96 | low.insert(b);
|
---|
97 | }
|
---|
98 | } else if (a < mid && b > mid) {
|
---|
99 | low.erase(low.find(a));
|
---|
100 | low.insert(mid);
|
---|
101 | mid = *high.begin();
|
---|
102 | high.erase(high.begin());
|
---|
103 | high.insert(b);
|
---|
104 | } else { // a >mid && b < mid
|
---|
105 | if (! ( a>mid && b<mid)) {
|
---|
106 | cout << "assertion failed " << b << " " << mid << " " << a << endl;
|
---|
107 | abort();
|
---|
108 | }
|
---|
109 | high.erase(high.find(a));
|
---|
110 | high.insert(mid);
|
---|
111 | mid = *low.rbegin();
|
---|
112 | multiset<double>::iterator i = low.end(); i--;
|
---|
113 | low.erase(i);
|
---|
114 | low.insert(b);
|
---|
115 | }
|
---|
116 | if (low.size() != w/2 || high.size() != w/2) {
|
---|
117 | cout << "assertion failed " << low.size() << " " << high.size() << endl;
|
---|
118 | abort();
|
---|
119 | }
|
---|
120 | // if ( (i-w/2)%100 == 0)
|
---|
121 | // cout << i-w/2 << " -> " << mid << endl;
|
---|
122 | putData(0, i-w/2, mid);
|
---|
123 | }}
|
---|
124 | }
|
---|
125 |
|
---|