JeVoisBase  1.22
JeVois Smart Embedded Machine Vision Toolkit Base Modules
Share this page:
Loading...
Searching...
No Matches
Kalman4D.C
Go to the documentation of this file.
1// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4// California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5//
6// This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7// redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8// Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10// License for more details. You should have received a copy of the GNU General Public License along with this program;
11// if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12//
13// Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14// Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16/*! \file */
17
20#include <cmath>
21
22// ####################################################################################################
23Kalman4D::Kalman4D(std::string const & instance) :
24 jevois::Component(instance), itsKF(6, 4, 0), itsProcessNoise(6, 1, CV_32F),
25 itsMeasurement(4, 1, CV_32F), itsLatest(4, 1, CV_32F), itsFresh(false)
26{
27 cv::setIdentity(itsKF.measurementMatrix);
28}
29
30// ####################################################################################################
33
34// ####################################################################################################
36{
37 itsKF.statePost.at<float>(0) = 0.0F; // middle of screen
38 itsKF.statePost.at<float>(1) = 0.0F; // middle of screen
39 itsKF.statePost.at<float>(2) = 1.0F; // small width
40 itsKF.statePost.at<float>(3) = 1.0F; // small height
41 itsKF.statePost.at<float>(4) = 0.0F; // not moving
42 itsKF.statePost.at<float>(5) = 0.0F; // not moving
43
44 // Predict once to get rolling:
45 itsKF.predict();
46}
47
48// ####################################################################################################
49void Kalman4D::onParamChange(kalman4d::usevel const & JEVOIS_UNUSED_PARAM(param), bool const & newval)
50{
51 if (newval)
52 itsKF.transitionMatrix = (cv::Mat_<float>(6, 6) <<
53 1,0,0,0,1,0, // x updated by xdot
54 0,1,0,0,0,1, // y updated by ydot
55 0,0,1,0,0,0, // constant width
56 0,0,0,1,0,0, // constant height
57 0,0,0,0,1,0, // constant xdot
58 0,0,0,0,0,1 // constant ydot
59 );
60 else
61 itsKF.transitionMatrix = (cv::Mat_<float>(6, 6) <<
62 1,0,0,0,0,0, // constant x
63 0,1,0,0,0,0, // constant y
64 0,0,1,0,0,0, // constant width
65 0,0,0,1,0,0, // constant height
66 0,0,0,0,1,0, // constant xdot
67 0,0,0,0,0,1 // constant ydot
68 );
69}
70
71// ####################################################################################################
72void Kalman4D::onParamChange(kalman4d::procnoise const & JEVOIS_UNUSED_PARAM(param), float const & newval)
73{
74 float constexpr e = 0.01F; // epsilon squared
75 float const n = newval * newval; // desired variance
76 itsKF.processNoiseCov = (cv::Mat_<float>(6, 6) <<
77 n, 0, 0, 0, 0, 0,
78 0, n, 0, 0, 0, 0,
79 0, 0, n, 0, 0, 0,
80 0, 0, 0, n, 0, 0,
81 0, 0, 0, 0, e, 0,
82 0, 0, 0, 0, 0, e );
83}
84
85// ####################################################################################################
86void Kalman4D::onParamChange(kalman4d::measnoise const & JEVOIS_UNUSED_PARAM(param), float const & newval)
87{
88 cv::setIdentity(itsKF.measurementNoiseCov, cv::Scalar::all(newval * newval));
89}
90
91// ####################################################################################################
92void Kalman4D::onParamChange(kalman4d::postnoise const & JEVOIS_UNUSED_PARAM(param), float const & newval)
93{
94 cv::setIdentity(itsKF.errorCovPost, cv::Scalar::all(newval * newval));
95}
96
97// ####################################################################################################
98void Kalman4D::set(float x, float y, float w, float h)
99{
100 itsMeasurement.at<float>(0) = x; itsMeasurement.at<float>(1) = y;
101 itsMeasurement.at<float>(2) = w; itsMeasurement.at<float>(3) = h;
102 itsLatest = itsKF.correct(itsMeasurement);
103 itsFresh = true; // itsLatest is "fresh", no need to predict() at the next get()
104}
105
106// ####################################################################################################
107void Kalman4D::set(float x, float y, float w, float h, unsigned int imgwidth, unsigned int imgheight)
108{
109 jevois::coords::imgToStd(x, y, imgwidth, imgheight, 0.0F);
110 jevois::coords::imgToStdSize(w, h, imgwidth, imgheight, 0.0F);
111 this->set(x, y, w, h);
112}
113
114// ####################################################################################################
115void Kalman4D::get(float & x, float & y, float & w, float & h, float const eps)
116{
117 // If we just had a fresh set(), use our latest result form correct(), otherwise predict the next position:
118 if (itsFresh)
119 {
120 x = itsLatest.at<float>(0);
121 y = itsLatest.at<float>(1);
122 w = itsLatest.at<float>(2);
123 h = itsLatest.at<float>(3);
124 itsFresh = false;
125
126 // Now predict and update itsLatest:
127 itsLatest = itsKF.predict();
128 }
129 else
130 {
131 // First predict and update itsLatest:
132 itsLatest = itsKF.predict();
133
134 x = itsLatest.at<float>(0);
135 y = itsLatest.at<float>(1);
136 w = itsLatest.at<float>(2);
137 h = itsLatest.at<float>(3);
138 }
139
140 if (eps)
141 {
142 x = std::round(x / eps) * eps;
143 y = std::round(y / eps) * eps;
144 w = std::round(w / eps) * eps;
145 h = std::round(h / eps) * eps;
146 }
147}
148
149// ####################################################################################################
150void Kalman4D::get(float & x, float & y, float & w, float & h, unsigned int imgwidth,
151 unsigned int imgheight, float const eps)
152{
153 this->get(x, y, w, h, 0.0F);
154 jevois::coords::stdToImg(x, y, imgwidth, imgheight, eps);
155 jevois::coords::imgToStdSize(w, h, imgwidth, imgheight, eps);
156}
157
158// ####################################################################################################
159void Kalman4D::get(float & rawx, float & rawy, float & raww, float & rawh, float & imgx, float & imgy,
160 float & imgw, float & imgh, unsigned int imgwidth, unsigned int imgheight,
161 float const raweps, float const imgeps)
162{
163 // First get the raw coords with no rounding:
164 this->get(rawx, rawy, raww, rawh, 0.0F);
165 imgx = rawx;
166 imgy = rawy;
167 imgw = raww;
168 imgh = rawh;
169
170 // Now round the raw coords:
171 if (raweps)
172 {
173 rawx = std::round(rawx / raweps) * raweps;
174 rawy = std::round(rawy / raweps) * raweps;
175 raww = std::round(raww / raweps) * raweps;
176 rawh = std::round(rawh / raweps) * raweps;
177 }
178
179 // Now compute the image coords with rounding:
180 jevois::coords::stdToImg(imgx, imgy, imgwidth, imgheight, imgeps);
181 jevois::coords::stdToImgSize(imgw, imgh, imgwidth, imgheight, imgeps);
182}
183
184// ####################################################################################################
185cv::Mat const & Kalman4D::getErrorCov() const
186{ return itsKF.errorCovPost; }
187
#define JEVOIS_UNUSED_PARAM(x)
int h
void postInit() override
Definition Kalman4D.C:35
virtual ~Kalman4D()
Destructor.
Definition Kalman4D.C:31
Kalman4D(std::string const &instance)
Constructor.
Definition Kalman4D.C:23
void get(float &x, float &y, float &w, float &h, float const eps=0.01F)
Function to call each time you want to get the Kalman-filtered coordinates.
Definition Kalman4D.C:115
void onParamChange(kalman4d::usevel const &param, bool const &newval) override
cv::Mat itsLatest
Definition Kalman4D.H:128
cv::KalmanFilter itsKF
Definition Kalman4D.H:125
bool itsFresh
Definition Kalman4D.H:129
void set(float x, float y, float w, float h)
Function to call each time you have a new measurement (output from a vision algorithm)
Definition Kalman4D.C:98
cv::Mat const & getErrorCov() const
Get the latest error covariance matrix (errorCovPost). It is updated after each get() or set()
Definition Kalman4D.C:185
cv::Mat itsMeasurement
Definition Kalman4D.H:127
void stdToImg(float &x, float &y, RawImage const &camimg, float const eps=0.1F)
void imgToStd(float &x, float &y, RawImage const &camimg, float const eps=0.1F)
void imgToStdSize(float &w, float &h, unsigned int const width, unsigned int const height, float const eps=0.1F)
void stdToImgSize(float &x, float &y, unsigned int const width, unsigned int const height, float const eps=0.1F)