SampleFilter.cpp
Go to the documentation of this file.
1 #include "cv.h"
2 #include "highgui.h"
3 #include <iostream>
4 #include <cstdlib>
5 #include <string>
6 #include "Filter.h"
7 #include "Kalman.h"
8 #include "Platform.h"
9 #include "AlvarException.h"
10 using namespace alvar;
11 using namespace std;
12 
13 const int res=320;
14 
15 void filter_none(double x, double y, double *fx, double *fy) {
16  *fx = x; *fy = y;
17 }
18 
19 void filter_average(double x, double y, double *fx, double *fy) {
20  static FilterAverage ax(30);
21  static FilterAverage ay(30);
22  *fx = ax.next(x);
23  *fy = ay.next(y);
24 }
25 
26 void filter_median(double x, double y, double *fx, double *fy) {
27  static FilterMedian ax(30);
28  static FilterMedian ay(30);
29  *fx = ax.next(x);
30  *fy = ay.next(y);
31 }
32 
33 void filter_running_average(double x, double y, double *fx, double *fy) {
34  static FilterRunningAverage ax(0.03);
35  static FilterRunningAverage ay(0.03);
36  *fx = ax.next(x);
37  *fy = ay.next(y);
38 }
39 
40 void filter_des(double x, double y, double *fx, double *fy) {
41  static FilterDoubleExponentialSmoothing ax(0.03,0.01);
42  static FilterDoubleExponentialSmoothing ay(0.03,0.01);
43  *fx = ax.next(x);
44  *fy = ay.next(y);
45 }
46 
47 void filter_kalman(double x, double y, double *fx, double *fy) {
48  static bool init=true;
49  static KalmanSensor sensor(4,2);
50  static Kalman kalman(4); // x, y, dx, dy
51  if (init) {
52  init = false;
53  // H
54  cvZero(sensor.H);
55  cvmSet(sensor.H, 0, 0, 1);
56  cvmSet(sensor.H, 1, 1, 1);
57  // R
58  cvSetIdentity(sensor.R, cvScalar(10));
59  // F
60  cvSetIdentity(kalman.F);
61  cvmSet(kalman.F, 0, 2, 1);
62  cvmSet(kalman.F, 1, 3, 1);
63  // Q
64  cvmSet(kalman.Q, 0, 0, 0.0001);
65  cvmSet(kalman.Q, 1, 1, 0.0001);
66  cvmSet(kalman.Q, 2, 2, 0.000001);
67  cvmSet(kalman.Q, 3, 3, 0.000001);
68  // P
69  cvSetIdentity(kalman.P, cvScalar(100));
70  }
71  cvmSet(sensor.z, 0, 0, x);
72  cvmSet(sensor.z, 1, 0, y);
73  kalman.predict_update(&sensor, (unsigned long)(cv::getTickCount() / cv::getTickFrequency() * 1000));
74  *fx = cvmGet(kalman.x, 0, 0);
75  *fy = cvmGet(kalman.x, 1, 0);
76 }
77 
78 void filter_array_average(double x, double y, double *fx, double *fy) {
79  static bool init=true;
80  static FilterArray<FilterAverage> fa(2);
81  if (init) {
82  init=false;
83  for (int i=0; i<2; i++) {
84  fa[i].setWindowSize(30);
85  }
86  }
87  *fx = fa[0].next(x);
88  *fy = fa[1].next(y);
89 }
90 
92  virtual void h(CvMat *x_pred, CvMat *_z_pred) {
93  double x = cvmGet(x_pred, 0, 0);
94  double y = cvmGet(x_pred, 1, 0);
95  double dx = cvmGet(x_pred, 2, 0);
96  double dy = cvmGet(x_pred, 3, 0);
97  cvmSet(_z_pred, 0, 0, x);
98  cvmSet(_z_pred, 1, 0, y);
99  }
100 public:
101  KalmanSensorOwn(int _n, int _m) : KalmanSensorEkf(_n, _m) {}
102 };
103 
104 class KalmanOwn : public KalmanEkf {
105  virtual void f(CvMat *_x, CvMat *_x_pred, double dt) {
106  double x = cvmGet(_x, 0, 0);
107  double y = cvmGet(_x, 1, 0);
108  double dx = cvmGet(_x, 2, 0);
109  double dy = cvmGet(_x, 3, 0);
110  cvmSet(_x_pred, 0, 0, x + dt*dx);
111  cvmSet(_x_pred, 1, 0, y + dt*dy);
112  cvmSet(_x_pred, 2, 0, dx);
113  cvmSet(_x_pred, 3, 0, dy);
114  }
115 public:
116  KalmanOwn(int _n) : KalmanEkf(_n) {}
117 };
118 
119 void filter_ekf(double x, double y, double *fx, double *fy) {
120  static bool init=true;
121  static KalmanSensorOwn sensor(4,2);
122  static KalmanOwn kalman(4); // x, y, dx, dy
123  if (init) {
124  init = false;
125  // R
126  cvSetIdentity(sensor.R, cvScalar(100));
127  // Q
128  cvmSet(kalman.Q, 0, 0, 0.001);
129  cvmSet(kalman.Q, 1, 1, 0.001);
130  cvmSet(kalman.Q, 2, 2, 0.01);
131  cvmSet(kalman.Q, 3, 3, 0.01);
132  // P
133  cvSetIdentity(kalman.P, cvScalar(100));
134  }
135  cvmSet(sensor.z, 0, 0, x);
136  cvmSet(sensor.z, 1, 0, y);
137  kalman.predict_update(&sensor, (unsigned long)(cv::getTickCount() / cv::getTickFrequency() * 1000));
138  *fx = cvmGet(kalman.x, 0, 0);
139  *fy = cvmGet(kalman.x, 1, 0);
140 }
141 
142 //Make list of filters
143 const int nof_filters = 8;
144 void (*(filters[nof_filters]))(double x, double y, double *fx, double *fy) = {
145  filter_none,
149  filter_des,
151  filter_ekf,
153 };
155  "No filter - Press any key to change",
156  "Average",
157  "Median",
158  "Running Average",
159  "Double Exponential Smoothing",
160  "Kalman",
161  "Extended Kalman",
162  "Array (average)"
163 };
164 
165 // Just generate some random data that can be used as sensor input
166 void get_measurement(double *x, double *y) {
167  static double xx=0;
168  static double yy=0;
169  static double dxx = 0.3;
170  static double dyy = 0.7;
171  xx += dxx; yy += dyy;
172  if ((xx > res) || (xx < 0)) dxx = -dxx;
173  if ((yy > res) || (yy < 0)) dyy = -dyy;
174  double rx = (rand()*20.0/RAND_MAX)-10.0;
175  double ry = (rand()*20.0/RAND_MAX)-10.0;
176 
177  // Add some outliers
178  if(fabs(rx*ry)>50)
179  {
180  rx *= 5;
181  ry *= 5;
182  }
183 
184  *x = xx + rx; *y = yy + ry;
185 }
186 
187 int main(int argc, char *argv[])
188 {
189  try {
190  // Output usage message
191  std::string filename(argv[0]);
192  filename = filename.substr(filename.find_last_of('\\') + 1);
193  std::cout << "SampleFilter" << std::endl;
194  std::cout << "============" << std::endl;
195  std::cout << std::endl;
196  std::cout << "Description:" << std::endl;
197  std::cout << " This is an example of how to use the 'FilterAverage', 'FilterMedian'," << std::endl;
198  std::cout << " 'FilterRunningAverage', 'FilterDoubleExponentialSmoothing', 'Kalman'" << std::endl;
199  std::cout << " 'KalmanEkf' and 'FilterArray' filtering classes. First the example" << std::endl;
200  std::cout << " shows unfiltered test data with outliers. The data is then filtered" << std::endl;
201  std::cout << " using the various filters. Press any key to cycle through the filters." << std::endl;
202  std::cout << std::endl;
203  std::cout << "Usage:" << std::endl;
204  std::cout << " " << filename << std::endl;
205  std::cout << std::endl;
206  std::cout << "Keyboard Shortcuts:" << std::endl;
207  std::cout << " any key: cycle through filters" << std::endl;
208  std::cout << " q: quit" << std::endl;
209  std::cout << std::endl;
210 
211  // Processing loop
212  IplImage *img = cvCreateImage(cvSize(res, res), IPL_DEPTH_8U, 3);
213  cvNamedWindow("SampleFilter");
214  CvFont font;
215  cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0);
216  for (int ii = 0; ii < nof_filters; ii++) {
217  int key = 0;
218  double x, y;
219  double fx, fy;
220  vector<CvPoint> tail;
221  while (1) {
222  get_measurement(&x, &y);
223  filters[ii](x, y, &fx, &fy);
224  cvZero(img);
225  cvPutText(img, filter_names[ii], cvPoint(3, res - 10), &font, CV_RGB(255, 255, 255));
226  cvCircle(img, cvPoint(int(x), int(y)), 2, CV_RGB(0, 255, 255));
227  cvCircle(img, cvPoint(int(x), int(y)), 3, CV_RGB(255, 255, 255));
228  CvPoint fp;
229  fp.x = int(fx);
230  fp.y = int(fy);
231  tail.push_back(fp);
232  for (size_t iii = 0; iii < tail.size(); iii++) {
233  cvCircle(img, tail[iii], 0, CV_RGB(255, 255, 0));
234  }
235  cvCircle(img, fp, 2, CV_RGB(255, 0, 255));
236  cvShowImage("SampleFilter", img);
237  key = cvWaitKey(10);
238  if (key != -1) {
239  break;
240  }
241  }
242  if (key == 'q') {
243  break;
244  }
245  }
246  cvReleaseImage(&img);
247  return 0;
248  }
249  catch (const std::exception &e) {
250  std::cout << "Exception: " << e.what() << endl;
251  }
252  catch (...) {
253  std::cout << "Exception: unknown" << std::endl;
254  }
255 }
Extended Kalman Filter (EKF) sensor implementation.
Definition: Kalman.h:225
Main ALVAR namespace.
Definition: Alvar.h:174
void filter_kalman(double x, double y, double *fx, double *fy)
filename
void filter_average(double x, double y, double *fx, double *fy)
void filter_running_average(double x, double y, double *fx, double *fy)
FilterDoubleExponentialSmoothing provides an weighted running average filter
Definition: Filter.h:187
Extended Kalman Filter (EKF) implementation.
Definition: Kalman.h:247
char filter_names[nof_filters][64]
KalmanSensorOwn(int _n, int _m)
virtual void h(CvMat *x_pred, CvMat *_z_pred)
void get_measurement(double *x, double *y)
CvMat * predict_update(KalmanSensor *sensor, unsigned long tick)
Predict the Kalman state vector for the given time step and update the state using the Kalman gain...
Definition: Kalman.cpp:185
CvFont font
Definition: SampleTrack.cpp:12
This file implements multiple filters.
CvMat * P
The error covariance matrix describing the accuracy of the state estimate.
Definition: Kalman.h:184
TFSIMD_FORCE_INLINE const tfScalar & y() const
void filters(double x, double y, double *fx, double *fy)
void filter_median(double x, double y, double *fx, double *fy)
const int nof_filters
CvMat * R
The covariance matrix for the observation noise.
Definition: Kalman.h:124
Kalman sensor implementation.
Definition: Kalman.h:118
virtual double next(double y)
Update the value. All inherited classes need to update value in next().
Definition: Filter.cpp:78
FilterRunningAverage provides an weighted running average filter
Definition: Filter.h:159
void filter_ekf(double x, double y, double *fx, double *fy)
This file implements a versatile Kalman filter.
int main(int argc, char *argv[])
TFSIMD_FORCE_INLINE const tfScalar & x() const
Class for handling an array of filtered values.
Definition: Filter.h:206
CvMat * H
The matrix (m*n) mapping Kalman state vector into this sensor&#39;s measurements vector.
Definition: Kalman.h:52
CvMat * F
The matrix (n*n) containing the transition model for the internal state.
Definition: Kalman.h:91
FilterAverage provides an average filter
Definition: Filter.h:106
bool init
virtual double next(double y)
Update the value. All inherited classes need to update value in next().
Definition: Filter.cpp:48
FilterMedian provides an median filter
Definition: Filter.h:133
CvMat * Q
The covariance matrix for the process noise.
Definition: Kalman.h:186
CvMat * z
Latest measurement vector (m*1)
Definition: Kalman.h:50
CvMat * x
The Kalman state vector (n*1)
Definition: Kalman.h:89
void filter_des(double x, double y, double *fx, double *fy)
This file implements the ALVAR exception class.
void filter_array_average(double x, double y, double *fx, double *fy)
void filter_none(double x, double y, double *fx, double *fy)
KalmanOwn(int _n)
const int res
virtual double next(double y)
Update the value. All inherited classes need to update value in next().
Definition: Filter.cpp:99
virtual double next(double y)
Update the value. All inherited classes need to update value in next().
Definition: Filter.cpp:87
Kalman implementation.
Definition: Kalman.h:178
virtual void f(CvMat *_x, CvMat *_x_pred, double dt)
This file implements generic platform specific methods.


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Mon Jun 10 2019 12:47:04