Visual Servoing Platform  version 3.6.1 under development (2025-02-17)
vpRBSilhouetteMeTracker.cpp
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 
31 #include <visp3/rbt/vpRBSilhouetteMeTracker.h>
32 
33 #define VISP_DEBUG_ME_TRACKER 0
34 
35 BEGIN_VISP_NAMESPACE
36 
41 {
42  m_controlPoints.clear();
43  m_controlPoints.reserve(frame.silhouettePoints.size());
44  const vpHomogeneousMatrix &cMo = frame.renders.cMo;
45  const vpHomogeneousMatrix oMc = cMo.inverse();
46  vpColVector oC = oMc.getRotationMatrix() * vpColVector({ 0.0, 0.0, -1.0 });
47  for (const vpRBSilhouettePoint &sp: frame.silhouettePoints) {
48  // float angle = vpMath::deg(acos(sp.normal * oC));
49  // if (angle > 89.0) {
50  // continue;
51  // }
52  // std::cout << angle << std::endl;
53 #if VISP_DEBUG_ME_TRACKER
54  if (sp.Z == 0) {
55  throw vpException(vpException::badValue, "Got a point with Z == 0");
56  }
57  if (std::isnan(sp.orientation)) {
58  throw vpException(vpException::badValue, "Got a point with theta nan");
59  }
60 #endif
61 
62  if (m_useMask && frame.hasMask()) {
63  float confidence = frame.mask[sp.i][sp.j];
64  if (confidence < m_minMaskConfidence) {
65  continue;
66  }
67  }
68 
70  p.buildPoint((int)sp.i, (int)sp.j, sp.Z, sp.orientation, sp.normal, cMo, oMc, frame.cam, m_me);
71  if (previousFrame.I.getSize() == frame.I.getSize()) {
72  p.initControlPoint(previousFrame.I, 0);
73  }
74  else {
75  p.initControlPoint(frame.I, 0);
76  }
77 
78  p.setNumCandidates(m_numCandidates);
79  m_controlPoints.push_back(p);
80  }
81  m_numFeatures = m_controlPoints.size();
82 
83  m_robust.setMinMedianAbsoluteDeviation(m_robustMadMin / frame.cam.get_px());
84 }
85 
87 {
88  if (m_numCandidates <= 1) {
89  for (vpRBSilhouetteControlPoint &p: m_controlPoints) {
90  p.track(frame.I);
91  }
92  }
93  else {
94  for (vpRBSilhouetteControlPoint &p: m_controlPoints) {
95  p.trackMultipleHypotheses(frame.I);
96  }
97  }
98 }
99 
100 void vpRBSilhouetteMeTracker::initVVS(const vpRBFeatureTrackerInput & /*frame*/, const vpRBFeatureTrackerInput & /*previousFrame*/, const vpHomogeneousMatrix & /*cMo*/)
101 {
102  if (m_numFeatures == 0) {
103  return;
104  }
105 
108  m_weights = 0;
109  m_L.resize(m_numFeatures, 6, false, false);
111  m_vvsConverged = false;
112  m_error.resize(m_numFeatures, false);
113 }
114 
115 void vpRBSilhouetteMeTracker::computeVVSIter(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cMo, unsigned int /*iteration*/)
116 {
117  vpColVector factor(m_numFeatures, 1.0);
118  const double threshold = m_singlePointConvergedThresholdPixels / frame.cam.get_px(); //Transformation limite pixel en limite metre.
119 
120  unsigned count = 0;
121  unsigned countValidSites = 0;
122 
123  for (unsigned int k = 0; k < m_controlPoints.size(); k++) {
124  vpRBSilhouetteControlPoint &p = m_controlPoints[k];
125  //p.update(cMo);
126  if (m_numCandidates <= 1) {
128  }
129  else {
131  }
132 
133  m_weights[k] = 1;
134  if (!p.siteIsValid() || !p.isValid()) {
135  factor[k] = 0.0;
136  for (unsigned int j = 0; j < 6; j++) {
137  m_L[k][j] = 0;
138  }
139  }
140  else {
141  countValidSites++;
142  if (m_error[k] <= threshold) {
143  ++count;
144  }
145  }
146  }
147 
148  if (countValidSites == 0) {
149  m_vvsConverged = false;
150  }
151  else {
152  const double percentageConverged = (double)count / (double)countValidSites;
153  if (percentageConverged < m_globalVVSConvergenceThreshold) {
154  m_vvsConverged = false;
155  }
156  else {
157  m_vvsConverged = true;
158  }
159  }
160 
162 
163  for (unsigned int i = 0; i < m_error.size(); i++) {
164  const double wi = m_weights[i] * factor[i];
165  const double eri = m_error[i];
166  m_covWeightDiag[i] = wi * wi;
167  m_weighted_error[i] = wi * eri;
168  for (unsigned int j = 0; j < 6; j++) {
169  m_L[i][j] = wi * m_L[i][j];
170  }
171  }
172 
173  m_LTL = m_L.AtA();
175 
176 #if VISP_DEBUG_ME_TRACKER
177  for (unsigned int i = 0; i < 6; ++i) {
178  if (std::isnan(m_LTR[i])) {
179  std::cerr << m_L << std::endl;
180  throw vpException(vpException::badValue, "Some components were nan in ME tracker computation");
181  }
182  }
183 #endif
184 }
185 
187  const vpImage<vpRGBa> &/*IRGB*/, const vpImage<unsigned char> &/*depth*/) const
188 {
189 
190  for (const vpRBSilhouetteControlPoint &p: m_controlPoints) {
191  const vpMeSite &s = p.getSite();
192  s.display(I);
193  }
194 
195 }
196 
197 END_VISP_NAMESPACE
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:442
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:429
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1148
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.
vpRotationMatrix getRotationMatrix() const
vpHomogeneousMatrix inverse() const
unsigned int getSize() const
Definition: vpImage.h:221
vpMatrix AtA() const
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition: vpMeSite.h:68
void display(const vpImage< unsigned char > &I) const
Definition: vpMeSite.cpp:486
All the data related to a single tracking frame. This contains both the input data (from a real camer...
vpImage< unsigned char > I
std::vector< vpRBSilhouettePoint > silhouettePoints
vpImage< float > mask
depth image, 0 sized if depth is not available
vpRBRenderData renders
camera parameters
vpColVector m_weights
Weighted VS error.
vpMatrix m_LTL
Error jacobian (In VS terms, the interaction matrix)
vpColVector m_covWeightDiag
Covariance matrix.
vpColVector m_LTR
Left side of the Gauss newton minimization.
static void computeJTR(const vpMatrix &interaction, const vpColVector &error, vpColVector &JTR)
bool m_vvsConverged
User-defined weight for this specific type of feature.
unsigned m_numFeatures
Error weights.
vpColVector m_weighted_error
Raw VS Error vector.
Trackable silhouette point representation.
void setNumCandidates(unsigned numCandidates)
Set the number of candidates to use for multiple hypotheses testing.
void buildPoint(int n, int m, const double &Z, double orient, const vpColVector &normo, const vpHomogeneousMatrix &cMo, const vpHomogeneousMatrix &oMc, const vpCameraParameters &cam, const vpMe &me)
void computeMeInteractionMatrixError(const vpHomogeneousMatrix &cMo, unsigned int i, vpMatrix &L, vpColVector &e)
void initControlPoint(const vpImage< unsigned char > &I, double cvlt)
void computeMeInteractionMatrixErrorMH(const vpHomogeneousMatrix &cMo, unsigned int i, vpMatrix &L, vpColVector &e)
void initVVS(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
void display(const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpImage< vpRGBa > &IRGB, const vpImage< unsigned char > &depth) const VP_OVERRIDE
void extractFeatures(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
Extract the geometric features from the list of collected silhouette points.
void trackFeatures(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
Track the features.
void computeVVSIter(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cMo, unsigned int iteration) VP_OVERRIDE
Silhouette point simple candidate representation.
double Z
angle of the normal in the image.
vpColVector normal
Pixel coordinates of the silhouette point.
double orientation
Normal to the silhouette at point i,j, in world frame.
@ TUKEY
Tukey influence function.
Definition: vpRobust.h:89
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Definition: vpRobust.cpp:130
void setMinMedianAbsoluteDeviation(double mad_min)
Definition: vpRobust.h:136
vpHomogeneousMatrix cMo