Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
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
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 const vpColVector oC = oMc.getRotationMatrix() * vpColVector({ 0.0, 0.0, -1.0 });
47 const vpImage<unsigned char> &initImage = previousFrame.I.getSize() == frame.I.getSize() ? previousFrame.I : frame.I;
48
49#ifdef VISP_HAVE_OPENMP
50#pragma omp parallel
51#endif
52 {
53 std::vector<vpRBSilhouetteControlPoint> localPoints;
54#ifdef VISP_HAVE_OPENMP
55#pragma omp for nowait
56#endif
57 for (int i = 0; i < static_cast<int>(frame.silhouettePoints.size()); ++i) {
58 const vpRBSilhouettePoint &sp = frame.silhouettePoints[i];
59 // float angle = vpMath::deg(acos(sp.normal * oC));
60 // if (angle > 89.0) {
61 // continue;
62 // }
63 // std::cout << angle << std::endl;
64#if VISP_DEBUG_ME_TRACKER
65 if (sp.Z == 0) {
66 throw vpException(vpException::badValue, "Got a point with Z == 0");
67 }
68 if (std::isnan(sp.orientation)) {
69 throw vpException(vpException::badValue, "Got a point with theta nan");
70 }
71#endif
73 p.buildPoint(static_cast<int>(sp.i), static_cast<int>(sp.j), sp.Z, sp.orientation, sp.normal, cMo, oMc, frame.cam, m_me, sp.isSilhouette);
74 if (p.tooCloseToBorder(frame.I.getHeight(), frame.I.getWidth(), m_me.getRange())) {
75 continue;
76 }
77 if (m_useMask && frame.hasMask()) {
78 double maxMaskGradient;
79 if (p.isSilhouette()) { // If it is a silhouette point, we check that the mask actually considers it an object border
80 maxMaskGradient = p.getMaxMaskGradientAlongLine(frame.mask, m_me.getRange());
81 }
82 else { // Otherwise, we just check that the site is considered as belonging to the object
83 maxMaskGradient = frame.mask[sp.i][sp.j];
84 }
85 if (maxMaskGradient < m_minMaskConfidence) {
86 continue;
87 }
88 }
89
90 p.initControlPoint(initImage, 0);
91 p.setNumCandidates(m_numCandidates);
92 localPoints.push_back(std::move(p));
93 }
94
95#ifdef VISP_HAVE_OPENMP
96#pragma omp critical
97#endif
98 {
99 m_controlPoints.insert(m_controlPoints.end(), localPoints.begin(), localPoints.end());
100 }
101 }
102
103 m_numFeatures = static_cast<unsigned int>(m_controlPoints.size());
104
105 m_robust.setMinMedianAbsoluteDeviation(m_robustMadMin / frame.cam.get_px());
106}
107
109{
110 if (m_numCandidates <= 1) {
111#ifdef VISP_HAVE_OPENMP
112#pragma omp parallel for
113#endif
114 for (int i = 0; i < static_cast<int>(m_controlPoints.size()); ++i) {
115 m_controlPoints[i].track(frame.I);
116 }
117 }
118 else {
119#ifdef VISP_HAVE_OPENMP
120#pragma omp parallel for
121#endif
122 for (int i = 0; i < static_cast<int>(m_controlPoints.size()); ++i) {
123 m_controlPoints[i].trackMultipleHypotheses(frame.I);
124 }
125 }
126}
127
128void vpRBSilhouetteMeTracker::initVVS(const vpRBFeatureTrackerInput & /*frame*/, const vpRBFeatureTrackerInput & /*previousFrame*/, const vpHomogeneousMatrix & /*cMo*/)
129{
130 if (m_numFeatures == 0) {
131 return;
132 }
133
134 m_weighted_error.resize(m_numFeatures, false);
135 m_weights.resize(m_numFeatures, false);
136 m_weights = 0;
137 m_L.resize(m_numFeatures, 6, false, false);
138 m_covWeightDiag.resize(m_numFeatures, false);
139 m_vvsConverged = false;
140 m_error.resize(m_numFeatures, false);
141}
142
143void vpRBSilhouetteMeTracker::computeVVSIter(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cMo, unsigned int /*iteration*/)
144{
145 vpColVector factor(m_numFeatures, 1.0);
146 const double threshold = m_singlePointConvergedThresholdPixels / frame.cam.get_px(); //Transformation limite pixel en limite metre.
147
148 unsigned count = 0;
149 unsigned countValidSites = 0;
150
151 for (unsigned int k = 0; k < m_controlPoints.size(); k++) {
152 vpRBSilhouetteControlPoint &p = m_controlPoints[k];
153 //p.update(cMo);
154 if (m_numCandidates <= 1) {
155 p.computeMeInteractionMatrixError(cMo, k, m_L, m_error);
156 }
157 else {
158 p.computeMeInteractionMatrixErrorMH(cMo, k, m_L, m_error);
159 }
160
161 m_weights[k] = 1;
162 if (!p.siteIsValid() || !p.isValid()) {
163 factor[k] = 0.0;
164 for (unsigned int j = 0; j < 6; j++) {
165 m_L[k][j] = 0;
166 }
167 }
168 else {
169 countValidSites++;
170 if (m_error[k] <= threshold) {
171 ++count;
172 }
173 }
174 }
175
176 if (countValidSites == 0) {
177 m_vvsConverged = false;
178 }
179 else {
180 const double percentageConverged = static_cast<double>(count) / static_cast<double>(countValidSites);
181 if (percentageConverged < m_globalVVSConvergenceThreshold) {
182 m_vvsConverged = false;
183 }
184 else {
185 m_vvsConverged = true;
186 }
187 }
188
189 if (m_numFeatures == 0) {
190 return;
191 }
192
193 m_robust.MEstimator(vpRobust::TUKEY, m_error, m_weights);
194
196
197#if VISP_DEBUG_ME_TRACKER
198 for (unsigned int i = 0; i < 6; ++i) {
199 if (std::isnan(m_LTR[i])) {
200 std::cerr << m_L << std::endl;
201 throw vpException(vpException::badValue, "Some components were nan in ME tracker computation");
202 }
203 }
204#endif
205}
206
208 const vpImage<vpRGBa> &/*IRGB*/, const vpImage<unsigned char> &/*depth*/) const
209{
210
211 for (const vpRBSilhouetteControlPoint &p: m_controlPoints) {
212 const vpMeSite &s = p.getSite();
213 s.display(I);
214 }
215
216}
217
218END_VISP_NAMESPACE
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
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
Definition of the vpImage class member functions.
Definition vpImage.h:131
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getSize() const
Definition vpImage.h:221
unsigned int getHeight() const
Definition vpImage.h:181
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition vpMeSite.h:75
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
void updateOptimizerTerms(const vpHomogeneousMatrix &cMo)
vpColVector m_weights
Weighted VS error.
vpColVector m_covWeightDiag
Covariance matrix.
vpColVector m_LTR
Left side of the Gauss newton minimization.
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 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.
bool isSilhouette
Point depth.
@ TUKEY
Tukey influence function.
Definition vpRobust.h:89
vpHomogeneousMatrix cMo