Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMbEdgeKltTracker.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 * Hybrid tracker based on edges (vpMbt) and points of interests (KLT)
32 */
33
34//#define VP_DEBUG_MODE 1 // Activate debug level 1
35
36#include <visp3/core/vpDebug.h>
37#include <visp3/core/vpTrackingException.h>
38#include <visp3/core/vpVelocityTwistMatrix.h>
39#include <visp3/mbt/vpMbEdgeKltTracker.h>
40#include <visp3/mbt/vpMbtXmlGenericParser.h>
41
42#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
43
47{
48 computeCovariance = false;
49
50#ifdef VISP_HAVE_OGRE
51 faces.getOgreContext()->setWindowName("MBT Hybrid");
52#endif
53
54 m_lambda = 0.8;
55 m_maxIter = 200;
56}
57
63
71{
73
75
77
78 unsigned int i = static_cast<unsigned int>(scales.size());
79 do {
80 i--;
81 if (scales[i]) {
82 downScale(i);
84 upScale(i);
85 }
86 } while (i != 0);
87
89}
90
101{
103
105
106 if (useScanLine) {
107 m_cam.computeFov(I.getWidth(), I.getHeight());
108 faces.computeClippedPolygons(m_cMo, m_cam);
109 faces.computeScanLineRender(m_cam, I.getWidth(), I.getHeight());
110 }
111
113
114 unsigned int i = static_cast<unsigned int>(scales.size());
115 do {
116 i--;
117 if (scales[i]) {
118 downScale(i);
120 upScale(i);
121 }
122 } while (i != 0);
123
125}
126
137{
140
142
143 if (useScanLine) {
144 m_cam.computeFov(m_I.getWidth(), m_I.getHeight());
145 faces.computeClippedPolygons(m_cMo, m_cam);
146 faces.computeScanLineRender(m_cam, m_I.getWidth(), m_I.getHeight());
147 }
148
150
151 unsigned int i = static_cast<unsigned int>(scales.size());
152 do {
153 i--;
154 if (scales[i]) {
155 downScale(i);
157 upScale(i);
158 }
159 } while (i != 0);
160
162}
163
173
174unsigned int vpMbEdgeKltTracker::initMbtTracking(unsigned int lvl)
175{
176 if (lvl >= scales.size() || !scales[lvl]) {
177 throw vpException(vpException::dimensionError, "lvl not used.");
178 }
179
180 unsigned int nbrow = 0;
181 for (std::list<vpMbtDistanceLine *>::iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
182 vpMbtDistanceLine *l = *it;
183
184 if (l->isTracked()) {
186 nbrow += l->nbFeatureTotal;
187 }
188 }
189
190 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
191 ++it) {
192 vpMbtDistanceCylinder *cy = *it;
193
194 if (cy->isTracked()) {
196 nbrow += cy->nbFeature;
197 }
198 }
199
200 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
201 vpMbtDistanceCircle *ci = *it;
202
203 if (ci->isTracked()) {
205 nbrow += ci->nbFeature;
206 }
207 }
208
209 return nbrow;
210}
211
273void vpMbEdgeKltTracker::loadConfigFile(const std::string &configFile, bool verbose)
274{
275#if defined(VISP_HAVE_PUGIXML)
276// Load projection error config
277 vpMbTracker::loadConfigFile(configFile, verbose);
278
280 xmlp.setVerbose(verbose);
284
285 xmlp.setEdgeMe(me);
286
287 xmlp.setKltMaxFeatures(10000);
288 xmlp.setKltWindowSize(5);
289 xmlp.setKltQuality(0.01);
290 xmlp.setKltMinDistance(5);
291 xmlp.setKltHarrisParam(0.01);
292 xmlp.setKltBlockSize(3);
293 xmlp.setKltPyramidLevels(3);
295
296 try {
297 if (verbose) {
298 std::cout << " *********** Parsing XML for Mb Edge KLT Tracker ************ " << std::endl;
299 }
300 xmlp.parse(configFile.c_str());
301 }
302 catch (...) {
303 vpERROR_TRACE("Can't open XML file \"%s\"\n ", configFile.c_str());
304 throw vpException(vpException::ioError, "problem to parse configuration file.");
305 }
306
307 vpCameraParameters camera;
308 xmlp.getCameraParameters(camera);
309 setCameraParameters(camera);
310
313
314 if (xmlp.hasNearClippingDistance())
316
317 if (xmlp.hasFarClippingDistance())
319
320 if (xmlp.getFovClipping()) {
322 }
323
324 useLodGeneral = xmlp.getLodState();
327
329 if (this->getNbPolygon() > 0) {
334 }
335
336 vpMe meParser;
337 xmlp.getEdgeMe(meParser);
339
340 tracker.setMaxFeatures(static_cast<int>(xmlp.getKltMaxFeatures()));
341 tracker.setWindowSize(static_cast<int>(xmlp.getKltWindowSize()));
342 tracker.setQuality(xmlp.getKltQuality());
343 tracker.setMinDistance(xmlp.getKltMinDistance());
344 tracker.setHarrisFreeParameter(xmlp.getKltHarrisParam());
345 tracker.setBlockSize(static_cast<int>(xmlp.getKltBlockSize()));
346 tracker.setPyramidLevels(static_cast<int>(xmlp.getKltPyramidLevels()));
348
349 // if(useScanLine)
350 faces.getMbScanLineRenderer().setMaskBorder(maskBorder);
351#else
352 (void)configFile;
353 (void)verbose;
354 throw(vpException(vpException::ioError, "vpMbEdgeKltTracker::loadConfigFile() needs pugixml built-in 3rdparty"));
355#endif
356}
357
362 unsigned int lvl)
363{
364 postTrackingMbt(w_mbt, lvl);
365
366 if (displayFeatures) {
367 if (lvl == 0) {
368 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
369 vpMbtDistanceLine *l = *it;
370 if (l->isVisible() && l->isTracked()) {
371 l->displayMovingEdges(I);
372 }
373 }
374
375 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
376 ++it) {
377 vpMbtDistanceCylinder *cy = *it;
378 // A cylinder is always visible: #FIXME AY: Still valid?
379 if (cy->isTracked())
380 cy->displayMovingEdges(I);
381 }
382
383 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
384 vpMbtDistanceCircle *ci = *it;
385 if (ci->isVisible() && ci->isTracked()) {
386 ci->displayMovingEdges(I);
387 }
388 }
389 }
390 }
391
392 bool reInit = vpMbKltTracker::postTracking(I, w_klt);
393
394 if (useScanLine) {
395 m_cam.computeFov(I.getWidth(), I.getHeight());
396 faces.computeClippedPolygons(m_cMo, m_cam);
397 faces.computeScanLineRender(m_cam, I.getWidth(), I.getHeight());
398 }
399
401
404
407
408 if (reInit)
409 return true;
410
411 return false;
412}
413
418 unsigned int lvl)
419{
420 postTrackingMbt(w_mbt, lvl);
421
422 if (displayFeatures) {
423 if (lvl == 0) {
424 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
425 vpMbtDistanceLine *l = *it;
426 if (l->isVisible() && l->isTracked()) {
427 l->displayMovingEdges(I_color);
428 }
429 }
430
431 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
432 ++it) {
433 vpMbtDistanceCylinder *cy = *it;
434 // A cylinder is always visible: #FIXME AY: Still valid?
435 if (cy->isTracked())
437 }
438
439 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
440 vpMbtDistanceCircle *ci = *it;
441 if (ci->isVisible() && ci->isTracked()) {
443 }
444 }
445 }
446 }
447
448 bool reInit = vpMbKltTracker::postTracking(m_I, w_klt);
449
450 if (useScanLine) {
451 m_cam.computeFov(m_I.getWidth(), m_I.getHeight());
452 faces.computeClippedPolygons(m_cMo, m_cam);
453 faces.computeScanLineRender(m_cam, m_I.getWidth(), m_I.getHeight());
454 }
455
457
460
463
464 if (reInit)
465 return true;
466
467 return false;
468}
469
481{
482 if (lvl >= scales.size() || !scales[lvl]) {
483 throw vpException(vpException::dimensionError, "_lvl not used.");
484 }
485
486 unsigned int n = 0;
488 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
489 if ((*it)->isTracked()) {
490 l = *it;
491 unsigned int indexLine = 0;
492 double wmean = 0;
493
494 for (size_t a = 0; a < l->meline.size(); a++) {
495 std::list<vpMeSite>::iterator itListLine;
496 if (l->nbFeature[a] > 0)
497 itListLine = l->meline[a]->getMeList().begin();
498
499 for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
500 wmean += w[n + indexLine];
501 vpMeSite p = *itListLine;
502 if (w[n + indexLine] < 0.5) {
503 p.setState(vpMeSite::M_ESTIMATOR);
504 *itListLine = p;
505 }
506
507 ++itListLine;
508 indexLine++;
509 }
510 }
511
512 n += l->nbFeatureTotal;
513
514 if (l->nbFeatureTotal != 0)
515 wmean /= l->nbFeatureTotal;
516 else
517 wmean = 1;
518
519 l->setMeanWeight(wmean);
520
521 if (wmean < 0.8)
522 l->Reinit = true;
523 }
524 }
525
526 // Same thing with cylinders as with lines
528 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
529 ++it) {
530 if ((*it)->isTracked()) {
531 cy = *it;
532 double wmean = 0;
533 std::list<vpMeSite>::iterator itListCyl1;
534 std::list<vpMeSite>::iterator itListCyl2;
535 if (cy->nbFeature > 0) {
536 itListCyl1 = cy->meline1->getMeList().begin();
537 itListCyl2 = cy->meline2->getMeList().begin();
538 }
539
540 wmean = 0;
541 for (unsigned int i = 0; i < cy->nbFeaturel1; i++) {
542 wmean += w[n + i];
543 vpMeSite p = *itListCyl1;
544 if (w[n + i] < 0.5) {
545 p.setState(vpMeSite::M_ESTIMATOR);
546
547 *itListCyl1 = p;
548 }
549
550 ++itListCyl1;
551 }
552
553 if (cy->nbFeaturel1 != 0)
554 wmean /= cy->nbFeaturel1;
555 else
556 wmean = 1;
557
558 cy->setMeanWeight1(wmean);
559
560 if (wmean < 0.8) {
561 cy->Reinit = true;
562 }
563
564 wmean = 0;
565 for (unsigned int i = cy->nbFeaturel1; i < cy->nbFeature; i++) {
566 wmean += w[n + i];
567 vpMeSite p = *itListCyl2;
568 if (w[n + i] < 0.5) {
569 p.setState(vpMeSite::M_ESTIMATOR);
570
571 *itListCyl2 = p;
572 }
573
574 ++itListCyl2;
575 }
576
577 if (cy->nbFeaturel2 != 0)
578 wmean /= cy->nbFeaturel2;
579 else
580 wmean = 1;
581
582 cy->setMeanWeight2(wmean);
583
584 if (wmean < 0.8) {
585 cy->Reinit = true;
586 }
587
588 n += cy->nbFeature;
589 }
590 }
591
592 // Same thing with circles as with lines
594 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
595 if ((*it)->isTracked()) {
596 ci = *it;
597 double wmean = 0;
598 std::list<vpMeSite>::iterator itListCir;
599
600 if (ci->nbFeature > 0) {
601 itListCir = ci->meEllipse->getMeList().begin();
602 }
603
604 wmean = 0;
605 for (unsigned int i = 0; i < ci->nbFeature; i++) {
606 wmean += w[n + i];
607 vpMeSite p = *itListCir;
608 if (w[n + i] < 0.5) {
609 p.setState(vpMeSite::M_ESTIMATOR);
610
611 *itListCir = p;
612 }
613
614 ++itListCir;
615 }
616
617 if (ci->nbFeature != 0)
618 wmean /= ci->nbFeature;
619 else
620 wmean = 1;
621
622 ci->setMeanWeight(wmean);
623
624 if (wmean < 0.8) {
625 ci->Reinit = true;
626 }
627
628 n += ci->nbFeature;
629 }
630 }
631}
632
643void vpMbEdgeKltTracker::computeVVS(const vpImage<unsigned char> &I, const unsigned int &nbInfos, unsigned int &nbrow,
644 unsigned int lvl, double *edge_residual, double *klt_residual)
645{
646 vpColVector factor;
647 nbrow = trackFirstLoop(I, factor, lvl);
648
649 if (nbrow < 4 && nbInfos < 4) {
650 throw vpTrackingException(vpTrackingException::notEnoughPointError, "Error: not enough features");
651 }
652 else if (nbrow < 4)
653 nbrow = 0;
654
655 unsigned int totalNbRows = nbrow + 2 * nbInfos;
656 double residu = 0;
657 double residu_1 = -1;
658 unsigned int iter = 0;
659
660 vpMatrix L(totalNbRows, 6);
661 vpMatrix L_mbt, L_klt; // interaction matrix
662 vpColVector weighted_error(totalNbRows);
663 vpColVector R_mbt, R_klt; // residu
664 vpMatrix L_true;
665 vpMatrix LVJ_true;
666
667 if (nbrow != 0) {
668 L_mbt.resize(nbrow, 6, false, false);
669 R_mbt.resize(nbrow, false);
670 }
671
672 if (nbInfos != 0) {
673 L_klt.resize(2 * nbInfos, 6, false, false);
674 R_klt.resize(2 * nbInfos, false);
675 }
676
677 vpColVector v; // "speed" for VVS
678 vpRobust robust_mbt, robust_klt;
679 vpHomography H;
680
681 vpMatrix LTL;
682 vpColVector LTR;
683
684 double factorMBT; // = 1.0;
685 double factorKLT; // = 1.0;
686
687 // More efficient weight repartition for hybrid tracker should come soon...
688 // factorMBT = 1.0 - (double)nbrow / (double)(nbrow + nbInfos);
689 // factorKLT = 1.0 - factorMBT;
690 factorMBT = 0.35;
691 factorKLT = 0.65;
692
693 if (nbrow < 4)
694 factorKLT = 1.;
695 if (nbInfos < 4)
696 factorMBT = 1.;
697
698 if (edge_residual != nullptr)
699 *edge_residual = 0;
700 if (klt_residual != nullptr)
701 *klt_residual = 0;
702
703 vpHomogeneousMatrix cMoPrev;
704 vpHomogeneousMatrix ctTc0_Prev;
705 vpColVector m_error_prev;
706 vpColVector m_w_prev;
707
708 bool isoJoIdentity = m_isoJoIdentity; // Backup since it can be modified if L is not full rank
709 if (isoJoIdentity)
710 oJo.eye();
711
712 // Init size
713 m_error_hybrid.resize(totalNbRows, false);
714 m_w_hybrid.resize(totalNbRows, false);
715
716 if (nbrow != 0) {
717 m_w_mbt.resize(nbrow, false);
718 m_w_mbt = 1; // needed in vpRobust::psiTukey()
719 }
720
721 if (nbInfos != 0) {
722 m_w_klt.resize(2 * nbInfos, false);
723 m_w_klt = 1; // needed in vpRobust::psiTukey()
724 }
725
726 double mu = m_initialMu;
727
728 while ((static_cast<int>((residu - residu_1) * 1e8) != 0) && (iter < m_maxIter)) {
729 if (nbrow >= 4)
730 trackSecondLoop(I, L_mbt, R_mbt, m_cMo, lvl);
731
732 if (nbInfos >= 4) {
733 unsigned int shift = 0;
734
735 for (std::list<vpMbtDistanceKltPoints *>::const_iterator it = vpMbKltTracker::kltPolygons.begin();
736 it != vpMbKltTracker::kltPolygons.end(); ++it) {
737 vpMbtDistanceKltPoints *kltpoly = *it;
738 if (kltpoly->polygon->isVisible() && kltpoly->isTracked() && kltpoly->hasEnoughPoints()) {
739 vpSubColVector subR(R_klt, shift, 2 * kltpoly->getCurrentNumberPoints());
740 vpSubMatrix subL(L_klt, shift, 0, 2 * kltpoly->getCurrentNumberPoints(), 6);
741 kltpoly->computeHomography(ctTc0, H);
742 kltpoly->computeInteractionMatrixAndResidu(subR, subL);
743 shift += 2 * kltpoly->getCurrentNumberPoints();
744 }
745 }
746
747 for (std::list<vpMbtDistanceKltCylinder *>::const_iterator it = kltCylinders.begin(); it != kltCylinders.end();
748 ++it) {
749 vpMbtDistanceKltCylinder *kltPolyCylinder = *it;
750
751 if (kltPolyCylinder->isTracked() && kltPolyCylinder->hasEnoughPoints()) {
752 vpSubColVector subR(R_klt, shift, 2 * kltPolyCylinder->getCurrentNumberPoints());
753 vpSubMatrix subL(L_klt, shift, 0, 2 * kltPolyCylinder->getCurrentNumberPoints(), 6);
754 try {
755 kltPolyCylinder->computeInteractionMatrixAndResidu(ctTc0, subR, subL);
756 }
757 catch (...) {
758 throw vpTrackingException(vpTrackingException::fatalError, "Cannot compute interaction matrix");
759 }
760
761 shift += 2 * kltPolyCylinder->getCurrentNumberPoints();
762 }
763 }
764 }
765
766 /* residuals */
767 if (nbrow > 3) {
768 m_error_hybrid.insert(0, R_mbt);
769 }
770
771 if (nbInfos > 3) {
772 m_error_hybrid.insert(nbrow, R_klt);
773 }
774
775 unsigned int cpt = 0;
776 while (cpt < (nbrow + 2 * nbInfos)) {
777 if (cpt < static_cast<unsigned int>(nbrow)) {
778 m_w_hybrid[cpt] = ((m_w_mbt[cpt] * factor[cpt]) * factorMBT);
779 }
780 else {
781 m_w_hybrid[cpt] = (m_w_klt[cpt - nbrow] * factorKLT);
782 }
783 cpt++;
784 }
785
786 bool reStartFromLastIncrement = false;
787 computeVVSCheckLevenbergMarquardt(iter, m_error_hybrid, m_error_prev, cMoPrev, mu, reStartFromLastIncrement,
788 &m_w_prev);
789 if (reStartFromLastIncrement) {
790 ctTc0 = ctTc0_Prev;
791 }
792
793 if (!reStartFromLastIncrement) {
794 /* robust */
795 if (nbrow > 3) {
796 if (edge_residual != nullptr) {
797 *edge_residual = 0;
798 for (unsigned int i = 0; i < R_mbt.getRows(); i++)
799 *edge_residual += fabs(R_mbt[i]);
800 *edge_residual /= R_mbt.getRows();
801 }
802
804 robust_mbt.MEstimator(vpRobust::TUKEY, R_mbt, m_w_mbt);
805
806 L.insert(L_mbt, 0, 0);
807 }
808
809 if (nbInfos > 3) {
810 if (klt_residual != nullptr) {
811 *klt_residual = 0;
812 for (unsigned int i = 0; i < R_klt.getRows(); i++)
813 *klt_residual += fabs(R_klt[i]);
814 *klt_residual /= R_klt.getRows();
815 }
816
818 robust_klt.MEstimator(vpRobust::TUKEY, R_klt, m_w_klt);
819
820 L.insert(L_klt, nbrow, 0);
821 }
822
823 cpt = 0;
824 while (cpt < (nbrow + 2 * nbInfos)) {
825 if (cpt < static_cast<unsigned int>(nbrow)) {
826 m_w_hybrid[cpt] = ((m_w_mbt[cpt] * factor[cpt]) * factorMBT);
827 }
828 else {
829 m_w_hybrid[cpt] = (m_w_klt[cpt - nbrow] * factorKLT);
830 }
831 cpt++;
832 }
833
834 if (computeCovariance) {
835 L_true = L;
836 if (!isoJoIdentity) {
838 cVo.buildFrom(m_cMo);
839 LVJ_true = (L * cVo * oJo);
840 }
841 }
842
843 residu_1 = residu;
844 residu = 0;
845 double num = 0;
846 double den = 0;
847
848 for (unsigned int i = 0; i < weighted_error.getRows(); i++) {
849 num += m_w_hybrid[i] * vpMath::sqr(m_error_hybrid[i]);
850 den += m_w_hybrid[i];
851
852 weighted_error[i] = m_error_hybrid[i] * m_w_hybrid[i];
854 for (unsigned int j = 0; j < 6; j += 1) {
855 L[i][j] *= m_w_hybrid[i];
856 }
857 }
858 }
859
860 residu = sqrt(num / den);
861
862 computeVVSPoseEstimation(isoJoIdentity, iter, L, LTL, weighted_error, m_error_hybrid, m_error_prev, LTR, mu, v,
863 &m_w_hybrid, &m_w_prev);
864
865 cMoPrev = m_cMo;
866 ctTc0_Prev = ctTc0;
868 m_cMo = ctTc0 * c0Mo;
869 }
870
871 iter++;
872 }
873
874 computeCovarianceMatrixVVS(isoJoIdentity, m_w_hybrid, cMoPrev, L_true, LVJ_true, m_error_hybrid);
875}
876
878{
879 throw vpException(vpException::fatalError, "vpMbEdgeKltTracker::computeVVSInit() should not be called!");
880}
881
883{
884 throw vpException(vpException::fatalError, "vpMbEdgeKltTracker::"
885 "computeVVSInteractionMatrixAndR"
886 "esidu() should not be called!");
887}
888
897{
898 try {
900 }
901 catch (...) {
902 }
903
904 if (m_nbInfos >= 4) {
905 unsigned int old_maxIter = m_maxIter;
908 m_maxIter = old_maxIter;
909 }
910 else {
911 m_nbInfos = 0;
912 // std::cout << "[Warning] Unable to init with KLT" << std::endl;
913 }
914
916
917 unsigned int nbrow = 0;
918 computeVVS(I, m_nbInfos, nbrow);
919
920 if (postTracking(I, m_w_mbt, m_w_klt)) {
922
923 // AY : Removed as edge tracked, if necessary, is reinitialized in
924 // postTracking()
925
926 // initPyramid(I, Ipyramid);
927
928 // unsigned int i = (unsigned int)scales.size();
929 // do {
930 // i--;
931 // if(scales[i]){
932 // downScale(i);
933 // initMovingEdge(*Ipyramid[i], cMo);
934 // upScale(i);
935 // }
936 // } while(i != 0);
937
938 // cleanPyramid(Ipyramid);
939 }
940
941 if (displayFeatures) {
943 }
944}
945
954{
956 try {
958 }
959 catch (...) {
960 }
961
962 if (m_nbInfos >= 4) {
963 unsigned int old_maxIter = m_maxIter;
966 m_maxIter = old_maxIter;
967 }
968 else {
969 m_nbInfos = 0;
970 // std::cout << "[Warning] Unable to init with KLT" << std::endl;
971 }
972
974
975 unsigned int nbrow = 0;
976 computeVVS(m_I, m_nbInfos, nbrow);
977
978 if (postTracking(I_color, m_w_mbt, m_w_klt)) {
980
981 // AY : Removed as edge tracked, if necessary, is reinitialized in
982 // postTracking()
983
984 // initPyramid(I, Ipyramid);
985
986 // unsigned int i = (unsigned int)scales.size();
987 // do {
988 // i--;
989 // if(scales[i]){
990 // downScale(i);
991 // initMovingEdge(*Ipyramid[i], cMo);
992 // upScale(i);
993 // }
994 // } while(i != 0);
995
996 // cleanPyramid(Ipyramid);
997 }
998
999 if (displayFeatures) {
1001 }
1002}
1003
1004unsigned int vpMbEdgeKltTracker::trackFirstLoop(const vpImage<unsigned char> &I, vpColVector &factor, unsigned int lvl)
1005{
1009
1010 if (lvl >= scales.size() || !scales[lvl]) {
1011 throw vpException(vpException::dimensionError, "_lvl not used.");
1012 }
1013
1014 unsigned int nbrow = initMbtTracking(lvl);
1015
1016 if (nbrow == 0) {
1017 // throw vpTrackingException(vpTrackingException::notEnoughPointError,
1018 // "Error: not enough features in the interaction matrix...");
1019 return nbrow;
1020 }
1021
1022 factor.resize(nbrow, false);
1023 factor = 1;
1024
1025 unsigned int n = 0;
1026 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
1027 if ((*it)->isTracked()) {
1028 l = *it;
1030
1031 double fac = 1;
1032 for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
1033 ++itindex) {
1034 int index = *itindex;
1035 if (l->hiddenface->isAppearing(static_cast<unsigned int>(index))) {
1036 fac = 0.2;
1037 break;
1038 }
1039 if (l->closeToImageBorder(I, 10)) {
1040 fac = 0.1;
1041 break;
1042 }
1043 }
1044
1045 for (size_t a = 0; a < l->meline.size(); a++) {
1046 std::list<vpMeSite>::const_iterator itListLine;
1047 if (l->meline[a] != nullptr) {
1048 itListLine = l->meline[a]->getMeList().begin();
1049
1050 for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
1051 factor[n + i] = fac;
1052 vpMeSite site = *itListLine;
1053 if (site.getState() != vpMeSite::NO_SUPPRESSION)
1054 factor[n + i] = 0.2;
1055 ++itListLine;
1056 }
1057 n += l->nbFeature[a];
1058 }
1059 }
1060 }
1061 }
1062
1063 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
1064 ++it) {
1065 if ((*it)->isTracked()) {
1066 cy = *it;
1068 double fac = 1.0;
1069
1070 std::list<vpMeSite>::const_iterator itCyl1;
1071 std::list<vpMeSite>::const_iterator itCyl2;
1072 if ((cy->meline1 != nullptr || cy->meline2 != nullptr)) {
1073 itCyl1 = cy->meline1->getMeList().begin();
1074 itCyl2 = cy->meline2->getMeList().begin();
1075 }
1076
1077 for (unsigned int i = 0; i < cy->nbFeature; i++) {
1078 factor[n + i] = fac;
1079 vpMeSite site;
1080 if (i < cy->nbFeaturel1) {
1081 site = *itCyl1;
1082 ++itCyl1;
1083 }
1084 else {
1085 site = *itCyl2;
1086 ++itCyl2;
1087 }
1088 if (site.getState() != vpMeSite::NO_SUPPRESSION)
1089 factor[n + i] = 0.2;
1090 }
1091
1092 n += cy->nbFeature;
1093 }
1094 }
1095
1096 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
1097 if ((*it)->isTracked()) {
1098 ci = *it;
1100 double fac = 1.0;
1101
1102 std::list<vpMeSite>::const_iterator itCir;
1103 if (ci->meEllipse != nullptr) {
1104 itCir = ci->meEllipse->getMeList().begin();
1105 }
1106
1107 for (unsigned int i = 0; i < ci->nbFeature; i++) {
1108 factor[n + i] = fac;
1109 vpMeSite site = *itCir;
1110 if (site.getState() != vpMeSite::NO_SUPPRESSION)
1111 factor[n + i] = 0.2;
1112 ++itCir;
1113 }
1114
1115 n += ci->nbFeature;
1116 }
1117 }
1118
1119 return nbrow;
1120}
1121
1123 const vpHomogeneousMatrix &cMo, unsigned int lvl)
1124{
1128
1129 unsigned int n = 0;
1130 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
1131 if ((*it)->isTracked()) {
1132 l = *it;
1134 for (unsigned int i = 0; i < l->nbFeatureTotal; i++) {
1135 for (unsigned int j = 0; j < 6; j++) {
1136 L[n + i][j] = l->L[i][j];
1137 error[n + i] = l->error[i];
1138 }
1139 }
1140 n += l->nbFeatureTotal;
1141 }
1142 }
1143
1144 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
1145 ++it) {
1146 if ((*it)->isTracked()) {
1147 cy = *it;
1149 for (unsigned int i = 0; i < cy->nbFeature; i++) {
1150 for (unsigned int j = 0; j < 6; j++) {
1151 L[n + i][j] = cy->L[i][j];
1152 error[n + i] = cy->error[i];
1153 }
1154 }
1155 n += cy->nbFeature;
1156 }
1157 }
1158 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
1159 if ((*it)->isTracked()) {
1160 ci = *it;
1162 for (unsigned int i = 0; i < ci->nbFeature; i++) {
1163 for (unsigned int j = 0; j < 6; j++) {
1164 L[n + i][j] = ci->L[i][j];
1165 error[n + i] = ci->error[i];
1166 }
1167 }
1168
1169 n += ci->nbFeature;
1170 }
1171 }
1172}
1173
1186
1198
1209
1221void vpMbEdgeKltTracker::initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius, int idFace,
1222 const std::string &name)
1223{
1224 vpMbEdgeTracker::initCircle(p1, p2, p3, radius, idFace, name);
1225}
1226
1237void vpMbEdgeKltTracker::initCylinder(const vpPoint &p1, const vpPoint &p2, double radius, int idFace,
1238 const std::string &name)
1239{
1240 vpMbEdgeTracker::initCylinder(p1, p2, radius, idFace, name);
1241 vpMbKltTracker::initCylinder(p1, p2, radius, idFace, name);
1242}
1243
1256 const vpCameraParameters &cam, const vpColor &col, unsigned int thickness,
1257 bool displayFullModel)
1258{
1259 std::vector<std::vector<double> > models =
1260 vpMbEdgeKltTracker::getModelForDisplay(I.getWidth(), I.getHeight(), cMo, cam, displayFullModel);
1261
1262 for (size_t i = 0; i < models.size(); i++) {
1263 if (vpMath::equal(models[i][0], 0)) {
1264 vpImagePoint ip1(models[i][1], models[i][2]);
1265 vpImagePoint ip2(models[i][3], models[i][4]);
1266 vpDisplay::displayLine(I, ip1, ip2, col, thickness);
1267 }
1268 else if (vpMath::equal(models[i][0], 1)) {
1269 vpImagePoint center(models[i][1], models[i][2]);
1270 double n20 = models[i][3];
1271 double n11 = models[i][4];
1272 double n02 = models[i][5];
1273 vpDisplay::displayEllipse(I, center, n20, n11, n02, true, col, thickness);
1274 }
1275 }
1276
1277 if (displayFeatures) {
1278 for (size_t i = 0; i < m_featuresToBeDisplayedKlt.size(); i++) {
1282
1284 double id = m_featuresToBeDisplayedKlt[i][5];
1285 std::stringstream ss;
1286 ss << id;
1287 vpDisplay::displayText(I, ip2, ss.str(), vpColor::red);
1288 }
1289 }
1290 }
1291
1292#ifdef VISP_HAVE_OGRE
1293 if (useOgre)
1294 faces.displayOgre(cMo);
1295#endif
1296}
1297
1310 const vpCameraParameters &cam, const vpColor &col, unsigned int thickness,
1311 bool displayFullModel)
1312{
1313 std::vector<std::vector<double> > models =
1314 getModelForDisplay(I.getWidth(), I.getHeight(), cMo, cam, displayFullModel);
1315
1316 for (size_t i = 0; i < models.size(); i++) {
1317 if (vpMath::equal(models[i][0], 0)) {
1318 vpImagePoint ip1(models[i][1], models[i][2]);
1319 vpImagePoint ip2(models[i][3], models[i][4]);
1320 vpDisplay::displayLine(I, ip1, ip2, col, thickness);
1321 }
1322 else if (vpMath::equal(models[i][0], 1)) {
1323 vpImagePoint center(models[i][1], models[i][2]);
1324 double n20 = models[i][3];
1325 double n11 = models[i][4];
1326 double n02 = models[i][5];
1327 vpDisplay::displayEllipse(I, center, n20, n11, n02, true, col, thickness);
1328 }
1329 }
1330
1331 if (displayFeatures) {
1332 for (size_t i = 0; i < m_featuresToBeDisplayedKlt.size(); i++) {
1336
1338 double id = m_featuresToBeDisplayedKlt[i][5];
1339 std::stringstream ss;
1340 ss << id;
1341 vpDisplay::displayText(I, ip2, ss.str(), vpColor::red);
1342 }
1343 }
1344 }
1345
1346#ifdef VISP_HAVE_OGRE
1347 if (useOgre)
1348 faces.displayOgre(cMo);
1349#endif
1350}
1351
1352std::vector<std::vector<double> > vpMbEdgeKltTracker::getModelForDisplay(unsigned int width, unsigned int height,
1353 const vpHomogeneousMatrix &cMo,
1354 const vpCameraParameters &cam,
1355 bool displayFullModel)
1356{
1357 std::vector<std::vector<double> > models;
1358
1359 for (unsigned int i = 0; i < scales.size(); i += 1) {
1360 if (scales[i]) {
1361 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1362 ++it) {
1363 std::vector<std::vector<double> > currentModel =
1364 (*it)->getModelForDisplay(width, height, cMo, cam, displayFullModel);
1365 models.insert(models.end(), currentModel.begin(), currentModel.end());
1366 }
1367
1368 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1369 it != cylinders[scaleLevel].end(); ++it) {
1370 std::vector<std::vector<double> > currentModel =
1371 (*it)->getModelForDisplay(width, height, cMo, cam, displayFullModel);
1372 models.insert(models.end(), currentModel.begin(), currentModel.end());
1373 }
1374
1375 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1376 it != circles[scaleLevel].end(); ++it) {
1377 std::vector<double> paramsCircle = (*it)->getModelForDisplay(cMo, cam, displayFullModel);
1378 models.push_back(paramsCircle);
1379 }
1380
1381 break; // displaying model on one scale only
1382 }
1383 }
1384
1385#ifdef VISP_HAVE_OGRE
1386 if (useOgre)
1387 faces.displayOgre(cMo);
1388#endif
1389
1390 return models;
1391}
1392
1405void vpMbEdgeKltTracker::reInitModel(const vpImage<unsigned char> &I, const std::string &cad_name,
1406 const vpHomogeneousMatrix &cMo, bool verbose, const vpHomogeneousMatrix &T)
1407{
1408 // Reinit klt
1409
1410 // delete the Klt Polygon features
1411 for (std::list<vpMbtDistanceKltPoints *>::const_iterator it = kltPolygons.begin(); it != kltPolygons.end(); ++it) {
1412 vpMbtDistanceKltPoints *kltpoly = *it;
1413 if (kltpoly != nullptr) {
1414 delete kltpoly;
1415 }
1416 kltpoly = nullptr;
1417 }
1418 kltPolygons.clear();
1419
1420 for (std::list<vpMbtDistanceKltCylinder *>::const_iterator it = kltCylinders.begin(); it != kltCylinders.end();
1421 ++it) {
1422 vpMbtDistanceKltCylinder *kltPolyCylinder = *it;
1423 if (kltPolyCylinder != nullptr) {
1424 delete kltPolyCylinder;
1425 }
1426 kltPolyCylinder = nullptr;
1427 }
1428 kltCylinders.clear();
1429
1430 // delete the structures used to display circles
1432 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles_disp.begin(); it != circles_disp.end(); ++it) {
1433 ci = *it;
1434 if (ci != nullptr) {
1435 delete ci;
1436 }
1437 ci = nullptr;
1438 }
1439
1440 circles_disp.clear();
1441
1442 firstInitialisation = true;
1443
1444 // Reinit edge
1447
1448 for (unsigned int i = 0; i < scales.size(); i += 1) {
1449 if (scales[i]) {
1450 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
1451 l = *it;
1452 if (l != nullptr)
1453 delete l;
1454 l = nullptr;
1455 }
1456
1457 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
1458 ++it) {
1459 cy = *it;
1460 if (cy != nullptr)
1461 delete cy;
1462 cy = nullptr;
1463 }
1464
1465 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
1466 ci = *it;
1467 if (ci != nullptr)
1468 delete ci;
1469 ci = nullptr;
1470 }
1471
1472 lines[i].clear();
1473 cylinders[i].clear();
1474 circles[i].clear();
1475 }
1476 }
1477
1478 // compute_interaction=1;
1479 nline = 0;
1480 ncylinder = 0;
1481 ncircle = 0;
1482 // lambda = 1;
1484
1485 // Reinit common parts
1486 faces.reset();
1487
1488 loadModel(cad_name, verbose, T);
1489
1490 m_cMo = cMo;
1491 init(I);
1492}
1493END_VISP_NAMESPACE
1494#elif !defined(VISP_BUILD_SHARED_LIBS)
1495// Work around to avoid warning: libvisp_mbt.a(vpMbEdgeKltTracker.cpp.o) has
1496// no symbols
1497void dummy_vpMbEdgeKltTracker() { }
1498#endif // VISP_HAVE_OPENCV
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition vpArray2D.h:448
unsigned int getRows() const
Definition vpArray2D.h:433
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
void resize(unsigned int i, bool flagNullify=true)
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
static const vpColor red
Definition vpColor.h:198
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 displayEllipse(const vpImage< unsigned char > &I, const vpImagePoint &center, const double &coef1, const double &coef2, const double &coef3, bool use_normalized_centered_moments, const vpColor &color, unsigned int thickness=1, bool display_center=false, bool display_arc=false)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ ioError
I/O error.
Definition vpException.h:67
@ dimensionError
Bad dimension.
Definition vpException.h:71
@ 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
Implementation of an homography and operations on homographies.
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
double m_thresholdKLT
The threshold used in the robust estimation of KLT.
virtual void initCircle(const vpPoint &, const vpPoint &, const vpPoint &, double r, int idFace=0, const std::string &name="") VP_OVERRIDE
void reInitModel(const vpImage< unsigned char > &I, const std::string &cad_name, const vpHomogeneousMatrix &cMo, bool verbose=false, const vpHomogeneousMatrix &T=vpHomogeneousMatrix()) 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
virtual void loadConfigFile(const std::string &configFile, bool verbose=true) VP_OVERRIDE
virtual void init(const vpImage< unsigned char > &I) VP_OVERRIDE
virtual void setNearClippingDistance(const double &dist) VP_OVERRIDE
virtual void computeVVSInit() VP_OVERRIDE
void resetTracker() VP_OVERRIDE
virtual void setCameraParameters(const vpCameraParameters &cam) VP_OVERRIDE
vpColVector m_w_mbt
Robust weights for Edge.
bool postTracking(const vpImage< unsigned char > &I, vpColVector &w_mbt, vpColVector &w_klt, unsigned int lvl=0)
virtual void initFaceFromLines(vpMbtPolygon &polygon) VP_OVERRIDE
unsigned int trackFirstLoop(const vpImage< unsigned char > &I, vpColVector &factor, unsigned int lvl=0)
void postTrackingMbt(vpColVector &w, unsigned int level=0)
void trackSecondLoop(const vpImage< unsigned char > &I, vpMatrix &L, vpColVector &_error, const vpHomogeneousMatrix &cMo, unsigned int lvl=0)
virtual void computeCovarianceMatrixVVS(const bool isoJoIdentity, const vpColVector &w_true, const vpHomogeneousMatrix &cMoPrev, const vpMatrix &L_true, const vpMatrix &LVJ_true, const vpColVector &error)
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)
unsigned int initMbtTracking(unsigned int level=0)
virtual void initFaceFromCorners(vpMbtPolygon &polygon) VP_OVERRIDE
virtual void track(const vpImage< unsigned char > &I) VP_OVERRIDE
vpColVector m_error_hybrid
(s - s*)
virtual void initCylinder(const vpPoint &, const vpPoint &, double r, int idFace, const std::string &name="") VP_OVERRIDE
virtual void setClipping(const unsigned int &flags) VP_OVERRIDE
virtual void setFarClippingDistance(const double &dist) VP_OVERRIDE
vpColVector m_w_klt
Robust weights for KLT.
double m_thresholdMBT
The threshold used in the robust estimation of MBT.
virtual void computeVVSInteractionMatrixAndResidu() VP_OVERRIDE
unsigned int m_maxIterKlt
The maximum iteration of the virtual visual servoing stage.
virtual std::vector< std::vector< double > > getModelForDisplay(unsigned int width, unsigned int height, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false) VP_OVERRIDE
virtual void setPose(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cdMo) VP_OVERRIDE
vpColVector m_w_hybrid
Robust weights.
void upScale(const unsigned int _scale)
std::vector< std::list< vpMbtDistanceLine * > > lines
vpMe me
The moving edges parameters.
void computeProjectionError(const vpImage< unsigned char > &_I)
unsigned int ncylinder
void downScale(const unsigned int _scale)
void cleanPyramid(std::vector< const vpImage< unsigned char > * > &_pyramid)
std::vector< std::list< vpMbtDistanceCylinder * > > cylinders
Vector of the tracked cylinders.
void initPyramid(const vpImage< unsigned char > &_I, std::vector< const vpImage< unsigned char > * > &_pyramid)
unsigned int nbvisiblepolygone
Number of polygon (face) currently visible.
std::vector< std::list< vpMbtDistanceCircle * > > circles
Vector of the tracked circles.
unsigned int scaleLevel
virtual void initFaceFromLines(vpMbtPolygon &polygon) VP_OVERRIDE
void trackMovingEdge(const vpImage< unsigned char > &I)
std::vector< const vpImage< unsigned char > * > Ipyramid
unsigned int ncircle
virtual void initFaceFromCorners(vpMbtPolygon &polygon) VP_OVERRIDE
std::vector< bool > scales
Vector of scale level to use for the multi-scale tracking.
void updateMovingEdge(const vpImage< unsigned char > &I)
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
void resetTracker() VP_OVERRIDE
virtual void initCylinder(const vpPoint &p1, const vpPoint &p2, double radius, int idFace=0, const std::string &name="") VP_OVERRIDE
void setMovingEdge(const vpMe &me)
virtual void setCameraParameters(const vpCameraParameters &cam) VP_OVERRIDE
virtual void initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius, int idFace=0, const std::string &name="") VP_OVERRIDE
void initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo, const bool &useInitRange=true)
unsigned int nline
bool isAppearing(unsigned int i)
std::list< vpMbtDistanceKltCylinder * > kltCylinders
vpHomogeneousMatrix c0Mo
Initial pose.
vpHomogeneousMatrix ctTc0
std::list< vpMbtDistanceKltPoints * > kltPolygons
void resetTracker() VP_OVERRIDE
void setCameraParameters(const vpCameraParameters &cam) VP_OVERRIDE
std::list< vpMbtDistanceCircle * > circles_disp
Vector of the circles used here only to display the full model.
vpKltOpencv tracker
Points tracker.
virtual std::vector< std::vector< double > > getFeaturesForDisplayKlt()
virtual void init(const vpImage< unsigned char > &I) VP_OVERRIDE
void preTracking(const vpImage< unsigned char > &I)
virtual void initCylinder(const vpPoint &, const vpPoint &, double, int, const std::string &name="") VP_OVERRIDE
virtual void initFaceFromCorners(vpMbtPolygon &polygon) VP_OVERRIDE
unsigned int m_nbInfos
bool postTracking(const vpImage< unsigned char > &I, vpColVector &w)
virtual void reinit(const vpImage< unsigned char > &I)
virtual void setPose(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cdMo) VP_OVERRIDE
unsigned int maskBorder
Erosion of the mask.
std::vector< std::vector< double > > m_featuresToBeDisplayedKlt
Display features.
virtual void initFaceFromLines(vpMbtPolygon &polygon) VP_OVERRIDE
double m_lambda
Gain of the virtual visual servoing stage.
double minLineLengthThresholdGeneral
Minimum line length threshold for LOD mode (general setting).
virtual void setMinLineLengthThresh(double minLineLengthThresh, const std::string &name="")
vpImage< unsigned char > m_I
Grayscale image buffer, used when passing color images.
bool useLodGeneral
True if LOD mode is enabled.
double minPolygonAreaThresholdGeneral
Minimum polygon area threshold for LOD mode (general setting).
bool m_computeInteraction
vpMatrix oJo
The Degrees of Freedom to estimate.
virtual void setMinPolygonAreaThresh(double minPolygonAreaThresh, const std::string &name="")
double m_initialMu
Initial Mu for Levenberg Marquardt optimization loop.
bool computeProjError
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.
bool useOgre
Use Ogre3d for global visibility tests.
vpMbHiddenFaces< vpMbtPolygon > faces
Set of faces describing the object.
virtual void setLod(bool useLod, const std::string &name="")
bool displayFeatures
If true, the features are displayed.
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 unsigned int getNbPolygon() const
bool applyLodSettingInConfig
bool m_isoJoIdentity
Boolean to know if oJo is identity (for fast computation).
bool useScanLine
Use Scanline for global visibility tests.
double angleAppears
Angle used to detect a face appearance.
bool computeCovariance
Flag used to specify if the covariance matrix has to be computed or not.
unsigned int m_maxIter
Maximum number of iterations of the virtual visual servoing stage.
unsigned int clippingFlag
Flags specifying which clipping to used.
virtual void loadConfigFile(const std::string &configFile, bool verbose=true)
Manage a circle used in the model-based tracker.
vpColVector error
The error vector.
unsigned int nbFeature
The number of moving edges.
vpMatrix L
The interaction matrix.
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
void setMeanWeight(double _wmean)
void displayMovingEdges(const vpImage< unsigned char > &I)
bool Reinit
Indicates if the circle has to be reinitialized.
vpMbtMeEllipse * meEllipse
The moving edge containers.
Manage a cylinder used in the model-based tracker.
void setMeanWeight1(double wmean)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo, const vpImage< unsigned char > &I)
vpMbtMeLine * meline2
The moving edge containers (second line of the cylinder).
vpMatrix L
The interaction matrix.
unsigned int nbFeaturel2
The number of moving edges on line 2.
bool Reinit
Indicates if the line has to be reinitialized.
void setMeanWeight2(double wmean)
unsigned int nbFeaturel1
The number of moving edges on line 1.
vpColVector error
The error vector.
void displayMovingEdges(const vpImage< unsigned char > &I)
unsigned int nbFeature
The number of moving edges.
vpMbtMeLine * meline1
The moving edge containers (first line of the cylinder).
Implementation of a polygon of the model containing points of interest. It is used by the model-based...
void computeInteractionMatrixAndResidu(const vpHomogeneousMatrix &cMc0, vpColVector &_R, vpMatrix &_J)
unsigned int getCurrentNumberPoints() const
Implementation of a polygon of the model containing points of interest. It is used by the model-based...
void computeInteractionMatrixAndResidu(vpColVector &_R, vpMatrix &_J)
unsigned int getCurrentNumberPoints() const
vpMbtPolygon * polygon
Pointer to the polygon that define a face.
void computeHomography(const vpHomogeneousMatrix &_cTc0, vpHomography &cHc0)
Manage the line of a polygon used in the model-based tracker.
std::vector< unsigned int > nbFeature
The number of moving edges.
void displayMovingEdges(const vpImage< unsigned char > &I)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
std::list< int > Lindex_polygon
Index of the faces which contain the line.
unsigned int nbFeatureTotal
The number of moving edges.
bool Reinit
Indicates if the line has to be reinitialized.
vpColVector error
The error vector.
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
bool closeToImageBorder(const vpImage< unsigned char > &I, const unsigned int threshold)
std::vector< vpMbtMeLine * > meline
The moving edge container.
vpMatrix L
The interaction matrix.
void setMeanWeight(double w_mean)
Implementation of a polygon of the model used by the model-based tracker.
virtual bool isVisible(const vpHomogeneousMatrix &cMo, double alpha, const bool &modulo=false, const vpCameraParameters &cam=vpCameraParameters(), unsigned int width=0, unsigned int height=0)
Parse an Xml file to extract configuration parameters of a mbtConfig object.
unsigned int getKltMaxFeatures() const
void setKltMinDistance(const double &mD)
unsigned int getKltBlockSize() const
void getCameraParameters(vpCameraParameters &cam) const
void setEdgeMe(const vpMe &ecm)
void setKltMaskBorder(const unsigned int &mb)
void getEdgeMe(vpMe &ecm) const
double getLodMinLineLengthThreshold() const
unsigned int getKltMaskBorder() const
void setAngleDisappear(const double &adisappear)
void setKltPyramidLevels(const unsigned int &pL)
void setKltWindowSize(const unsigned int &w)
void setKltMaxFeatures(const unsigned int &mF)
void setAngleAppear(const double &aappear)
void setKltBlockSize(const unsigned int &bs)
void setKltHarrisParam(const double &hp)
void parse(const std::string &filename)
void setKltQuality(const double &q)
unsigned int getKltPyramidLevels() const
unsigned int getKltWindowSize() const
void setCameraParameters(const vpCameraParameters &cam)
double getLodMinPolygonAreaThreshold() const
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition vpMeSite.h:75
@ M_ESTIMATOR
Point detected as an outlier during virtual visual-servoing.
Definition vpMeSite.h:99
@ NO_SUPPRESSION
Point successfully tracked.
Definition vpMeSite.h:93
vpMeSiteState getState() const
Definition vpMeSite.h:306
Definition vpMe.h:143
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
Contains an M-estimator and various influence function.
Definition vpRobust.h:84
@ TUKEY
Tukey influence function.
Definition vpRobust.h:89
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Definition vpRobust.cpp:130
void setMinMedianAbsoluteDeviation(double mad_min)
Definition vpRobust.h:136
Definition of the vpSubMatrix class that provides a mask on a vpMatrix. All properties of vpMatrix ar...
Definition vpSubMatrix.h:57
Error that can be emitted by the vpTracker class and its derivatives.
@ notEnoughPointError
Not enough point to track.
@ fatalError
Tracker fatal error.
vpVelocityTwistMatrix & buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
#define vpERROR_TRACE
Definition vpDebug.h:423