Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMbDepthDenseTracker.cpp
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 * Description:
31 * Model-based tracker using depth dense features.
32 */
33
34#include <iostream>
35
36#include <visp3/core/vpConfig.h>
37
38#if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_COMMON)
39#include <pcl/point_cloud.h>
40#endif
41
42#include <visp3/core/vpDisplay.h>
43#include <visp3/core/vpExponentialMap.h>
44#include <visp3/core/vpTrackingException.h>
45#include <visp3/mbt/vpMbDepthDenseTracker.h>
46#include <visp3/mbt/vpMbtXmlGenericParser.h>
47
48#if DEBUG_DISPLAY_DEPTH_DENSE
49#include <visp3/gui/vpDisplayGDI.h>
50#include <visp3/gui/vpDisplayX.h>
51#endif
52
61#if DEBUG_DISPLAY_DEPTH_DENSE
62 ,
63 m_debugDisp_depthDense(nullptr), m_debugImage_depthDense()
64#endif
65{
66#ifdef VISP_HAVE_OGRE
67 faces.getOgreContext()->setWindowName("MBT Depth Dense");
68#endif
69
70#if defined(VISP_HAVE_X11) && DEBUG_DISPLAY_DEPTH_DENSE
71 m_debugDisp_depthDense = new vpDisplayX;
72#elif defined(VISP_HAVE_GDI) && DEBUG_DISPLAY_DEPTH_DENSE
73 m_debugDisp_depthDense = new vpDisplayGDI;
74#endif
75}
76
81{
82 *this = tracker;
83}
84
89{
90 m_depthDenseHiddenFacesDisplay = tracker.m_depthDenseHiddenFacesDisplay;
91 m_depthDenseListOfActiveFaces = tracker.m_depthDenseListOfActiveFaces;
92 m_denseDepthNbFeatures = tracker.m_denseDepthNbFeatures;
93 m_depthDenseFaces = tracker.m_depthDenseFaces;
94 m_depthDenseSamplingStepX = tracker.m_depthDenseSamplingStepX;
95 m_depthDenseSamplingStepY = tracker.m_depthDenseSamplingStepY;
96 m_error_depthDense = tracker.m_error_depthDense;
97 m_L_depthDense = tracker.m_L_depthDense;
98 m_robust_depthDense = tracker.m_robust_depthDense;
99 m_w_depthDense = tracker.m_w_depthDense;
100 m_weightedError_depthDense = tracker.m_weightedError_depthDense;
101
102#if DEBUG_DISPLAY_DEPTH_DENSE
103 m_debugDisp_depthDense = tracker.m_debugDisp_depthDense;
104 m_debugImage_depthDense = tracker.m_debugImage_depthDense;
105#endif
106
107 return *this;
108}
109
111{
112 for (size_t i = 0; i < m_depthDenseFaces.size(); i++) {
113 delete m_depthDenseFaces[i];
114 }
115
116#if DEBUG_DISPLAY_DEPTH_DENSE
117 delete m_debugDisp_depthDense;
118#endif
119}
120
121void vpMbDepthDenseTracker::addFace(vpMbtPolygon &polygon, bool alreadyClose)
122{
123 if (polygon.nbpt < 3) {
124 return;
125 }
126
127 // Copy hidden faces
129
130 vpMbtFaceDepthDense *normal_face = new vpMbtFaceDepthDense;
131 normal_face->m_hiddenFace = &faces;
132 normal_face->m_polygon = &polygon;
133 normal_face->m_cam = m_cam;
134 normal_face->m_useScanLine = useScanLine;
135 normal_face->m_clippingFlag = clippingFlag;
136 normal_face->m_distNearClip = distNearClip;
137 normal_face->m_distFarClip = distFarClip;
138
139 // Add lines that compose the face
140 unsigned int nbpt = polygon.getNbPoint();
141 if (nbpt > 0) {
142 for (unsigned int i = 0; i < nbpt - 1; i++) {
143 normal_face->addLine(polygon.p[i], polygon.p[i + 1], &m_depthDenseHiddenFacesDisplay, m_rand, polygon.getIndex(),
144 polygon.getName());
145 }
146
147 if (!alreadyClose) {
148 // Add last line that closes the face
149 normal_face->addLine(polygon.p[nbpt - 1], polygon.p[0], &m_depthDenseHiddenFacesDisplay, m_rand,
150 polygon.getIndex(), polygon.getName());
151 }
152 }
153
154 // Construct a vpPlane in object frame
155 vpPoint pts[3];
156 pts[0] = polygon.p[0];
157 pts[1] = polygon.p[1];
158 pts[2] = polygon.p[2];
159 normal_face->m_planeObject = vpPlane(pts[0], pts[1], pts[2], vpPlane::object_frame);
160
161 m_depthDenseFaces.push_back(normal_face);
162}
163
164void vpMbDepthDenseTracker::computeVisibility(unsigned int width, unsigned int height)
165{
166 bool changed = false;
167 faces.setVisible(width, height, m_cam, m_cMo, angleAppears, angleDisappears, changed);
168
169 if (useScanLine) {
170 // if (clippingFlag <= 2) {
171 // cam.computeFov(width, height);
172 // }
173
174 faces.computeClippedPolygons(m_cMo, m_cam);
175 faces.computeScanLineRender(m_cam, width, height);
176 }
177
178 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
179 ++it) {
180 vpMbtFaceDepthDense *face_normal = *it;
181 face_normal->computeVisibility();
182 }
183}
184
186{
187 double normRes = 0;
188 double normRes_1 = -1;
189 unsigned int iter = 0;
190
192
194 vpMatrix LTL;
195 vpColVector LTR, v;
196
197 double mu = m_initialMu;
198 vpHomogeneousMatrix cMo_prev;
199
200 bool isoJoIdentity = m_isoJoIdentity; // Backup since it can be modified if L is not full rank
201 if (isoJoIdentity)
202 oJo.eye();
203
205 vpMatrix L_true, LVJ_true;
206
207 while (std::fabs(normRes_1 - normRes) > m_stopCriteriaEpsilon && (iter < m_maxIter)) {
209
210 bool reStartFromLastIncrement = false;
211 computeVVSCheckLevenbergMarquardt(iter, m_error_depthDense, error_prev, cMo_prev, mu, reStartFromLastIncrement);
212
213 if (!reStartFromLastIncrement) {
215
216 if (computeCovariance) {
217 L_true = m_L_depthDense;
218 if (!isoJoIdentity) {
219 cVo.buildFrom(m_cMo);
220 LVJ_true = (m_L_depthDense * cVo * oJo);
221 }
222 }
223
224 // Compute DoF only once
225 if (iter == 0) {
226 // If all the 6 dof should be estimated, we check if the interaction
227 // matrix is full rank. If not we remove automatically the dof that
228 // cannot be estimated. This is particularly useful when considering
229 // circles (rank 5) and cylinders (rank 4)
230 if (isoJoIdentity) {
231 cVo.buildFrom(m_cMo);
232
233 vpMatrix K; // kernel
234 unsigned int rank = (m_L_depthDense * cVo).kernel(K);
235 if (rank == 0) {
236 throw vpException(vpException::fatalError, "Rank=0, cannot estimate the pose !");
237 }
238
239 if (rank != 6) {
240 vpMatrix I; // Identity
241 I.eye(6);
242 oJo = I - K.AtA();
243
244 isoJoIdentity = false;
245 }
246 }
247 }
248
249 double num = 0.0, den = 0.0;
250 for (unsigned int i = 0; i < m_L_depthDense.getRows(); i++) {
251 // Compute weighted errors and stop criteria
254 den += m_w_depthDense[i];
255
256 // weight interaction matrix
257 for (unsigned int j = 0; j < 6; j++) {
258 m_L_depthDense[i][j] *= m_w_depthDense[i];
259 }
260 }
261
263 m_error_depthDense, error_prev, LTR, mu, v);
264
265 cMo_prev = m_cMo;
267
268 normRes_1 = normRes;
269 normRes = sqrt(num / den);
270 }
271
272 iter++;
273 }
274
275 computeCovarianceMatrixVVS(isoJoIdentity, m_w_depthDense, cMo_prev, L_true, LVJ_true, m_error_depthDense);
276}
277
279{
281
282 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseListOfActiveFaces.begin();
283 it != m_depthDenseListOfActiveFaces.end(); ++it) {
284 vpMbtFaceDepthDense *face = *it;
286 }
287
288 m_L_depthDense.resize(m_denseDepthNbFeatures, 6, false, false);
291
293 m_w_depthDense = 1;
294}
295
297{
298 unsigned int start_index = 0;
299 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseListOfActiveFaces.begin();
300 it != m_depthDenseListOfActiveFaces.end(); ++it) {
301 vpMbtFaceDepthDense *face = *it;
302
303 vpMatrix L_face;
304 vpColVector error;
305
306 face->computeInteractionMatrixAndResidu(m_cMo, L_face, error);
307
308 m_error_depthDense.insert(start_index, error);
309 m_L_depthDense.insert(L_face, start_index, 0);
310
311 start_index += error.getRows();
312 }
313}
314
319
321 const vpCameraParameters &cam, const vpColor &col, unsigned int thickness,
322 bool displayFullModel)
323{
324 std::vector<std::vector<double> > models =
325 vpMbDepthDenseTracker::getModelForDisplay(I.getWidth(), I.getHeight(), cMo, cam, displayFullModel);
326
327 for (size_t i = 0; i < models.size(); i++) {
328 if (vpMath::equal(models[i][0], 0)) {
329 vpImagePoint ip1(models[i][1], models[i][2]);
330 vpImagePoint ip2(models[i][3], models[i][4]);
331 vpDisplay::displayLine(I, ip1, ip2, col, thickness);
332 }
333 }
334}
335
337 const vpCameraParameters &cam, const vpColor &col, unsigned int thickness,
338 bool displayFullModel)
339{
340 std::vector<std::vector<double> > models =
341 vpMbDepthDenseTracker::getModelForDisplay(I.getWidth(), I.getHeight(), cMo, cam, displayFullModel);
342
343 for (size_t i = 0; i < models.size(); i++) {
344 if (vpMath::equal(models[i][0], 0)) {
345 vpImagePoint ip1(models[i][1], models[i][2]);
346 vpImagePoint ip2(models[i][3], models[i][4]);
347 vpDisplay::displayLine(I, ip1, ip2, col, thickness);
348 }
349 }
350}
351
367std::vector<std::vector<double> > vpMbDepthDenseTracker::getModelForDisplay(unsigned int width, unsigned int height,
368 const vpHomogeneousMatrix &cMo,
369 const vpCameraParameters &cam,
370 bool displayFullModel)
371{
372 std::vector<std::vector<double> > models;
373
374 vpCameraParameters c = cam;
375
376 bool changed = false;
377 m_depthDenseHiddenFacesDisplay.setVisible(width, height, c, cMo, angleAppears, angleDisappears, changed);
378
379 if (useScanLine) {
380 c.computeFov(width, height);
381
382 m_depthDenseHiddenFacesDisplay.computeClippedPolygons(cMo, c);
383 m_depthDenseHiddenFacesDisplay.computeScanLineRender(c, width, height);
384 }
385
386 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
387 ++it) {
388 vpMbtFaceDepthDense *face_dense = *it;
389 std::vector<std::vector<double> > modelLines =
390 face_dense->getModelForDisplay(width, height, cMo, cam, displayFullModel);
391 models.insert(models.end(), modelLines.begin(), modelLines.end());
392 }
393
394 return models;
395}
396
398{
399 if (!modelInitialised) {
400 throw vpException(vpException::fatalError, "model not initialized");
401 }
402
403 bool reInitialisation = false;
404 if (!useOgre) {
405 faces.setVisible(I.getWidth(), I.getHeight(), m_cam, m_cMo, angleAppears, angleDisappears, reInitialisation);
406 }
407 else {
408#ifdef VISP_HAVE_OGRE
409 if (!faces.isOgreInitialised()) {
410 faces.setBackgroundSizeOgre(I.getHeight(), I.getWidth());
411 faces.setOgreShowConfigDialog(ogreShowConfigDialog);
412 faces.initOgre(m_cam);
413 // Turn off Ogre config dialog display for the next call to this
414 // function since settings are saved in the ogre.cfg file and used
415 // during the next call
416 ogreShowConfigDialog = false;
417 }
418
419 faces.setVisibleOgre(I.getWidth(), I.getHeight(), m_cam, m_cMo, angleAppears, angleDisappears, reInitialisation);
420#else
421 faces.setVisible(I.getWidth(), I.getHeight(), m_cam, m_cMo, angleAppears, angleDisappears, reInitialisation);
422#endif
423 }
424
425 if (useScanLine || clippingFlag > 3)
426 m_cam.computeFov(I.getWidth(), I.getHeight());
427
428 computeVisibility(I.getWidth(), I.getHeight());
429}
430
431void vpMbDepthDenseTracker::loadConfigFile(const std::string &configFile, bool verbose)
432{
433#if defined(VISP_HAVE_PUGIXML)
435 xmlp.setVerbose(verbose);
439
442
443 try {
444 if (verbose) {
445 std::cout << " *********** Parsing XML for Mb Depth Dense Tracker ************ " << std::endl;
446 }
447 xmlp.parse(configFile);
448 }
449 catch (const vpException &e) {
450 std::cerr << "Exception: " << e.what() << std::endl;
451 throw vpException(vpException::ioError, "Cannot open XML file \"%s\"", configFile.c_str());
452 }
453
454 vpCameraParameters camera;
455 xmlp.getCameraParameters(camera);
456 setCameraParameters(camera);
457
460
461 if (xmlp.hasNearClippingDistance())
463
464 if (xmlp.hasFarClippingDistance())
466
467 if (xmlp.getFovClipping())
469
471#else
472 (void)configFile;
473 (void)verbose;
474 throw(vpException(vpException::ioError, "vpMbDepthDenseTracker::loadConfigFile() needs pugixml built-in 3rdparty"));
475#endif
476}
477
478void vpMbDepthDenseTracker::reInitModel(const vpImage<unsigned char> &I, const std::string &cad_name,
479 const vpHomogeneousMatrix &cMo, bool verbose)
480{
481 m_cMo.eye();
482
483 for (size_t i = 0; i < m_depthDenseFaces.size(); i++) {
484 delete m_depthDenseFaces[i];
485 m_depthDenseFaces[i] = nullptr;
486 }
487
488 m_depthDenseFaces.clear();
489
490 loadModel(cad_name, verbose);
491 initFromPose(I, cMo);
492}
493
494#if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_COMMON)
495void vpMbDepthDenseTracker::reInitModel(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &point_cloud,
496 const std::string &cad_name, const vpHomogeneousMatrix &cMo, bool verbose)
497{
498 vpImage<unsigned char> I_dummy(point_cloud->height, point_cloud->width);
499 reInitModel(I_dummy, cad_name, cMo, verbose);
500}
501
502#endif
503
505{
506 m_cMo.eye();
507
508 for (std::vector<vpMbtFaceDepthDense *>::iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
509 ++it) {
510 vpMbtFaceDepthDense *normal_face = *it;
511 delete normal_face;
512 normal_face = nullptr;
513 }
514
515 m_depthDenseFaces.clear();
516
518 computeCovariance = false;
519
522
524
525 m_lambda = 1.0;
526 m_maxIter = 30;
527
528 faces.reset();
529
531
532 useScanLine = false;
533
534#ifdef VISP_HAVE_OGRE
535 useOgre = false;
536#endif
537
539}
540
542{
543 m_cam = cam;
544
545 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
546 ++it) {
547 (*it)->setCameraParameters(cam);
548 }
549}
550
552{
553 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
554 ++it) {
555 (*it)->setDepthDenseFilteringMaxDistance(maxDistance);
556 }
557}
558
560{
561 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
562 ++it) {
563 (*it)->setDepthDenseFilteringMethod(method);
564 }
565}
566
568{
569 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
570 ++it) {
571 (*it)->setDepthDenseFilteringMinDistance(minDistance);
572 }
573}
574
576{
577 if (occupancyRatio < 0.0 || occupancyRatio > 1.0) {
578 std::cerr << "occupancyRatio < 0.0 || occupancyRatio > 1.0" << std::endl;
579 return;
580 }
581
582 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
583 ++it) {
584 (*it)->setDepthDenseFilteringOccupancyRatio(occupancyRatio);
585 }
586}
587
588#if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_COMMON)
589void vpMbDepthDenseTracker::segmentPointCloud(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &point_cloud)
590{
592
593#if DEBUG_DISPLAY_DEPTH_DENSE
594 if (!m_debugDisp_depthDense->isInitialised()) {
595 m_debugImage_depthDense.resize(point_cloud->height, point_cloud->width);
596 m_debugDisp_depthDense->init(m_debugImage_depthDense, 50, 0, "Debug display dense depth tracker");
597 }
598
599 m_debugImage_depthDense = 0;
600 std::vector<std::vector<vpImagePoint> > roiPts_vec;
601#endif
602
603 for (std::vector<vpMbtFaceDepthDense *>::iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
604 ++it) {
605 vpMbtFaceDepthDense *face = *it;
606
607 if (face->isVisible() && face->isTracked()) {
608#if DEBUG_DISPLAY_DEPTH_DENSE
609 std::vector<std::vector<vpImagePoint> > roiPts_vec_;
610#endif
612#if DEBUG_DISPLAY_DEPTH_DENSE
613 ,
614 m_debugImage_depthDense, roiPts_vec_
615#endif
616 ,
617 m_mask)) {
618 m_depthDenseListOfActiveFaces.push_back(*it);
619
620#if DEBUG_DISPLAY_DEPTH_DENSE
621 roiPts_vec.insert(roiPts_vec.end(), roiPts_vec_.begin(), roiPts_vec_.end());
622#endif
623 }
624 }
625 }
626
627#if DEBUG_DISPLAY_DEPTH_DENSE
628 vpDisplay::display(m_debugImage_depthDense);
629
630 for (size_t i = 0; i < roiPts_vec.size(); i++) {
631 if (roiPts_vec[i].empty())
632 continue;
633
634 for (size_t j = 0; j < roiPts_vec[i].size() - 1; j++) {
635 vpDisplay::displayLine(m_debugImage_depthDense, roiPts_vec[i][j], roiPts_vec[i][j + 1], vpColor::red, 2);
636 }
637 vpDisplay::displayLine(m_debugImage_depthDense, roiPts_vec[i][0], roiPts_vec[i][roiPts_vec[i].size() - 1],
638 vpColor::red, 2);
639 }
640
641 vpDisplay::flush(m_debugImage_depthDense);
642#endif
643}
644#endif
645
646void vpMbDepthDenseTracker::segmentPointCloud(const std::vector<vpColVector> &point_cloud, unsigned int width,
647 unsigned int height)
648{
650
651#if DEBUG_DISPLAY_DEPTH_DENSE
652 if (!m_debugDisp_depthDense->isInitialised()) {
653 m_debugImage_depthDense.resize(height, width);
654 m_debugDisp_depthDense->init(m_debugImage_depthDense, 50, 0, "Debug display dense depth tracker");
655 }
656
657 m_debugImage_depthDense = 0;
658 std::vector<std::vector<vpImagePoint> > roiPts_vec;
659#endif
660
661 for (std::vector<vpMbtFaceDepthDense *>::iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
662 ++it) {
663 vpMbtFaceDepthDense *face = *it;
664
665 if (face->isVisible() && face->isTracked()) {
666#if DEBUG_DISPLAY_DEPTH_DENSE
667 std::vector<std::vector<vpImagePoint> > roiPts_vec_;
668#endif
669 if (face->computeDesiredFeatures(m_cMo, width, height, point_cloud, m_depthDenseSamplingStepX,
671#if DEBUG_DISPLAY_DEPTH_DENSE
672 ,
673 m_debugImage_depthDense, roiPts_vec_
674#endif
675 ,
676 m_mask)) {
677 m_depthDenseListOfActiveFaces.push_back(*it);
678
679#if DEBUG_DISPLAY_DEPTH_DENSE
680 roiPts_vec.insert(roiPts_vec.end(), roiPts_vec_.begin(), roiPts_vec_.end());
681#endif
682 }
683 }
684 }
685
686#if DEBUG_DISPLAY_DEPTH_DENSE
687 vpDisplay::display(m_debugImage_depthDense);
688
689 for (size_t i = 0; i < roiPts_vec.size(); i++) {
690 if (roiPts_vec[i].empty())
691 continue;
692
693 for (size_t j = 0; j < roiPts_vec[i].size() - 1; j++) {
694 vpDisplay::displayLine(m_debugImage_depthDense, roiPts_vec[i][j], roiPts_vec[i][j + 1], vpColor::red, 2);
695 }
696 vpDisplay::displayLine(m_debugImage_depthDense, roiPts_vec[i][0], roiPts_vec[i][roiPts_vec[i].size() - 1],
697 vpColor::red, 2);
698 }
699
700 vpDisplay::flush(m_debugImage_depthDense);
701#endif
702}
703
704
705void vpMbDepthDenseTracker::segmentPointCloud(const vpMatrix &point_cloud, unsigned int width,
706 unsigned int height)
707{
709
710#if DEBUG_DISPLAY_DEPTH_DENSE
711 if (!m_debugDisp_depthDense->isInitialised()) {
712 m_debugImage_depthDense.resize(height, width);
713 m_debugDisp_depthDense->init(m_debugImage_depthDense, 50, 0, "Debug display dense depth tracker");
714 }
715
716 m_debugImage_depthDense = 0;
717 std::vector<std::vector<vpImagePoint> > roiPts_vec;
718#endif
719
720 for (std::vector<vpMbtFaceDepthDense *>::iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
721 ++it) {
722 vpMbtFaceDepthDense *face = *it;
723
724 if (face->isVisible() && face->isTracked()) {
725#if DEBUG_DISPLAY_DEPTH_DENSE
726 std::vector<std::vector<vpImagePoint> > roiPts_vec_;
727#endif
728 if (face->computeDesiredFeatures(m_cMo, width, height, point_cloud, m_depthDenseSamplingStepX,
730#if DEBUG_DISPLAY_DEPTH_DENSE
731 ,
732 m_debugImage_depthDense, roiPts_vec_
733#endif
734 ,
735 m_mask)) {
736 m_depthDenseListOfActiveFaces.push_back(*it);
737
738#if DEBUG_DISPLAY_DEPTH_DENSE
739 roiPts_vec.insert(roiPts_vec.end(), roiPts_vec_.begin(), roiPts_vec_.end());
740#endif
741 }
742 }
743 }
744
745#if DEBUG_DISPLAY_DEPTH_DENSE
746 vpDisplay::display(m_debugImage_depthDense);
747
748 for (size_t i = 0; i < roiPts_vec.size(); i++) {
749 if (roiPts_vec[i].empty())
750 continue;
751
752 for (size_t j = 0; j < roiPts_vec[i].size() - 1; j++) {
753 vpDisplay::displayLine(m_debugImage_depthDense, roiPts_vec[i][j], roiPts_vec[i][j + 1], vpColor::red, 2);
754 }
755 vpDisplay::displayLine(m_debugImage_depthDense, roiPts_vec[i][0], roiPts_vec[i][roiPts_vec[i].size() - 1],
756 vpColor::red, 2);
757 }
758
759 vpDisplay::flush(m_debugImage_depthDense);
760#endif
761}
762
764{
766#ifdef VISP_HAVE_OGRE
767 faces.getOgreContext()->setWindowName("MBT Depth Dense");
768#endif
769}
770
772{
773 m_cMo = cdMo;
774 init(I);
775}
776
778{
779 m_cMo = cdMo;
781 init(m_I);
782}
783
784#if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_COMMON)
785void vpMbDepthDenseTracker::setPose(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &point_cloud,
786 const vpHomogeneousMatrix &cdMo)
787{
788 m_I.resize(point_cloud->height, point_cloud->width);
789 m_cMo = cdMo;
790 init(m_I);
791}
792#endif
793
795{
797
798 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
799 ++it) {
800 (*it)->setScanLineVisibilityTest(v);
801 }
802}
803
804void vpMbDepthDenseTracker::setUseDepthDenseTracking(const std::string &name, const bool &useDepthDenseTracking)
805{
806 for (std::vector<vpMbtFaceDepthDense *>::const_iterator it = m_depthDenseFaces.begin(); it != m_depthDenseFaces.end();
807 ++it) {
808 vpMbtFaceDepthDense *face = *it;
809 if (face->m_polygon->getName() == name) {
810 face->setTracked(useDepthDenseTracking);
811 }
812 }
813}
814
816
818{
819 throw vpException(vpException::fatalError, "Cannot track with a grayscale image!");
820}
821
823{
824 throw vpException(vpException::fatalError, "Cannot track with a color image!");
825}
826
827#if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_COMMON)
828void vpMbDepthDenseTracker::track(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &point_cloud)
829{
830 segmentPointCloud(point_cloud);
831
832 computeVVS();
833
834 computeVisibility(point_cloud->width, point_cloud->height);
835}
836#endif
837
838void vpMbDepthDenseTracker::track(const std::vector<vpColVector> &point_cloud, unsigned int width, unsigned int height)
839{
840 segmentPointCloud(point_cloud, width, height);
841
842 computeVVS();
843
844 computeVisibility(width, height);
845}
846
847void vpMbDepthDenseTracker::initCircle(const vpPoint & /*p1*/, const vpPoint & /*p2*/, const vpPoint & /*p3*/,
848 double /*radius*/, int /*idFace*/, const std::string & /*name*/)
849{
850 throw vpException(vpException::fatalError, "vpMbDepthDenseTracker::initCircle() should not be called!");
851}
852
853void vpMbDepthDenseTracker::initCylinder(const vpPoint & /*p1*/, const vpPoint & /*p2*/, double /*radius*/,
854 int /*idFace*/, const std::string & /*name*/)
855{
856 throw vpException(vpException::fatalError, "vpMbDepthDenseTracker::initCylinder() should not be called!");
857}
858
860
862END_VISP_NAMESPACE
Generic class defining intrinsic camera parameters.
void computeFov(const unsigned int &w, const unsigned int &h)
Implementation of column vector and the associated operations.
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
static const vpColor red
Definition vpColor.h:198
Display for windows using GDI (available on any windows 32 platform).
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition vpDisplayX.h:135
static void display(const vpImage< unsigned char > &I)
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static void flush(const vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ ioError
I/O error.
Definition vpException.h:67
@ fatalError
Fatal error.
Definition vpException.h:72
static vpHomogeneousMatrix direct(const vpColVector &v)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
Definition vpImage.h:131
static double rad(double deg)
Definition vpMath.h:129
static double sqr(double x)
Definition vpMath.h:203
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
static double deg(double rad)
Definition vpMath.h:119
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
virtual void initFaceFromLines(vpMbtPolygon &polygon) VP_OVERRIDE
virtual void initFaceFromCorners(vpMbtPolygon &polygon) VP_OVERRIDE
void segmentPointCloud(const pcl::PointCloud< pcl::PointXYZ >::ConstPtr &point_cloud)
virtual std::vector< std::vector< double > > getModelForDisplay(unsigned int width, unsigned int height, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false) VP_OVERRIDE
vpMbtTukeyEstimator< double > m_robust_depthDense
Tukey M-Estimator.
virtual void setScanLineVisibilityTest(const bool &v) VP_OVERRIDE
virtual void setDepthDenseFilteringMaxDistance(double maxDistance)
void computeVisibility(unsigned int width, unsigned int height)
virtual void setCameraParameters(const vpCameraParameters &camera) VP_OVERRIDE
vpMbDepthDenseTracker & operator=(const vpMbDepthDenseTracker &tracker)
virtual void setDepthDenseFilteringMethod(int method)
virtual void init(const vpImage< unsigned char > &I) VP_OVERRIDE
void reInitModel(const vpImage< unsigned char > &I, const std::string &cad_name, const vpHomogeneousMatrix &cMo, bool verbose=false)
vpColVector m_weightedError_depthDense
Weighted error.
unsigned int m_depthDenseSamplingStepY
Sampling step in y-direction.
virtual ~vpMbDepthDenseTracker() VP_OVERRIDE
virtual void resetTracker() VP_OVERRIDE
virtual void setPose(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cdMo) VP_OVERRIDE
vpMbHiddenFaces< vpMbtPolygon > m_depthDenseHiddenFacesDisplay
Set of faces describing the object used only for display with scan line.
virtual void testTracking() VP_OVERRIDE
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false) VP_OVERRIDE
void setUseDepthDenseTracking(const std::string &name, const bool &useDepthDenseTracking)
unsigned int m_depthDenseSamplingStepX
Sampling step in x-direction.
vpColVector m_error_depthDense
(s - s*)
virtual void computeVVSInteractionMatrixAndResidu() VP_OVERRIDE
virtual void initCylinder(const vpPoint &p1, const vpPoint &p2, double radius, int idFace=0, const std::string &name="") VP_OVERRIDE
vpMatrix m_L_depthDense
Interaction matrix.
std::vector< vpMbtFaceDepthDense * > m_depthDenseListOfActiveFaces
List of current active (visible and features extracted) faces.
virtual void computeVVSInit() VP_OVERRIDE
virtual void track(const vpImage< unsigned char > &) VP_OVERRIDE
void setDepthDenseSamplingStep(unsigned int stepX, unsigned int stepY)
void addFace(vpMbtPolygon &polygon, bool alreadyClose)
virtual void setOgreVisibilityTest(const bool &v) VP_OVERRIDE
virtual void setDepthDenseFilteringMinDistance(double minDistance)
unsigned int m_denseDepthNbFeatures
Nb features.
vpColVector m_w_depthDense
Robust weights.
virtual void loadConfigFile(const std::string &configFile, bool verbose=true) VP_OVERRIDE
virtual void setDepthDenseFilteringOccupancyRatio(double occupancyRatio)
virtual void initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius, int idFace=0, const std::string &name="") VP_OVERRIDE
std::vector< vpMbtFaceDepthDense * > m_depthDenseFaces
List of faces.
double m_lambda
Gain of the virtual visual servoing stage.
bool modelInitialised
vpImage< unsigned char > m_I
Grayscale image buffer, used when passing color images.
bool m_computeInteraction
vpMatrix oJo
The Degrees of Freedom to estimate.
vpUniRand m_rand
Random number generator used in vpMbtDistanceLine::buildFrom().
double m_initialMu
Initial Mu for Levenberg Marquardt optimization loop.
vpHomogeneousMatrix m_cMo
The current pose.
virtual void computeVVSCheckLevenbergMarquardt(unsigned int iter, vpColVector &error, const vpColVector &m_error_prev, const vpHomogeneousMatrix &cMoPrev, double &mu, bool &reStartFromLastIncrement, vpColVector *const w=nullptr, const vpColVector *const m_w_prev=nullptr)
vpCameraParameters m_cam
The camera parameters.
double m_stopCriteriaEpsilon
Epsilon threshold to stop the VVS optimization loop.
bool useOgre
Use Ogre3d for global visibility tests.
vpMbHiddenFaces< vpMbtPolygon > faces
Set of faces describing the object.
virtual void setScanLineVisibilityTest(const bool &v)
virtual void setOgreVisibilityTest(const bool &v)
virtual void computeCovarianceMatrixVVS(const bool isoJoIdentity, const vpColVector &w_true, const vpHomogeneousMatrix &cMoPrev, const vpMatrix &L_true, const vpMatrix &LVJ_true, const vpColVector &error)
vpMbtOptimizationMethod m_optimizationMethod
Optimization method used.
virtual void computeVVSPoseEstimation(const bool isoJoIdentity, unsigned int iter, vpMatrix &L, vpMatrix &LTL, vpColVector &R, const vpColVector &error, vpColVector &error_prev, vpColVector &LTR, double &mu, vpColVector &v, const vpColVector *const w=nullptr, vpColVector *const m_w_prev=nullptr)
virtual void loadModel(const std::string &modelFile, bool verbose=false, const vpHomogeneousMatrix &od_M_o=vpHomogeneousMatrix())
double angleDisappears
Angle used to detect a face disappearance.
virtual void setNearClippingDistance(const double &dist)
virtual void setFarClippingDistance(const double &dist)
double distFarClip
Distance for near clipping.
bool m_isoJoIdentity
Boolean to know if oJo is identity (for fast computation).
bool useScanLine
Use Scanline for global visibility tests.
virtual void setClipping(const unsigned int &flags)
double angleAppears
Angle used to detect a face appearance.
const vpImage< bool > * m_mask
Mask used to disable tracking on a part of image.
virtual void initFromPose(const vpImage< unsigned char > &I, const std::string &initFile)
bool computeCovariance
Flag used to specify if the covariance matrix has to be computed or not.
double distNearClip
Distance for near clipping.
unsigned int m_maxIter
Maximum number of iterations of the virtual visual servoing stage.
bool ogreShowConfigDialog
unsigned int clippingFlag
Flags specifying which clipping to used.
Manage depth dense features for a particular face.
vpMbHiddenFaces< vpMbtPolygon > * m_hiddenFace
Pointer to the list of faces.
double m_distFarClip
Distance for near clipping.
vpPlane m_planeObject
Plane equation described in the object frame.
std::vector< std::vector< double > > getModelForDisplay(unsigned int width, unsigned int height, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false)
unsigned int getNbFeatures() const
void setTracked(bool tracked)
void computeInteractionMatrixAndResidu(const vpHomogeneousMatrix &cMo, vpMatrix &L, vpColVector &error)
vpMbtPolygon * m_polygon
Polygon defining the face.
bool m_useScanLine
Scan line visibility.
bool computeDesiredFeatures(const vpHomogeneousMatrix &cMo, const pcl::PointCloud< pcl::PointXYZ >::ConstPtr &point_cloud, unsigned int stepX, unsigned int stepY, const vpImage< bool > *mask=nullptr)
unsigned int m_clippingFlag
Flags specifying which clipping to used.
vpCameraParameters m_cam
Camera intrinsic parameters.
double m_distNearClip
Distance for near clipping.
void addLine(vpPoint &p1, vpPoint &p2, vpMbHiddenFaces< vpMbtPolygon > *const faces, vpUniRand &rand_gen, int polygon=-1, std::string name="")
Implementation of a polygon of the model used by the model-based tracker.
std::string getName() const
int getIndex() const
Parse an Xml file to extract configuration parameters of a mbtConfig object.
void getCameraParameters(vpCameraParameters &cam) const
void setDepthDenseSamplingStepY(unsigned int stepY)
void setAngleDisappear(const double &adisappear)
void setDepthDenseSamplingStepX(unsigned int stepX)
void setAngleAppear(const double &aappear)
unsigned int getDepthDenseSamplingStepY() const
void parse(const std::string &filename)
unsigned int getDepthDenseSamplingStepX() const
void setCameraParameters(const vpCameraParameters &cam)
This class defines the container for a plane geometrical structure.
Definition vpPlane.h:56
@ object_frame
Definition vpPlane.h:64
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
unsigned int nbpt
Number of points used to define the polygon.
Definition vpPolygon3D.h:74
unsigned int getNbPoint() const
vpPoint * p
corners in the object frame
Definition vpPolygon3D.h:79
vpVelocityTwistMatrix & buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)