Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpRBDenseDepthTracker.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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_DENSE_DEPTH_TRACKER_H
37#define VP_RB_DENSE_DEPTH_TRACKER_H
38
39#include <visp3/core/vpConfig.h>
40#include <visp3/core/vpImage.h>
41#include <visp3/core/vpCameraParameters.h>
42#include <visp3/core/vpPixelMeterConversion.h>
43#include <visp3/core/vpMeterPixelConversion.h>
44
45#include <visp3/core/vpRobust.h>
46#include <visp3/core/vpPoint.h>
47#include <visp3/core/vpHomogeneousMatrix.h>
48
49// #if defined(VISP_HAVE_SIMDLIB)
50// #include <Simd/SimdLib.h>
51// #endif
52#include <visp3/rbt/vpRBFeatureTracker.h>
53
54#include <vector>
55#include <iostream>
56#include <algorithm>
57
58#if defined(VISP_HAVE_NLOHMANN_JSON)
59#include VISP_NLOHMANN_JSON(json.hpp)
60#endif
61
63
76class VISP_EXPORT vpRBDenseDepthTracker : public vpRBFeatureTracker
77{
78public:
79
88
90
91 virtual ~vpRBDenseDepthTracker() = default;
92
93 bool requiresRGB() const VP_OVERRIDE { return false; }
94 bool requiresDepth() const VP_OVERRIDE { return true; }
95 bool requiresSilhouetteCandidates() const VP_OVERRIDE { return false; }
96
101 unsigned int getStep() const { return m_step; }
102 void setStep(unsigned int step)
103 {
104 if (step == 0) {
105 throw vpException(vpException::badValue, "Step should be greater than 0");
106 }
107 m_step = step;
108 }
109
110 unsigned int getMaxNumFeatures() const { return m_maxFeatures; }
111 void setMaxNumFeatures(unsigned int num)
112 {
113 m_maxFeatures = num;
114 }
115
120 bool shouldUseMask() const { return m_useMask; }
121 void setShouldUseMask(bool useMask) { m_useMask = useMask; }
122
129 void setMinimumMaskConfidence(float confidence)
130 {
131 if (confidence > 1.f || confidence < 0.f) {
132 throw vpException(vpException::badValue, "Mask confidence should be between 0 and 1");
133 }
134 m_minMaskConfidence = confidence;
135 }
136
138
140 {
141 if (type == DT_INVALID) {
142 throw vpException(vpException::badValue, "Depth tracker display type is invalid");
143 }
144 m_displayType = type;
145 }
146
151
155 void onTrackingIterStart(const vpRBFeatureTrackerInput &, const vpHomogeneousMatrix & /*cMo*/) VP_OVERRIDE { }
156 void onTrackingIterEnd(const vpHomogeneousMatrix & /*cMo*/) VP_OVERRIDE { }
157
158 void extractFeatures(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE;
159 void trackFeatures(const vpRBFeatureTrackerInput &/*frame*/, const vpRBFeatureTrackerInput &/*previousFrame*/, const vpHomogeneousMatrix &/*cMo*/) VP_OVERRIDE { }
160 void initVVS(const vpRBFeatureTrackerInput &/*frame*/, const vpRBFeatureTrackerInput &/*previousFrame*/, const vpHomogeneousMatrix &/*cMo*/) VP_OVERRIDE { }
161 void computeVVSIter(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cMo, unsigned int iteration) VP_OVERRIDE;
162
163 void display(const vpCameraParameters &cam, const vpImage<unsigned char> &I, const vpImage<vpRGBa> &IRGB, const vpImage<unsigned char> &depth) const VP_OVERRIDE;
164
166 {
168 public:
169 std::array<double, 3> oX, observation, objectNormal;
170 std::array<double, 2> pixelPos;
171
172 };
173
175 {
176 public:
178 {
179
180 }
181 void build(const std::vector<vpDepthPoint> &points)
182 {
183 unsigned int numPoints = static_cast<unsigned int>(points.size());
184 std::vector<vpMatrix *> matrices = { &m_oXt, &m_oNt, &m_cXt, &m_cNt, &m_observations };
185 for (vpMatrix *m: matrices) {
186 m->resize(3, numPoints, false, false);
187 }
188 m_valid.resize(numPoints);
189
190 for (unsigned int i = 0; i < numPoints; ++i) {
191 m_valid[i] = true;
192 for (unsigned int j = 0; j < 3; ++j) {
193 m_oXt[j][i] = points[i].oX[j];
194 m_oNt[j][i] = points[i].objectNormal[j];
195 m_observations[j][i] = points[i].observation[j];
196 }
197 }
198 }
200 {
201 const vpRotationMatrix cRo = cMo.getRotationMatrix();
202 const vpTranslationVector t = cMo.getTranslationVector();
203 vpMatrix::mult2Matrices(cRo, m_oXt, m_cXt);
204 vpMatrix::mult2Matrices(cRo, m_oNt, m_cNt);
205
206 const unsigned int numPoints = m_oXt.getCols();
207 e.resize(numPoints, false);
208 L.resize(numPoints, 6, false, false);
209
210#ifdef VISP_HAVE_OPENMP
211#pragma omp parallel for
212#endif
213 for (int i = 0; i < static_cast<int>(numPoints); ++i) {
214
215 //Step 1: update and filter out points that are no longer valid
216 {
217
218 for (unsigned int j = 0; j < 3; ++j) {
219 m_cXt[j][i] += t[j];
220 }
221 // Plane points away from the camera: this surface is no longer visible due to rotation
222 if (m_cNt[2][i] >= 0.0) {
223 m_valid[i] = false;
224 continue;
225 }
226 double x, y, u, v;
227 x = m_cXt[0][i] / m_cXt[2][i];
228 y = m_cXt[1][i] / m_cXt[2][i];
229
230 vpMeterPixelConversion::convertPointWithoutDistortion(cam, x, y, u, v);
231 // Point is no longer in image: depth value cannot be sampled
232 if (u < 0 || v < 0 || u >= depth.getWidth() || v >= depth.getHeight()) {
233 m_valid[i] = false;
234 continue;
235 }
236 const double Z = depth[static_cast<unsigned int>(v)][static_cast<unsigned int>(u)];
237 // Z value in the depth image from the camera is invalid
238 if (Z <= 0.0) {
239 m_valid[i] = false;
240 continue;
241 }
242
243 m_valid[i] = true;
244 m_observations[0][i] = x * Z;
245 m_observations[1][i] = y * Z;
246 m_observations[2][i] = Z;
247 }
248 // Step 2: update Jacobian and error for valid points
249 {
250 const double X = m_cXt[0][i], Y = m_cXt[1][i], Z = m_cXt[2][i];
251 const double nX = m_cNt[0][i], nY = m_cNt[1][i], nZ = m_cNt[2][i];
252
253 const double D = -((nX * X) + (nY * Y) + (nZ * Z));
254 double projNormal = nX * m_observations[0][i] + nY * m_observations[1][i] + nZ * m_observations[2][i];
255
256 e[i] = D + projNormal;
257
258 L[i][0] = nX;
259 L[i][1] = nY;
260 L[i][2] = nZ;
261 L[i][3] = nZ * Y - nY * Z;
262 L[i][4] = nX * Z - nZ * X;
263 L[i][5] = nY * X - nX * Y;
264
265 }
266 }
267
268 // Disable invalid points
269 for (unsigned int i = 0; i < numPoints; ++i) {
270 if (!m_valid[i]) {
271 e[i] = 0.0;
272
273 L[i][0] = 0;
274 L[i][1] = 0;
275 L[i][2] = 0;
276 L[i][3] = 0;
277 L[i][4] = 0;
278 L[i][5] = 0;
279 }
280 }
281 }
282
283 const vpMatrix &getPointsObject() const { return m_oXt; }
284 const vpMatrix &getNormalsObject() const { return m_oNt; }
285 const vpMatrix &getPointsCamera() const { return m_cXt; }
286 const vpMatrix &getNormalsCamera() const { return m_cNt; }
287
288 private:
289 vpMatrix m_observations; // A 3xN matrix containing the observed 3D points from the camera
290 vpMatrix m_oXt; // a 3xN matrix containing the 3D points in object frame
291 vpMatrix m_oNt; // a 3xN matrix containing the 3D normals on the object
292 vpMatrix m_cXt;
293 vpMatrix m_cNt;
294 std::vector<bool> m_valid;
295
296 };
297
298#if defined(VISP_HAVE_NLOHMANN_JSON)
299
300#if defined(__clang__)
301// Mute warning : declaration requires an exit-time destructor [-Wexit-time-destructors]
302// message : expanded from macro 'NLOHMANN_JSON_SERIALIZE_ENUM'
303# pragma clang diagnostic push
304# pragma clang diagnostic ignored "-Wexit-time-destructors"
305#endif
306
313 });
314
315 virtual void loadJsonConfiguration(const nlohmann::json &j) VP_OVERRIDE
316 {
318 setMaxNumFeatures(j.value("maxNumFeatures", m_maxFeatures));
319 setStep(j.value("step", m_step));
320
321 setShouldUseMask(j.value("useMask", m_useMask));
322 setMinimumMaskConfidence(j.value("minMaskConfidence", m_minMaskConfidence));
323 setDisplayType(j.value("displayType", m_displayType));
324 }
325
326#if defined(__clang__)
327# pragma clang diagnostic pop
328#endif
329
330#endif
331
332protected:
333
334 std::vector<vpDepthPoint> m_depthPoints;
337 unsigned int m_step;
338 unsigned int m_maxFeatures;
342};
343
344END_VISP_NAMESPACE
345
346#endif
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.
Definition of the vpImage class member functions.
Definition vpImage.h:131
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
static void mult2Matrices(const vpMatrix &A, const vpMatrix &B, vpMatrix &C)
void build(const std::vector< vpDepthPoint > &points)
void updateAndErrorAndInteractionMatrix(const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const vpImage< float > &depth, vpColVector &e, vpMatrix &L)
bool requiresSilhouetteCandidates() const VP_OVERRIDE
Whether this tracker requires Silhouette candidates.
void setMinimumMaskConfidence(float confidence)
void initVVS(const vpRBFeatureTrackerInput &, const vpRBFeatureTrackerInput &, const vpHomogeneousMatrix &) VP_OVERRIDE
void trackFeatures(const vpRBFeatureTrackerInput &, const vpRBFeatureTrackerInput &, const vpHomogeneousMatrix &) VP_OVERRIDE
Track the features.
bool requiresRGB() const VP_OVERRIDE
Whether this tracker requires RGB image to extract features.
virtual void loadJsonConfiguration(const nlohmann::json &j) VP_OVERRIDE
unsigned int getStep() const
void setMaxNumFeatures(unsigned int num)
void setStep(unsigned int step)
bool shouldUseMask() const
Returns whether the tracking algorithm should filter out points that are unlikely to be on the object...
bool requiresDepth() const VP_OVERRIDE
Whether this tracker requires depth image to extract features.
std::vector< vpDepthPoint > m_depthPoints
float getMinimumMaskConfidence() const
Returns the minimum mask confidence that a pixel linked to depth point should have if it should be ke...
unsigned int getMaxNumFeatures() const
NLOHMANN_JSON_SERIALIZE_ENUM(vpRBDenseDepthTracker::vpDisplayType, { {vpRBDenseDepthTracker::vpDisplayType::DT_INVALID, nullptr}, {vpRBDenseDepthTracker::vpDisplayType::DT_SIMPLE, "simple"}, {vpRBDenseDepthTracker::vpDisplayType::DT_WEIGHT, "weight"}, {vpRBDenseDepthTracker::vpDisplayType::DT_ERROR, "error"}, {vpRBDenseDepthTracker::vpDisplayType::DT_WEIGHT_AND_ERROR, "weightAndError"} })
void onTrackingIterStart(const vpRBFeatureTrackerInput &, const vpHomogeneousMatrix &) VP_OVERRIDE
Method called when starting a tracking iteration.
void setDisplayType(vpDisplayType type)
void onTrackingIterEnd(const vpHomogeneousMatrix &) VP_OVERRIDE
Method called after the tracking iteration has finished.
void setShouldUseMask(bool useMask)
vpDisplayType getDisplayType() const
virtual ~vpRBDenseDepthTracker()=default
All the data related to a single tracking frame. This contains both the input data (from a real camer...
virtual void extractFeatures(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo)=0
Extract features from the frame data and the current pose estimate.
virtual void display(const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpImage< vpRGBa > &IRGB, const vpImage< unsigned char > &depth) const =0
virtual void loadJsonConfiguration(const nlohmann::json &j)
virtual void computeVVSIter(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cMo, unsigned int iteration)=0
Contains an M-estimator and various influence function.
Definition vpRobust.h:84
Implementation of a rotation matrix and operations on such kind of matrices.
Class that consider the case of a translation vector.