Visual Servoing Platform  version 3.6.1 under development (2025-02-11)
vpRBDenseDepthTracker.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/vpRBDenseDepthTracker.h>
32 #include <visp3/core/vpMeterPixelConversion.h>
33 #include <visp3/core/vpDisplay.h>
34 BEGIN_VISP_NAMESPACE
35 
36 void fastRotationMatmul(const vpRotationMatrix &cRo, const vpRGBf &v, vpColVector &res)
37 {
38  res.resize(3, false);
39  const double r = static_cast<double>(v.R), g = static_cast<double>(v.G), b = static_cast<double>(v.B);
40  const double *R = cRo.data;
41  res[0] = R[0] * r + R[1] * g + R[2] * b;
42  res[1] = R[3] * r + R[4] * g + R[5] * b;
43  res[2] = R[6] * r + R[7] * g + R[8] * b;
44 }
45 
46 void fastProjection(const vpHomogeneousMatrix &oTc, double X, double Y, double Z, vpPoint &p)
47 {
48  const double *T = oTc.data;
49  p.set_oX(T[0] * X + T[1] * Y + T[2] * Z + T[3]);
50  p.set_oY(T[4] * X + T[5] * Y + T[6] * Z + T[7]);
51  p.set_oZ(T[8] * X + T[9] * Y + T[10] * Z + T[11]);
52  p.set_oW(1.0);
53 }
54 
56 {
57  const vpImage<float> &depthMap = frame.depth;
58  const vpImage<float> &renderDepth = frame.renders.depth;
59  vpRect bb = frame.renders.boundingBox;
60  const vpHomogeneousMatrix &cMo = frame.renders.cMo;
61  vpHomogeneousMatrix oMc = cMo.inverse();
63  bool useMask = m_useMask && frame.hasMask();
64  m_depthPoints.clear();
65  m_depthPoints.reserve(static_cast<size_t>(bb.getArea() / (m_step * m_step * 2)));
66  vpDepthPoint point;
67  for (unsigned int i = static_cast<unsigned int>(bb.getTop()); i < static_cast<unsigned int>(bb.getBottom()); i += m_step) {
68  for (unsigned int j = static_cast<unsigned int>(bb.getLeft()); j < static_cast<unsigned int>(bb.getRight()); j += m_step) {
69  // if (renderDepth[i][j] > frame.renders.zNear && renderDepth[i][j] < frame.renders.zFar && depthMap[i][j] > frame.renders.zNear * 0.33 && depthMap[i][j] < frame.renders.zFar * 3.0) {
70  double Z = renderDepth[i][j];
71  double currZ = depthMap[i][j];
72  if (Z > 0.f && currZ > 0.f) {
73  if (useMask && frame.mask[i][j] < m_minMaskConfidence) {
74  continue;
75  }
76  double x = 0.0, y = 0.0;
77  vpPixelMeterConversion::convertPoint(frame.cam, j, i, x, y);
78  //vpColVector objectNormal({ frame.renders.normals[i][j].R, frame.renders.normals[i][j].G, frame.renders.normals[i][j].B });
79  point.objectNormal[0] = frame.renders.normals[i][j].R;
80  point.objectNormal[1] = frame.renders.normals[i][j].G;
81  point.objectNormal[2] = frame.renders.normals[i][j].B;
82 
83  //fastRotationMatmul(cRo, frame.renders.normals[i][j], point.objectNormal);
84  //vpColVector cameraNormal = cRo * objectNormal;
85  // if (acos(cameraNormal * vpColVector({ 0.0, 0.0, -1.0 })) > vpMath::rad(70.0)) {
86  // continue;
87  // }
88  // vpColVector cp({ x * Z, y * Z, Z, 1 });
89  // vpColVector oP = oMc * cp;
90  fastProjection(oMc, x * Z, y * Z, Z, point.oP);
91  // point.oP = vpPoint(oP);
92  point.pixelPos.set_ij(i, j);
93  point.currentPoint[0] = x * currZ;
94  point.currentPoint[1] = y * currZ;
95  point.currentPoint[2] = currZ;
96 
97  m_depthPoints.push_back(point);
98  }
99  }
100  }
101  if (m_depthPoints.size() > 0) {
102  m_error.resize(m_depthPoints.size(), false);
103  m_weights.resize(m_depthPoints.size(), false);
104  m_weighted_error.resize(m_depthPoints.size(), false);
105  m_L.resize(m_depthPoints.size(), 6, false, false);
107  m_cov.resize(6, 6, false, false);
108  m_covWeightDiag.resize(m_depthPoints.size(), false);
109  }
110  else {
111  m_numFeatures = 0;
112  }
113 }
114 
115 void vpRBDenseDepthTracker::computeVVSIter(const vpRBFeatureTrackerInput &/*frame*/, const vpHomogeneousMatrix &cMo, unsigned int /*iteration*/)
116 {
117  if (m_numFeatures == 0) {
118  m_LTL = 0;
119  m_LTR = 0;
120  m_error = 0;
121  m_weights = 1.0;
122  m_weighted_error = 0.0;
123  m_cov = 0.0;
124  m_covWeightDiag = 0.0;
125  return;
126  }
128 #ifdef VISP_HAVE_OPENMP
129 #pragma omp parallel for
130 #endif
131  for (unsigned int i = 0; i < m_depthPoints.size(); ++i) {
132  vpDepthPoint &depthPoint = m_depthPoints[i];
133  depthPoint.update(cMo, cRo);
134  depthPoint.error(m_error, i);
135  depthPoint.interaction(m_L, i);
136  }
137 
138  //m_weights = 0.0;
139  //m_robust.setMinMedianAbsoluteDeviation(1e-3);
141  for (unsigned int i = 0; i < m_depthPoints.size(); ++i) {
142  m_weighted_error[i] = m_error[i] * m_weights[i];
143  m_covWeightDiag[i] = m_weights[i] * m_weights[i];
144  for (unsigned int dof = 0; dof < 6; ++dof) {
145  m_L[i][dof] *= m_weights[i];
146  }
147  }
148 
149  m_LTL = m_L.AtA();
151  m_vvsConverged = false;
152 }
153 
155  const vpImage<vpRGBa> &/*IRGB*/, const vpImage<unsigned char> &depth) const
156 {
157  for (unsigned int i = 0; i < m_depthPoints.size(); ++i) {
158  const vpDepthPoint &p = m_depthPoints[i];
159  vpColor c(0, static_cast<unsigned char>(m_weights[i] * 255), 0);
160  vpDisplay::displayPoint(depth, p.pixelPos, c, 2);
161  }
162 
163 }
164 
165 END_VISP_NAMESPACE
Type * data
Address of the first element of the data array.
Definition: vpArray2D.h:148
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:442
unsigned int getRows() const
Definition: vpArray2D.h:427
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
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:157
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpRotationMatrix getRotationMatrix() const
vpHomogeneousMatrix inverse() const
void set_ij(double ii, double jj)
Definition: vpImagePoint.h:320
vpMatrix AtA() const
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:79
void set_oW(double oW)
Set the point oW coordinate in the object frame.
Definition: vpPoint.cpp:465
void set_oY(double oY)
Set the point oY coordinate in the object frame.
Definition: vpPoint.cpp:461
void set_oZ(double oZ)
Set the point oZ coordinate in the object frame.
Definition: vpPoint.cpp:463
void set_oX(double oX)
Set the point oX coordinate in the object frame.
Definition: vpPoint.cpp:459
void display(const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpImage< vpRGBa > &IRGB, const vpImage< unsigned char > &depth) const VP_OVERRIDE
std::vector< vpDepthPoint > m_depthPoints
void computeVVSIter(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cMo, unsigned int iteration) VP_OVERRIDE
void extractFeatures(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
Extract features from the frame data and the current pose estimate.
All the data related to a single tracking frame. This contains both the input data (from a real camer...
vpImage< float > mask
depth image, 0 sized if depth is not available
vpImage< float > depth
RGB image, 0 sized if RGB 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.
vpMatrix m_cov
Right side of the Gauss Newton minimization.
Definition: vpRGBf.h:64
float B
Blue component.
Definition: vpRGBf.h:157
float G
Green component.
Definition: vpRGBf.h:156
float R
Red component.
Definition: vpRGBf.h:155
Defines a rectangle in the plane.
Definition: vpRect.h:79
double getLeft() const
Definition: vpRect.h:173
double getRight() const
Definition: vpRect.h:179
double getBottom() const
Definition: vpRect.h:97
double getArea() const
Definition: vpRect.h:91
double getTop() const
Definition: vpRect.h:192
@ TUKEY
Tukey influence function.
Definition: vpRobust.h:89
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Definition: vpRobust.cpp:130
Implementation of a rotation matrix and operations on such kind of matrices.
void update(const vpHomogeneousMatrix &cMo, const vpRotationMatrix &cRo)
void error(vpColVector &e, unsigned i) const
void interaction(vpMatrix &L, unsigned i)
vpImage< float > depth
Image containing the per-pixel normal vector (RGB, in object space)
vpHomogeneousMatrix cMo
vpImage< vpRGBf > normals