Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpRBProbabilistic3DDriftDetector.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 */
30
35
36#ifndef VP_RB_PROBABILISTIC_3D_DRIFT_DETECTOR_H
37#define VP_RB_PROBABILISTIC_3D_DRIFT_DETECTOR_H
38
39#include <visp3/core/vpCameraParameters.h>
40#include <visp3/core/vpRGBf.h>
41#include <visp3/core/vpRGBa.h>
42
43#include <visp3/rbt/vpRBDriftDetector.h>
44
45#include <array>
46
48
49template <typename T> class vpImage;
50
100{
101public:
102
104 {
105
117 {
118 ColorStatistics() = default;
119
120 void init(const vpRGBf &c, const vpRGBf &var)
121 {
122 mean = c;
123 variance = var;
124 initVariance = var;
125 // computeStddev();
126 }
127
135 void update(const vpRGBf &c, float weight)
136 {
137 const vpRGBf diff(c.R - mean.R, c.G - mean.G, c.B - mean.B);
138 const vpRGBf diffSqr(diff.R * diff.R, diff.G * diff.G, diff.B * diff.B);
139 mean = mean + weight * diff;
140 variance = (1 - weight) * (variance + weight * diffSqr);
141 // computeStddev();
142 }
143
150 double probability(const vpRGBf &c)
151 {
152 vpRGBf diff(c.R - mean.R, c.G - mean.G, c.B - mean.B);
153 diff.R = (diff.R * (1.f / sqrt(initVariance.R)));
154 diff.G = (diff.G * (1.f / sqrt(initVariance.G)));
155 diff.B = (diff.B * (1.f / sqrt(initVariance.B)));
156
157
158 // const double dist = sqrt(diff.R + diff.G + diff.B);
159
160 // const double dist = sqrt(
161 // std::pow((c.R - mean.R) / (standardDev.R), 2) +
162 // std::pow((c.G - mean.G) / (standardDev.G), 2) +
163 // std::pow((c.B - mean.B) / (standardDev.B), 2));
164
165 // const double proba = 1.0 - erf(dist / sqrt(2));
166
167 const double proba = 1.0 - erf(std::max(std::max(abs(diff.R), abs(diff.G)), abs(diff.B)) / sqrt(2));
168 // const double proba = 1.0 - erf(dist / sqrt(2));
169
170
171 return proba;
172 }
173
174 double trace()
175 {
176 return static_cast<double>(variance.R + variance.G + variance.B);
177 }
178
179 // void computeStddev()
180 // {
181 // standardDev.R = sqrt(variance.R);
182 // standardDev.G = sqrt(variance.G);
183 // standardDev.B = sqrt(variance.B);
184 // }
185
187 {
188 // Compute the scale factor as the first eigenvalue of the covariance matrix
189 // Since our matrix is diagonal, it is the heighest variance value
190
191 return std::max(variance.R, std::max(variance.G, variance.B));
192 }
193
197 };
198
199 inline void update(const vpHomogeneousMatrix &cTo, const vpHomogeneousMatrix &renderTo, const vpCameraParameters &cam)
200 {
203 }
204
205 inline double squaredDist(const std::array<double, 3> &p) const
206 {
207 return std::pow(p[0] - X[0], 2) + std::pow(p[1] - X[1], 2) + std::pow(p[2] - X[2], 2);
208 }
209
210 inline void fastProjection(const vpHomogeneousMatrix &cTo, const vpCameraParameters &cam,
211 std::array<double, 3> &pC, std::array<double, 2> &proj, std::array<int, 2> &px)
212 {
213 const double *T = cTo.data;
214 pC[0] = (T[0] * X[0] + T[1] * X[1] + T[2] * X[2] + T[3]);
215 pC[1] = (T[4] * X[0] + T[5] * X[1] + T[6] * X[2] + T[7]);
216 pC[2] = (T[8] * X[0] + T[9] * X[1] + T[10] * X[2] + T[11]);
217 proj[0] = pC[0] / pC[2];
218 proj[1] = pC[1] / pC[2];
219 px[0] = static_cast<int>((proj[0] * cam.get_px()) + cam.get_u0());
220 px[1] = static_cast<int>((proj[1] * cam.get_py()) + cam.get_v0());
221 }
222
223 void updateColor(const vpRGBf &currentColor, float updateRate)
224 {
225 stats.update(currentColor, updateRate);
226 }
227
229 {
230 return vpRGBa(static_cast<unsigned int>(stats.mean.R), static_cast<unsigned int>(stats.mean.G), static_cast<unsigned int>(stats.mean.B));
231 }
232
233 std::array<double, 3> X; // Point position in object frame
235 std::array<double, 3> currX, renderX;
236 std::array<double, 2> projCurr, projRender; // Projection in camera normalized coordinates of the point for the current and previous camera poses.
237 std::array<int, 2> projCurrPx, projRenderPx; // Projection in pixels of the point for the current and previous camera poses.
238 bool visible; // Whether the point is visible
239 };
240
241public:
242
243 vpRBProbabilistic3DDriftDetector() : m_colorUpdateRate(0.2), m_initialColorSigma(25.0), m_depthSigma(0.04), m_maxError3D(0.001), m_minDist3DNewPoint(0.003), m_sampleStep(4)
244 { }
245
246 void update(const vpRBFeatureTrackerInput &previousFrame, const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cTo, const vpHomogeneousMatrix &cprevTo) VP_OVERRIDE;
247
248 double score(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cTo) VP_OVERRIDE;
249
250
251
252
257 double getScore() const VP_OVERRIDE;
258
259 bool hasDiverged() const VP_OVERRIDE;
260
261 void reset() VP_OVERRIDE
262 {
263 m_points.clear();
264 }
265
266 void display(const vpImage<vpRGBa> &I) VP_OVERRIDE;
267
272
282 double getMinDistForNew3DPoints() const { return m_minDist3DNewPoint; }
283
284 void setMinDistForNew3DPoints(double distance)
285 {
286 if (distance <= 0.0) {
287 throw vpException(vpException::badValue, "Distance criterion for candidate rejection should be greater than 0.");
288 }
289 m_minDist3DNewPoint = distance;
290 }
291
301 double getFilteringMax3DError() const { return m_maxError3D; }
302
303 void setFilteringMax3DError(double maxError)
304 {
305 if (maxError <= 0.0) {
306 throw vpException(vpException::badValue, "Maximum 3D error for rejection should be greater than 0.");
307 }
308 m_maxError3D = maxError;
309 }
310
316 double getDepthStandardDeviation() const { return m_depthSigma; }
317 void setDepthStandardDeviation(double sigma)
318 {
319 if (sigma < 0.0) {
320 throw vpException(vpException::badValue, "Depth standard deviation should be greater than 0");
321 }
322 m_depthSigma = sigma;
323 }
324
330 double getInitialColorStandardDeviation() const { return m_depthSigma; }
332 {
333 if (sigma < 0.0) {
334 throw vpException(vpException::badValue, "Initial color standard deviation should be greater than 0");
335 }
336 m_initialColorSigma = sigma;
337 }
338
349 double getColorUpdateRate() const { return m_colorUpdateRate; }
350
356 void setColorUpdateRate(double updateRate)
357 {
358 if (updateRate < 0.0 || updateRate > 1.f) {
359 throw vpException(vpException::badValue, "Color update rate should be between 0 and 1");
360 }
361 m_colorUpdateRate = updateRate;
362 }
363
364 unsigned int getSampleStep() const { return m_sampleStep; }
365 void setSampleStep(unsigned int sampleStep)
366 {
367 if (sampleStep == 0) {
368 throw vpException(vpException::badValue, "Image sample step should be greater than 0");
369 }
370 m_sampleStep = sampleStep;
371 }
372
373#if defined(VISP_HAVE_NLOHMANN_JSON)
374 void loadJsonConfiguration(const nlohmann::json &) VP_OVERRIDE;
375 void loadRepresentation(const std::string &);
376 void saveRepresentation(const std::string &) const;
377#endif
378
383
384private:
385 double m_colorUpdateRate;
386 double m_initialColorSigma;
387 double m_depthSigma;
388 double m_maxError3D;
389 double m_minDist3DNewPoint;
390 unsigned int m_sampleStep;
391
392 double m_score;
393
394 std::vector<vpStored3DSurfaceColorPoint> m_points;
395};
396
397#ifdef VISP_HAVE_NLOHMANN_JSON
398inline void from_json(const nlohmann::json &j, vpRBProbabilistic3DDriftDetector::vpStored3DSurfaceColorPoint::ColorStatistics &c)
399{
400 c.mean = j.at("mean").get<vpRGBf>();
401 c.variance = j.at("variance").get<vpRGBf>();
402 // c.computeStddev();
403}
404
405inline void to_json(nlohmann::json &j, const vpRBProbabilistic3DDriftDetector::vpStored3DSurfaceColorPoint::ColorStatistics &c)
406{
407 j["mean"] = c.mean;
408 j["variance"] = c.variance;
409}
410
411inline void from_json(const nlohmann::json &j, vpRBProbabilistic3DDriftDetector::vpStored3DSurfaceColorPoint &p)
412{
413 p.X = j.at("X");
414 p.stats = j.at("stats");
415}
416
417inline void to_json(nlohmann::json &j, const vpRBProbabilistic3DDriftDetector::vpStored3DSurfaceColorPoint &p)
418{
419 j["X"] = p.X;
420 j["stats"] = p.stats;
421}
422
423
424
425#endif
426
427END_VISP_NAMESPACE
428
429#endif
Type * data
Address of the first element of the data array.
Definition vpArray2D.h:149
Generic class defining intrinsic camera parameters.
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition vpException.h:73
Implementation of an homogeneous matrix and operations on such kind of matrices.
Definition of the vpImage class member functions.
Definition vpImage.h:131
virtual double getScore() const =0
Get the estimated tracking reliability. A high score should mean that the tracking is reliable....
virtual void loadJsonConfiguration(const nlohmann::json &)=0
vpRBDriftDetector()=default
virtual double score(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cTo)=0
virtual void update(const vpRBFeatureTrackerInput &previousFrame, const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cTo, const vpHomogeneousMatrix &cprevTo)=0
Update the algorithm after a new tracking step.
virtual void display(const vpImage< vpRGBa > &I)=0
Displays the information used for drift detection.
All the data related to a single tracking frame. This contains both the input data (from a real camer...
double getMinDistForNew3DPoints() const
Get the minimum distance criterion (in meters) that is used when trying to add new points to track fo...
double getInitialColorStandardDeviation() const
Get the standard deviation that is used to initialize the color distribution when adding a new surfac...
void setColorUpdateRate(double updateRate)
Set the update rate for the color distribution. It should be between 0 and 1.
double getColorUpdateRate() const
Get the rate at which the colors of surface points are updated.
double getDepthStandardDeviation() const
Get the standard deviation that is used when computing the probability that the observed depth Z is t...
double getFilteringMax3DError() const
Returns the maximum 3D distance (in meters) above which a tracked surface point is rejected for the d...
float B
Blue component.
Definition vpRGBf.h:161
float G
Green component.
Definition vpRGBf.h:160
float R
Red component.
Definition vpRGBf.h:159
Online estimation of a Gaussian color distribution , Where is a diagonal variance matrix .
double probability(const vpRGBf &c)
Computes the probability that the input color was sampled from the estimated distribution.
void update(const vpRGBf &c, float weight)
Update the color distribution with a new sample c.
std::array< double, 2 > projCurr
Point position in the current and previous camera frames.
void fastProjection(const vpHomogeneousMatrix &cTo, const vpCameraParameters &cam, std::array< double, 3 > &pC, std::array< double, 2 > &proj, std::array< int, 2 > &px)
void update(const vpHomogeneousMatrix &cTo, const vpHomogeneousMatrix &renderTo, const vpCameraParameters &cam)
std::array< double, 3 > currX
Color statistics associated to this point.