31#include <visp3/rbt/vpRBKltTracker.h>
33#if defined(VP_HAVE_RB_KLT_TRACKER)
35#include <visp3/core/vpImageConvert.h>
36#include <visp3/core/vpPixelMeterConversion.h>
37#include <visp3/core/vpMeterPixelConversion.h>
38#include <visp3/core/vpDisplay.h>
42inline bool isTooCloseToBorder(
unsigned int i,
unsigned int j,
unsigned int h,
unsigned w,
unsigned int border)
44 return i < border || j < border || i >(h - border) ||
j >(
w - border);
47inline void vpRBKltTracker::tryAddNewPoint(
49 std::map<long, vpRBKltTracker::vpTrackedKltPoint> &points,
50 long id,
const float u,
const float v,
53 unsigned int uu =
static_cast<unsigned int>(round(u)), uv =
static_cast<unsigned int>(round(v));
59 if (Z <= 0.f || (frame.
hasDepth() && frame.
depth[uv][uu] > 0.f && fabs(frame.
depth[uv][uu] - Z) > 5e-3)) {
62 vpRBKltTracker::vpTrackedKltPoint
p;
65 p.normal = vpColVector({ normalRGB.
R, normalRGB.
G, normalRGB.
B });
66 double x = 0.0,
y = 0.0;
68 vpColVector oC({
x * Z,
y * Z, Z, 1.0 });
69 vpColVector oX = oMc * oC;
71 p.oX = vpPoint(oX[0], oX[1], oX[2]);
72 p.currentPos = vpImagePoint(y, x);
78 vpRBFeatureTracker(), m_numPointsReinit(20), m_newPointsDistanceThreshold(5.0), m_border(5),
79 m_maxErrorOutliersPixels(10.0), m_useMask(false), m_minMaskConfidence(0.0)
87 const vpHomogeneousMatrix oMc =
cMo.inverse();
88 if (m_maxErrorOutliersPixels > 0.0) {
89 const double distanceThresholdPxSquare =
vpMath::sqr(m_maxErrorOutliersPixels);
90 const unsigned int nbFeatures =
static_cast<unsigned int>(m_klt.getNbFeatures());
91 std::vector<unsigned> kltIndicesToRemove;
93 for (
unsigned int i = 0;
i < nbFeatures; ++
i) {
95 float u = 0.f,
v = 0.f;
96 m_klt.getFeature(i,
id, u, v);
97 if (m_points.find(
id) == m_points.end()) {
100 unsigned int uu =
static_cast<unsigned int>(round(u)), uv =
static_cast<unsigned int>(round(v));
110 double x = 0.0,
y = 0.0;
112 vpColVector oXn = oMc * vpColVector({
x * Z,
y * Z, Z, 1.0 });
115 double x1 =
p.oX.get_x(), y1 =
p.oX.get_y();
116 double u1 = 0.0, v1 = 0.0;
120 vpColVector oX =
p.oX.get_oP();
121 if (distancePx > distanceThresholdPxSquare) {
123 kltIndicesToRemove.push_back(i);
127 for (
int i =
static_cast<int>(kltIndicesToRemove.size()) - 1; i >= 0; --i) {
128 m_klt.suppressFeature(kltIndicesToRemove[i]);
132 cv::Mat mask = cv::Mat::zeros(m_I.rows, m_I.cols, CV_8U);
134 for (
unsigned int i =
static_cast<unsigned int>(
bb.getTop()); i <
static_cast<unsigned int>(
bb.getBottom()); ++i) {
135 for (
unsigned int j =
static_cast<unsigned int>(
bb.getLeft()); j <
static_cast<unsigned int>(
bb.getRight()); ++j) {
136 mask.at<
unsigned char>(
i,
j) = (frame.
renders.
depth[i][j] > 0.f) * 255;
140 cv::Rect roi(
static_cast<int>(
bb.getLeft()),
static_cast<int>(
bb.getTop()),
static_cast<int>(
bb.getWidth()),
static_cast<int>(
bb.getHeight()));
141 cv::Mat maskRoi = mask(roi);
143 if (m_Iprev.rows > 0) {
145 if (m_points.size() < m_numPointsReinit) {
146 cv::Mat IprevRoi = m_Iprev(roi);
147 m_klt.initTracking(m_Iprev, mask);
148 const unsigned int nbFeatures =
static_cast<unsigned int>(m_klt.getNbFeatures());
150 for (
unsigned int i = 0;
i < nbFeatures; ++
i) {
153 m_klt.getFeature(i,
id, u, v);
154 tryAddNewPoint(frame, m_points,
id, u, v, cMo, oMc);
167 const unsigned int nbFeaturesTemp =
static_cast<unsigned int>(kltTemp.
getNbFeatures());
168 const unsigned int nbFeatures =
static_cast<unsigned int>(m_klt.getNbFeatures());
169 for (
unsigned int i = 0;
i < nbFeaturesTemp; ++
i) {
170 double threshold =
vpMath::sqr(m_newPointsDistanceThreshold);
171 double tooClose =
false;
176 u +=
static_cast<float>(
bb.getLeft());
177 v +=
static_cast<float>(
bb.getTop());
178 for (
unsigned int j = 0;
j < nbFeatures; ++
j) {
181 m_klt.getFeature(j, idj, uj, vj);
191 m_klt.addFeature(u, v);
192 const std::vector<long> &ids = m_klt.getFeaturesId();
193 id = ids[ids.size() - 1];
194 tryAddNewPoint(frame, m_points,
id, u, v, cMo, oMc);
199 m_klt.initTracking(m_I, mask);
201 const unsigned int nbFeatures =
static_cast<unsigned int>(m_klt.getNbFeatures());
202 for (
unsigned int i = 0;
i < nbFeatures; ++
i) {
205 m_klt.getFeature(i,
id, u, v);
206 tryAddNewPoint(frame, m_points,
id, u, v, cMo, oMc);
213 unsigned int nbKltFeatures =
static_cast<unsigned int>(m_klt.getNbFeatures());
214 if (nbKltFeatures > 0) {
217 std::map<long, vpTrackedKltPoint> newPoints;
218 const vpHomogeneousMatrix oMc =
cMo.inverse();
220 bool testMask = m_useMask && frame.
hasMask();
221 nbKltFeatures =
static_cast<unsigned int>(m_klt.getNbFeatures());
222 std::vector<unsigned> kltIndicesToRemove;
223 for (
unsigned int i = 0;
i < nbKltFeatures; ++
i) {
225 float u = 0.f,
v = 0.f;
226 double x = 0.0,
y = 0.0;
227 m_klt.getFeature(i,
id, u, v);
228 unsigned int uu =
static_cast<unsigned int>(round(u)), uv =
static_cast<unsigned int>(round(v));
238 if (testMask && frame.
mask[uv][uu] < m_minMaskConfidence) {
242 if (m_points.find(
id) != m_points.end()) {
248 p.currentPos = vpImagePoint(y, x);
252 kltIndicesToRemove.push_back(i);
257 for (
int i =
static_cast<int>(kltIndicesToRemove.size()) - 1; i >= 0; --i) {
258 m_klt.suppressFeature(kltIndicesToRemove[i]);
261 m_points = newPoints;
262 m_numFeatures =
static_cast<unsigned int>(m_points.size()) * 2;
275 m_LTL.resize(6, 6,
false,
false);
276 m_LTR.resize(6,
false);
277 m_cov.resize(6, 6,
false,
false);
290 unsigned int pointIndex = 0;
292 for (std::pair<const long, vpTrackedKltPoint> &p : m_points) {
293 p.second.update(cMo);
294 p.second.interaction(
m_L, pointIndex);
295 p.second.error(
m_error, pointIndex);
308 for (
const std::pair<const long, vpTrackedKltPoint> &p : m_points) {
309 double u = 0.0,
v = 0.0;
Generic class defining intrinsic camera parameters.
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.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Definition of the vpImage class member functions.
unsigned int getCols() const
unsigned int getRows() const
void setBlockSize(int blockSize)
void setQuality(double qualityLevel)
int getNbFeatures() const
Get the number of current features.
void setHarrisFreeParameter(double harris_k)
void getFeature(const int &index, long &id, float &x, float &y) const
void setMaxFeatures(int maxCount)
void initTracking(const cv::Mat &I, const cv::Mat &mask=cv::Mat())
void setMinDistance(double minDistance)
void setWindowSize(int winSize)
void setPyramidLevels(int pyrMaxLevel)
static double rad(double deg)
static double sqr(double x)
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
A base class for all features that can be used and tracked in the vpRBTracker.
void updateOptimizerTerms(const vpHomogeneousMatrix &cMo)
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.
unsigned m_numFeatures
Error weights.
vpColVector m_weighted_error
Raw VS Error vector.
vpMatrix m_cov
Right side of the Gauss Newton minimization.
void extractFeatures(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
Extract features from the frame data and the current pose estimate.
void trackFeatures(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
Track the features.
void display(const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpImage< vpRGBa > &IRGB, const vpImage< unsigned char > &depth) const VP_OVERRIDE
void initVVS(const vpRBFeatureTrackerInput &frame, const vpRBFeatureTrackerInput &previousFrame, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
void computeVVSIter(const vpRBFeatureTrackerInput &frame, const vpHomogeneousMatrix &cMo, unsigned int iteration) VP_OVERRIDE
@ TUKEY
Tukey influence function.
vpImage< float > depth
Image containing the per-pixel normal vector (RGB, in object space).
vpImage< vpRGBf > normals