Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMbEdgeTracker.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 * Make the complete tracking of an object by using its CAD model
32 */
33
38
39#include <visp3/core/vpDebug.h>
40#include <visp3/core/vpException.h>
41#include <visp3/core/vpExponentialMap.h>
42#include <visp3/core/vpMath.h>
43#include <visp3/core/vpMatrixException.h>
44#include <visp3/core/vpPixelMeterConversion.h>
45#include <visp3/core/vpPolygon3D.h>
46#include <visp3/core/vpTrackingException.h>
47#include <visp3/core/vpVelocityTwistMatrix.h>
48#include <visp3/mbt/vpMbEdgeTracker.h>
49#include <visp3/mbt/vpMbtDistanceLine.h>
50#include <visp3/mbt/vpMbtXmlGenericParser.h>
51#include <visp3/vision/vpPose.h>
52
53#include <float.h>
54#include <limits>
55#include <map>
56#include <sstream>
57#include <string>
58
76
81{
85
86 for (unsigned int i = 0; i < scales.size(); i += 1) {
87 if (scales[i]) {
88 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
89 l = *it;
90 if (l != nullptr) {
91 delete l;
92 }
93 l = nullptr;
94 }
95
96 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
97 ++it) {
98 cy = *it;
99 if (cy != nullptr) {
100 delete cy;
101 }
102 cy = nullptr;
103 }
104
105 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
106 ci = *it;
107 if (ci != nullptr) {
108 delete ci;
109 }
110 ci = nullptr;
111 }
112
113 lines[i].clear();
114 cylinders[i].clear();
115 circles[i].clear();
116 }
117 }
118
120}
121
128{
129 this->me = p_me;
130
131 for (unsigned int i = 0; i < scales.size(); i += 1) {
132 if (scales[i]) {
133 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
134 vpMbtDistanceLine *l = *it;
135 l->setMovingEdge(&(this->me));
136 }
137
138 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
139 ++it) {
140 vpMbtDistanceCylinder *cy = *it;
141 cy->setMovingEdge(&(this->me));
142 }
143
144 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
145 vpMbtDistanceCircle *ci = *it;
146 ci->setMovingEdge(&(this->me));
147 }
148 }
149 }
150}
151
162{
163 double residu_1 = 1e3;
164 double r = 1e3 - 1;
165
166 unsigned int iter = 0;
167
169 unsigned int nbrow = m_error_edge.getRows();
170
171 bool reloop = true;
172
173 bool isoJoIdentity = m_isoJoIdentity; // Backup since it can be modified if L is not full rank
174 if (isoJoIdentity)
175 oJo.eye();
176
177 /*** First phase ***/
178
179 while (reloop == true && iter < 10) {
180 double count = 0;
181
182 computeVVSFirstPhase(I_, iter, count, lvl);
183
184 count = count / static_cast<double>(nbrow);
185 if (count >= 0.85) {
186 reloop = false;
187 }
188
189 computeVVSFirstPhasePoseEstimation(iter, isoJoIdentity);
190
191 iter++;
192 }
193
194 // std::cout << "\t First minimization in " << iter << " iteration give as
195 // initial cMo: \n" << cMo << std::endl;
196
197 /*** Second phase ***/
198 vpHomogeneousMatrix cMoPrev;
199 vpColVector W_true(nbrow);
200 vpMatrix L_true;
201 vpMatrix LVJ_true;
202
203 double mu = m_initialMu;
204 vpColVector m_error_prev;
205 vpColVector m_w_prev;
206
207 // To avoid to create these matrices each iteration
208 vpMatrix LTL;
209 vpColVector LTR;
210 vpColVector v;
211
212 iter = 0;
213 m_w_edge = 1;
214
215 // while ( (static_cast<int>((residu_1 - r)*1e8) !=0 ) && (iter<30))
216 while (std::fabs((residu_1 - r) * 1e8) > std::numeric_limits<double>::epsilon() && (iter < m_maxIter)) {
218
219 bool reStartFromLastIncrement = false;
220 computeVVSCheckLevenbergMarquardt(iter, m_error_edge, m_error_prev, cMoPrev, mu, reStartFromLastIncrement,
221 &m_w_edge, &m_w_prev);
222
223 if (!reStartFromLastIncrement) {
225
226 L_true = m_L_edge;
228
229 if (computeCovariance) {
230 L_true = m_L_edge;
231 if (!isoJoIdentity) {
232 cVo.buildFrom(m_cMo);
233 LVJ_true = (m_L_edge * cVo * oJo);
234 }
235 }
236
237 double wi = 0.0, eri = 0.0;
238 double num = 0.0, den = 0.0;
239 if ((iter == 0) || m_computeInteraction) {
240 for (unsigned int i = 0; i < nbrow; i++) {
241 wi = m_w_edge[i] * m_factor[i];
242 W_true[i] = wi;
243 eri = m_error_edge[i];
244 num += wi * vpMath::sqr(eri);
245 den += wi;
246
247 m_weightedError_edge[i] = wi * eri;
248
249 for (unsigned int j = 0; j < 6; j++) {
250 m_L_edge[i][j] = wi * m_L_edge[i][j];
251 }
252 }
253 }
254 else {
255 for (unsigned int i = 0; i < nbrow; i++) {
256 wi = m_w_edge[i] * m_factor[i];
257 W_true[i] = wi;
258 eri = m_error_edge[i];
259 num += wi * vpMath::sqr(eri);
260 den += wi;
261
262 m_weightedError_edge[i] = wi * eri;
263 }
264 }
265
266 residu_1 = r;
267 r = sqrt(num / den); // Le critere d'arret prend en compte le poids
268
269 computeVVSPoseEstimation(isoJoIdentity, iter, m_L_edge, LTL, m_weightedError_edge, m_error_edge, m_error_prev,
270 LTR, mu, v, &m_w_edge, &m_w_prev);
271
272 cMoPrev = m_cMo;
274
275 } // endif(!restartFromLast)
276
277 iter++;
278 }
279
280 computeCovarianceMatrixVVS(isoJoIdentity, W_true, cMoPrev, L_true, LVJ_true, m_error_edge);
281
283}
284
285void vpMbEdgeTracker::computeVVSFirstPhase(const vpImage<unsigned char> &I_, unsigned int iter, double &count,
286 unsigned int lvl)
287{
291
292 double limite = 3; // Une limite de 3 pixels
293 limite = limite / m_cam.get_px(); // Transformation limite pixel en limite metre.
294
295 unsigned int n = 0;
296
297 // Parametre pour la premiere phase d'asservissement
298 double e_prev = 0, e_cur, e_next;
299
300 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
301 if ((*it)->isTracked()) {
302 l = *it;
304
305 double fac = 1;
306 if (iter == 0) {
307 for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
308 ++itindex) {
309 int index = *itindex;
310 if (l->hiddenface->isAppearing(static_cast<unsigned int>(index))) {
311 fac = 0.2;
312 break;
313 }
314 if (l->closeToImageBorder(I_, 10)) {
315 fac = 0.1;
316 break;
317 }
318 }
319 }
320
321 std::list<vpMeSite>::const_iterator itListLine;
322
323 unsigned int indexFeature = 0;
324
325 for (size_t a = 0; a < l->meline.size(); a++) {
326 if (iter == 0 && l->meline[a] != nullptr)
327 itListLine = l->meline[a]->getMeList().begin();
328
329 for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
330 for (unsigned int j = 0; j < 6; j++) {
331 m_L_edge[n + i][j] = l->L[indexFeature][j]; // On remplit la matrice d'interaction globale
332 }
333 m_error_edge[n + i] = l->error[indexFeature]; // On remplit la matrice d'erreur
334
335 if (m_error_edge[n + i] <= limite)
336 count = count + 1.0; // Si erreur proche de 0 on incremente cur
337
338 m_w_edge[n + i] = 0;
339
340 if (iter == 0) {
341 m_factor[n + i] = fac;
342 vpMeSite site = *itListLine;
344 m_factor[n + i] = 0.2;
345 ++itListLine;
346 }
347
348 // If pour la premiere extremite des moving edges
349 if (indexFeature == 0) {
350 e_cur = l->error[0];
351 if (l->nbFeature[a] > 1) {
352 e_next = l->error[1];
353 if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
354 m_w_edge[n + i] = 1 /*0.5*/;
355 }
356 e_prev = e_cur;
357 }
358 else
359 m_w_edge[n + i] = 1;
360 }
361
362 // If pour la derniere extremite des moving edges
363 else if (indexFeature == l->nbFeatureTotal - 1) {
364 e_cur = l->error[indexFeature];
365 if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
366 m_w_edge[n + i] += 1 /*0.5*/;
367 }
368 }
369
370 else {
371 e_cur = l->error[indexFeature];
372 e_next = l->error[indexFeature + 1];
373 if (fabs(e_cur - e_prev) < limite) {
374 m_w_edge[n + i] += 0.5;
375 }
376 if (fabs(e_cur - e_next) < limite) {
377 m_w_edge[n + i] += 0.5;
378 }
379 e_prev = e_cur;
380 }
381 indexFeature++;
382 }
383 n += l->nbFeature[a];
384 }
385 }
386 }
387
388 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
389 ++it) {
390 if ((*it)->isTracked()) {
391 cy = *it;
393 double fac = 1.0;
394
395 std::list<vpMeSite>::const_iterator itCyl1;
396 std::list<vpMeSite>::const_iterator itCyl2;
397 if (iter == 0 && (cy->meline1 != nullptr || cy->meline2 != nullptr)) {
398 itCyl1 = cy->meline1->getMeList().begin();
399 itCyl2 = cy->meline2->getMeList().begin();
400 }
401
402 for (unsigned int i = 0; i < cy->nbFeature; i++) {
403 for (unsigned int j = 0; j < 6; j++) {
404 m_L_edge[n + i][j] = cy->L[i][j]; // On remplit la matrice d'interaction globale
405 }
406 m_error_edge[n + i] = cy->error[i]; // On remplit la matrice d'erreur
407
408 if (m_error_edge[n + i] <= limite)
409 count = count + 1.0; // Si erreur proche de 0 on incremente cur
410
411 m_w_edge[n + i] = 0;
412
413 if (iter == 0) {
414 m_factor[n + i] = fac;
415 vpMeSite site;
416 if (i < cy->nbFeaturel1) {
417 site = *itCyl1;
418 ++itCyl1;
419 }
420 else {
421 site = *itCyl2;
422 ++itCyl2;
423 }
425 m_factor[n + i] = 0.2;
426 }
427
428 // If pour la premiere extremite des moving edges
429 if (i == 0) {
430 e_cur = cy->error[0];
431 if (cy->nbFeature > 1) {
432 e_next = cy->error[1];
433 if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
434 m_w_edge[n + i] = 1 /*0.5*/;
435 }
436 e_prev = e_cur;
437 }
438 else
439 m_w_edge[n + i] = 1;
440 }
441 if (i == cy->nbFeaturel1) {
442 e_cur = cy->error[i];
443 if (cy->nbFeaturel2 > 1) {
444 e_next = cy->error[i + 1];
445 if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
446 m_w_edge[n + i] = 1 /*0.5*/;
447 }
448 e_prev = e_cur;
449 }
450 else
451 m_w_edge[n + i] = 1;
452 }
453
454 // If pour la derniere extremite des moving edges
455 else if (i == cy->nbFeaturel1 - 1) {
456 e_cur = cy->error[i];
457 if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
458 m_w_edge[n + i] += 1 /*0.5*/;
459 }
460 }
461 // If pour la derniere extremite des moving edges
462 else if (i == cy->nbFeature - 1) {
463 e_cur = cy->error[i];
464 if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
465 m_w_edge[n + i] += 1 /*0.5*/;
466 }
467 }
468
469 else {
470 e_cur = cy->error[i];
471 e_next = cy->error[i + 1];
472 if (fabs(e_cur - e_prev) < limite) {
473 m_w_edge[n + i] += 0.5;
474 }
475 if (fabs(e_cur - e_next) < limite) {
476 m_w_edge[n + i] += 0.5;
477 }
478 e_prev = e_cur;
479 }
480 }
481
482 n += cy->nbFeature;
483 }
484 }
485
486 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
487 if ((*it)->isTracked()) {
488 ci = *it;
490 double fac = 1.0;
491
492 std::list<vpMeSite>::const_iterator itCir;
493 if (iter == 0 && (ci->meEllipse != nullptr)) {
494 itCir = ci->meEllipse->getMeList().begin();
495 }
496
497 for (unsigned int i = 0; i < ci->nbFeature; i++) {
498 for (unsigned int j = 0; j < 6; j++) {
499 m_L_edge[n + i][j] = ci->L[i][j]; // On remplit la matrice d'interaction globale
500 }
501 m_error_edge[n + i] = ci->error[i]; // On remplit la matrice d'erreur
502
503 if (m_error_edge[n + i] <= limite)
504 count = count + 1.0; // Si erreur proche de 0 on incremente cur
505
506 m_w_edge[n + i] = 0;
507
508 if (iter == 0) {
509 m_factor[n + i] = fac;
510 vpMeSite site = *itCir;
512 m_factor[n + i] = 0.2;
513 ++itCir;
514 }
515
516 // If pour la premiere extremite des moving edges
517 if (i == 0) {
518 e_cur = ci->error[0];
519 if (ci->nbFeature > 1) {
520 e_next = ci->error[1];
521 if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
522 m_w_edge[n + i] = 1 /*0.5*/;
523 }
524 e_prev = e_cur;
525 }
526 else
527 m_w_edge[n + i] = 1;
528 }
529
530 // If pour la derniere extremite des moving edges
531 else if (i == ci->nbFeature - 1) {
532 e_cur = ci->error[i];
533 if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
534 m_w_edge[n + i] += 1 /*0.5*/;
535 }
536 }
537
538 else {
539 e_cur = ci->error[i];
540 e_next = ci->error[i + 1];
541 if (fabs(e_cur - e_prev) < limite) {
542 m_w_edge[n + i] += 0.5;
543 }
544 if (fabs(e_cur - e_next) < limite) {
545 m_w_edge[n + i] += 0.5;
546 }
547 e_prev = e_cur;
548 }
549 }
550
551 n += ci->nbFeature;
552 }
553 }
554}
555
557{
561
562 unsigned int n = 0;
563 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
564 if ((*it)->isTracked()) {
565 l = *it;
567
568 double fac = 1;
569 for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
570 ++itindex) {
571 int index = *itindex;
572 if (l->hiddenface->isAppearing(static_cast<unsigned int>(index))) {
573 fac = 0.2;
574 break;
575 }
576 if (l->closeToImageBorder(I, 10)) {
577 fac = 0.1;
578 break;
579 }
580 }
581
582 for (size_t a = 0; a < l->meline.size(); a++) {
583 std::list<vpMeSite>::const_iterator itListLine;
584 if (l->meline[a] != nullptr) {
585 itListLine = l->meline[a]->getMeList().begin();
586
587 for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
588 m_factor[n + i] = fac;
589 vpMeSite site = *itListLine;
591 m_factor[n + i] = 0.2;
592 ++itListLine;
593 }
594 n += l->nbFeature[a];
595 }
596 }
597 }
598 }
599
600 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
601 ++it) {
602 if ((*it)->isTracked()) {
603 cy = *it;
605
606 std::list<vpMeSite>::const_iterator itCyl1;
607 std::list<vpMeSite>::const_iterator itCyl2;
608 if ((cy->meline1 != nullptr || cy->meline2 != nullptr)) {
609 itCyl1 = cy->meline1->getMeList().begin();
610 itCyl2 = cy->meline2->getMeList().begin();
611
612 double fac = 1.0;
613 for (unsigned int i = 0; i < cy->nbFeature; i++) {
614 m_factor[n + i] = fac;
615 vpMeSite site;
616 if (i < cy->nbFeaturel1) {
617 site = *itCyl1;
618 ++itCyl1;
619 }
620 else {
621 site = *itCyl2;
622 ++itCyl2;
623 }
625 m_factor[n + i] = 0.2;
626 }
627 n += cy->nbFeature;
628 }
629 }
630 }
631
632 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
633 if ((*it)->isTracked()) {
634 ci = *it;
636
637 std::list<vpMeSite>::const_iterator itCir;
638 if (ci->meEllipse != nullptr) {
639 itCir = ci->meEllipse->getMeList().begin();
640 double fac = 1.0;
641
642 for (unsigned int i = 0; i < ci->nbFeature; i++) {
643 m_factor[n + i] = fac;
644 vpMeSite site = *itCir;
646 m_factor[n + i] = 0.2;
647 ++itCir;
648 }
649 n += ci->nbFeature;
650 }
651 }
652 }
653}
654
655void vpMbEdgeTracker::computeVVSFirstPhasePoseEstimation(unsigned int iter, bool &isoJoIdentity)
656{
657 unsigned int nerror = m_weightedError_edge.getRows();
658
659 double wi, eri;
660 if ((iter == 0) || m_computeInteraction) {
661 for (unsigned int i = 0; i < nerror; i++) {
662 wi = m_w_edge[i] * m_factor[i];
663 eri = m_error_edge[i];
664
665 m_weightedError_edge[i] = wi * eri;
666
667 for (unsigned int j = 0; j < 6; j++) {
668 m_L_edge[i][j] = wi * m_L_edge[i][j];
669 }
670 }
671 }
672 else {
673 for (unsigned int i = 0; i < nerror; i++) {
674 wi = m_w_edge[i] * m_factor[i];
675 eri = m_error_edge[i];
676
677 m_weightedError_edge[i] = wi * eri;
678 }
679 }
680
682
683 // If all the 6 dof should be estimated, we check if the interaction matrix
684 // is full rank. If not we remove automatically the dof that cannot be
685 // estimated This is particularly useful when considering circles (rank 5) and
686 // cylinders (rank 4)
687 if (isoJoIdentity) {
688 cVo.buildFrom(m_cMo);
689
690 vpMatrix K; // kernel
691 unsigned int rank = (m_L_edge * cVo).kernel(K);
692 if (rank == 0) {
693 throw vpException(vpException::fatalError, "Rank=0, cannot estimate the pose !");
694 }
695 if (rank != 6) {
696 vpMatrix I; // Identity
697 I.eye(6);
698 oJo = I - K.AtA();
699
700 isoJoIdentity = false;
701 }
702 }
703
704 vpColVector v;
705 vpMatrix LTL;
706 vpColVector LTR;
707
708 if (isoJoIdentity) {
709 LTL = m_L_edge.AtA();
711 v = -0.7 * LTL.pseudoInverse(LTL.getRows() * std::numeric_limits<double>::epsilon()) * LTR;
712 }
713 else {
714 cVo.buildFrom(m_cMo);
715 vpMatrix LVJ = (m_L_edge * cVo * oJo);
716 vpMatrix LVJTLVJ = (LVJ).AtA();
717 vpColVector LVJTR;
718 computeJTR(LVJ, m_weightedError_edge, LVJTR);
719 v = -0.7 * LVJTLVJ.pseudoInverse(LVJTLVJ.getRows() * std::numeric_limits<double>::epsilon()) * LVJTR;
720 v = cVo * v;
721 }
722
724}
725
727{
728 // Nombre de moving edges
729 unsigned int nbrow = 0;
730 unsigned int nberrors_lines = 0;
731 unsigned int nberrors_cylinders = 0;
732 unsigned int nberrors_circles = 0;
733
734 nbrow = initMbtTracking(nberrors_lines, nberrors_cylinders, nberrors_circles);
735
736 if (nbrow == 0) {
738 "No data found to compute the interaction matrix...");
739 }
740
741 m_L_edge.resize(nbrow, 6, false, false);
742 m_error_edge.resize(nbrow, false);
743
744 m_weightedError_edge.resize(nbrow, false);
745 m_w_edge.resize(nbrow, false);
746 m_w_edge = 1;
747 m_factor.resize(nbrow, false);
748 m_factor = 1;
749
750 m_robustLines.setMinMedianAbsoluteDeviation(2.0 / m_cam.get_px());
751 m_robustCylinders.setMinMedianAbsoluteDeviation(2.0 / m_cam.get_px());
752 m_robustCircles.setMinMedianAbsoluteDeviation(vpMath::sqr(2.0 / m_cam.get_px()));
753
754 m_wLines.resize(nberrors_lines, false);
755 m_wLines = 1;
756 m_wCylinders.resize(nberrors_cylinders, false);
757 m_wCylinders = 1;
758 m_wCircles.resize(nberrors_circles, false);
759 m_wCircles = 1;
760
761 m_errorLines.resize(nberrors_lines, false);
762 m_errorCylinders.resize(nberrors_cylinders, false);
763 m_errorCircles.resize(nberrors_circles, false);
764}
765
767{
768 throw vpException(vpException::fatalError, "vpMbEdgeTracker::"
769 "computeVVSInteractionMatrixAndR"
770 "esidu() should not be called!");
771}
772
774{
778
779 unsigned int n = 0;
780 unsigned int nlines = 0;
781 unsigned int ncylinders = 0;
782 unsigned int ncircles = 0;
783
784 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
785 ++it) {
786 if ((*it)->isTracked()) {
787 l = *it;
789 for (unsigned int i = 0; i < l->nbFeatureTotal; i++) {
790 for (unsigned int j = 0; j < 6; j++) {
791 m_L_edge[n + i][j] = l->L[i][j];
792 m_error_edge[n + i] = l->error[i];
793 m_errorLines[nlines + i] = m_error_edge[n + i];
794 }
795 }
796 n += l->nbFeatureTotal;
797 nlines += l->nbFeatureTotal;
798 }
799 }
800
801 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
802 it != cylinders[scaleLevel].end(); ++it) {
803 if ((*it)->isTracked()) {
804 cy = *it;
806 for (unsigned int i = 0; i < cy->nbFeature; i++) {
807 for (unsigned int j = 0; j < 6; j++) {
808 m_L_edge[n + i][j] = cy->L[i][j];
809 m_error_edge[n + i] = cy->error[i];
810 m_errorCylinders[ncylinders + i] = m_error_edge[n + i];
811 }
812 }
813
814 n += cy->nbFeature;
815 ncylinders += cy->nbFeature;
816 }
817 }
818
819 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
820 it != circles[scaleLevel].end(); ++it) {
821 if ((*it)->isTracked()) {
822 ci = *it;
824 for (unsigned int i = 0; i < ci->nbFeature; i++) {
825 for (unsigned int j = 0; j < 6; j++) {
826 m_L_edge[n + i][j] = ci->L[i][j];
827 m_error_edge[n + i] = ci->error[i];
828 m_errorCircles[ncircles + i] = m_error_edge[n + i];
829 }
830 }
831
832 n += ci->nbFeature;
833 ncircles += ci->nbFeature;
834 }
835 }
836}
837
839{
840 unsigned int nberrors_lines = m_errorLines.getRows(), nberrors_cylinders = m_errorCylinders.getRows(),
841 nberrors_circles = m_errorCircles.getRows();
842
843 if (nberrors_lines > 0)
845 if (nberrors_cylinders > 0)
847 if (nberrors_circles > 0)
849
850 m_w_edge.insert(0, m_wLines);
851 m_w_edge.insert(m_wLines.getRows(), m_wCylinders);
852 m_w_edge.insert(m_wLines.getRows() + m_wCylinders.getRows(), m_wCircles);
853}
854
864{
865 projectionError = 0.0;
866 unsigned int nbFeatures = 0;
867 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
868 ++it) {
869 vpMbtDistanceLine *l = *it;
870 if (l->isVisible() && l->isTracked()) {
871 for (size_t a = 0; a < l->meline.size(); a++) {
872 if (l->meline[a] != nullptr) {
873 double lineNormGradient;
874 unsigned int lineNbFeatures;
875 l->meline[a]->computeProjectionError(I_, lineNormGradient, lineNbFeatures, m_SobelX, m_SobelY,
878 projectionError += lineNormGradient;
879 nbFeatures += lineNbFeatures;
880 }
881 }
882 }
883 }
884
885 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
886 it != cylinders[scaleLevel].end(); ++it) {
887 vpMbtDistanceCylinder *cy = *it;
888 if (cy->isVisible() && cy->isTracked()) {
889 if (cy->meline1 != nullptr) {
890 double cylinderNormGradient = 0;
891 unsigned int cylinderNbFeatures = 0;
892 cy->meline1->computeProjectionError(I_, cylinderNormGradient, cylinderNbFeatures, m_SobelX, m_SobelY,
895 projectionError += cylinderNormGradient;
896 nbFeatures += cylinderNbFeatures;
897 }
898
899 if (cy->meline2 != nullptr) {
900 double cylinderNormGradient = 0;
901 unsigned int cylinderNbFeatures = 0;
902 cy->meline2->computeProjectionError(I_, cylinderNormGradient, cylinderNbFeatures, m_SobelX, m_SobelY,
905 projectionError += cylinderNormGradient;
906 nbFeatures += cylinderNbFeatures;
907 }
908 }
909 }
910
911 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
912 it != circles[scaleLevel].end(); ++it) {
913 vpMbtDistanceCircle *c = *it;
914 if (c->isVisible() && c->isTracked() && c->meEllipse != nullptr) {
915 double circleNormGradient = 0;
916 unsigned int circleNbFeatures = 0;
917 c->meEllipse->computeProjectionError(I_, circleNormGradient, circleNbFeatures, m_SobelX, m_SobelY,
920 projectionError += circleNormGradient;
921 nbFeatures += circleNbFeatures;
922 }
923 }
924
925 if (nbFeatures > 0) {
926 projectionError = vpMath::deg(projectionError / static_cast<double>(nbFeatures));
927 }
928 else {
929 projectionError = 90.0;
930 }
931
933 // std::cout << "Norm Gradient = " << errorGradient << std::endl;
934}
935
942{
943 int nbExpectedPoint = 0;
944 int nbGoodPoint = 0;
945 int nbBadPoint = 0;
946
947 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
948 ++it) {
949 vpMbtDistanceLine *l = *it;
950 if (l->isVisible() && l->isTracked()) {
951 for (size_t a = 0; a < l->meline.size(); a++) {
952 if (l->meline[a] != nullptr) {
953 nbExpectedPoint += static_cast<int>(l->meline[a]->expecteddensity);
954 for (std::list<vpMeSite>::const_iterator itme = l->meline[a]->getMeList().begin();
955 itme != l->meline[a]->getMeList().end(); ++itme) {
956 vpMeSite pix = *itme;
958 nbGoodPoint++;
959 else
960 nbBadPoint++;
961 }
962 }
963 }
964 }
965 }
966
967 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
968 it != cylinders[scaleLevel].end(); ++it) {
969 vpMbtDistanceCylinder *cy = *it;
970 if ((cy->meline1 != nullptr && cy->meline2 != nullptr) && cy->isVisible() && cy->isTracked()) {
971 nbExpectedPoint += static_cast<int>(cy->meline1->expecteddensity);
972 for (std::list<vpMeSite>::const_iterator itme1 = cy->meline1->getMeList().begin();
973 itme1 != cy->meline1->getMeList().end(); ++itme1) {
974 vpMeSite pix = *itme1;
976 nbGoodPoint++;
977 else
978 nbBadPoint++;
979 }
980 nbExpectedPoint += static_cast<int>(cy->meline2->expecteddensity);
981 for (std::list<vpMeSite>::const_iterator itme2 = cy->meline2->getMeList().begin();
982 itme2 != cy->meline2->getMeList().end(); ++itme2) {
983 vpMeSite pix = *itme2;
985 nbGoodPoint++;
986 else
987 nbBadPoint++;
988 }
989 }
990 }
991
992 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
993 it != circles[scaleLevel].end(); ++it) {
994 vpMbtDistanceCircle *ci = *it;
995 if (ci->isVisible() && ci->isTracked() && ci->meEllipse != nullptr) {
996 nbExpectedPoint += ci->meEllipse->getExpectedDensity();
997 for (std::list<vpMeSite>::const_iterator itme = ci->meEllipse->getMeList().begin();
998 itme != ci->meEllipse->getMeList().end(); ++itme) {
999 vpMeSite pix = *itme;
1001 nbGoodPoint++;
1002 else
1003 nbBadPoint++;
1004 }
1005 }
1006 }
1007
1008 // Compare the number of good points with the min between the number of
1009 // expected points and number of points that are tracked
1010 int nb_min = static_cast<int>(vpMath::minimum(percentageGdPt * nbExpectedPoint, percentageGdPt * (nbGoodPoint + nbBadPoint)));
1011 if (nbGoodPoint < nb_min || nbExpectedPoint < 2) {
1012 std::ostringstream oss;
1013 oss << "Not enough moving edges (" << nbGoodPoint << ") to track the object: expected " << nb_min
1014 << ". Try to reduce the threshold=" << percentageGdPt
1015 << " using vpMbTracker::setGoodMovingEdgesRatioThreshold()";
1017 }
1018}
1019
1028{
1030
1031 unsigned int lvl = static_cast<unsigned int>(scales.size());
1032 do {
1033 lvl--;
1034
1035 projectionError = 90.0;
1036
1037 if (scales[lvl]) {
1038 vpHomogeneousMatrix cMo_1 = m_cMo;
1039 try {
1040 downScale(lvl);
1041
1042 try {
1044 }
1045 catch (...) {
1046 vpTRACE("Error in moving edge tracking");
1047 throw;
1048 }
1049
1050 // initialize the vector that contains the error and the matrix that
1051 // contains the interaction matrix AY: Useless as it is done in
1052 // coputeVVS()
1053 /*
1054 for(std::list<vpMbtDistanceLine*>::const_iterator
1055 it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){ l = *it; if
1056 (l->isVisible()){ l->initInteractionMatrixError();
1057 }
1058 }
1059
1060 for(std::list<vpMbtDistanceCylinder*>::const_iterator
1061 it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){ cy = *it;
1062 if(cy->isVisible()) {
1063 cy->initInteractionMatrixError();
1064 }
1065 }
1066
1067 for(std::list<vpMbtDistanceCircle*>::const_iterator
1068 it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){ ci = *it; if
1069 (ci->isVisible()){ ci->initInteractionMatrixError();
1070 }
1071 }
1072 */
1073
1074 try {
1075 computeVVS(*Ipyramid[lvl], lvl);
1076 }
1077 catch (...) {
1078 covarianceMatrix = -1;
1079 throw; // throw the original exception
1080 }
1081
1082 testTracking();
1083
1084 if (displayFeatures) {
1086 }
1087
1088 // Looking for new visible face
1089 bool newvisibleface = false;
1090 visibleFace(I, m_cMo, newvisibleface);
1091
1092 // cam.computeFov(I.getWidth(), I.getHeight());
1093 if (useScanLine) {
1094 faces.computeClippedPolygons(m_cMo, m_cam);
1095 faces.computeScanLineRender(m_cam, I.getWidth(), I.getHeight());
1096 }
1097
1099
1101 // Reinit the moving edge for the lines which need it.
1103
1104 if (computeProjError)
1106
1107 upScale(lvl);
1108 }
1109 catch (const vpException &e) {
1110 if (lvl != 0) {
1111 m_cMo = cMo_1;
1112 reInitLevel(lvl);
1113 upScale(lvl);
1114 }
1115 else {
1116 upScale(lvl);
1117 throw(e);
1118 }
1119 }
1120 }
1121 } while (lvl != 0);
1122
1124}
1125
1131
1138{
1139 if (!modelInitialised) {
1140 throw vpException(vpException::fatalError, "model not initialized");
1141 }
1142
1143 bool a = false;
1144
1145#ifdef VISP_HAVE_OGRE
1146 if (useOgre) {
1147 if (!faces.isOgreInitialised()) {
1148 faces.setBackgroundSizeOgre(I.getHeight(), I.getWidth());
1149 faces.setOgreShowConfigDialog(ogreShowConfigDialog);
1150 faces.initOgre(m_cam);
1151 // Turn off Ogre config dialog display for the next call to this
1152 // function since settings are saved in the ogre.cfg file and used
1153 // during the next call
1154 ogreShowConfigDialog = false;
1155 }
1156 }
1157#endif
1158
1159 if (clippingFlag > 2)
1160 m_cam.computeFov(I.getWidth(), I.getHeight());
1161
1162 visibleFace(I, m_cMo, a);
1164
1165 if (useScanLine) {
1166 if (clippingFlag <= 2)
1167 m_cam.computeFov(I.getWidth(), I.getHeight());
1168
1169 faces.computeClippedPolygons(m_cMo, m_cam);
1170 faces.computeScanLineRender(m_cam, I.getWidth(), I.getHeight());
1171 }
1172
1174 unsigned int i = static_cast<unsigned int>(scales.size());
1175 do {
1176 i--;
1177 if (scales[i]) {
1178 downScale(i);
1180 upScale(i);
1181 }
1182 } while (i != 0);
1183
1185}
1186
1195{
1196 m_cMo = cdMo;
1197
1198 init(I);
1199}
1200
1209{
1210 m_cMo = cdMo;
1211
1212 vpImageConvert::convert(I_color, m_I);
1213 init(m_I);
1214}
1215
1227void vpMbEdgeTracker::loadConfigFile(const std::string &configFile, bool verbose)
1228{
1229#if defined(VISP_HAVE_PUGIXML)
1230// Load projection error config
1231 vpMbTracker::loadConfigFile(configFile, verbose);
1232
1234 xmlp.setVerbose(verbose);
1238 xmlp.setEdgeMe(me);
1239
1240 try {
1241 if (verbose) {
1242 std::cout << " *********** Parsing XML for Mb Edge Tracker ************ " << std::endl;
1243 }
1244 xmlp.parse(configFile);
1245 }
1246 catch (...) {
1247 throw vpException(vpException::ioError, "Cannot open XML file \"%s\"", configFile.c_str());
1248 }
1249
1250 vpCameraParameters camera;
1251 vpMe meParser;
1252 xmlp.getCameraParameters(camera);
1253 xmlp.getEdgeMe(meParser);
1254
1255 setCameraParameters(camera);
1256 setMovingEdge(meParser);
1259
1260 if (xmlp.hasNearClippingDistance())
1262
1263 if (xmlp.hasFarClippingDistance())
1265
1266 if (xmlp.getFovClipping())
1268
1269 useLodGeneral = xmlp.getLodState();
1272
1274 if (this->getNbPolygon() > 0) {
1279 }
1280#else
1281 (void)configFile;
1282 (void)verbose;
1283 throw(vpException(vpException::ioError, "vpMbEdgeTracker::loadConfigFile() needs pugixml built-in 3rdparty"));
1284#endif
1285}
1286
1299 const vpCameraParameters &cam, const vpColor &col, unsigned int thickness,
1300 bool displayFullModel)
1301{
1302 // Display first the Moving-Edges
1303 if (displayFeatures) {
1305 }
1306
1307 std::vector<std::vector<double> > models =
1308 vpMbEdgeTracker::getModelForDisplay(I.getWidth(), I.getHeight(), cMo, cam, displayFullModel);
1309
1310 for (size_t i = 0; i < models.size(); i++) {
1311 if (vpMath::equal(models[i][0], 0)) {
1312 vpImagePoint ip1(models[i][1], models[i][2]);
1313 vpImagePoint ip2(models[i][3], models[i][4]);
1314 vpDisplay::displayLine(I, ip1, ip2, col, thickness);
1315 }
1316 else if (vpMath::equal(models[i][0], 1)) {
1317 vpImagePoint center(models[i][1], models[i][2]);
1318 double n20 = models[i][3];
1319 double n11 = models[i][4];
1320 double n02 = models[i][5];
1321 vpDisplay::displayEllipse(I, center, n20, n11, n02, true, col, thickness);
1322 }
1323 }
1324
1325#ifdef VISP_HAVE_OGRE
1326 if (useOgre)
1327 faces.displayOgre(cMo);
1328#endif
1329}
1330
1343 const vpColor &col, unsigned int thickness, bool displayFullModel)
1344{
1345 // Display first the Moving-Edges
1346 if (displayFeatures) {
1348 }
1349
1350 std::vector<std::vector<double> > models =
1351 vpMbEdgeTracker::getModelForDisplay(I.getWidth(), I.getHeight(), cMo, cam, displayFullModel);
1352
1353 for (size_t i = 0; i < models.size(); i++) {
1354 if (vpMath::equal(models[i][0], 0)) {
1355 vpImagePoint ip1(models[i][1], models[i][2]);
1356 vpImagePoint ip2(models[i][3], models[i][4]);
1357 vpDisplay::displayLine(I, ip1, ip2, col, thickness);
1358 }
1359 else if (vpMath::equal(models[i][0], 1)) {
1360 vpImagePoint center(models[i][1], models[i][2]);
1361 double n20 = models[i][3];
1362 double n11 = models[i][4];
1363 double n02 = models[i][5];
1364 vpDisplay::displayEllipse(I, center, n20, n11, n02, true, col, thickness);
1365 }
1366 }
1367
1368#ifdef VISP_HAVE_OGRE
1369 if (useOgre)
1370 faces.displayOgre(cMo);
1371#endif
1372}
1373
1374std::vector<std::vector<double> > vpMbEdgeTracker::getFeaturesForDisplayEdge()
1375{
1376 std::vector<std::vector<double> > features;
1377
1378 const unsigned int lvl = 0;
1379 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
1380 vpMbtDistanceLine *l = *it;
1381 if (l->isVisible() && l->isTracked()) {
1382 std::vector<std::vector<double> > currentFeatures = l->getFeaturesForDisplay();
1383 features.insert(features.end(), currentFeatures.begin(), currentFeatures.end());
1384 }
1385 }
1386
1387 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
1388 ++it) {
1389 vpMbtDistanceCylinder *cy = *it;
1390 if (cy->isVisible() && cy->isTracked()) {
1391 std::vector<std::vector<double> > currentFeatures = cy->getFeaturesForDisplay();
1392 features.insert(features.end(), currentFeatures.begin(), currentFeatures.end());
1393 }
1394 }
1395
1396 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
1397 vpMbtDistanceCircle *ci = *it;
1398 if (ci->isVisible() && ci->isTracked()) {
1399 std::vector<std::vector<double> > currentFeatures = ci->getFeaturesForDisplay();
1400 features.insert(features.end(), currentFeatures.begin(), currentFeatures.end());
1401 }
1402 }
1403
1404 return features;
1405}
1406
1422std::vector<std::vector<double> > vpMbEdgeTracker::getModelForDisplay(unsigned int width, unsigned int height,
1423 const vpHomogeneousMatrix &cMo,
1424 const vpCameraParameters &cam,
1425 bool displayFullModel)
1426{
1427 std::vector<std::vector<double> > models;
1428
1429 for (unsigned int i = 0; i < scales.size(); i += 1) {
1430 if (scales[i]) {
1431 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1432 ++it) {
1433 std::vector<std::vector<double> > currentModel =
1434 (*it)->getModelForDisplay(width, height, cMo, cam, displayFullModel);
1435 models.insert(models.end(), currentModel.begin(), currentModel.end());
1436 }
1437
1438 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1439 it != cylinders[scaleLevel].end(); ++it) {
1440 std::vector<std::vector<double> > currentModel =
1441 (*it)->getModelForDisplay(width, height, cMo, cam, displayFullModel);
1442 models.insert(models.end(), currentModel.begin(), currentModel.end());
1443 }
1444
1445 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1446 it != circles[scaleLevel].end(); ++it) {
1447 std::vector<double> paramsCircle = (*it)->getModelForDisplay(cMo, cam, displayFullModel);
1448 if (!paramsCircle.empty()) {
1449 models.push_back(paramsCircle);
1450 }
1451 }
1452 break; // displaying model on one scale only
1453 }
1454 }
1455
1456 return models;
1457}
1458
1460{
1461 for (size_t i = 0; i < m_featuresToBeDisplayedEdge.size(); i++) {
1464 int state = static_cast<int>(m_featuresToBeDisplayedEdge[i][3]);
1465
1466 switch (state) {
1469 break;
1470
1471 case vpMeSite::CONTRAST:
1473 break;
1474
1477 break;
1478
1481 break;
1482
1483 case vpMeSite::TOO_NEAR:
1485 break;
1486
1487 default:
1489 }
1490 }
1491 }
1492}
1493
1495{
1496 for (size_t i = 0; i < m_featuresToBeDisplayedEdge.size(); i++) {
1499 int state = static_cast<int>(m_featuresToBeDisplayedEdge[i][3]);
1500
1501 switch (state) {
1504 break;
1505
1506 case vpMeSite::CONTRAST:
1508 break;
1509
1512 break;
1513
1516 break;
1517
1518 case vpMeSite::TOO_NEAR:
1520 break;
1521
1522 default:
1524 }
1525 }
1526 }
1527}
1528
1539void vpMbEdgeTracker::initMovingEdge(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &_cMo, const bool &useInitRange)
1540{
1541 const bool doNotTrack = false;
1542 int initRange_;
1543 if (useInitRange) {
1544 initRange_ = me.getInitRange();
1545 }
1546 else {
1547 initRange_ = -1; // Asks to use default values
1548 }
1549
1550 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1551 ++it) {
1552 vpMbtDistanceLine *l = *it;
1553 bool isvisible = false;
1554
1555 for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
1556 ++itindex) {
1557 int index = *itindex;
1558 if (index == -1)
1559 isvisible = true;
1560 else {
1561 if (l->hiddenface->isVisible(static_cast<unsigned int>(index)))
1562 isvisible = true;
1563 }
1564 }
1565
1566 // Si la ligne n'appartient a aucune face elle est tout le temps visible
1567 if (l->Lindex_polygon.empty())
1568 isvisible = true; // Not sure that this can occur
1569
1570 if (isvisible) {
1571 l->setVisible(true);
1572 l->updateTracked();
1573 if (l->meline.empty() && l->isTracked()) {
1574 l->initMovingEdge(I, _cMo, doNotTrack, m_mask, initRange_);
1575 }
1576 }
1577 else {
1578 l->setVisible(false);
1579 for (size_t a = 0; a < l->meline.size(); a++) {
1580 if (l->meline[a] != nullptr)
1581 delete l->meline[a];
1582 if (a < l->nbFeature.size())
1583 l->nbFeature[a] = 0;
1584 }
1585 l->nbFeatureTotal = 0;
1586 l->meline.clear();
1587 l->nbFeature.clear();
1588 }
1589 }
1590
1591 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1592 it != cylinders[scaleLevel].end(); ++it) {
1593 vpMbtDistanceCylinder *cy = *it;
1594
1595 bool isvisible = false;
1596
1597 int index = cy->index_polygon;
1598 if (index == -1)
1599 isvisible = true;
1600 else {
1601 if (cy->hiddenface->isVisible(static_cast<unsigned int>(index) + 1) || cy->hiddenface->isVisible(static_cast<unsigned int>(index) + 2) ||
1602 cy->hiddenface->isVisible(static_cast<unsigned int>(index) + 3) || cy->hiddenface->isVisible(static_cast<unsigned int>(index) + 4))
1603 isvisible = true;
1604 }
1605 // vpTRACE("cyl with index %d is visible: %d", index, isvisible);
1606
1607 if (isvisible) {
1608 cy->setVisible(true);
1609 if (cy->meline1 == nullptr || cy->meline2 == nullptr) {
1610 if (cy->isTracked()) {
1611 cy->initMovingEdge(I, _cMo, doNotTrack, m_mask, initRange_);
1612 }
1613 }
1614 }
1615 else {
1616 cy->setVisible(false);
1617 if (cy->meline1 != nullptr)
1618 delete cy->meline1;
1619 if (cy->meline2 != nullptr)
1620 delete cy->meline2;
1621 cy->meline1 = nullptr;
1622 cy->meline2 = nullptr;
1623 cy->nbFeature = 0;
1624 cy->nbFeaturel1 = 0;
1625 cy->nbFeaturel2 = 0;
1626 }
1627 }
1628
1629 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1630 it != circles[scaleLevel].end(); ++it) {
1631 vpMbtDistanceCircle *ci = *it;
1632 bool isvisible = false;
1633
1634 int index = ci->index_polygon;
1635 if (index == -1)
1636 isvisible = true;
1637 else {
1638 if (ci->hiddenface->isVisible(static_cast<unsigned int>(index)))
1639 isvisible = true;
1640 }
1641
1642 if (isvisible) {
1643 ci->setVisible(true);
1644 if (ci->meEllipse == nullptr) {
1645 if (ci->isTracked()) {
1646 ci->initMovingEdge(I, _cMo, doNotTrack, m_mask, initRange_);
1647 }
1648 }
1649 }
1650 else {
1651 ci->setVisible(false);
1652 if (ci->meEllipse != nullptr)
1653 delete ci->meEllipse;
1654 ci->meEllipse = nullptr;
1655 ci->nbFeature = 0;
1656 }
1657 }
1658}
1659
1666{
1667 const bool doNotTrack = false;
1668
1669 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1670 ++it) {
1671 vpMbtDistanceLine *l = *it;
1672 if (l->isVisible() && l->isTracked()) {
1673 if (l->meline.empty()) {
1674 l->initMovingEdge(I, m_cMo, doNotTrack, m_mask);
1675 }
1676 l->trackMovingEdge(I);
1677 }
1678 }
1679
1680 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1681 it != cylinders[scaleLevel].end(); ++it) {
1682 vpMbtDistanceCylinder *cy = *it;
1683 if (cy->isVisible() && cy->isTracked()) {
1684 if (cy->meline1 == nullptr || cy->meline2 == nullptr) {
1685 cy->initMovingEdge(I, m_cMo, doNotTrack, m_mask);
1686 }
1687 cy->trackMovingEdge(I, m_cMo);
1688 }
1689 }
1690
1691 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1692 it != circles[scaleLevel].end(); ++it) {
1693 vpMbtDistanceCircle *ci = *it;
1694 if (ci->isVisible() && ci->isTracked()) {
1695 if (ci->meEllipse == nullptr) {
1696 ci->initMovingEdge(I, m_cMo, doNotTrack, m_mask);
1697 }
1698 ci->trackMovingEdge(I, m_cMo);
1699 }
1700 }
1701}
1702
1709{
1711 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1712 ++it) {
1713 if ((*it)->isTracked()) {
1714 l = *it;
1715 l->updateMovingEdge(I, m_cMo);
1716 if (l->nbFeatureTotal == 0 && l->isVisible()) {
1717 l->Reinit = true;
1718 }
1719 }
1720 }
1721
1723 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1724 it != cylinders[scaleLevel].end(); ++it) {
1725 if ((*it)->isTracked()) {
1726 cy = *it;
1727 cy->updateMovingEdge(I, m_cMo);
1728 if ((cy->nbFeaturel1 == 0 || cy->nbFeaturel2 == 0) && cy->isVisible()) {
1729 cy->Reinit = true;
1730 }
1731 }
1732 }
1733
1735 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1736 it != circles[scaleLevel].end(); ++it) {
1737 if ((*it)->isTracked()) {
1738 ci = *it;
1739 ci->updateMovingEdge(I, m_cMo);
1740 if (ci->nbFeature == 0 && ci->isVisible()) {
1741 ci->Reinit = true;
1742 }
1743 }
1744 }
1745}
1746
1748{
1749 unsigned int n = 0;
1750
1752 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1753 ++it) {
1754 if ((*it)->isTracked()) {
1755 l = *it;
1756 unsigned int indexLine = 0;
1757 double wmean = 0;
1758 for (size_t a = 0; a < l->meline.size(); a++) {
1759 if (l->nbFeature[a] > 0) {
1760 std::list<vpMeSite>::iterator itListLine;
1761 itListLine = l->meline[a]->getMeList().begin();
1762
1763 for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
1764 wmean += m_w_edge[n + indexLine];
1765 vpMeSite p = *itListLine;
1766 if (m_w_edge[n + indexLine] < 0.5) {
1767 p.setState(vpMeSite::M_ESTIMATOR);
1768
1769 *itListLine = p;
1770 }
1771
1772 ++itListLine;
1773 indexLine++;
1774 }
1775 }
1776 }
1777 n += l->nbFeatureTotal;
1778
1779 if (l->nbFeatureTotal != 0)
1780 wmean /= l->nbFeatureTotal;
1781 else
1782 wmean = 1;
1783
1784 l->setMeanWeight(wmean);
1785
1786 if (wmean < 0.8)
1787 l->Reinit = true;
1788 }
1789 }
1790
1791 // Same thing with cylinders as with lines
1793 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1794 it != cylinders[scaleLevel].end(); ++it) {
1795 if ((*it)->isTracked()) {
1796 cy = *it;
1797 double wmean = 0;
1798 std::list<vpMeSite>::iterator itListCyl1;
1799 std::list<vpMeSite>::iterator itListCyl2;
1800
1801 if (cy->nbFeature > 0) {
1802 itListCyl1 = cy->meline1->getMeList().begin();
1803 itListCyl2 = cy->meline2->getMeList().begin();
1804
1805 for (unsigned int i = 0; i < cy->nbFeaturel1; i++) {
1806 wmean += m_w_edge[n + i];
1807 vpMeSite p = *itListCyl1;
1808 if (m_w_edge[n + i] < 0.5) {
1809 p.setState(vpMeSite::M_ESTIMATOR);
1810
1811 *itListCyl1 = p;
1812 }
1813
1814 ++itListCyl1;
1815 }
1816 }
1817
1818 if (cy->nbFeaturel1 != 0)
1819 wmean /= cy->nbFeaturel1;
1820 else
1821 wmean = 1;
1822
1823 cy->setMeanWeight1(wmean);
1824
1825 if (wmean < 0.8) {
1826 cy->Reinit = true;
1827 }
1828
1829 wmean = 0;
1830 for (unsigned int i = cy->nbFeaturel1; i < cy->nbFeature; i++) {
1831 wmean += m_w_edge[n + i];
1832 vpMeSite p = *itListCyl2;
1833 if (m_w_edge[n + i] < 0.5) {
1834 p.setState(vpMeSite::M_ESTIMATOR);
1835
1836 *itListCyl2 = p;
1837 }
1838
1839 ++itListCyl2;
1840 }
1841
1842 if (cy->nbFeaturel2 != 0)
1843 wmean /= cy->nbFeaturel2;
1844 else
1845 wmean = 1;
1846
1847 cy->setMeanWeight2(wmean);
1848
1849 if (wmean < 0.8) {
1850 cy->Reinit = true;
1851 }
1852
1853 n += cy->nbFeature;
1854 }
1855 }
1856
1857 // Same thing with circles as with lines
1859 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1860 it != circles[scaleLevel].end(); ++it) {
1861 if ((*it)->isTracked()) {
1862 ci = *it;
1863 double wmean = 0;
1864 std::list<vpMeSite>::iterator itListCir;
1865
1866 if (ci->nbFeature > 0) {
1867 itListCir = ci->meEllipse->getMeList().begin();
1868 }
1869
1870 wmean = 0;
1871 for (unsigned int i = 0; i < ci->nbFeature; i++) {
1872 wmean += m_w_edge[n + i];
1873 vpMeSite p = *itListCir;
1874 if (m_w_edge[n + i] < 0.5) {
1875 p.setState(vpMeSite::M_ESTIMATOR);
1876
1877 *itListCir = p;
1878 }
1879
1880 ++itListCir;
1881 }
1882
1883 if (ci->nbFeature != 0)
1884 wmean /= ci->nbFeature;
1885 else
1886 wmean = 1;
1887
1888 ci->setMeanWeight(wmean);
1889
1890 if (wmean < 0.8) {
1891 ci->Reinit = true;
1892 }
1893
1894 n += ci->nbFeature;
1895 }
1896 }
1897}
1898
1909{
1911 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1912 ++it) {
1913 if ((*it)->isTracked()) {
1914 l = *it;
1915 if (l->Reinit && l->isVisible())
1916 l->reinitMovingEdge(I, _cMo, m_mask);
1917 }
1918 }
1919
1921 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1922 it != cylinders[scaleLevel].end(); ++it) {
1923 if ((*it)->isTracked()) {
1924 cy = *it;
1925 if (cy->Reinit && cy->isVisible())
1926 cy->reinitMovingEdge(I, _cMo, m_mask);
1927 }
1928 }
1929
1931 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1932 it != circles[scaleLevel].end(); ++it) {
1933 if ((*it)->isTracked()) {
1934 ci = *it;
1935 if (ci->Reinit && ci->isVisible())
1936 ci->reinitMovingEdge(I, _cMo, m_mask);
1937 }
1938 }
1939}
1940
1942{
1943 // Clear ME to be displayed
1945
1946 for (unsigned int i = 0; i < scales.size(); i += 1) {
1947 if (scales[i]) {
1948 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
1949 for (size_t a = 0; a < (*it)->meline.size(); a++) {
1950 if ((*it)->meline[a] != nullptr) {
1951 delete (*it)->meline[a];
1952 (*it)->meline[a] = nullptr;
1953 }
1954 }
1955
1956 (*it)->meline.clear();
1957 (*it)->nbFeature.clear();
1958 (*it)->nbFeatureTotal = 0;
1959 }
1960
1961 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
1962 ++it) {
1963 if ((*it)->meline1 != nullptr) {
1964 delete (*it)->meline1;
1965 (*it)->meline1 = nullptr;
1966 }
1967 if ((*it)->meline2 != nullptr) {
1968 delete (*it)->meline2;
1969 (*it)->meline2 = nullptr;
1970 }
1971
1972 (*it)->nbFeature = 0;
1973 (*it)->nbFeaturel1 = 0;
1974 (*it)->nbFeaturel2 = 0;
1975 }
1976
1977 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
1978 if ((*it)->meEllipse != nullptr) {
1979 delete (*it)->meEllipse;
1980 (*it)->meEllipse = nullptr;
1981 }
1982 (*it)->nbFeature = 0;
1983 }
1984 }
1985 }
1986}
1987
2000void vpMbEdgeTracker::addLine(vpPoint &P1, vpPoint &P2, int polygon, std::string name)
2001{
2002 {
2003 // suppress line already in the model
2004 bool already_here = false;
2006
2007 for (unsigned int i = 0; i < scales.size(); i += 1) {
2008 if (scales[i]) {
2009 downScale(i);
2010 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2011 l = *it;
2012 if ((samePoint(*(l->p1), P1) && samePoint(*(l->p2), P2)) ||
2013 (samePoint(*(l->p1), P2) && samePoint(*(l->p2), P1))) {
2014 already_here = true;
2015 l->addPolygon(polygon);
2016 l->hiddenface = &faces;
2017 }
2018 }
2019
2020 if (!already_here) {
2021 l = new vpMbtDistanceLine;
2022
2024 l->buildFrom(P1, P2, m_rand);
2025 l->addPolygon(polygon);
2026 l->setMovingEdge(&me);
2027 l->hiddenface = &faces;
2029
2030 l->setIndex(nline);
2031 l->setName(name);
2032
2035
2038
2041
2042 nline += 1;
2043 lines[i].push_back(l);
2044 }
2045 upScale(i);
2046 }
2047 }
2048 }
2049}
2050
2056void vpMbEdgeTracker::removeLine(const std::string &name)
2057{
2059
2060 for (unsigned int i = 0; i < scales.size(); i++) {
2061 if (scales[i]) {
2062 for (std::list<vpMbtDistanceLine *>::iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2063 l = *it;
2064 if (name.compare(l->getName()) == 0) {
2065 lines[i].erase(it);
2066 break;
2067 }
2068 }
2069 }
2070 }
2071}
2072
2084void vpMbEdgeTracker::addCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, double r, int idFace,
2085 const std::string &name)
2086{
2087 {
2088 bool already_here = false;
2090
2091 for (unsigned int i = 0; i < scales.size(); i += 1) {
2092 if (scales[i]) {
2093 downScale(i);
2094 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2095 ci = *it;
2096 if ((samePoint(*(ci->p1), P1) && samePoint(*(ci->p2), P2) && samePoint(*(ci->p3), P3)) ||
2097 (samePoint(*(ci->p1), P1) && samePoint(*(ci->p2), P3) && samePoint(*(ci->p3), P2))) {
2098 already_here =
2099 (std::fabs(ci->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(ci->radius, r));
2100 }
2101 }
2102
2103 if (!already_here) {
2104 ci = new vpMbtDistanceCircle;
2105
2107 ci->buildFrom(P1, P2, P3, r);
2108 ci->setMovingEdge(&me);
2109 ci->setIndex(ncircle);
2110 ci->setName(name);
2111 ci->index_polygon = idFace;
2112 ci->hiddenface = &faces;
2113
2114 // if(clippingFlag != vpPolygon3D::NO_CLIPPING)
2115 // ci->getPolygon().setClipping(clippingFlag);
2116
2117 // if((clippingFlag & vpPolygon3D::NEAR_CLIPPING) ==
2118 // vpPolygon3D::NEAR_CLIPPING)
2119 // ci->getPolygon().setNearClippingDistance(distNearClip);
2120
2121 // if((clippingFlag & vpPolygon3D::FAR_CLIPPING) ==
2122 // vpPolygon3D::FAR_CLIPPING)
2123 // ci->getPolygon().setFarClippingDistance(distFarClip);
2124
2125 ncircle += 1;
2126 circles[i].push_back(ci);
2127 }
2128 upScale(i);
2129 }
2130 }
2131 }
2132}
2133
2143void vpMbEdgeTracker::addCylinder(const vpPoint &P1, const vpPoint &P2, double r, int idFace, const std::string &name)
2144{
2145 {
2146 bool already_here = false;
2148
2149 for (unsigned int i = 0; i < scales.size(); i += 1) {
2150 if (scales[i]) {
2151 downScale(i);
2152 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2153 ++it) {
2154 cy = *it;
2155 if ((samePoint(*(cy->p1), P1) && samePoint(*(cy->p2), P2)) ||
2156 (samePoint(*(cy->p1), P2) && samePoint(*(cy->p2), P1))) {
2157 already_here =
2158 (std::fabs(cy->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(cy->radius, r));
2159 }
2160 }
2161
2162 if (!already_here) {
2163 cy = new vpMbtDistanceCylinder;
2164
2166 cy->buildFrom(P1, P2, r);
2167 cy->setMovingEdge(&me);
2168 cy->setIndex(ncylinder);
2169 cy->setName(name);
2170 cy->index_polygon = idFace;
2171 cy->hiddenface = &faces;
2172 ncylinder += 1;
2173 cylinders[i].push_back(cy);
2174 }
2175 upScale(i);
2176 }
2177 }
2178 }
2179}
2180
2186void vpMbEdgeTracker::removeCylinder(const std::string &name)
2187{
2189
2190 for (unsigned int i = 0; i < scales.size(); i++) {
2191 if (scales[i]) {
2192 for (std::list<vpMbtDistanceCylinder *>::iterator it = cylinders[i].begin(); it != cylinders[i].end(); ++it) {
2193 cy = *it;
2194 if (name.compare(cy->getName()) == 0) {
2195 cylinders[i].erase(it);
2196 break;
2197 }
2198 }
2199 }
2200 }
2201}
2202
2208void vpMbEdgeTracker::removeCircle(const std::string &name)
2209{
2211
2212 for (unsigned int i = 0; i < scales.size(); i++) {
2213 if (scales[i]) {
2214 for (std::list<vpMbtDistanceCircle *>::iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2215 ci = *it;
2216 if (name.compare(ci->getName()) == 0) {
2217 circles[i].erase(it);
2218 break;
2219 }
2220 }
2221 }
2222 }
2223}
2224
2231{
2232 unsigned int nbpt = p.getNbPoint();
2233 if (nbpt > 0) {
2234 for (unsigned int i = 0; i < nbpt - 1; i++)
2235 addLine(p.p[i], p.p[i + 1], p.getIndex());
2236 addLine(p.p[nbpt - 1], p.p[0], p.getIndex());
2237 }
2238}
2239
2251void vpMbEdgeTracker::visibleFace(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo, bool &newvisibleline)
2252{
2253 unsigned int n;
2254 bool changed = false;
2255
2256 if (!useOgre) {
2257 n = faces.setVisible(I.getWidth(), I.getHeight(), m_cam, cMo, angleAppears, angleDisappears, changed);
2258 }
2259 else {
2260#ifdef VISP_HAVE_OGRE
2261 n = faces.setVisibleOgre(I.getWidth(), I.getHeight(), m_cam, cMo, angleAppears, angleDisappears, changed);
2262#else
2263 n = faces.setVisible(I.getWidth(), I.getHeight(), m_cam, cMo, angleAppears, angleDisappears, changed);
2264#endif
2265 }
2266
2267 if (n > nbvisiblepolygone) {
2268 // cout << "une nouvelle face est visible " << endl;
2269 newvisibleline = true;
2270 }
2271 else
2272 newvisibleline = false;
2273
2275}
2276
2293{
2294 unsigned int nbpt = polygon.getNbPoint();
2295 if (nbpt > 0) {
2296 for (unsigned int i = 0; i < nbpt - 1; i++)
2297 vpMbEdgeTracker::addLine(polygon.p[i], polygon.p[i + 1], polygon.getIndex(), polygon.getName());
2298 vpMbEdgeTracker::addLine(polygon.p[nbpt - 1], polygon.p[0], polygon.getIndex(), polygon.getName());
2299 }
2300}
2301
2317{
2318 unsigned int nbpt = polygon.getNbPoint();
2319 if (nbpt > 0) {
2320 for (unsigned int i = 0; i < nbpt - 1; i++)
2321 vpMbEdgeTracker::addLine(polygon.p[i], polygon.p[i + 1], polygon.getIndex(), polygon.getName());
2322 }
2323}
2324
2325unsigned int vpMbEdgeTracker::initMbtTracking(unsigned int &nberrors_lines, unsigned int &nberrors_cylinders,
2326 unsigned int &nberrors_circles)
2327{
2328 unsigned int nbrow = 0;
2329 nberrors_lines = 0;
2330 nberrors_cylinders = 0;
2331 nberrors_circles = 0;
2332
2333 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
2334 ++it) {
2335
2336 vpMbtDistanceLine *l = *it;
2337
2338 if (l->isTracked()) {
2340 nbrow += l->nbFeatureTotal;
2341 nberrors_lines += l->nbFeatureTotal;
2342 }
2343 }
2344
2345 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
2346 it != cylinders[scaleLevel].end(); ++it) {
2347 vpMbtDistanceCylinder *cy = *it;
2348
2349 if (cy->isTracked()) {
2351 nbrow += cy->nbFeature;
2352 nberrors_cylinders += cy->nbFeature;
2353 }
2354 }
2355
2356 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
2357 it != circles[scaleLevel].end(); ++it) {
2358 vpMbtDistanceCircle *ci = *it;
2359
2360 if (ci->isTracked()) {
2362 nbrow += ci->nbFeature;
2363 nberrors_circles += ci->nbFeature;
2364 }
2365 }
2366
2367 return nbrow;
2368}
2369
2381void vpMbEdgeTracker::initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius, int idFace,
2382 const std::string &name)
2383{
2384 addCircle(p1, p2, p3, radius, static_cast<int>(idFace), name);
2385}
2386
2397void vpMbEdgeTracker::initCylinder(const vpPoint &p1, const vpPoint &p2, double radius, int idFace,
2398 const std::string &name)
2399{
2400 addCylinder(p1, p2, radius, static_cast<int>(idFace), name);
2401}
2402
2409{
2410 m_cMo.eye();
2414
2415 for (unsigned int i = 0; i < scales.size(); i += 1) {
2416 if (scales[i]) {
2417 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2418 l = *it;
2419 if (l != nullptr)
2420 delete l;
2421 l = nullptr;
2422 }
2423
2424 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2425 ++it) {
2426 cy = *it;
2427 if (cy != nullptr)
2428 delete cy;
2429 cy = nullptr;
2430 }
2431
2432 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2433 ci = *it;
2434 if (ci != nullptr)
2435 delete ci;
2436 ci = nullptr;
2437 }
2438 lines[i].clear();
2439 cylinders[i].clear();
2440 circles[i].clear();
2441 }
2442 }
2443
2444 faces.reset();
2445
2446 useScanLine = false;
2447
2448#ifdef VISP_HAVE_OGRE
2449 useOgre = false;
2450#endif
2451
2452 m_computeInteraction = true;
2453 nline = 0;
2454 ncylinder = 0;
2455 m_lambda = 1.0;
2457 percentageGdPt = 0.4;
2458
2462
2464
2465 // reinitialization of the scales.
2466 this->setScales(scales);
2467}
2468
2481void vpMbEdgeTracker::reInitModel(const vpImage<unsigned char> &I, const std::string &cad_name,
2482 const vpHomogeneousMatrix &cMo, bool verbose, const vpHomogeneousMatrix &T)
2483{
2484 m_cMo.eye();
2488
2489 for (unsigned int i = 0; i < scales.size(); i += 1) {
2490 if (scales[i]) {
2491 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2492 l = *it;
2493 if (l != nullptr)
2494 delete l;
2495 l = nullptr;
2496 }
2497
2498 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2499 ++it) {
2500 cy = *it;
2501 if (cy != nullptr)
2502 delete cy;
2503 cy = nullptr;
2504 }
2505
2506 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2507 ci = *it;
2508 if (ci != nullptr)
2509 delete ci;
2510 ci = nullptr;
2511 }
2512
2513 lines[i].clear();
2514 cylinders[i].clear();
2515 circles[i].clear();
2516 }
2517 }
2518
2519 faces.reset();
2520
2521 // compute_interaction=1;
2522 nline = 0;
2523 ncylinder = 0;
2524 ncircle = 0;
2525 // lambda = 1;
2527
2528 loadModel(cad_name, verbose, T);
2529 initFromPose(I, cMo);
2530}
2531
2542unsigned int vpMbEdgeTracker::getNbPoints(unsigned int level) const
2543{
2544 if ((level > scales.size()) || !scales[level]) {
2545 throw vpException(vpException::dimensionError, "Cannot get the number of points for level %d: level is not used",
2546 level);
2547 }
2548
2549 unsigned int nbGoodPoints = 0;
2551 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[level].begin(); it != lines[level].end(); ++it) {
2552 l = *it;
2553 if (l->isVisible() && l->isTracked()) {
2554 for (size_t a = 0; a < l->meline.size(); a++) {
2555 if (l->nbFeature[a] != 0)
2556 for (std::list<vpMeSite>::const_iterator itme = l->meline[a]->getMeList().begin();
2557 itme != l->meline[a]->getMeList().end(); ++itme) {
2558 if (itme->getState() == vpMeSite::NO_SUPPRESSION)
2559 nbGoodPoints++;
2560 }
2561 }
2562 }
2563 }
2564
2566 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[level].begin(); it != cylinders[level].end();
2567 ++it) {
2568 cy = *it;
2569 if (cy->isVisible() && cy->isTracked() && (cy->meline1 != nullptr || cy->meline2 != nullptr)) {
2570 for (std::list<vpMeSite>::const_iterator itme1 = cy->meline1->getMeList().begin();
2571 itme1 != cy->meline1->getMeList().end(); ++itme1) {
2572 if (itme1->getState() == vpMeSite::NO_SUPPRESSION)
2573 nbGoodPoints++;
2574 }
2575 for (std::list<vpMeSite>::const_iterator itme2 = cy->meline2->getMeList().begin();
2576 itme2 != cy->meline2->getMeList().end(); ++itme2) {
2577 if (itme2->getState() == vpMeSite::NO_SUPPRESSION)
2578 nbGoodPoints++;
2579 }
2580 }
2581 }
2582
2584 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[level].begin(); it != circles[level].end(); ++it) {
2585 ci = *it;
2586 if (ci->isVisible() && ci->isTracked() && ci->meEllipse != nullptr) {
2587 for (std::list<vpMeSite>::const_iterator itme = ci->meEllipse->getMeList().begin();
2588 itme != ci->meEllipse->getMeList().end(); ++itme) {
2589 if (itme->getState() == vpMeSite::NO_SUPPRESSION)
2590 nbGoodPoints++;
2591 }
2592 }
2593 }
2594
2595 return nbGoodPoints;
2596}
2597
2619void vpMbEdgeTracker::setScales(const std::vector<bool> &scale)
2620{
2621 unsigned int nbActivatedLevels = 0;
2622 for (unsigned int i = 0; i < scale.size(); i++) {
2623 if (scale[i]) {
2624 nbActivatedLevels++;
2625 }
2626 }
2627
2628 if (scale.empty() || (nbActivatedLevels == 0)) {
2629 vpERROR_TRACE(" !! WARNING : must use at least one level for the "
2630 "tracking. Use the global one");
2631 this->scales.clear();
2632 this->scales.push_back(true);
2633
2634 lines.resize(1);
2635 lines[0].clear();
2636
2637 cylinders.resize(1);
2638 cylinders[0].clear();
2639
2640 circles.resize(1);
2641 circles[0].clear();
2642 }
2643 else {
2644 this->scales = scale;
2645
2646 lines.resize(scale.size());
2647 cylinders.resize(scale.size());
2648 circles.resize(scale.size());
2649
2650 for (unsigned int i = 0; i < lines.size(); i++) {
2651 lines[i].clear();
2652 cylinders[i].clear();
2653 circles[i].clear();
2654 }
2655 }
2656}
2657
2664{
2666 std::cerr << "Far clipping value cannot be inferior than near clipping "
2667 "value. Far clipping won't be considered."
2668 << std::endl;
2669 else if (dist < 0)
2670 std::cerr << "Far clipping value cannot be inferior than 0. Far clipping "
2671 "won't be considered."
2672 << std::endl;
2673 else {
2676
2677 for (unsigned int i = 0; i < scales.size(); i += 1) {
2678 if (scales[i]) {
2679 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2680 l = *it;
2682 }
2683 }
2684 }
2685 }
2686}
2687
2694{
2696 std::cerr << "Near clipping value cannot be superior than far clipping "
2697 "value. Near clipping won't be considered."
2698 << std::endl;
2699 else if (dist < 0)
2700 std::cerr << "Near clipping value cannot be inferior than 0. Near "
2701 "clipping won't be considered."
2702 << std::endl;
2703 else {
2706
2707 for (unsigned int i = 0; i < scales.size(); i += 1) {
2708 if (scales[i]) {
2709 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2710 l = *it;
2712 }
2713 }
2714 }
2715 }
2716}
2717
2725void vpMbEdgeTracker::setClipping(const unsigned int &flags)
2726{
2728
2730
2731 for (unsigned int i = 0; i < scales.size(); i += 1) {
2732 if (scales[i]) {
2733 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2734 l = *it;
2736 }
2737 }
2738 }
2739}
2740
2757 std::vector<const vpImage<unsigned char> *> &_pyramid)
2758{
2759 _pyramid.resize(scales.size());
2760
2761 if (scales[0]) {
2762 _pyramid[0] = &I_;
2763 }
2764 else {
2765 _pyramid[0] = nullptr;
2766 }
2767
2768 for (unsigned int i = 1; i < _pyramid.size(); i += 1) {
2769 if (scales[i]) {
2770 unsigned int cScale = static_cast<unsigned int>(pow(2., static_cast<int>(i)));
2771 vpImage<unsigned char> *I = new vpImage<unsigned char>(I_.getHeight() / cScale, I_.getWidth() / cScale);
2772 for (unsigned int k = 0, ii = 0; k < I->getHeight(); k += 1, ii += cScale) {
2773 for (unsigned int l = 0, jj = 0; l < I->getWidth(); l += 1, jj += cScale) {
2774 (*I)[k][l] = I_[ii][jj];
2775 }
2776 }
2777 _pyramid[i] = I;
2778 }
2779 else {
2780 _pyramid[i] = nullptr;
2781 }
2782 }
2783}
2784
2791void vpMbEdgeTracker::cleanPyramid(std::vector<const vpImage<unsigned char> *> &_pyramid)
2792{
2793 if (_pyramid.size() > 0) {
2794 _pyramid[0] = nullptr;
2795 for (unsigned int i = 1; i < _pyramid.size(); i += 1) {
2796 if (_pyramid[i] != nullptr) {
2797 delete _pyramid[i];
2798 _pyramid[i] = nullptr;
2799 }
2800 }
2801 _pyramid.resize(0);
2802 }
2803}
2804
2815void vpMbEdgeTracker::getLline(std::list<vpMbtDistanceLine *> &linesList, unsigned int level) const
2816{
2817 if (level > scales.size() || !scales[level]) {
2818 std::ostringstream oss;
2819 oss << level;
2820 std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2822 }
2823
2824 linesList = lines[level];
2825}
2826
2837void vpMbEdgeTracker::getLcylinder(std::list<vpMbtDistanceCylinder *> &cylindersList, unsigned int level) const
2838{
2839 if (level > scales.size() || !scales[level]) {
2840 std::ostringstream oss;
2841 oss << level;
2842 std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2844 }
2845
2846 cylindersList = cylinders[level];
2847}
2848
2859void vpMbEdgeTracker::getLcircle(std::list<vpMbtDistanceCircle *> &circlesList, unsigned int level) const
2860{
2861 if (level > scales.size() || !scales[level]) {
2862 std::ostringstream oss;
2863 oss << level;
2864 std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2866 }
2867
2868 circlesList = circles[level];
2869}
2870
2877void vpMbEdgeTracker::downScale(const unsigned int _scale)
2878{
2879 const double ratio = pow(2., static_cast<int>(_scale));
2880 scaleLevel = _scale;
2881
2882 vpMatrix K = m_cam.get_K();
2883
2884 K[0][0] /= ratio;
2885 K[1][1] /= ratio;
2886 K[0][2] /= ratio;
2887 K[1][2] /= ratio;
2888
2889 m_cam.initFromCalibrationMatrix(K);
2890}
2891
2898void vpMbEdgeTracker::upScale(const unsigned int _scale)
2899{
2900 const double ratio = pow(2., static_cast<int>(_scale));
2901 scaleLevel = 0;
2902
2903 vpMatrix K = m_cam.get_K();
2904
2905 K[0][0] *= ratio;
2906 K[1][1] *= ratio;
2907 K[0][2] *= ratio;
2908 K[1][2] *= ratio;
2909
2910 m_cam.initFromCalibrationMatrix(K);
2911}
2912
2920void vpMbEdgeTracker::reInitLevel(const unsigned int _lvl)
2921{
2922 unsigned int scaleLevel_1 = scaleLevel;
2923 scaleLevel = _lvl;
2924
2926 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
2927 ++it) {
2928 if ((*it)->isTracked()) {
2929 l = *it;
2931 }
2932 }
2933
2935 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
2936 it != cylinders[scaleLevel].end(); ++it) {
2937 if ((*it)->isTracked()) {
2938 cy = *it;
2939 cy->reinitMovingEdge(*Ipyramid[_lvl], m_cMo, m_mask);
2940 }
2941 }
2942
2944 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
2945 it != circles[scaleLevel].end(); ++it) {
2946 if ((*it)->isTracked()) {
2947 ci = *it;
2948 ci->reinitMovingEdge(*Ipyramid[_lvl], m_cMo, m_mask);
2949 }
2950 }
2951
2952 trackMovingEdge(*Ipyramid[_lvl]);
2953 updateMovingEdge(*Ipyramid[_lvl]);
2954 scaleLevel = scaleLevel_1;
2955}
2956
2964void vpMbEdgeTracker::setUseEdgeTracking(const std::string &name, const bool &useEdgeTracking)
2965{
2966 for (unsigned int i = 0; i < scales.size(); i += 1) {
2967 if (scales[i]) {
2968 for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2969 /*(*it)->setTracked(useEdgeTracking);
2970 for(std::list<int>::const_iterator
2971 itpoly=(*it)->Lindex_polygon.begin();
2972 itpoly!=(*it)->Lindex_polygon.end(); ++itpoly){
2973 if(faces[(*itpoly)]->getName() != name){
2974 (*it)->setTracked(true);
2975 break;
2976 }
2977 }*/
2978
2979 (*it)->setTracked(name, useEdgeTracking);
2980 }
2981
2982 for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2983 ++it) {
2984 if (faces[static_cast<unsigned int>((*it)->index_polygon)]->getName() == name) {
2985 (*it)->setTracked(useEdgeTracking);
2986 }
2987 }
2988
2989 for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2990 if (faces[static_cast<unsigned int>((*it)->index_polygon)]->getName() == name) {
2991 (*it)->setTracked(useEdgeTracking);
2992 }
2993 }
2994 }
2995 }
2996}
2997END_VISP_NAMESPACE
unsigned int getRows() const
Definition vpArray2D.h:433
Generic class defining intrinsic camera parameters.
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
static const vpColor cyan
Definition vpColor.h:207
static const vpColor blue
Definition vpColor.h:204
static const vpColor purple
Definition vpColor.h:209
static const vpColor yellow
Definition vpColor.h:206
static const vpColor green
Definition vpColor.h:201
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)
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
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
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:181
static double rad(double deg)
Definition vpMath.h:129
static Type maximum(const Type &a, const Type &b)
Definition vpMath.h:257
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 Type minimum(const Type &a, const Type &b)
Definition vpMath.h:265
static int sign(double x)
Definition vpMath.h:432
static double deg(double rad)
Definition vpMath.h:119
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
vpMatrix pseudoInverse(double svThreshold=1e-6) const
void removeCircle(const std::string &name)
void computeVVS(const vpImage< unsigned char > &_I, unsigned int lvl)
vpColVector m_errorCircles
vpColVector m_w_edge
Robust weights.
void upScale(const unsigned int _scale)
void addLine(vpPoint &p1, vpPoint &p2, int polygon=-1, std::string name="")
vpRobust m_robust_edge
Robust.
virtual void reInitModel(const vpImage< unsigned char > &I, const std::string &cad_name, const vpHomogeneousMatrix &cMo, bool verbose=false, const vpHomogeneousMatrix &T=vpHomogeneousMatrix())
std::vector< std::list< vpMbtDistanceLine * > > lines
vpMe me
The moving edges parameters.
virtual void computeVVSInteractionMatrixAndResidu() VP_OVERRIDE
void displayFeaturesOnImage(const vpImage< unsigned char > &I)
void getLcylinder(std::list< vpMbtDistanceCylinder * > &cylindersList, unsigned int level=0) const
virtual void init(const vpImage< unsigned char > &I) VP_OVERRIDE
vpColVector m_wLines
void computeProjectionError(const vpImage< unsigned char > &_I)
virtual void testTracking() VP_OVERRIDE
virtual void setNearClippingDistance(const double &dist) VP_OVERRIDE
virtual void computeVVSWeights()
virtual void track(const vpImage< unsigned char > &I) 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
vpColVector m_error_edge
(s - s*)
unsigned int ncylinder
void downScale(const unsigned int _scale)
void cleanPyramid(std::vector< const vpImage< unsigned char > * > &_pyramid)
void removeCylinder(const std::string &name)
std::vector< std::list< vpMbtDistanceCylinder * > > cylinders
Vector of the tracked cylinders.
void computeVVSFirstPhase(const vpImage< unsigned char > &I, unsigned int iter, double &count, unsigned int lvl=0)
void addCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, double r, int idFace=-1, const std::string &name="")
void initPyramid(const vpImage< unsigned char > &_I, std::vector< const vpImage< unsigned char > * > &_pyramid)
std::vector< std::vector< double > > m_featuresToBeDisplayedEdge
Display features.
unsigned int nbvisiblepolygone
Number of polygon (face) currently visible.
void addCylinder(const vpPoint &P1, const vpPoint &P2, double r, int idFace=-1, const std::string &name="")
virtual void computeVVSInit() VP_OVERRIDE
std::vector< std::list< vpMbtDistanceCircle * > > circles
Vector of the tracked circles.
void getLcircle(std::list< vpMbtDistanceCircle * > &circlesList, unsigned int level=0) const
unsigned int scaleLevel
void removeLine(const std::string &name)
virtual std::vector< std::vector< double > > getFeaturesForDisplayEdge()
virtual void initFaceFromLines(vpMbtPolygon &polygon) VP_OVERRIDE
void setScales(const std::vector< bool > &_scales)
void trackMovingEdge(const vpImage< unsigned char > &I)
std::vector< const vpImage< unsigned char > * > Ipyramid
virtual void setFarClippingDistance(const double &dist) VP_OVERRIDE
virtual unsigned int getNbPoints(unsigned int level=0) const
vpColVector m_weightedError_edge
Weighted error.
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 computeVVSFirstPhaseFactor(const vpImage< unsigned char > &I, unsigned int lvl=0)
void updateMovingEdge(const vpImage< unsigned char > &I)
virtual ~vpMbEdgeTracker() VP_OVERRIDE
vpMatrix m_L_edge
Interaction matrix.
vpRobust m_robustCylinders
unsigned int initMbtTracking(unsigned int &nberrors_lines, unsigned int &nberrors_cylinders, unsigned int &nberrors_circles)
void reInitLevel(const unsigned int _lvl)
virtual void setClipping(const unsigned int &flags) VP_OVERRIDE
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
virtual std::vector< std::vector< double > > getModelForDisplay(unsigned int width, unsigned int height, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false) VP_OVERRIDE
void computeVVSFirstPhasePoseEstimation(unsigned int iter, bool &isoJoIdentity)
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)
void setUseEdgeTracking(const std::string &name, const bool &useEdgeTracking)
virtual void setCameraParameters(const vpCameraParameters &cam) VP_OVERRIDE
void getLline(std::list< vpMbtDistanceLine * > &linesList, unsigned int level=0) const
vpColVector m_wCylinders
virtual void initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius, int idFace=0, const std::string &name="") VP_OVERRIDE
unsigned int nbFeaturesForProjErrorComputation
Number of features used in the computation of the projection error.
vpColVector m_factor
Edge VVS variables.
vpColVector m_errorLines
void visibleFace(const vpImage< unsigned char > &_I, const vpHomogeneousMatrix &_cMo, bool &newvisibleline)
vpColVector m_wCircles
void initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo, const bool &useInitRange=true)
void addPolygon(vpMbtPolygon &p)
unsigned int nline
virtual void setPose(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cdMo) VP_OVERRIDE
vpColVector m_errorCylinders
virtual void loadConfigFile(const std::string &configFile, bool verbose=true) VP_OVERRIDE
bool isAppearing(unsigned int i)
bool isVisible(unsigned int i)
double m_lambda
Gain of the virtual visual servoing stage.
bool modelInitialised
double minLineLengthThresholdGeneral
Minimum line length threshold for LOD mode (general setting).
bool m_projectionErrorDisplay
Display gradient and model orientation for projection error computation.
virtual void setMinLineLengthThresh(double minLineLengthThresh, const std::string &name="")
vpImage< unsigned char > m_I
Grayscale image buffer, used when passing color images.
unsigned int m_projectionErrorDisplayLength
Length of the arrows used to show the gradient and model orientation.
bool samePoint(const vpPoint &P1, const vpPoint &P2) const
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="")
vpUniRand m_rand
Random number generator used in vpMbtDistanceLine::buildFrom().
vpMatrix covarianceMatrix
Covariance matrix.
double m_initialMu
Initial Mu for Levenberg Marquardt optimization loop.
bool computeProjError
vpHomogeneousMatrix m_cMo
The current pose.
vpMatrix m_SobelX
Sobel kernel in X.
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 projectionError
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="")
unsigned int m_projectionErrorDisplayThickness
Thickness of the arrows used to show the gradient and model orientation.
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)
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
virtual void setNearClippingDistance(const double &dist)
bool applyLodSettingInConfig
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.
void computeJTR(const vpMatrix &J, const vpColVector &R, vpColVector &JTR) const
vpMatrix m_SobelY
Sobel kernel in Y.
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.
virtual void loadConfigFile(const std::string &configFile, bool verbose=true)
Manage a circle used in the model-based tracker.
void setVisible(bool _isvisible)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
std::vector< std::vector< double > > getFeaturesForDisplay()
void setCameraParameters(const vpCameraParameters &camera)
vpColVector error
The error vector.
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
vpPoint * p1
The center of the circle.
unsigned int nbFeature
The number of moving edges.
vpMatrix L
The interaction matrix.
void setIndex(unsigned int i)
std::string getName() const
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const vpPoint &_p3, double r)
vpPoint * p2
A point on the plane containing the circle.
void setMeanWeight(double _wmean)
bool Reinit
Indicates if the circle has to be reinitialized.
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpImage< bool > *mask=nullptr)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=nullptr, const int &initRange=1U)
double radius
The radius of the circle.
int index_polygon
Index of the faces which contain the line.
vpPoint * p3
An other point on the plane containing the circle.
vpMbtMeEllipse * meEllipse
The moving edge containers.
void setName(const std::string &circle_name)
Manage a cylinder used in the model-based tracker.
void setMeanWeight1(double wmean)
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, double r)
void setCameraParameters(const vpCameraParameters &camera)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo, const vpImage< unsigned char > &I)
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpImage< bool > *mask=nullptr)
void setName(const std::string &cyl_name)
vpMbtMeLine * meline2
The moving edge containers (second line of the cylinder).
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=nullptr, const int &initRange=0)
void setVisible(bool _isvisible)
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.
vpPoint * p2
The second extremity on the axe.
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
void setMeanWeight2(double wmean)
double radius
The radius of the cylinder.
unsigned int nbFeaturel1
The number of moving edges on line 1.
vpColVector error
The error vector.
std::string getName() const
std::vector< std::vector< double > > getFeaturesForDisplay()
unsigned int nbFeature
The number of moving edges.
int index_polygon
Index of the face which contains the cylinder.
void setIndex(unsigned int i)
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpPoint * p1
The first extremity on the axe.
vpMbtMeLine * meline1
The moving edge containers (first line of the cylinder).
Manage the line of a polygon used in the model-based tracker.
void setMovingEdge(vpMe *Me)
std::vector< unsigned int > nbFeature
The number of moving edges.
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=nullptr, const int &initRange=0)
void setIndex(unsigned int i)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
vpPoint * p2
The second extremity.
std::list< int > Lindex_polygon
Index of the faces which contain the line.
void buildFrom(vpPoint &_p1, vpPoint &_p2, vpUniRand &rand_gen)
unsigned int nbFeatureTotal
The number of moving edges.
bool Reinit
Indicates if the line has to be reinitialized.
std::string getName() const
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)
vpMbtPolygon & getPolygon()
std::vector< std::vector< double > > getFeaturesForDisplay()
bool useScanLine
Use scanline rendering.
vpPoint * p1
The first extremity.
std::vector< vpMbtMeLine * > meline
The moving edge container.
vpMatrix L
The interaction matrix.
void setCameraParameters(const vpCameraParameters &camera)
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpImage< bool > *mask=nullptr)
void setName(const std::string &line_name)
void setMeanWeight(double w_mean)
void setVisible(bool _isvisible)
void addPolygon(const int &index)
void trackMovingEdge(const vpImage< unsigned char > &I)
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 setEdgeMe(const vpMe &ecm)
void getEdgeMe(vpMe &ecm) const
double getLodMinLineLengthThreshold() const
void setAngleDisappear(const double &adisappear)
void setAngleAppear(const double &aappear)
void parse(const std::string &filename)
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
@ TOO_NEAR
Point not tracked anymore, since too near from its neighbor.
Definition vpMeSite.h:100
@ THRESHOLD
Point not tracked due to the likelihood that is below the threshold, but retained in the ME list.
Definition vpMeSite.h:98
@ CONTRAST
Point not tracked due to a contrast problem, but retained in the ME list.
Definition vpMeSite.h:94
@ 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
void setFarClippingDistance(const double &dist)
unsigned int getNbPoint() const
void setNearClippingDistance(const double &dist)
vpPoint * p
corners in the object frame
Definition vpPolygon3D.h:79
void setClipping(const unsigned int &flags)
@ TUKEY
Tukey influence function.
Definition vpRobust.h:89
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 vpTRACE
Definition vpDebug.h:450
#define vpERROR_TRACE
Definition vpDebug.h:423