Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpMbEdgeTracker.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Make the complete tracking of an object by using its CAD model
33  *
34 *****************************************************************************/
35 
41 #include <visp3/core/vpDebug.h>
42 #include <visp3/core/vpException.h>
43 #include <visp3/core/vpExponentialMap.h>
44 #include <visp3/core/vpMath.h>
45 #include <visp3/core/vpMatrixException.h>
46 #include <visp3/core/vpPixelMeterConversion.h>
47 #include <visp3/core/vpPolygon3D.h>
48 #include <visp3/core/vpTrackingException.h>
49 #include <visp3/core/vpVelocityTwistMatrix.h>
50 #include <visp3/mbt/vpMbEdgeTracker.h>
51 #include <visp3/mbt/vpMbtDistanceLine.h>
52 #include <visp3/mbt/vpMbtXmlGenericParser.h>
53 #include <visp3/vision/vpPose.h>
54 
55 #include <float.h>
56 #include <limits>
57 #include <map>
58 #include <sstream>
59 #include <string>
60 
66  : me(), lines(1), circles(1), cylinders(1), nline(0), ncircle(0), ncylinder(0), nbvisiblepolygone(0),
67  percentageGdPt(0.4), scales(1), Ipyramid(0), scaleLevel(0), nbFeaturesForProjErrorComputation(0), m_factor(),
68  m_robustLines(), m_robustCylinders(), m_robustCircles(), m_wLines(), m_wCylinders(), m_wCircles(), m_errorLines(),
69  m_errorCylinders(), m_errorCircles(), m_L_edge(), m_error_edge(), m_w_edge(), m_weightedError_edge(),
70  m_robust_edge(), m_featuresToBeDisplayedEdge()
71 {
72  scales[0] = true;
73 
74 #ifdef VISP_HAVE_OGRE
75  faces.getOgreContext()->setWindowName("MBT Edge");
76 #endif
77 }
78 
83 {
87 
88  for (unsigned int i = 0; i < scales.size(); i += 1) {
89  if (scales[i]) {
90  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
91  l = *it;
92  if (l != nullptr) {
93  delete l;
94  }
95  l = nullptr;
96  }
97 
98  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
99  ++it) {
100  cy = *it;
101  if (cy != nullptr) {
102  delete cy;
103  }
104  cy = nullptr;
105  }
106 
107  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
108  ci = *it;
109  if (ci != nullptr) {
110  delete ci;
111  }
112  ci = nullptr;
113  }
114 
115  lines[i].clear();
116  cylinders[i].clear();
117  circles[i].clear();
118  }
119  }
120 
122 }
123 
130 {
131  this->me = p_me;
132 
133  for (unsigned int i = 0; i < scales.size(); i += 1) {
134  if (scales[i]) {
135  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
136  vpMbtDistanceLine *l = *it;
137  l->setMovingEdge(&(this->me));
138  }
139 
140  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
141  ++it) {
142  vpMbtDistanceCylinder *cy = *it;
143  cy->setMovingEdge(&(this->me));
144  }
145 
146  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
147  vpMbtDistanceCircle *ci = *it;
148  ci->setMovingEdge(&(this->me));
149  }
150  }
151  }
152 }
153 
163 void vpMbEdgeTracker::computeVVS(const vpImage<unsigned char> &_I, unsigned int lvl)
164 {
165  double residu_1 = 1e3;
166  double r = 1e3 - 1;
167 
168  unsigned int iter = 0;
169 
170  computeVVSInit();
171  unsigned int nbrow = m_error_edge.getRows();
172 
173  bool reloop = true;
174 
175  bool isoJoIdentity = m_isoJoIdentity; // Backup since it can be modified if L is not full rank
176  if (isoJoIdentity)
177  oJo.eye();
178 
179  /*** First phase ***/
180 
181  while (reloop == true && iter < 10) {
182  double count = 0;
183 
184  computeVVSFirstPhase(_I, iter, count, lvl);
185 
186  count = count / (double)nbrow;
187  if (count >= 0.85) {
188  reloop = false;
189  }
190 
191  computeVVSFirstPhasePoseEstimation(iter, isoJoIdentity);
192 
193  iter++;
194  }
195 
196  // std::cout << "\t First minimization in " << iter << " iteration give as
197  // initial cMo: \n" << cMo << std::endl;
198 
199  /*** Second phase ***/
200  vpHomogeneousMatrix cMoPrev;
201  vpColVector W_true(nbrow);
202  vpMatrix L_true;
203  vpMatrix LVJ_true;
204 
205  double mu = m_initialMu;
206  vpColVector m_error_prev;
207  vpColVector m_w_prev;
208 
209  // To avoid to create these matrices each iteration
210  vpMatrix LTL;
211  vpColVector LTR;
212  vpColVector v;
213 
214  iter = 0;
215  m_w_edge = 1;
216 
217  // while ( ((int)((residu_1 - r)*1e8) !=0 ) && (iter<30))
218  while (std::fabs((residu_1 - r) * 1e8) > std::numeric_limits<double>::epsilon() && (iter < m_maxIter)) {
220 
221  bool reStartFromLastIncrement = false;
222  computeVVSCheckLevenbergMarquardt(iter, m_error_edge, m_error_prev, cMoPrev, mu, reStartFromLastIncrement,
223  &m_w_edge, &m_w_prev);
224 
225  if (!reStartFromLastIncrement) {
227 
228  L_true = m_L_edge;
230 
231  if (computeCovariance) {
232  L_true = m_L_edge;
233  if (!isoJoIdentity) {
234  cVo.build(m_cMo);
235  LVJ_true = (m_L_edge * cVo * oJo);
236  }
237  }
238 
239  double wi = 0.0, eri = 0.0;
240  double num = 0.0, den = 0.0;
241  if ((iter == 0) || m_computeInteraction) {
242  for (unsigned int i = 0; i < nbrow; i++) {
243  wi = m_w_edge[i] * m_factor[i];
244  W_true[i] = wi;
245  eri = m_error_edge[i];
246  num += wi * vpMath::sqr(eri);
247  den += wi;
248 
249  m_weightedError_edge[i] = wi * eri;
250 
251  for (unsigned int j = 0; j < 6; j++) {
252  m_L_edge[i][j] = wi * m_L_edge[i][j];
253  }
254  }
255  }
256  else {
257  for (unsigned int i = 0; i < nbrow; i++) {
258  wi = m_w_edge[i] * m_factor[i];
259  W_true[i] = wi;
260  eri = m_error_edge[i];
261  num += wi * vpMath::sqr(eri);
262  den += wi;
263 
264  m_weightedError_edge[i] = wi * eri;
265  }
266  }
267 
268  residu_1 = r;
269  r = sqrt(num / den); // Le critere d'arret prend en compte le poids
270 
271  computeVVSPoseEstimation(isoJoIdentity, iter, m_L_edge, LTL, m_weightedError_edge, m_error_edge, m_error_prev,
272  LTR, mu, v, &m_w_edge, &m_w_prev);
273 
274  cMoPrev = m_cMo;
276 
277  } // endif(!restartFromLast)
278 
279  iter++;
280  }
281 
282  computeCovarianceMatrixVVS(isoJoIdentity, W_true, cMoPrev, L_true, LVJ_true, m_error_edge);
283 
285 }
286 
287 void vpMbEdgeTracker::computeVVSFirstPhase(const vpImage<unsigned char> &_I, unsigned int iter, double &count,
288  unsigned int lvl)
289 {
293 
294  double limite = 3; // Une limite de 3 pixels
295  limite = limite / m_cam.get_px(); // Transformation limite pixel en limite metre.
296 
297  unsigned int n = 0;
298 
299  // Parametre pour la premiere phase d'asservissement
300  double e_prev = 0, e_cur, e_next;
301 
302  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
303  if ((*it)->isTracked()) {
304  l = *it;
306 
307  double fac = 1;
308  if (iter == 0) {
309  for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
310  ++itindex) {
311  int index = *itindex;
312  if (l->hiddenface->isAppearing((unsigned int)index)) {
313  fac = 0.2;
314  break;
315  }
316  if (l->closeToImageBorder(_I, 10)) {
317  fac = 0.1;
318  break;
319  }
320  }
321  }
322 
323  std::list<vpMeSite>::const_iterator itListLine;
324 
325  unsigned int indexFeature = 0;
326 
327  for (size_t a = 0; a < l->meline.size(); a++) {
328  if (iter == 0 && l->meline[a] != nullptr)
329  itListLine = l->meline[a]->getMeList().begin();
330 
331  for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
332  for (unsigned int j = 0; j < 6; j++) {
333  m_L_edge[n + i][j] = l->L[indexFeature][j]; // On remplit la matrice d'interaction globale
334  }
335  m_error_edge[n + i] = l->error[indexFeature]; // On remplit la matrice d'erreur
336 
337  if (m_error_edge[n + i] <= limite)
338  count = count + 1.0; // Si erreur proche de 0 on incremente cur
339 
340  m_w_edge[n + i] = 0;
341 
342  if (iter == 0) {
343  m_factor[n + i] = fac;
344  vpMeSite site = *itListLine;
345  if (site.getState() != vpMeSite::NO_SUPPRESSION)
346  m_factor[n + i] = 0.2;
347  ++itListLine;
348  }
349 
350  // If pour la premiere extremite des moving edges
351  if (indexFeature == 0) {
352  e_cur = l->error[0];
353  if (l->nbFeature[a] > 1) {
354  e_next = l->error[1];
355  if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
356  m_w_edge[n + i] = 1 /*0.5*/;
357  }
358  e_prev = e_cur;
359  }
360  else
361  m_w_edge[n + i] = 1;
362  }
363 
364  // If pour la derniere extremite des moving edges
365  else if (indexFeature == l->nbFeatureTotal - 1) {
366  e_cur = l->error[indexFeature];
367  if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
368  m_w_edge[n + i] += 1 /*0.5*/;
369  }
370  }
371 
372  else {
373  e_cur = l->error[indexFeature];
374  e_next = l->error[indexFeature + 1];
375  if (fabs(e_cur - e_prev) < limite) {
376  m_w_edge[n + i] += 0.5;
377  }
378  if (fabs(e_cur - e_next) < limite) {
379  m_w_edge[n + i] += 0.5;
380  }
381  e_prev = e_cur;
382  }
383  indexFeature++;
384  }
385  n += l->nbFeature[a];
386  }
387  }
388  }
389 
390  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
391  ++it) {
392  if ((*it)->isTracked()) {
393  cy = *it;
395  double fac = 1.0;
396 
397  std::list<vpMeSite>::const_iterator itCyl1;
398  std::list<vpMeSite>::const_iterator itCyl2;
399  if (iter == 0 && (cy->meline1 != nullptr || cy->meline2 != nullptr)) {
400  itCyl1 = cy->meline1->getMeList().begin();
401  itCyl2 = cy->meline2->getMeList().begin();
402  }
403 
404  for (unsigned int i = 0; i < cy->nbFeature; i++) {
405  for (unsigned int j = 0; j < 6; j++) {
406  m_L_edge[n + i][j] = cy->L[i][j]; // On remplit la matrice d'interaction globale
407  }
408  m_error_edge[n + i] = cy->error[i]; // On remplit la matrice d'erreur
409 
410  if (m_error_edge[n + i] <= limite)
411  count = count + 1.0; // Si erreur proche de 0 on incremente cur
412 
413  m_w_edge[n + i] = 0;
414 
415  if (iter == 0) {
416  m_factor[n + i] = fac;
417  vpMeSite site;
418  if (i < cy->nbFeaturel1) {
419  site = *itCyl1;
420  ++itCyl1;
421  }
422  else {
423  site = *itCyl2;
424  ++itCyl2;
425  }
426  if (site.getState() != vpMeSite::NO_SUPPRESSION)
427  m_factor[n + i] = 0.2;
428  }
429 
430  // If pour la premiere extremite des moving edges
431  if (i == 0) {
432  e_cur = cy->error[0];
433  if (cy->nbFeature > 1) {
434  e_next = cy->error[1];
435  if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
436  m_w_edge[n + i] = 1 /*0.5*/;
437  }
438  e_prev = e_cur;
439  }
440  else
441  m_w_edge[n + i] = 1;
442  }
443  if (i == cy->nbFeaturel1) {
444  e_cur = cy->error[i];
445  if (cy->nbFeaturel2 > 1) {
446  e_next = cy->error[i + 1];
447  if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
448  m_w_edge[n + i] = 1 /*0.5*/;
449  }
450  e_prev = e_cur;
451  }
452  else
453  m_w_edge[n + i] = 1;
454  }
455 
456  // If pour la derniere extremite des moving edges
457  else if (i == cy->nbFeaturel1 - 1) {
458  e_cur = cy->error[i];
459  if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
460  m_w_edge[n + i] += 1 /*0.5*/;
461  }
462  }
463  // If pour la derniere extremite des moving edges
464  else if (i == cy->nbFeature - 1) {
465  e_cur = cy->error[i];
466  if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
467  m_w_edge[n + i] += 1 /*0.5*/;
468  }
469  }
470 
471  else {
472  e_cur = cy->error[i];
473  e_next = cy->error[i + 1];
474  if (fabs(e_cur - e_prev) < limite) {
475  m_w_edge[n + i] += 0.5;
476  }
477  if (fabs(e_cur - e_next) < limite) {
478  m_w_edge[n + i] += 0.5;
479  }
480  e_prev = e_cur;
481  }
482  }
483 
484  n += cy->nbFeature;
485  }
486  }
487 
488  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
489  if ((*it)->isTracked()) {
490  ci = *it;
492  double fac = 1.0;
493 
494  std::list<vpMeSite>::const_iterator itCir;
495  if (iter == 0 && (ci->meEllipse != nullptr)) {
496  itCir = ci->meEllipse->getMeList().begin();
497  }
498 
499  for (unsigned int i = 0; i < ci->nbFeature; i++) {
500  for (unsigned int j = 0; j < 6; j++) {
501  m_L_edge[n + i][j] = ci->L[i][j]; // On remplit la matrice d'interaction globale
502  }
503  m_error_edge[n + i] = ci->error[i]; // On remplit la matrice d'erreur
504 
505  if (m_error_edge[n + i] <= limite)
506  count = count + 1.0; // Si erreur proche de 0 on incremente cur
507 
508  m_w_edge[n + i] = 0;
509 
510  if (iter == 0) {
511  m_factor[n + i] = fac;
512  vpMeSite site = *itCir;
513  if (site.getState() != vpMeSite::NO_SUPPRESSION)
514  m_factor[n + i] = 0.2;
515  ++itCir;
516  }
517 
518  // If pour la premiere extremite des moving edges
519  if (i == 0) {
520  e_cur = ci->error[0];
521  if (ci->nbFeature > 1) {
522  e_next = ci->error[1];
523  if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
524  m_w_edge[n + i] = 1 /*0.5*/;
525  }
526  e_prev = e_cur;
527  }
528  else
529  m_w_edge[n + i] = 1;
530  }
531 
532  // If pour la derniere extremite des moving edges
533  else if (i == ci->nbFeature - 1) {
534  e_cur = ci->error[i];
535  if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
536  m_w_edge[n + i] += 1 /*0.5*/;
537  }
538  }
539 
540  else {
541  e_cur = ci->error[i];
542  e_next = ci->error[i + 1];
543  if (fabs(e_cur - e_prev) < limite) {
544  m_w_edge[n + i] += 0.5;
545  }
546  if (fabs(e_cur - e_next) < limite) {
547  m_w_edge[n + i] += 0.5;
548  }
549  e_prev = e_cur;
550  }
551  }
552 
553  n += ci->nbFeature;
554  }
555  }
556 }
557 
559 {
563 
564  unsigned int n = 0;
565  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
566  if ((*it)->isTracked()) {
567  l = *it;
569 
570  double fac = 1;
571  for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
572  ++itindex) {
573  int index = *itindex;
574  if (l->hiddenface->isAppearing((unsigned int)index)) {
575  fac = 0.2;
576  break;
577  }
578  if (l->closeToImageBorder(I, 10)) {
579  fac = 0.1;
580  break;
581  }
582  }
583 
584  for (size_t a = 0; a < l->meline.size(); a++) {
585  std::list<vpMeSite>::const_iterator itListLine;
586  if (l->meline[a] != nullptr) {
587  itListLine = l->meline[a]->getMeList().begin();
588 
589  for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
590  m_factor[n + i] = fac;
591  vpMeSite site = *itListLine;
592  if (site.getState() != vpMeSite::NO_SUPPRESSION)
593  m_factor[n + i] = 0.2;
594  ++itListLine;
595  }
596  n += l->nbFeature[a];
597  }
598  }
599  }
600  }
601 
602  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
603  ++it) {
604  if ((*it)->isTracked()) {
605  cy = *it;
607 
608  std::list<vpMeSite>::const_iterator itCyl1;
609  std::list<vpMeSite>::const_iterator itCyl2;
610  if ((cy->meline1 != nullptr || cy->meline2 != nullptr)) {
611  itCyl1 = cy->meline1->getMeList().begin();
612  itCyl2 = cy->meline2->getMeList().begin();
613 
614  double fac = 1.0;
615  for (unsigned int i = 0; i < cy->nbFeature; i++) {
616  m_factor[n + i] = fac;
617  vpMeSite site;
618  if (i < cy->nbFeaturel1) {
619  site = *itCyl1;
620  ++itCyl1;
621  }
622  else {
623  site = *itCyl2;
624  ++itCyl2;
625  }
626  if (site.getState() != vpMeSite::NO_SUPPRESSION)
627  m_factor[n + i] = 0.2;
628  }
629  n += cy->nbFeature;
630  }
631  }
632  }
633 
634  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
635  if ((*it)->isTracked()) {
636  ci = *it;
638 
639  std::list<vpMeSite>::const_iterator itCir;
640  if (ci->meEllipse != nullptr) {
641  itCir = ci->meEllipse->getMeList().begin();
642  double fac = 1.0;
643 
644  for (unsigned int i = 0; i < ci->nbFeature; i++) {
645  m_factor[n + i] = fac;
646  vpMeSite site = *itCir;
647  if (site.getState() != vpMeSite::NO_SUPPRESSION)
648  m_factor[n + i] = 0.2;
649  ++itCir;
650  }
651  n += ci->nbFeature;
652  }
653  }
654  }
655 }
656 
657 void vpMbEdgeTracker::computeVVSFirstPhasePoseEstimation(unsigned int iter, bool &isoJoIdentity)
658 {
659  unsigned int nerror = m_weightedError_edge.getRows();
660 
661  double wi, eri;
662  if ((iter == 0) || m_computeInteraction) {
663  for (unsigned int i = 0; i < nerror; i++) {
664  wi = m_w_edge[i] * m_factor[i];
665  eri = m_error_edge[i];
666 
667  m_weightedError_edge[i] = wi * eri;
668 
669  for (unsigned int j = 0; j < 6; j++) {
670  m_L_edge[i][j] = wi * m_L_edge[i][j];
671  }
672  }
673  }
674  else {
675  for (unsigned int i = 0; i < nerror; i++) {
676  wi = m_w_edge[i] * m_factor[i];
677  eri = m_error_edge[i];
678 
679  m_weightedError_edge[i] = wi * eri;
680  }
681  }
682 
684 
685  // If all the 6 dof should be estimated, we check if the interaction matrix
686  // is full rank. If not we remove automatically the dof that cannot be
687  // estimated This is particularly useful when considering circles (rank 5) and
688  // cylinders (rank 4)
689  if (isoJoIdentity) {
690  cVo.build(m_cMo);
691 
692  vpMatrix K; // kernel
693  unsigned int rank = (m_L_edge * cVo).kernel(K);
694  if (rank == 0) {
695  throw vpException(vpException::fatalError, "Rank=0, cannot estimate the pose !");
696  }
697  if (rank != 6) {
698  vpMatrix I; // Identity
699  I.eye(6);
700  oJo = I - K.AtA();
701 
702  isoJoIdentity = false;
703  }
704  }
705 
706  vpColVector v;
707  vpMatrix LTL;
708  vpColVector LTR;
709 
710  if (isoJoIdentity) {
711  LTL = m_L_edge.AtA();
713  v = -0.7 * LTL.pseudoInverse(LTL.getRows() * std::numeric_limits<double>::epsilon()) * LTR;
714  }
715  else {
716  cVo.build(m_cMo);
717  vpMatrix LVJ = (m_L_edge * cVo * oJo);
718  vpMatrix LVJTLVJ = (LVJ).AtA();
719  vpColVector LVJTR;
720  computeJTR(LVJ, m_weightedError_edge, LVJTR);
721  v = -0.7 * LVJTLVJ.pseudoInverse(LVJTLVJ.getRows() * std::numeric_limits<double>::epsilon()) * LVJTR;
722  v = cVo * v;
723  }
724 
726 }
727 
729 {
730  // Nombre de moving edges
731  unsigned int nbrow = 0;
732  unsigned int nberrors_lines = 0;
733  unsigned int nberrors_cylinders = 0;
734  unsigned int nberrors_circles = 0;
735 
736  nbrow = initMbtTracking(nberrors_lines, nberrors_cylinders, nberrors_circles);
737 
738  if (nbrow == 0) {
740  "No data found to compute the interaction matrix...");
741  }
742 
743  m_L_edge.resize(nbrow, 6, false, false);
744  m_error_edge.resize(nbrow, false);
745 
746  m_weightedError_edge.resize(nbrow, false);
747  m_w_edge.resize(nbrow, false);
748  m_w_edge = 1;
749  m_factor.resize(nbrow, false);
750  m_factor = 1;
751 
755 
756  m_wLines.resize(nberrors_lines, false);
757  m_wLines = 1;
758  m_wCylinders.resize(nberrors_cylinders, false);
759  m_wCylinders = 1;
760  m_wCircles.resize(nberrors_circles, false);
761  m_wCircles = 1;
762 
763  m_errorLines.resize(nberrors_lines, false);
764  m_errorCylinders.resize(nberrors_cylinders, false);
765  m_errorCircles.resize(nberrors_circles, false);
766 }
767 
769 {
770  throw vpException(vpException::fatalError, "vpMbEdgeTracker::"
771  "computeVVSInteractionMatrixAndR"
772  "esidu() should not be called!");
773 }
774 
776 {
780 
781  unsigned int n = 0;
782  unsigned int nlines = 0;
783  unsigned int ncylinders = 0;
784  unsigned int ncircles = 0;
785 
786  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
787  ++it) {
788  if ((*it)->isTracked()) {
789  l = *it;
791  for (unsigned int i = 0; i < l->nbFeatureTotal; i++) {
792  for (unsigned int j = 0; j < 6; j++) {
793  m_L_edge[n + i][j] = l->L[i][j];
794  m_error_edge[n + i] = l->error[i];
795  m_errorLines[nlines + i] = m_error_edge[n + i];
796  }
797  }
798  n += l->nbFeatureTotal;
799  nlines += l->nbFeatureTotal;
800  }
801  }
802 
803  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
804  it != cylinders[scaleLevel].end(); ++it) {
805  if ((*it)->isTracked()) {
806  cy = *it;
808  for (unsigned int i = 0; i < cy->nbFeature; i++) {
809  for (unsigned int j = 0; j < 6; j++) {
810  m_L_edge[n + i][j] = cy->L[i][j];
811  m_error_edge[n + i] = cy->error[i];
812  m_errorCylinders[ncylinders + i] = m_error_edge[n + i];
813  }
814  }
815 
816  n += cy->nbFeature;
817  ncylinders += cy->nbFeature;
818  }
819  }
820 
821  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
822  it != circles[scaleLevel].end(); ++it) {
823  if ((*it)->isTracked()) {
824  ci = *it;
826  for (unsigned int i = 0; i < ci->nbFeature; i++) {
827  for (unsigned int j = 0; j < 6; j++) {
828  m_L_edge[n + i][j] = ci->L[i][j];
829  m_error_edge[n + i] = ci->error[i];
830  m_errorCircles[ncircles + i] = m_error_edge[n + i];
831  }
832  }
833 
834  n += ci->nbFeature;
835  ncircles += ci->nbFeature;
836  }
837  }
838 }
839 
841 {
842  unsigned int nberrors_lines = m_errorLines.getRows(), nberrors_cylinders = m_errorCylinders.getRows(),
843  nberrors_circles = m_errorCircles.getRows();
844 
845  if (nberrors_lines > 0)
847  if (nberrors_cylinders > 0)
849  if (nberrors_circles > 0)
851 
855 }
856 
866 {
867  projectionError = 0.0;
868  unsigned int nbFeatures = 0;
869  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
870  ++it) {
871  vpMbtDistanceLine *l = *it;
872  if (l->isVisible() && l->isTracked()) {
873  for (size_t a = 0; a < l->meline.size(); a++) {
874  if (l->meline[a] != nullptr) {
875  double lineNormGradient;
876  unsigned int lineNbFeatures;
877  l->meline[a]->computeProjectionError(_I, lineNormGradient, lineNbFeatures, m_SobelX, m_SobelY,
880  projectionError += lineNormGradient;
881  nbFeatures += lineNbFeatures;
882  }
883  }
884  }
885  }
886 
887  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
888  it != cylinders[scaleLevel].end(); ++it) {
889  vpMbtDistanceCylinder *cy = *it;
890  if (cy->isVisible() && cy->isTracked()) {
891  if (cy->meline1 != nullptr) {
892  double cylinderNormGradient = 0;
893  unsigned int cylinderNbFeatures = 0;
894  cy->meline1->computeProjectionError(_I, cylinderNormGradient, cylinderNbFeatures, m_SobelX, m_SobelY,
897  projectionError += cylinderNormGradient;
898  nbFeatures += cylinderNbFeatures;
899  }
900 
901  if (cy->meline2 != nullptr) {
902  double cylinderNormGradient = 0;
903  unsigned int cylinderNbFeatures = 0;
904  cy->meline2->computeProjectionError(_I, cylinderNormGradient, cylinderNbFeatures, m_SobelX, m_SobelY,
907  projectionError += cylinderNormGradient;
908  nbFeatures += cylinderNbFeatures;
909  }
910  }
911  }
912 
913  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
914  it != circles[scaleLevel].end(); ++it) {
915  vpMbtDistanceCircle *c = *it;
916  if (c->isVisible() && c->isTracked() && c->meEllipse != nullptr) {
917  double circleNormGradient = 0;
918  unsigned int circleNbFeatures = 0;
919  c->meEllipse->computeProjectionError(_I, circleNormGradient, circleNbFeatures, m_SobelX, m_SobelY,
922  projectionError += circleNormGradient;
923  nbFeatures += circleNbFeatures;
924  }
925  }
926 
927  if (nbFeatures > 0) {
928  projectionError = vpMath::deg(projectionError / (double)nbFeatures);
929  }
930  else {
931  projectionError = 90.0;
932  }
933 
935  // std::cout << "Norm Gradient = " << errorGradient << std::endl;
936 }
937 
944 {
945  int nbExpectedPoint = 0;
946  int nbGoodPoint = 0;
947  int nbBadPoint = 0;
948 
949  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
950  ++it) {
951  vpMbtDistanceLine *l = *it;
952  if (l->isVisible() && l->isTracked()) {
953  for (size_t a = 0; a < l->meline.size(); a++) {
954  if (l->meline[a] != nullptr) {
955  nbExpectedPoint += (int)l->meline[a]->expecteddensity;
956  for (std::list<vpMeSite>::const_iterator itme = l->meline[a]->getMeList().begin();
957  itme != l->meline[a]->getMeList().end(); ++itme) {
958  vpMeSite pix = *itme;
959  if (pix.getState() == vpMeSite::NO_SUPPRESSION)
960  nbGoodPoint++;
961  else
962  nbBadPoint++;
963  }
964  }
965  }
966  }
967  }
968 
969  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
970  it != cylinders[scaleLevel].end(); ++it) {
971  vpMbtDistanceCylinder *cy = *it;
972  if ((cy->meline1 != nullptr && cy->meline2 != nullptr) && cy->isVisible() && cy->isTracked()) {
973  nbExpectedPoint += (int)cy->meline1->expecteddensity;
974  for (std::list<vpMeSite>::const_iterator itme1 = cy->meline1->getMeList().begin();
975  itme1 != cy->meline1->getMeList().end(); ++itme1) {
976  vpMeSite pix = *itme1;
977  if (pix.getState() == vpMeSite::NO_SUPPRESSION)
978  nbGoodPoint++;
979  else
980  nbBadPoint++;
981  }
982  nbExpectedPoint += (int)cy->meline2->expecteddensity;
983  for (std::list<vpMeSite>::const_iterator itme2 = cy->meline2->getMeList().begin();
984  itme2 != cy->meline2->getMeList().end(); ++itme2) {
985  vpMeSite pix = *itme2;
986  if (pix.getState() == vpMeSite::NO_SUPPRESSION)
987  nbGoodPoint++;
988  else
989  nbBadPoint++;
990  }
991  }
992  }
993 
994  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
995  it != circles[scaleLevel].end(); ++it) {
996  vpMbtDistanceCircle *ci = *it;
997  if (ci->isVisible() && ci->isTracked() && ci->meEllipse != nullptr) {
998  nbExpectedPoint += ci->meEllipse->getExpectedDensity();
999  for (std::list<vpMeSite>::const_iterator itme = ci->meEllipse->getMeList().begin();
1000  itme != ci->meEllipse->getMeList().end(); ++itme) {
1001  vpMeSite pix = *itme;
1002  if (pix.getState() == vpMeSite::NO_SUPPRESSION)
1003  nbGoodPoint++;
1004  else
1005  nbBadPoint++;
1006  }
1007  }
1008  }
1009 
1010  // Compare the number of good points with the min between the number of
1011  // expected points and number of points that are tracked
1012  int nb_min = (int)vpMath::minimum(percentageGdPt * nbExpectedPoint, percentageGdPt * (nbGoodPoint + nbBadPoint));
1013  if (nbGoodPoint < nb_min || nbExpectedPoint < 2) {
1014  std::ostringstream oss;
1015  oss << "Not enough moving edges (" << nbGoodPoint << ") to track the object: expected " << nb_min
1016  << ". Try to reduce the threshold=" << percentageGdPt
1017  << " using vpMbTracker::setGoodMovingEdgesRatioThreshold()";
1019  }
1020 }
1021 
1030 {
1031  initPyramid(I, Ipyramid);
1032 
1033  unsigned int lvl = (unsigned int)scales.size();
1034  do {
1035  lvl--;
1036 
1037  projectionError = 90.0;
1038 
1039  if (scales[lvl]) {
1040  vpHomogeneousMatrix cMo_1 = m_cMo;
1041  try {
1042  downScale(lvl);
1043 
1044  try {
1045  trackMovingEdge(*Ipyramid[lvl]);
1046  }
1047  catch (...) {
1048  vpTRACE("Error in moving edge tracking");
1049  throw;
1050  }
1051 
1052  // initialize the vector that contains the error and the matrix that
1053  // contains the interaction matrix AY: Useless as it is done in
1054  // coputeVVS()
1055  /*
1056  for(std::list<vpMbtDistanceLine*>::const_iterator
1057  it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){ l = *it; if
1058  (l->isVisible()){ l->initInteractionMatrixError();
1059  }
1060  }
1061 
1062  for(std::list<vpMbtDistanceCylinder*>::const_iterator
1063  it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){ cy = *it;
1064  if(cy->isVisible()) {
1065  cy->initInteractionMatrixError();
1066  }
1067  }
1068 
1069  for(std::list<vpMbtDistanceCircle*>::const_iterator
1070  it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){ ci = *it; if
1071  (ci->isVisible()){ ci->initInteractionMatrixError();
1072  }
1073  }
1074  */
1075 
1076  try {
1077  computeVVS(*Ipyramid[lvl], lvl);
1078  }
1079  catch (...) {
1080  covarianceMatrix = -1;
1081  throw; // throw the original exception
1082  }
1083 
1084  testTracking();
1085 
1086  if (displayFeatures) {
1088  }
1089 
1090  // Looking for new visible face
1091  bool newvisibleface = false;
1092  visibleFace(I, m_cMo, newvisibleface);
1093 
1094  // cam.computeFov(I.getWidth(), I.getHeight());
1095  if (useScanLine) {
1098  }
1099 
1100  updateMovingEdge(I);
1101 
1102  initMovingEdge(I, m_cMo);
1103  // Reinit the moving edge for the lines which need it.
1104  reinitMovingEdge(I, m_cMo);
1105 
1106  if (computeProjError)
1108 
1109  upScale(lvl);
1110  }
1111  catch (const vpException &e) {
1112  if (lvl != 0) {
1113  m_cMo = cMo_1;
1114  reInitLevel(lvl);
1115  upScale(lvl);
1116  }
1117  else {
1118  upScale(lvl);
1119  throw(e);
1120  }
1121  }
1122  }
1123  } while (lvl != 0);
1124 
1126 }
1127 
1129 {
1131  track(m_I);
1132 }
1133 
1140 {
1141  if (!modelInitialised) {
1142  throw vpException(vpException::fatalError, "model not initialized");
1143  }
1144 
1145  bool a = false;
1146 
1147 #ifdef VISP_HAVE_OGRE
1148  if (useOgre) {
1149  if (!faces.isOgreInitialised()) {
1152  faces.initOgre(m_cam);
1153  // Turn off Ogre config dialog display for the next call to this
1154  // function since settings are saved in the ogre.cfg file and used
1155  // during the next call
1156  ogreShowConfigDialog = false;
1157  }
1158  }
1159 #endif
1160 
1161  if (clippingFlag > 2)
1162  m_cam.computeFov(I.getWidth(), I.getHeight());
1163 
1164  visibleFace(I, m_cMo, a);
1165  resetMovingEdge();
1166 
1167  if (useScanLine) {
1168  if (clippingFlag <= 2)
1169  m_cam.computeFov(I.getWidth(), I.getHeight());
1170 
1173  }
1174 
1175  initPyramid(I, Ipyramid);
1176  unsigned int i = (unsigned int)scales.size();
1177  do {
1178  i--;
1179  if (scales[i]) {
1180  downScale(i);
1182  upScale(i);
1183  }
1184  } while (i != 0);
1185 
1187 }
1188 
1197 {
1198  m_cMo = cdMo;
1199 
1200  init(I);
1201 }
1202 
1211 {
1212  m_cMo = cdMo;
1213 
1214  vpImageConvert::convert(I_color, m_I);
1215  init(m_I);
1216 }
1217 
1229 void vpMbEdgeTracker::loadConfigFile(const std::string &configFile, bool verbose)
1230 {
1231 #if defined(VISP_HAVE_PUGIXML)
1232 // Load projection error config
1233  vpMbTracker::loadConfigFile(configFile, verbose);
1234 
1236  xmlp.setVerbose(verbose);
1237  xmlp.setCameraParameters(m_cam);
1240  xmlp.setEdgeMe(me);
1241 
1242  try {
1243  if (verbose) {
1244  std::cout << " *********** Parsing XML for Mb Edge Tracker ************ " << std::endl;
1245  }
1246  xmlp.parse(configFile);
1247  }
1248  catch (...) {
1249  throw vpException(vpException::ioError, "Cannot open XML file \"%s\"", configFile.c_str());
1250  }
1251 
1252  vpCameraParameters camera;
1253  vpMe meParser;
1254  xmlp.getCameraParameters(camera);
1255  xmlp.getEdgeMe(meParser);
1256 
1257  setCameraParameters(camera);
1258  setMovingEdge(meParser);
1261 
1262  if (xmlp.hasNearClippingDistance())
1264 
1265  if (xmlp.hasFarClippingDistance())
1267 
1268  if (xmlp.getFovClipping())
1270 
1271  useLodGeneral = xmlp.getLodState();
1274 
1275  applyLodSettingInConfig = false;
1276  if (this->getNbPolygon() > 0) {
1277  applyLodSettingInConfig = true;
1281  }
1282 #else
1283  (void)configFile;
1284  (void)verbose;
1285  throw(vpException(vpException::ioError, "vpMbEdgeTracker::loadConfigFile() needs pugixml built-in 3rdparty"));
1286 #endif
1287 }
1288 
1301  const vpCameraParameters &cam, const vpColor &col, unsigned int thickness,
1302  bool displayFullModel)
1303 {
1304  // Display first the Moving-Edges
1305  if (displayFeatures) {
1307  }
1308 
1309  std::vector<std::vector<double> > models =
1310  vpMbEdgeTracker::getModelForDisplay(I.getWidth(), I.getHeight(), cMo, cam, displayFullModel);
1311 
1312  for (size_t i = 0; i < models.size(); i++) {
1313  if (vpMath::equal(models[i][0], 0)) {
1314  vpImagePoint ip1(models[i][1], models[i][2]);
1315  vpImagePoint ip2(models[i][3], models[i][4]);
1316  vpDisplay::displayLine(I, ip1, ip2, col, thickness);
1317  }
1318  else if (vpMath::equal(models[i][0], 1)) {
1319  vpImagePoint center(models[i][1], models[i][2]);
1320  double n20 = models[i][3];
1321  double n11 = models[i][4];
1322  double n02 = models[i][5];
1323  vpDisplay::displayEllipse(I, center, n20, n11, n02, true, col, thickness);
1324  }
1325  }
1326 
1327 #ifdef VISP_HAVE_OGRE
1328  if (useOgre)
1329  faces.displayOgre(cMo);
1330 #endif
1331 }
1332 
1345  const vpColor &col, unsigned int thickness, bool displayFullModel)
1346 {
1347  // Display first the Moving-Edges
1348  if (displayFeatures) {
1350  }
1351 
1352  std::vector<std::vector<double> > models =
1353  vpMbEdgeTracker::getModelForDisplay(I.getWidth(), I.getHeight(), cMo, cam, displayFullModel);
1354 
1355  for (size_t i = 0; i < models.size(); i++) {
1356  if (vpMath::equal(models[i][0], 0)) {
1357  vpImagePoint ip1(models[i][1], models[i][2]);
1358  vpImagePoint ip2(models[i][3], models[i][4]);
1359  vpDisplay::displayLine(I, ip1, ip2, col, thickness);
1360  }
1361  else if (vpMath::equal(models[i][0], 1)) {
1362  vpImagePoint center(models[i][1], models[i][2]);
1363  double n20 = models[i][3];
1364  double n11 = models[i][4];
1365  double n02 = models[i][5];
1366  vpDisplay::displayEllipse(I, center, n20, n11, n02, true, col, thickness);
1367  }
1368  }
1369 
1370 #ifdef VISP_HAVE_OGRE
1371  if (useOgre)
1372  faces.displayOgre(cMo);
1373 #endif
1374 }
1375 
1376 std::vector<std::vector<double> > vpMbEdgeTracker::getFeaturesForDisplayEdge()
1377 {
1378  std::vector<std::vector<double> > features;
1379 
1380  const unsigned int lvl = 0;
1381  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
1382  vpMbtDistanceLine *l = *it;
1383  if (l->isVisible() && l->isTracked()) {
1384  std::vector<std::vector<double> > currentFeatures = l->getFeaturesForDisplay();
1385  features.insert(features.end(), currentFeatures.begin(), currentFeatures.end());
1386  }
1387  }
1388 
1389  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
1390  ++it) {
1391  vpMbtDistanceCylinder *cy = *it;
1392  if (cy->isVisible() && cy->isTracked()) {
1393  std::vector<std::vector<double> > currentFeatures = cy->getFeaturesForDisplay();
1394  features.insert(features.end(), currentFeatures.begin(), currentFeatures.end());
1395  }
1396  }
1397 
1398  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
1399  vpMbtDistanceCircle *ci = *it;
1400  if (ci->isVisible() && ci->isTracked()) {
1401  std::vector<std::vector<double> > currentFeatures = ci->getFeaturesForDisplay();
1402  features.insert(features.end(), currentFeatures.begin(), currentFeatures.end());
1403  }
1404  }
1405 
1406  return features;
1407 }
1408 
1424 std::vector<std::vector<double> > vpMbEdgeTracker::getModelForDisplay(unsigned int width, unsigned int height,
1425  const vpHomogeneousMatrix &cMo,
1426  const vpCameraParameters &cam,
1427  bool displayFullModel)
1428 {
1429  std::vector<std::vector<double> > models;
1430 
1431  for (unsigned int i = 0; i < scales.size(); i += 1) {
1432  if (scales[i]) {
1433  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1434  ++it) {
1435  std::vector<std::vector<double> > currentModel =
1436  (*it)->getModelForDisplay(width, height, cMo, cam, displayFullModel);
1437  models.insert(models.end(), currentModel.begin(), currentModel.end());
1438  }
1439 
1440  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1441  it != cylinders[scaleLevel].end(); ++it) {
1442  std::vector<std::vector<double> > currentModel =
1443  (*it)->getModelForDisplay(width, height, cMo, cam, displayFullModel);
1444  models.insert(models.end(), currentModel.begin(), currentModel.end());
1445  }
1446 
1447  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1448  it != circles[scaleLevel].end(); ++it) {
1449  std::vector<double> paramsCircle = (*it)->getModelForDisplay(cMo, cam, displayFullModel);
1450  if (!paramsCircle.empty()) {
1451  models.push_back(paramsCircle);
1452  }
1453  }
1454  break; // displaying model on one scale only
1455  }
1456  }
1457 
1458  return models;
1459 }
1460 
1462 {
1463  for (size_t i = 0; i < m_featuresToBeDisplayedEdge.size(); i++) {
1466  int state = static_cast<int>(m_featuresToBeDisplayedEdge[i][3]);
1467 
1468  switch (state) {
1471  break;
1472 
1473  case vpMeSite::CONTRAST:
1474  vpDisplay::displayCross(I, ip, 3, vpColor::blue, 1);
1475  break;
1476 
1477  case vpMeSite::THRESHOLD:
1479  break;
1480 
1481  case vpMeSite::M_ESTIMATOR:
1482  vpDisplay::displayCross(I, ip, 3, vpColor::red, 1);
1483  break;
1484 
1485  case vpMeSite::TOO_NEAR:
1486  vpDisplay::displayCross(I, ip, 3, vpColor::cyan, 1);
1487  break;
1488 
1489  default:
1491  }
1492  }
1493  }
1494 }
1495 
1497 {
1498  for (size_t i = 0; i < m_featuresToBeDisplayedEdge.size(); i++) {
1501  int state = static_cast<int>(m_featuresToBeDisplayedEdge[i][3]);
1502 
1503  switch (state) {
1506  break;
1507 
1508  case vpMeSite::CONTRAST:
1509  vpDisplay::displayCross(I, ip, 3, vpColor::blue, 1);
1510  break;
1511 
1512  case vpMeSite::THRESHOLD:
1514  break;
1515 
1516  case vpMeSite::M_ESTIMATOR:
1517  vpDisplay::displayCross(I, ip, 3, vpColor::red, 1);
1518  break;
1519 
1520  case vpMeSite::TOO_NEAR:
1521  vpDisplay::displayCross(I, ip, 3, vpColor::cyan, 1);
1522  break;
1523 
1524  default:
1526  }
1527  }
1528  }
1529 }
1530 
1540 {
1541  const bool doNotTrack = false;
1542 
1543  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1544  ++it) {
1545  vpMbtDistanceLine *l = *it;
1546  bool isvisible = false;
1547 
1548  for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
1549  ++itindex) {
1550  int index = *itindex;
1551  if (index == -1)
1552  isvisible = true;
1553  else {
1554  if (l->hiddenface->isVisible((unsigned int)index))
1555  isvisible = true;
1556  }
1557  }
1558 
1559  // Si la ligne n'appartient a aucune face elle est tout le temps visible
1560  if (l->Lindex_polygon.empty())
1561  isvisible = true; // Not sure that this can occur
1562 
1563  if (isvisible) {
1564  l->setVisible(true);
1565  l->updateTracked();
1566  if (l->meline.empty() && l->isTracked())
1567  l->initMovingEdge(I, _cMo, doNotTrack, m_mask);
1568  }
1569  else {
1570  l->setVisible(false);
1571  for (size_t a = 0; a < l->meline.size(); a++) {
1572  if (l->meline[a] != nullptr)
1573  delete l->meline[a];
1574  if (a < l->nbFeature.size())
1575  l->nbFeature[a] = 0;
1576  }
1577  l->nbFeatureTotal = 0;
1578  l->meline.clear();
1579  l->nbFeature.clear();
1580  }
1581  }
1582 
1583  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1584  it != cylinders[scaleLevel].end(); ++it) {
1585  vpMbtDistanceCylinder *cy = *it;
1586 
1587  bool isvisible = false;
1588 
1589  int index = cy->index_polygon;
1590  if (index == -1)
1591  isvisible = true;
1592  else {
1593  if (cy->hiddenface->isVisible((unsigned int)index + 1) || cy->hiddenface->isVisible((unsigned int)index + 2) ||
1594  cy->hiddenface->isVisible((unsigned int)index + 3) || cy->hiddenface->isVisible((unsigned int)index + 4))
1595  isvisible = true;
1596  }
1597  // vpTRACE("cyl with index %d is visible: %d", index, isvisible);
1598 
1599  if (isvisible) {
1600  cy->setVisible(true);
1601  if (cy->meline1 == nullptr || cy->meline2 == nullptr) {
1602  if (cy->isTracked())
1603  cy->initMovingEdge(I, _cMo, doNotTrack, m_mask);
1604  }
1605  }
1606  else {
1607  cy->setVisible(false);
1608  if (cy->meline1 != nullptr)
1609  delete cy->meline1;
1610  if (cy->meline2 != nullptr)
1611  delete cy->meline2;
1612  cy->meline1 = nullptr;
1613  cy->meline2 = nullptr;
1614  cy->nbFeature = 0;
1615  cy->nbFeaturel1 = 0;
1616  cy->nbFeaturel2 = 0;
1617  }
1618  }
1619 
1620  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1621  it != circles[scaleLevel].end(); ++it) {
1622  vpMbtDistanceCircle *ci = *it;
1623  bool isvisible = false;
1624 
1625  int index = ci->index_polygon;
1626  if (index == -1)
1627  isvisible = true;
1628  else {
1629  if (ci->hiddenface->isVisible((unsigned int)index))
1630  isvisible = true;
1631  }
1632 
1633  if (isvisible) {
1634  ci->setVisible(true);
1635  if (ci->meEllipse == nullptr) {
1636  if (ci->isTracked())
1637  ci->initMovingEdge(I, _cMo, doNotTrack, m_mask);
1638  }
1639  }
1640  else {
1641  ci->setVisible(false);
1642  if (ci->meEllipse != nullptr)
1643  delete ci->meEllipse;
1644  ci->meEllipse = nullptr;
1645  ci->nbFeature = 0;
1646  }
1647  }
1648 }
1649 
1656 {
1657  const bool doNotTrack = false;
1658 
1659  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1660  ++it) {
1661  vpMbtDistanceLine *l = *it;
1662  if (l->isVisible() && l->isTracked()) {
1663  if (l->meline.empty()) {
1664  l->initMovingEdge(I, m_cMo, doNotTrack, m_mask);
1665  }
1666  l->trackMovingEdge(I);
1667  }
1668  }
1669 
1670  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1671  it != cylinders[scaleLevel].end(); ++it) {
1672  vpMbtDistanceCylinder *cy = *it;
1673  if (cy->isVisible() && cy->isTracked()) {
1674  if (cy->meline1 == nullptr || cy->meline2 == nullptr) {
1675  cy->initMovingEdge(I, m_cMo, doNotTrack, m_mask);
1676  }
1677  cy->trackMovingEdge(I, m_cMo);
1678  }
1679  }
1680 
1681  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1682  it != circles[scaleLevel].end(); ++it) {
1683  vpMbtDistanceCircle *ci = *it;
1684  if (ci->isVisible() && ci->isTracked()) {
1685  if (ci->meEllipse == nullptr) {
1686  ci->initMovingEdge(I, m_cMo, doNotTrack, m_mask);
1687  }
1688  ci->trackMovingEdge(I, m_cMo);
1689  }
1690  }
1691 }
1692 
1699 {
1700  vpMbtDistanceLine *l;
1701  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1702  ++it) {
1703  if ((*it)->isTracked()) {
1704  l = *it;
1705  l->updateMovingEdge(I, m_cMo);
1706  if (l->nbFeatureTotal == 0 && l->isVisible()) {
1707  l->Reinit = true;
1708  }
1709  }
1710  }
1711 
1713  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1714  it != cylinders[scaleLevel].end(); ++it) {
1715  if ((*it)->isTracked()) {
1716  cy = *it;
1717  cy->updateMovingEdge(I, m_cMo);
1718  if ((cy->nbFeaturel1 == 0 || cy->nbFeaturel2 == 0) && cy->isVisible()) {
1719  cy->Reinit = true;
1720  }
1721  }
1722  }
1723 
1724  vpMbtDistanceCircle *ci;
1725  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1726  it != circles[scaleLevel].end(); ++it) {
1727  if ((*it)->isTracked()) {
1728  ci = *it;
1729  ci->updateMovingEdge(I, m_cMo);
1730  if (ci->nbFeature == 0 && ci->isVisible()) {
1731  ci->Reinit = true;
1732  }
1733  }
1734  }
1735 }
1736 
1738 {
1739  unsigned int n = 0;
1740 
1741  vpMbtDistanceLine *l;
1742  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1743  ++it) {
1744  if ((*it)->isTracked()) {
1745  l = *it;
1746  unsigned int indexLine = 0;
1747  double wmean = 0;
1748  for (size_t a = 0; a < l->meline.size(); a++) {
1749  if (l->nbFeature[a] > 0) {
1750  std::list<vpMeSite>::iterator itListLine;
1751  itListLine = l->meline[a]->getMeList().begin();
1752 
1753  for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
1754  wmean += m_w_edge[n + indexLine];
1755  vpMeSite p = *itListLine;
1756  if (m_w_edge[n + indexLine] < 0.5) {
1758 
1759  *itListLine = p;
1760  }
1761 
1762  ++itListLine;
1763  indexLine++;
1764  }
1765  }
1766  }
1767  n += l->nbFeatureTotal;
1768 
1769  if (l->nbFeatureTotal != 0)
1770  wmean /= l->nbFeatureTotal;
1771  else
1772  wmean = 1;
1773 
1774  l->setMeanWeight(wmean);
1775 
1776  if (wmean < 0.8)
1777  l->Reinit = true;
1778  }
1779  }
1780 
1781  // Same thing with cylinders as with lines
1783  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1784  it != cylinders[scaleLevel].end(); ++it) {
1785  if ((*it)->isTracked()) {
1786  cy = *it;
1787  double wmean = 0;
1788  std::list<vpMeSite>::iterator itListCyl1;
1789  std::list<vpMeSite>::iterator itListCyl2;
1790 
1791  if (cy->nbFeature > 0) {
1792  itListCyl1 = cy->meline1->getMeList().begin();
1793  itListCyl2 = cy->meline2->getMeList().begin();
1794 
1795  for (unsigned int i = 0; i < cy->nbFeaturel1; i++) {
1796  wmean += m_w_edge[n + i];
1797  vpMeSite p = *itListCyl1;
1798  if (m_w_edge[n + i] < 0.5) {
1800 
1801  *itListCyl1 = p;
1802  }
1803 
1804  ++itListCyl1;
1805  }
1806  }
1807 
1808  if (cy->nbFeaturel1 != 0)
1809  wmean /= cy->nbFeaturel1;
1810  else
1811  wmean = 1;
1812 
1813  cy->setMeanWeight1(wmean);
1814 
1815  if (wmean < 0.8) {
1816  cy->Reinit = true;
1817  }
1818 
1819  wmean = 0;
1820  for (unsigned int i = cy->nbFeaturel1; i < cy->nbFeature; i++) {
1821  wmean += m_w_edge[n + i];
1822  vpMeSite p = *itListCyl2;
1823  if (m_w_edge[n + i] < 0.5) {
1825 
1826  *itListCyl2 = p;
1827  }
1828 
1829  ++itListCyl2;
1830  }
1831 
1832  if (cy->nbFeaturel2 != 0)
1833  wmean /= cy->nbFeaturel2;
1834  else
1835  wmean = 1;
1836 
1837  cy->setMeanWeight2(wmean);
1838 
1839  if (wmean < 0.8) {
1840  cy->Reinit = true;
1841  }
1842 
1843  n += cy->nbFeature;
1844  }
1845  }
1846 
1847  // Same thing with circles as with lines
1848  vpMbtDistanceCircle *ci;
1849  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1850  it != circles[scaleLevel].end(); ++it) {
1851  if ((*it)->isTracked()) {
1852  ci = *it;
1853  double wmean = 0;
1854  std::list<vpMeSite>::iterator itListCir;
1855 
1856  if (ci->nbFeature > 0) {
1857  itListCir = ci->meEllipse->getMeList().begin();
1858  }
1859 
1860  wmean = 0;
1861  for (unsigned int i = 0; i < ci->nbFeature; i++) {
1862  wmean += m_w_edge[n + i];
1863  vpMeSite p = *itListCir;
1864  if (m_w_edge[n + i] < 0.5) {
1866 
1867  *itListCir = p;
1868  }
1869 
1870  ++itListCir;
1871  }
1872 
1873  if (ci->nbFeature != 0)
1874  wmean /= ci->nbFeature;
1875  else
1876  wmean = 1;
1877 
1878  ci->setMeanWeight(wmean);
1879 
1880  if (wmean < 0.8) {
1881  ci->Reinit = true;
1882  }
1883 
1884  n += ci->nbFeature;
1885  }
1886  }
1887 }
1888 
1899 {
1900  vpMbtDistanceLine *l;
1901  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1902  ++it) {
1903  if ((*it)->isTracked()) {
1904  l = *it;
1905  if (l->Reinit && l->isVisible())
1906  l->reinitMovingEdge(I, _cMo, m_mask);
1907  }
1908  }
1909 
1911  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1912  it != cylinders[scaleLevel].end(); ++it) {
1913  if ((*it)->isTracked()) {
1914  cy = *it;
1915  if (cy->Reinit && cy->isVisible())
1916  cy->reinitMovingEdge(I, _cMo, m_mask);
1917  }
1918  }
1919 
1920  vpMbtDistanceCircle *ci;
1921  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1922  it != circles[scaleLevel].end(); ++it) {
1923  if ((*it)->isTracked()) {
1924  ci = *it;
1925  if (ci->Reinit && ci->isVisible())
1926  ci->reinitMovingEdge(I, _cMo, m_mask);
1927  }
1928  }
1929 }
1930 
1932 {
1933  // Clear ME to be displayed
1935 
1936  for (unsigned int i = 0; i < scales.size(); i += 1) {
1937  if (scales[i]) {
1938  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
1939  for (size_t a = 0; a < (*it)->meline.size(); a++) {
1940  if ((*it)->meline[a] != nullptr) {
1941  delete (*it)->meline[a];
1942  (*it)->meline[a] = nullptr;
1943  }
1944  }
1945 
1946  (*it)->meline.clear();
1947  (*it)->nbFeature.clear();
1948  (*it)->nbFeatureTotal = 0;
1949  }
1950 
1951  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
1952  ++it) {
1953  if ((*it)->meline1 != nullptr) {
1954  delete (*it)->meline1;
1955  (*it)->meline1 = nullptr;
1956  }
1957  if ((*it)->meline2 != nullptr) {
1958  delete (*it)->meline2;
1959  (*it)->meline2 = nullptr;
1960  }
1961 
1962  (*it)->nbFeature = 0;
1963  (*it)->nbFeaturel1 = 0;
1964  (*it)->nbFeaturel2 = 0;
1965  }
1966 
1967  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
1968  if ((*it)->meEllipse != nullptr) {
1969  delete (*it)->meEllipse;
1970  (*it)->meEllipse = nullptr;
1971  }
1972  (*it)->nbFeature = 0;
1973  }
1974  }
1975  }
1976 }
1977 
1990 void vpMbEdgeTracker::addLine(vpPoint &P1, vpPoint &P2, int polygon, std::string name)
1991 {
1992  {
1993  // suppress line already in the model
1994  bool already_here = false;
1995  vpMbtDistanceLine *l;
1996 
1997  for (unsigned int i = 0; i < scales.size(); i += 1) {
1998  if (scales[i]) {
1999  downScale(i);
2000  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2001  l = *it;
2002  if ((samePoint(*(l->p1), P1) && samePoint(*(l->p2), P2)) ||
2003  (samePoint(*(l->p1), P2) && samePoint(*(l->p2), P1))) {
2004  already_here = true;
2005  l->addPolygon(polygon);
2006  l->hiddenface = &faces;
2007  }
2008  }
2009 
2010  if (!already_here) {
2011  l = new vpMbtDistanceLine;
2012 
2014  l->buildFrom(P1, P2, m_rand);
2015  l->addPolygon(polygon);
2016  l->setMovingEdge(&me);
2017  l->hiddenface = &faces;
2018  l->useScanLine = useScanLine;
2019 
2020  l->setIndex(nline);
2021  l->setName(name);
2022 
2025 
2028 
2031 
2032  nline += 1;
2033  lines[i].push_back(l);
2034  }
2035  upScale(i);
2036  }
2037  }
2038  }
2039 }
2040 
2046 void vpMbEdgeTracker::removeLine(const std::string &name)
2047 {
2048  vpMbtDistanceLine *l;
2049 
2050  for (unsigned int i = 0; i < scales.size(); i++) {
2051  if (scales[i]) {
2052  for (std::list<vpMbtDistanceLine *>::iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2053  l = *it;
2054  if (name.compare(l->getName()) == 0) {
2055  lines[i].erase(it);
2056  break;
2057  }
2058  }
2059  }
2060  }
2061 }
2062 
2073 void vpMbEdgeTracker::addCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, double r, int idFace,
2074  const std::string &name)
2075 {
2076  {
2077  bool already_here = false;
2078  vpMbtDistanceCircle *ci;
2079 
2080  for (unsigned int i = 0; i < scales.size(); i += 1) {
2081  if (scales[i]) {
2082  downScale(i);
2083  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2084  ci = *it;
2085  if ((samePoint(*(ci->p1), P1) && samePoint(*(ci->p2), P2) && samePoint(*(ci->p3), P3)) ||
2086  (samePoint(*(ci->p1), P1) && samePoint(*(ci->p2), P3) && samePoint(*(ci->p3), P2))) {
2087  already_here =
2088  (std::fabs(ci->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(ci->radius, r));
2089  }
2090  }
2091 
2092  if (!already_here) {
2093  ci = new vpMbtDistanceCircle;
2094 
2096  ci->buildFrom(P1, P2, P3, r);
2097  ci->setMovingEdge(&me);
2098  ci->setIndex(ncircle);
2099  ci->setName(name);
2100  ci->index_polygon = idFace;
2101  ci->hiddenface = &faces;
2102 
2103  // if(clippingFlag != vpPolygon3D::NO_CLIPPING)
2104  // ci->getPolygon().setClipping(clippingFlag);
2105 
2106  // if((clippingFlag & vpPolygon3D::NEAR_CLIPPING) ==
2107  // vpPolygon3D::NEAR_CLIPPING)
2108  // ci->getPolygon().setNearClippingDistance(distNearClip);
2109 
2110  // if((clippingFlag & vpPolygon3D::FAR_CLIPPING) ==
2111  // vpPolygon3D::FAR_CLIPPING)
2112  // ci->getPolygon().setFarClippingDistance(distFarClip);
2113 
2114  ncircle += 1;
2115  circles[i].push_back(ci);
2116  }
2117  upScale(i);
2118  }
2119  }
2120  }
2121 }
2122 
2132 void vpMbEdgeTracker::addCylinder(const vpPoint &P1, const vpPoint &P2, double r, int idFace, const std::string &name)
2133 {
2134  {
2135  bool already_here = false;
2137 
2138  for (unsigned int i = 0; i < scales.size(); i += 1) {
2139  if (scales[i]) {
2140  downScale(i);
2141  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2142  ++it) {
2143  cy = *it;
2144  if ((samePoint(*(cy->p1), P1) && samePoint(*(cy->p2), P2)) ||
2145  (samePoint(*(cy->p1), P2) && samePoint(*(cy->p2), P1))) {
2146  already_here =
2147  (std::fabs(cy->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(cy->radius, r));
2148  }
2149  }
2150 
2151  if (!already_here) {
2152  cy = new vpMbtDistanceCylinder;
2153 
2155  cy->buildFrom(P1, P2, r);
2156  cy->setMovingEdge(&me);
2157  cy->setIndex(ncylinder);
2158  cy->setName(name);
2159  cy->index_polygon = idFace;
2160  cy->hiddenface = &faces;
2161  ncylinder += 1;
2162  cylinders[i].push_back(cy);
2163  }
2164  upScale(i);
2165  }
2166  }
2167  }
2168 }
2169 
2175 void vpMbEdgeTracker::removeCylinder(const std::string &name)
2176 {
2178 
2179  for (unsigned int i = 0; i < scales.size(); i++) {
2180  if (scales[i]) {
2181  for (std::list<vpMbtDistanceCylinder *>::iterator it = cylinders[i].begin(); it != cylinders[i].end(); ++it) {
2182  cy = *it;
2183  if (name.compare(cy->getName()) == 0) {
2184  cylinders[i].erase(it);
2185  break;
2186  }
2187  }
2188  }
2189  }
2190 }
2191 
2197 void vpMbEdgeTracker::removeCircle(const std::string &name)
2198 {
2199  vpMbtDistanceCircle *ci;
2200 
2201  for (unsigned int i = 0; i < scales.size(); i++) {
2202  if (scales[i]) {
2203  for (std::list<vpMbtDistanceCircle *>::iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2204  ci = *it;
2205  if (name.compare(ci->getName()) == 0) {
2206  circles[i].erase(it);
2207  break;
2208  }
2209  }
2210  }
2211  }
2212 }
2213 
2220 {
2221  unsigned int nbpt = p.getNbPoint();
2222  if (nbpt > 0) {
2223  for (unsigned int i = 0; i < nbpt - 1; i++)
2224  addLine(p.p[i], p.p[i + 1], p.getIndex());
2225  addLine(p.p[nbpt - 1], p.p[0], p.getIndex());
2226  }
2227 }
2228 
2240 void vpMbEdgeTracker::visibleFace(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo, bool &newvisibleline)
2241 {
2242  unsigned int n;
2243  bool changed = false;
2244 
2245  if (!useOgre) {
2246  // n = faces.setVisible(_I.getWidth(), I.getHeight(), m_cam, cMo, vpMath::rad(89), vpMath::rad(89),
2247  // changed);
2248  n = faces.setVisible(I.getWidth(), I.getHeight(), m_cam, cMo, angleAppears, angleDisappears, changed);
2249  }
2250  else {
2251 #ifdef VISP_HAVE_OGRE
2252  n = faces.setVisibleOgre(I.getWidth(), I.getHeight(), m_cam, cMo, angleAppears, angleDisappears, changed);
2253 #else
2254  n = faces.setVisible(I.getWidth(), I.getHeight(), m_cam, cMo, angleAppears, angleDisappears, changed);
2255 #endif
2256  }
2257 
2258  if (n > nbvisiblepolygone) {
2259  // cout << "une nouvelle face est visible " << endl;
2260  newvisibleline = true;
2261  }
2262  else
2263  newvisibleline = false;
2264 
2265  nbvisiblepolygone = n;
2266 }
2267 
2284 {
2285  unsigned int nbpt = polygon.getNbPoint();
2286  if (nbpt > 0) {
2287  for (unsigned int i = 0; i < nbpt - 1; i++)
2288  vpMbEdgeTracker::addLine(polygon.p[i], polygon.p[i + 1], polygon.getIndex(), polygon.getName());
2289  vpMbEdgeTracker::addLine(polygon.p[nbpt - 1], polygon.p[0], polygon.getIndex(), polygon.getName());
2290  }
2291 }
2308 {
2309  unsigned int nbpt = polygon.getNbPoint();
2310  if (nbpt > 0) {
2311  for (unsigned int i = 0; i < nbpt - 1; i++)
2312  vpMbEdgeTracker::addLine(polygon.p[i], polygon.p[i + 1], polygon.getIndex(), polygon.getName());
2313  }
2314 }
2315 
2316 unsigned int vpMbEdgeTracker::initMbtTracking(unsigned int &nberrors_lines, unsigned int &nberrors_cylinders,
2317  unsigned int &nberrors_circles)
2318 {
2319  unsigned int nbrow = 0;
2320  nberrors_lines = 0;
2321  nberrors_cylinders = 0;
2322  nberrors_circles = 0;
2323 
2324  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
2325  ++it) {
2326 
2327  vpMbtDistanceLine *l = *it;
2328 
2329  if (l->isTracked()) {
2331  nbrow += l->nbFeatureTotal;
2332  nberrors_lines += l->nbFeatureTotal;
2333  }
2334  }
2335 
2336  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
2337  it != cylinders[scaleLevel].end(); ++it) {
2338  vpMbtDistanceCylinder *cy = *it;
2339 
2340  if (cy->isTracked()) {
2342  nbrow += cy->nbFeature;
2343  nberrors_cylinders += cy->nbFeature;
2344  }
2345  }
2346 
2347  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
2348  it != circles[scaleLevel].end(); ++it) {
2349  vpMbtDistanceCircle *ci = *it;
2350 
2351  if (ci->isTracked()) {
2353  nbrow += ci->nbFeature;
2354  nberrors_circles += ci->nbFeature;
2355  }
2356  }
2357 
2358  return nbrow;
2359 }
2360 
2372 void vpMbEdgeTracker::initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius, int idFace,
2373  const std::string &name)
2374 {
2375  addCircle(p1, p2, p3, radius, (int)idFace, name);
2376 }
2377 
2388 void vpMbEdgeTracker::initCylinder(const vpPoint &p1, const vpPoint &p2, double radius, int idFace,
2389  const std::string &name)
2390 {
2391  addCylinder(p1, p2, radius, (int)idFace, name);
2392 }
2393 
2400 {
2401  m_cMo.eye();
2402  vpMbtDistanceLine *l;
2404  vpMbtDistanceCircle *ci;
2405 
2406  for (unsigned int i = 0; i < scales.size(); i += 1) {
2407  if (scales[i]) {
2408  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2409  l = *it;
2410  if (l != nullptr)
2411  delete l;
2412  l = nullptr;
2413  }
2414 
2415  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2416  ++it) {
2417  cy = *it;
2418  if (cy != nullptr)
2419  delete cy;
2420  cy = nullptr;
2421  }
2422 
2423  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2424  ci = *it;
2425  if (ci != nullptr)
2426  delete ci;
2427  ci = nullptr;
2428  }
2429  lines[i].clear();
2430  cylinders[i].clear();
2431  circles[i].clear();
2432  }
2433  }
2434 
2435  faces.reset();
2436 
2437  useScanLine = false;
2438 
2439 #ifdef VISP_HAVE_OGRE
2440  useOgre = false;
2441 #endif
2442 
2443  m_computeInteraction = true;
2444  nline = 0;
2445  ncylinder = 0;
2446  m_lambda = 1.0;
2447  nbvisiblepolygone = 0;
2448  percentageGdPt = 0.4;
2449 
2450  angleAppears = vpMath::rad(89);
2453 
2455 
2456  // reinitialization of the scales.
2457  this->setScales(scales);
2458 }
2459 
2472 void vpMbEdgeTracker::reInitModel(const vpImage<unsigned char> &I, const std::string &cad_name,
2473  const vpHomogeneousMatrix &cMo, bool verbose, const vpHomogeneousMatrix &T)
2474 {
2475  m_cMo.eye();
2476  vpMbtDistanceLine *l;
2478  vpMbtDistanceCircle *ci;
2479 
2480  for (unsigned int i = 0; i < scales.size(); i += 1) {
2481  if (scales[i]) {
2482  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2483  l = *it;
2484  if (l != nullptr)
2485  delete l;
2486  l = nullptr;
2487  }
2488 
2489  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2490  ++it) {
2491  cy = *it;
2492  if (cy != nullptr)
2493  delete cy;
2494  cy = nullptr;
2495  }
2496 
2497  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2498  ci = *it;
2499  if (ci != nullptr)
2500  delete ci;
2501  ci = nullptr;
2502  }
2503 
2504  lines[i].clear();
2505  cylinders[i].clear();
2506  circles[i].clear();
2507  }
2508  }
2509 
2510  faces.reset();
2511 
2512  // compute_interaction=1;
2513  nline = 0;
2514  ncylinder = 0;
2515  ncircle = 0;
2516  // lambda = 1;
2517  nbvisiblepolygone = 0;
2518 
2519  loadModel(cad_name, verbose, T);
2520  initFromPose(I, cMo);
2521 }
2522 
2533 unsigned int vpMbEdgeTracker::getNbPoints(unsigned int level) const
2534 {
2535  if ((level > scales.size()) || !scales[level]) {
2536  throw vpException(vpException::dimensionError, "Cannot get the number of points for level %d: level is not used",
2537  level);
2538  }
2539 
2540  unsigned int nbGoodPoints = 0;
2541  vpMbtDistanceLine *l;
2542  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[level].begin(); it != lines[level].end(); ++it) {
2543  l = *it;
2544  if (l->isVisible() && l->isTracked()) {
2545  for (size_t a = 0; a < l->meline.size(); a++) {
2546  if (l->nbFeature[a] != 0)
2547  for (std::list<vpMeSite>::const_iterator itme = l->meline[a]->getMeList().begin();
2548  itme != l->meline[a]->getMeList().end(); ++itme) {
2549  if (itme->getState() == vpMeSite::NO_SUPPRESSION)
2550  nbGoodPoints++;
2551  }
2552  }
2553  }
2554  }
2555 
2557  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[level].begin(); it != cylinders[level].end();
2558  ++it) {
2559  cy = *it;
2560  if (cy->isVisible() && cy->isTracked() && (cy->meline1 != nullptr || cy->meline2 != nullptr)) {
2561  for (std::list<vpMeSite>::const_iterator itme1 = cy->meline1->getMeList().begin();
2562  itme1 != cy->meline1->getMeList().end(); ++itme1) {
2563  if (itme1->getState() == vpMeSite::NO_SUPPRESSION)
2564  nbGoodPoints++;
2565  }
2566  for (std::list<vpMeSite>::const_iterator itme2 = cy->meline2->getMeList().begin();
2567  itme2 != cy->meline2->getMeList().end(); ++itme2) {
2568  if (itme2->getState() == vpMeSite::NO_SUPPRESSION)
2569  nbGoodPoints++;
2570  }
2571  }
2572  }
2573 
2574  vpMbtDistanceCircle *ci;
2575  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[level].begin(); it != circles[level].end(); ++it) {
2576  ci = *it;
2577  if (ci->isVisible() && ci->isTracked() && ci->meEllipse != nullptr) {
2578  for (std::list<vpMeSite>::const_iterator itme = ci->meEllipse->getMeList().begin();
2579  itme != ci->meEllipse->getMeList().end(); ++itme) {
2580  if (itme->getState() == vpMeSite::NO_SUPPRESSION)
2581  nbGoodPoints++;
2582  }
2583  }
2584  }
2585 
2586  return nbGoodPoints;
2587 }
2588 
2610 void vpMbEdgeTracker::setScales(const std::vector<bool> &scale)
2611 {
2612  unsigned int nbActivatedLevels = 0;
2613  for (unsigned int i = 0; i < scale.size(); i++) {
2614  if (scale[i]) {
2615  nbActivatedLevels++;
2616  }
2617  }
2618 
2619  if (scale.empty() || (nbActivatedLevels == 0)) {
2620  vpERROR_TRACE(" !! WARNING : must use at least one level for the "
2621  "tracking. Use the global one");
2622  this->scales.clear();
2623  this->scales.push_back(true);
2624 
2625  lines.resize(1);
2626  lines[0].clear();
2627 
2628  cylinders.resize(1);
2629  cylinders[0].clear();
2630 
2631  circles.resize(1);
2632  circles[0].clear();
2633  }
2634  else {
2635  this->scales = scale;
2636 
2637  lines.resize(scale.size());
2638  cylinders.resize(scale.size());
2639  circles.resize(scale.size());
2640 
2641  for (unsigned int i = 0; i < lines.size(); i++) {
2642  lines[i].clear();
2643  cylinders[i].clear();
2644  circles[i].clear();
2645  }
2646  }
2647 }
2648 
2655 {
2657  std::cerr << "Far clipping value cannot be inferior than near clipping "
2658  "value. Far clipping won't be considered."
2659  << std::endl;
2660  else if (dist < 0)
2661  std::cerr << "Far clipping value cannot be inferior than 0. Far clipping "
2662  "won't be considered."
2663  << std::endl;
2664  else {
2666  vpMbtDistanceLine *l;
2667 
2668  for (unsigned int i = 0; i < scales.size(); i += 1) {
2669  if (scales[i]) {
2670  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2671  l = *it;
2673  }
2674  }
2675  }
2676  }
2677 }
2678 
2685 {
2687  std::cerr << "Near clipping value cannot be superior than far clipping "
2688  "value. Near clipping won't be considered."
2689  << std::endl;
2690  else if (dist < 0)
2691  std::cerr << "Near clipping value cannot be inferior than 0. Near "
2692  "clipping won't be considered."
2693  << std::endl;
2694  else {
2696  vpMbtDistanceLine *l;
2697 
2698  for (unsigned int i = 0; i < scales.size(); i += 1) {
2699  if (scales[i]) {
2700  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2701  l = *it;
2703  }
2704  }
2705  }
2706  }
2707 }
2708 
2716 void vpMbEdgeTracker::setClipping(const unsigned int &flags)
2717 {
2718  vpMbTracker::setClipping(flags);
2719 
2720  vpMbtDistanceLine *l;
2721 
2722  for (unsigned int i = 0; i < scales.size(); i += 1) {
2723  if (scales[i]) {
2724  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2725  l = *it;
2727  }
2728  }
2729  }
2730 }
2731 
2748  std::vector<const vpImage<unsigned char> *> &_pyramid)
2749 {
2750  _pyramid.resize(scales.size());
2751 
2752  if (scales[0]) {
2753  _pyramid[0] = &_I;
2754  }
2755  else {
2756  _pyramid[0] = nullptr;
2757  }
2758 
2759  for (unsigned int i = 1; i < _pyramid.size(); i += 1) {
2760  if (scales[i]) {
2761  unsigned int cScale = static_cast<unsigned int>(pow(2., (int)i));
2762  vpImage<unsigned char> *I = new vpImage<unsigned char>(_I.getHeight() / cScale, _I.getWidth() / cScale);
2763  for (unsigned int k = 0, ii = 0; k < I->getHeight(); k += 1, ii += cScale) {
2764  for (unsigned int l = 0, jj = 0; l < I->getWidth(); l += 1, jj += cScale) {
2765  (*I)[k][l] = _I[ii][jj];
2766  }
2767  }
2768  _pyramid[i] = I;
2769  }
2770  else {
2771  _pyramid[i] = nullptr;
2772  }
2773  }
2774 }
2775 
2782 void vpMbEdgeTracker::cleanPyramid(std::vector<const vpImage<unsigned char> *> &_pyramid)
2783 {
2784  if (_pyramid.size() > 0) {
2785  _pyramid[0] = nullptr;
2786  for (unsigned int i = 1; i < _pyramid.size(); i += 1) {
2787  if (_pyramid[i] != nullptr) {
2788  delete _pyramid[i];
2789  _pyramid[i] = nullptr;
2790  }
2791  }
2792  _pyramid.resize(0);
2793  }
2794 }
2795 
2806 void vpMbEdgeTracker::getLline(std::list<vpMbtDistanceLine *> &linesList, unsigned int level) const
2807 {
2808  if (level > scales.size() || !scales[level]) {
2809  std::ostringstream oss;
2810  oss << level;
2811  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2812  throw vpException(vpException::dimensionError, errorMsg);
2813  }
2814 
2815  linesList = lines[level];
2816 }
2817 
2828 void vpMbEdgeTracker::getLcylinder(std::list<vpMbtDistanceCylinder *> &cylindersList, unsigned int level) const
2829 {
2830  if (level > scales.size() || !scales[level]) {
2831  std::ostringstream oss;
2832  oss << level;
2833  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2834  throw vpException(vpException::dimensionError, errorMsg);
2835  }
2836 
2837  cylindersList = cylinders[level];
2838 }
2839 
2850 void vpMbEdgeTracker::getLcircle(std::list<vpMbtDistanceCircle *> &circlesList, unsigned int level) const
2851 {
2852  if (level > scales.size() || !scales[level]) {
2853  std::ostringstream oss;
2854  oss << level;
2855  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2856  throw vpException(vpException::dimensionError, errorMsg);
2857  }
2858 
2859  circlesList = circles[level];
2860 }
2861 
2868 void vpMbEdgeTracker::downScale(const unsigned int _scale)
2869 {
2870  const double ratio = pow(2., (int)_scale);
2871  scaleLevel = _scale;
2872 
2873  vpMatrix K = m_cam.get_K();
2874 
2875  K[0][0] /= ratio;
2876  K[1][1] /= ratio;
2877  K[0][2] /= ratio;
2878  K[1][2] /= ratio;
2879 
2881 }
2882 
2889 void vpMbEdgeTracker::upScale(const unsigned int _scale)
2890 {
2891  const double ratio = pow(2., (int)_scale);
2892  scaleLevel = 0;
2893 
2894  vpMatrix K = m_cam.get_K();
2895 
2896  K[0][0] *= ratio;
2897  K[1][1] *= ratio;
2898  K[0][2] *= ratio;
2899  K[1][2] *= ratio;
2900 
2902 }
2903 
2911 void vpMbEdgeTracker::reInitLevel(const unsigned int _lvl)
2912 {
2913  unsigned int scaleLevel_1 = scaleLevel;
2914  scaleLevel = _lvl;
2915 
2916  vpMbtDistanceLine *l;
2917  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
2918  ++it) {
2919  if ((*it)->isTracked()) {
2920  l = *it;
2921  l->reinitMovingEdge(*Ipyramid[_lvl], m_cMo, m_mask);
2922  }
2923  }
2924 
2926  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
2927  it != cylinders[scaleLevel].end(); ++it) {
2928  if ((*it)->isTracked()) {
2929  cy = *it;
2930  cy->reinitMovingEdge(*Ipyramid[_lvl], m_cMo, m_mask);
2931  }
2932  }
2933 
2934  vpMbtDistanceCircle *ci;
2935  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
2936  it != circles[scaleLevel].end(); ++it) {
2937  if ((*it)->isTracked()) {
2938  ci = *it;
2939  ci->reinitMovingEdge(*Ipyramid[_lvl], m_cMo, m_mask);
2940  }
2941  }
2942 
2943  trackMovingEdge(*Ipyramid[_lvl]);
2944  updateMovingEdge(*Ipyramid[_lvl]);
2945  scaleLevel = scaleLevel_1;
2946 }
2947 
2955 void vpMbEdgeTracker::setUseEdgeTracking(const std::string &name, const bool &useEdgeTracking)
2956 {
2957  for (unsigned int i = 0; i < scales.size(); i += 1) {
2958  if (scales[i]) {
2959  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2960  /*(*it)->setTracked(useEdgeTracking);
2961  for(std::list<int>::const_iterator
2962  itpoly=(*it)->Lindex_polygon.begin();
2963  itpoly!=(*it)->Lindex_polygon.end(); ++itpoly){
2964  if(faces[(*itpoly)]->getName() != name){
2965  (*it)->setTracked(true);
2966  break;
2967  }
2968  }*/
2969 
2970  (*it)->setTracked(name, useEdgeTracking);
2971  }
2972 
2973  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2974  ++it) {
2975  if (faces[(unsigned)(*it)->index_polygon]->getName() == name) {
2976  (*it)->setTracked(useEdgeTracking);
2977  }
2978  }
2979 
2980  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2981  if (faces[(unsigned)(*it)->index_polygon]->getName() == name) {
2982  (*it)->setTracked(useEdgeTracking);
2983  }
2984  }
2985  }
2986  }
2987 }
2988 END_VISP_NAMESPACE
void setWindowName(const Ogre::String &n)
Definition: vpAROgre.h:265
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:362
unsigned int getRows() const
Definition: vpArray2D.h:347
Generic class defining intrinsic camera parameters.
vpMatrix get_K() const
void computeFov(const unsigned int &w, const unsigned int &h)
void initFromCalibrationMatrix(const vpMatrix &_K)
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
void insert(unsigned int i, const vpColVector &v)
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1143
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:157
static const vpColor red
Definition: vpColor.h:217
static const vpColor cyan
Definition: vpColor.h:226
static const vpColor blue
Definition: vpColor.h:223
static const vpColor purple
Definition: vpColor.h:228
static const vpColor yellow
Definition: vpColor.h:225
static const vpColor green
Definition: vpColor.h:220
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: vpImagePoint.h:82
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:254
static double sqr(double x)
Definition: vpMath.h:203
static bool equal(double x, double y, double threshold=0.001)
Definition: vpMath.h:458
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:262
static int sign(double x)
Definition: vpMath.h:428
static double deg(double rad)
Definition: vpMath.h:119
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
vpMatrix AtA() const
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="")
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
vpRobust m_robustCircles
std::vector< std::list< vpMbtDistanceCircle * > > circles
Vector of the tracked circles.
void getLcircle(std::list< vpMbtDistanceCircle * > &circlesList, unsigned int level=0) const
void initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
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)
vpRobust m_robustLines
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 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
vpAROgre * getOgreContext()
void computeClippedPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
bool isAppearing(unsigned int i)
unsigned int setVisibleOgre(unsigned int width, unsigned int height, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
bool isVisible(unsigned int i)
void initOgre(const vpCameraParameters &cam=vpCameraParameters())
unsigned int setVisible(unsigned int width, unsigned int height, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed)
void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w)
void computeScanLineRender(const vpCameraParameters &cam, const unsigned int &w, const unsigned int &h)
void displayOgre(const vpHomogeneousMatrix &cMo)
void setOgreShowConfigDialog(bool showConfigDialog)
double m_lambda
Gain of the virtual visual servoing stage.
Definition: vpMbTracker.h:189
bool modelInitialised
Definition: vpMbTracker.h:125
double minLineLengthThresholdGeneral
Minimum line length threshold for LOD mode (general setting)
Definition: vpMbTracker.h:179
bool m_projectionErrorDisplay
Display gradient and model orientation for projection error computation.
Definition: vpMbTracker.h:215
virtual void setMinLineLengthThresh(double minLineLengthThresh, const std::string &name="")
vpImage< unsigned char > m_I
Grayscale image buffer, used when passing color images.
Definition: vpMbTracker.h:225
unsigned int m_projectionErrorDisplayLength
Length of the arrows used to show the gradient and model orientation.
Definition: vpMbTracker.h:217
bool samePoint(const vpPoint &P1, const vpPoint &P2) const
bool useLodGeneral
True if LOD mode is enabled.
Definition: vpMbTracker.h:174
double minPolygonAreaThresholdGeneral
Minimum polygon area threshold for LOD mode (general setting)
Definition: vpMbTracker.h:181
bool m_computeInteraction
Definition: vpMbTracker.h:187
vpMatrix oJo
The Degrees of Freedom to estimate.
Definition: vpMbTracker.h:117
virtual void setMinPolygonAreaThresh(double minPolygonAreaThresh, const std::string &name="")
vpUniRand m_rand
Random number generator used in vpMbtDistanceLine::buildFrom()
Definition: vpMbTracker.h:229
vpMatrix covarianceMatrix
Covariance matrix.
Definition: vpMbTracker.h:132
double m_initialMu
Initial Mu for Levenberg Marquardt optimization loop.
Definition: vpMbTracker.h:195
bool computeProjError
Definition: vpMbTracker.h:135
vpHomogeneousMatrix m_cMo
The current pose.
Definition: vpMbTracker.h:115
vpMatrix m_SobelX
Sobel kernel in X.
Definition: vpMbTracker.h:211
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.
Definition: vpMbTracker.h:113
double projectionError
Definition: vpMbTracker.h:138
bool useOgre
Use Ogre3d for visibility tests.
Definition: vpMbTracker.h:157
vpMbHiddenFaces< vpMbtPolygon > faces
Set of faces describing the object.
Definition: vpMbTracker.h:145
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.
Definition: vpMbTracker.h:219
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.
Definition: vpMbTracker.h:142
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.
Definition: vpMbTracker.h:140
double angleDisappears
Angle used to detect a face disappearance.
Definition: vpMbTracker.h:149
virtual unsigned int getNbPolygon() const
Definition: vpMbTracker.h:370
virtual void setNearClippingDistance(const double &dist)
bool applyLodSettingInConfig
Definition: vpMbTracker.h:177
virtual void setFarClippingDistance(const double &dist)
double distFarClip
Distance for near clipping.
Definition: vpMbTracker.h:153
bool m_isoJoIdentity
Boolean to know if oJo is identity (for fast computation)
Definition: vpMbTracker.h:119
bool useScanLine
Use Scanline for visibility tests.
Definition: vpMbTracker.h:160
void computeJTR(const vpMatrix &J, const vpColVector &R, vpColVector &JTR) const
vpMatrix m_SobelY
Sobel kernel in Y.
Definition: vpMbTracker.h:213
virtual void setClipping(const unsigned int &flags)
double angleAppears
Angle used to detect a face appearance.
Definition: vpMbTracker.h:147
const vpImage< bool > * m_mask
Mask used to disable tracking on a part of image.
Definition: vpMbTracker.h:223
virtual void initFromPose(const vpImage< unsigned char > &I, const std::string &initFile)
virtual void loadModel(const std::string &modelFile, bool verbose=false, const vpHomogeneousMatrix &T=vpHomogeneousMatrix())
bool computeCovariance
Flag used to specify if the covariance matrix has to be computed or not.
Definition: vpMbTracker.h:130
double distNearClip
Distance for near clipping.
Definition: vpMbTracker.h:151
unsigned int m_maxIter
Maximum number of iterations of the virtual visual servoing stage.
Definition: vpMbTracker.h:191
bool ogreShowConfigDialog
Definition: vpMbTracker.h:158
unsigned int clippingFlag
Flags specifying which clipping to used.
Definition: vpMbTracker.h:155
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)
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)
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)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=nullptr)
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)
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.
bool isVisible() const
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)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=nullptr)
std::vector< std::vector< double > > getFeaturesForDisplay()
bool isTracked() const
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)
vpMbtPolygon & getPolygon()
Implementation of a polygon of the model used by the model-based tracker.
Definition: vpMbtPolygon.h:60
std::string getName() const
Definition: vpMbtPolygon.h:100
int getIndex() const
Definition: vpMbtPolygon.h:93
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:68
@ TOO_NEAR
Point not tracked anymore, since too near from its neighbor.
Definition: vpMeSite.h:93
@ THRESHOLD
Point not tracked due to the likelihood that is below the threshold, but retained in the ME list.
Definition: vpMeSite.h:91
@ CONTRAST
Point not tracked due to a contrast problem, but retained in the ME list.
Definition: vpMeSite.h:87
@ M_ESTIMATOR
Point detected as an outlier during virtual visual-servoing.
Definition: vpMeSite.h:92
@ NO_SUPPRESSION
Point successfully tracked.
Definition: vpMeSite.h:86
vpMeSiteState getState() const
Definition: vpMeSite.h:269
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:259
Definition: vpMe.h:134
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)
Definition: vpPolygon3D.h:192
unsigned int getNbPoint() const
Definition: vpPolygon3D.h:130
void setNearClippingDistance(const double &dist)
Definition: vpPolygon3D.h:205
vpPoint * p
corners in the object frame
Definition: vpPolygon3D.h:79
void setClipping(const unsigned int &flags)
Definition: vpPolygon3D.h:185
@ 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
Error that can be emitted by the vpTracker class and its derivatives.
@ notEnoughPointError
Not enough point to track.
@ fatalError
Tracker fatal error.
vpVelocityTwistMatrix & build(const vpTranslationVector &t, const vpRotationMatrix &R)
#define vpTRACE
Definition: vpDebug.h:436
#define vpERROR_TRACE
Definition: vpDebug.h:409