Visual Servoing Platform  version 3.1.0
vpMbEdgeTracker.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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 http://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  * Authors:
35  * Nicolas Melchior
36  * Romain Tallonneau
37  * Eric Marchand
38  *
39  *****************************************************************************/
40 
46 #include <visp3/core/vpDebug.h>
47 #include <visp3/core/vpException.h>
48 #include <visp3/core/vpExponentialMap.h>
49 #include <visp3/core/vpMath.h>
50 #include <visp3/core/vpMatrixException.h>
51 #include <visp3/core/vpPixelMeterConversion.h>
52 #include <visp3/core/vpPolygon3D.h>
53 #include <visp3/core/vpTrackingException.h>
54 #include <visp3/core/vpVelocityTwistMatrix.h>
55 #include <visp3/mbt/vpMbEdgeTracker.h>
56 #include <visp3/mbt/vpMbtDistanceLine.h>
57 #include <visp3/mbt/vpMbtXmlParser.h>
58 #include <visp3/vision/vpPose.h>
59 
60 #include <float.h>
61 #include <limits>
62 #include <map>
63 #include <sstream>
64 #include <string>
65 
70  : me(), lines(1), circles(1), cylinders(1), nline(0), ncircle(0), ncylinder(0), nbvisiblepolygone(0),
71  percentageGdPt(0.4), scales(1), Ipyramid(0), scaleLevel(0), nbFeaturesForProjErrorComputation(0), m_factor(),
72  m_robustLines(), m_robustCylinders(), m_robustCircles(), m_wLines(), m_wCylinders(), m_wCircles(), m_errorLines(),
73  m_errorCylinders(), m_errorCircles(), m_L_edge(), m_error_edge(), m_w_edge(), m_weightedError_edge(),
74  m_robust_edge()
75 {
78 
79  scales[0] = true;
80 
81 #ifdef VISP_HAVE_OGRE
82  faces.getOgreContext()->setWindowName("MBT Edge");
83 #endif
84 }
85 
90 {
94 
95  for (unsigned int i = 0; i < scales.size(); i += 1) {
96  if (scales[i]) {
97  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
98  l = *it;
99  if (l != NULL) {
100  delete l;
101  }
102  l = NULL;
103  }
104 
105  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
106  ++it) {
107  cy = *it;
108  if (cy != NULL) {
109  delete cy;
110  }
111  cy = NULL;
112  }
113 
114  lines[i].clear();
115  cylinders[i].clear();
116  }
117  }
118  for (unsigned int i = 0; i < circles.size(); i += 1) {
119  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
120  ci = *it;
121  if (ci != NULL) {
122  delete ci;
123  }
124  ci = NULL;
125  }
126  circles[i].clear();
127  }
129 }
130 
137 {
138  this->me = p_me;
139 
140  for (unsigned int i = 0; i < scales.size(); i += 1) {
141  if (scales[i]) {
142  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
143  vpMbtDistanceLine *l = *it;
144  l->setMovingEdge(&(this->me));
145  }
146 
147  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
148  ++it) {
149  vpMbtDistanceCylinder *cy = *it;
150  cy->setMovingEdge(&(this->me));
151  }
152 
153  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
154  vpMbtDistanceCircle *ci = *it;
155  ci->setMovingEdge(&(this->me));
156  }
157  }
158  }
159 }
160 
170 void vpMbEdgeTracker::computeVVS(const vpImage<unsigned char> &_I, const unsigned int lvl)
171 {
172  double residu_1 = 1e3;
173  double r = 1e3 - 1;
174 
175  unsigned int iter = 0;
176 
177  computeVVSInit();
178  unsigned int nbrow = m_error_edge.getRows();
179 
180  bool reloop = true;
181 
182  bool isoJoIdentity_ = isoJoIdentity; // Backup since it can be modified if L is not full rank
183  if (isoJoIdentity_)
184  oJo.eye();
185 
186  /*** First phase ***/
187 
188  while (reloop == true && iter < 10) {
189  double count = 0;
190 
191  computeVVSFirstPhase(_I, iter, count, lvl);
192 
193  count = count / (double)nbrow;
194  if (count >= 0.85) {
195  reloop = false;
196  }
197 
198  computeVVSFirstPhasePoseEstimation(iter, isoJoIdentity_);
199 
200  iter++;
201  }
202 
203  // std::cout << "\t First minimization in " << iter << " iteration give as
204  // initial cMo: \n" << cMo << std::endl;
205 
206  /*** Second phase ***/
207  vpHomogeneousMatrix cMoPrev;
208  vpColVector W_true(nbrow);
209  vpMatrix L_true;
210  vpMatrix LVJ_true;
211 
212  double mu = m_initialMu;
213  vpColVector m_error_prev;
214  vpColVector m_w_prev;
215 
216  // To avoid to create these matrices each iteration
217  vpMatrix LTL;
218  vpColVector LTR;
219  vpColVector v;
220 
221  iter = 0;
222  m_w_edge = 1;
223 
224  // while ( ((int)((residu_1 - r)*1e8) !=0 ) && (iter<30))
225  while (std::fabs((residu_1 - r) * 1e8) > std::numeric_limits<double>::epsilon() && (iter < m_maxIter)) {
227 
228  bool reStartFromLastIncrement = false;
229  computeVVSCheckLevenbergMarquardt(iter, m_error_edge, m_error_prev, cMoPrev, mu, reStartFromLastIncrement,
230  &m_w_edge, &m_w_prev);
231 
232  if (!reStartFromLastIncrement) {
234 
235  L_true = m_L_edge;
237 
238  if (computeCovariance) {
239  L_true = m_L_edge;
240  if (!isoJoIdentity_) {
241  cVo.buildFrom(cMo);
242  LVJ_true = (m_L_edge * cVo * oJo);
243  }
244  }
245 
246  double wi = 0.0, eri = 0.0;
247  double num = 0.0, den = 0.0;
248  if ((iter == 0) || m_computeInteraction) {
249  for (unsigned int i = 0; i < nbrow; i++) {
250  wi = m_w_edge[i] * m_factor[i];
251  W_true[i] = wi;
252  eri = m_error_edge[i];
253  num += wi * vpMath::sqr(eri);
254  den += wi;
255 
256  m_weightedError_edge[i] = wi * eri;
257 
258  for (unsigned int j = 0; j < 6; j++) {
259  m_L_edge[i][j] = wi * m_L_edge[i][j];
260  }
261  }
262  } else {
263  for (unsigned int i = 0; i < nbrow; i++) {
264  wi = m_w_edge[i] * m_factor[i];
265  W_true[i] = wi;
266  eri = m_error_edge[i];
267  num += wi * vpMath::sqr(eri);
268  den += wi;
269 
270  m_weightedError_edge[i] = wi * eri;
271  }
272  }
273 
274  residu_1 = r;
275  r = sqrt(num / den); // Le critere d'arret prend en compte le poids
276 
277  computeVVSPoseEstimation(isoJoIdentity_, iter, m_L_edge, LTL, m_weightedError_edge, m_error_edge, m_error_prev,
278  LTR, mu, v, &m_w_edge, &m_w_prev);
279 
280  cMoPrev = cMo;
282 
283  } // endif(!restartFromLast)
284 
285  iter++;
286  }
287 
288  computeCovarianceMatrixVVS(isoJoIdentity_, W_true, cMoPrev, L_true, LVJ_true, m_error_edge);
289 
291 }
292 
293 void vpMbEdgeTracker::computeVVSFirstPhase(const vpImage<unsigned char> &_I, const unsigned int iter, double &count,
294  const unsigned int lvl)
295 {
299 
300  double limite = 3; // Une limite de 3 pixels
301  limite = limite / cam.get_px(); // Transformation limite pixel en limite metre.
302 
303  unsigned int n = 0;
304 
305  // Parametre pour la premiere phase d'asservissement
306  double e_prev = 0, e_cur, e_next;
307 
308  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
309  if ((*it)->isTracked()) {
310  l = *it;
312 
313  double fac = 1;
314  if (iter == 0) {
315  for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
316  ++itindex) {
317  int index = *itindex;
318  if (l->hiddenface->isAppearing((unsigned int)index)) {
319  fac = 0.2;
320  break;
321  }
322  if (l->closeToImageBorder(_I, 10)) {
323  fac = 0.1;
324  break;
325  }
326  }
327  }
328 
329  std::list<vpMeSite>::const_iterator itListLine;
330 
331  unsigned int indexFeature = 0;
332 
333  for (unsigned int a = 0; a < l->meline.size(); a++) {
334  if (iter == 0 && l->meline[a] != NULL)
335  itListLine = l->meline[a]->getMeList().begin();
336 
337  for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
338  for (unsigned int j = 0; j < 6; j++) {
339  m_L_edge[n + i][j] = l->L[indexFeature][j]; // On remplit la matrice d'interaction globale
340  }
341  m_error_edge[n + i] = l->error[indexFeature]; // On remplit la matrice d'erreur
342 
343  if (m_error_edge[n + i] <= limite)
344  count = count + 1.0; // Si erreur proche de 0 on incremente cur
345 
346  m_w_edge[n + i] = 0;
347 
348  if (iter == 0) {
349  m_factor[n + i] = fac;
350  vpMeSite site = *itListLine;
351  if (site.getState() != vpMeSite::NO_SUPPRESSION)
352  m_factor[n + i] = 0.2;
353  ++itListLine;
354  }
355 
356  // If pour la premiere extremite des moving edges
357  if (indexFeature == 0) {
358  e_cur = l->error[0];
359  if (l->nbFeature[a] > 1) {
360  e_next = l->error[1];
361  if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
362  m_w_edge[n + i] = 1 /*0.5*/;
363  }
364  e_prev = e_cur;
365  } else
366  m_w_edge[n + i] = 1;
367  }
368 
369  // If pour la derniere extremite des moving edges
370  else if (indexFeature == l->nbFeatureTotal - 1) {
371  e_cur = l->error[indexFeature];
372  if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
373  m_w_edge[n + i] += 1 /*0.5*/;
374  }
375  }
376 
377  else {
378  e_cur = l->error[indexFeature];
379  e_next = l->error[indexFeature + 1];
380  if (fabs(e_cur - e_prev) < limite) {
381  m_w_edge[n + i] += 0.5;
382  }
383  if (fabs(e_cur - e_next) < limite) {
384  m_w_edge[n + i] += 0.5;
385  }
386  e_prev = e_cur;
387  }
388  indexFeature++;
389  }
390  n += l->nbFeature[a];
391  }
392  }
393  }
394 
395  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
396  ++it) {
397  if ((*it)->isTracked()) {
398  cy = *it;
400  double fac = 1.0;
401 
402  std::list<vpMeSite>::const_iterator itCyl1;
403  std::list<vpMeSite>::const_iterator itCyl2;
404  if (iter == 0 && (cy->meline1 != NULL || cy->meline2 != NULL)) {
405  itCyl1 = cy->meline1->getMeList().begin();
406  itCyl2 = cy->meline2->getMeList().begin();
407  }
408 
409  for (unsigned int i = 0; i < cy->nbFeature; i++) {
410  for (unsigned int j = 0; j < 6; j++) {
411  m_L_edge[n + i][j] = cy->L[i][j]; // On remplit la matrice d'interaction globale
412  }
413  m_error_edge[n + i] = cy->error[i]; // On remplit la matrice d'erreur
414 
415  if (m_error_edge[n + i] <= limite)
416  count = count + 1.0; // Si erreur proche de 0 on incremente cur
417 
418  m_w_edge[n + i] = 0;
419 
420  if (iter == 0) {
421  m_factor[n + i] = fac;
422  vpMeSite site;
423  if (i < cy->nbFeaturel1) {
424  site = *itCyl1;
425  ++itCyl1;
426  } else {
427  site = *itCyl2;
428  ++itCyl2;
429  }
430  if (site.getState() != vpMeSite::NO_SUPPRESSION)
431  m_factor[n + i] = 0.2;
432  }
433 
434  // If pour la premiere extremite des moving edges
435  if (i == 0) {
436  e_cur = cy->error[0];
437  if (cy->nbFeature > 1) {
438  e_next = cy->error[1];
439  if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
440  m_w_edge[n + i] = 1 /*0.5*/;
441  }
442  e_prev = e_cur;
443  } else
444  m_w_edge[n + i] = 1;
445  }
446  if (i == cy->nbFeaturel1) {
447  e_cur = cy->error[i];
448  if (cy->nbFeaturel2 > 1) {
449  e_next = cy->error[i + 1];
450  if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
451  m_w_edge[n + i] = 1 /*0.5*/;
452  }
453  e_prev = e_cur;
454  } else
455  m_w_edge[n + i] = 1;
456  }
457 
458  // If pour la derniere extremite des moving edges
459  else if (i == cy->nbFeaturel1 - 1) {
460  e_cur = cy->error[i];
461  if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
462  m_w_edge[n + i] += 1 /*0.5*/;
463  }
464  }
465  // If pour la derniere extremite des moving edges
466  else if (i == cy->nbFeature - 1) {
467  e_cur = cy->error[i];
468  if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
469  m_w_edge[n + i] += 1 /*0.5*/;
470  }
471  }
472 
473  else {
474  e_cur = cy->error[i];
475  e_next = cy->error[i + 1];
476  if (fabs(e_cur - e_prev) < limite) {
477  m_w_edge[n + i] += 0.5;
478  }
479  if (fabs(e_cur - e_next) < limite) {
480  m_w_edge[n + i] += 0.5;
481  }
482  e_prev = e_cur;
483  }
484  }
485 
486  n += cy->nbFeature;
487  }
488  }
489 
490  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
491  if ((*it)->isTracked()) {
492  ci = *it;
494  double fac = 1.0;
495 
496  std::list<vpMeSite>::const_iterator itCir;
497  if (iter == 0 && (ci->meEllipse != NULL)) {
498  itCir = ci->meEllipse->getMeList().begin();
499  }
500 
501  for (unsigned int i = 0; i < ci->nbFeature; i++) {
502  for (unsigned int j = 0; j < 6; j++) {
503  m_L_edge[n + i][j] = ci->L[i][j]; // On remplit la matrice d'interaction globale
504  }
505  m_error_edge[n + i] = ci->error[i]; // On remplit la matrice d'erreur
506 
507  if (m_error_edge[n + i] <= limite)
508  count = count + 1.0; // Si erreur proche de 0 on incremente cur
509 
510  m_w_edge[n + i] = 0;
511 
512  if (iter == 0) {
513  m_factor[n + i] = fac;
514  vpMeSite site = *itCir;
515  if (site.getState() != vpMeSite::NO_SUPPRESSION)
516  m_factor[n + i] = 0.2;
517  ++itCir;
518  }
519 
520  // If pour la premiere extremite des moving edges
521  if (i == 0) {
522  e_cur = ci->error[0];
523  if (ci->nbFeature > 1) {
524  e_next = ci->error[1];
525  if (fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next)) {
526  m_w_edge[n + i] = 1 /*0.5*/;
527  }
528  e_prev = e_cur;
529  } else
530  m_w_edge[n + i] = 1;
531  }
532 
533  // If pour la derniere extremite des moving edges
534  else if (i == ci->nbFeature - 1) {
535  e_cur = ci->error[i];
536  if (fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev)) {
537  m_w_edge[n + i] += 1 /*0.5*/;
538  }
539  }
540 
541  else {
542  e_cur = ci->error[i];
543  e_next = ci->error[i + 1];
544  if (fabs(e_cur - e_prev) < limite) {
545  m_w_edge[n + i] += 0.5;
546  }
547  if (fabs(e_cur - e_next) < limite) {
548  m_w_edge[n + i] += 0.5;
549  }
550  e_prev = e_cur;
551  }
552  }
553 
554  n += ci->nbFeature;
555  }
556  }
557 }
558 
560 {
564 
565  unsigned int n = 0;
566  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
567  if ((*it)->isTracked()) {
568  l = *it;
570 
571  double fac = 1;
572  for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
573  ++itindex) {
574  int index = *itindex;
575  if (l->hiddenface->isAppearing((unsigned int)index)) {
576  fac = 0.2;
577  break;
578  }
579  if (l->closeToImageBorder(I, 10)) {
580  fac = 0.1;
581  break;
582  }
583  }
584 
585  unsigned int indexFeature = 0;
586  for (unsigned int a = 0; a < l->meline.size(); a++) {
587  std::list<vpMeSite>::const_iterator itListLine;
588  if (l->meline[a] != NULL) {
589  itListLine = l->meline[a]->getMeList().begin();
590 
591  for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
592  m_factor[n + i] = fac;
593  vpMeSite site = *itListLine;
594  if (site.getState() != vpMeSite::NO_SUPPRESSION)
595  m_factor[n + i] = 0.2;
596  ++itListLine;
597  indexFeature++;
598  }
599  n += l->nbFeature[a];
600  }
601  }
602  }
603  }
604 
605  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
606  ++it) {
607  if ((*it)->isTracked()) {
608  cy = *it;
610 
611  std::list<vpMeSite>::const_iterator itCyl1;
612  std::list<vpMeSite>::const_iterator itCyl2;
613  if ((cy->meline1 != NULL || cy->meline2 != NULL)) {
614  itCyl1 = cy->meline1->getMeList().begin();
615  itCyl2 = cy->meline2->getMeList().begin();
616 
617  double fac = 1.0;
618  for (unsigned int i = 0; i < cy->nbFeature; i++) {
619  m_factor[n + i] = fac;
620  vpMeSite site;
621  if (i < cy->nbFeaturel1) {
622  site = *itCyl1;
623  ++itCyl1;
624  } else {
625  site = *itCyl2;
626  ++itCyl2;
627  }
628  if (site.getState() != vpMeSite::NO_SUPPRESSION)
629  m_factor[n + i] = 0.2;
630  }
631  n += cy->nbFeature;
632  }
633  }
634  }
635 
636  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
637  if ((*it)->isTracked()) {
638  ci = *it;
640 
641  std::list<vpMeSite>::const_iterator itCir;
642  if (ci->meEllipse != NULL) {
643  itCir = ci->meEllipse->getMeList().begin();
644  double fac = 1.0;
645 
646  for (unsigned int i = 0; i < ci->nbFeature; i++) {
647  m_factor[n + i] = fac;
648  vpMeSite site = *itCir;
649  if (site.getState() != vpMeSite::NO_SUPPRESSION)
650  m_factor[n + i] = 0.2;
651  ++itCir;
652  }
653  n += ci->nbFeature;
654  }
655  }
656  }
657 }
658 
659 void vpMbEdgeTracker::computeVVSFirstPhasePoseEstimation(const unsigned int iter, bool &isoJoIdentity_)
660 {
661  unsigned int nerror = m_weightedError_edge.getRows();
662 
663  double wi, eri;
664  if ((iter == 0) || m_computeInteraction) {
665  for (unsigned int i = 0; i < nerror; i++) {
666  wi = m_w_edge[i] * m_factor[i];
667  eri = m_error_edge[i];
668 
669  m_weightedError_edge[i] = wi * eri;
670 
671  for (unsigned int j = 0; j < 6; j++) {
672  m_L_edge[i][j] = wi * m_L_edge[i][j];
673  }
674  }
675  } else {
676  for (unsigned int i = 0; i < nerror; i++) {
677  wi = m_w_edge[i] * m_factor[i];
678  eri = m_error_edge[i];
679 
680  m_weightedError_edge[i] = wi * eri;
681  }
682  }
683 
685 
686  // If all the 6 dof should be estimated, we check if the interaction matrix
687  // is full rank. If not we remove automatically the dof that cannot be
688  // estimated This is particularly useful when consering circles (rank 5) and
689  // cylinders (rank 4)
690  if (isoJoIdentity_) {
691  cVo.buildFrom(cMo);
692 
693  vpMatrix K; // kernel
694  unsigned int rank = (m_L_edge * cVo).kernel(K);
695  if (rank == 0) {
696  throw vpException(vpException::fatalError, "Rank=0, cannot estimate the pose !");
697  }
698  if (rank != 6) {
699  vpMatrix I; // Identity
700  I.eye(6);
701  oJo = I - K.AtA();
702 
703  isoJoIdentity_ = false;
704  }
705  }
706 
707  vpColVector v;
708  vpMatrix LTL;
709  vpColVector LTR;
710 
711  if (isoJoIdentity_) {
712  LTL = m_L_edge.AtA();
714  v = -0.7 * LTL.pseudoInverse(LTL.getRows() * std::numeric_limits<double>::epsilon()) * LTR;
715  } else {
716  cVo.buildFrom(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 
752  m_robustLines.resize(nberrors_lines);
753  m_robustCylinders.resize(nberrors_cylinders);
754  m_robustCircles.resize(nberrors_circles);
758 
759  m_wLines.resize(nberrors_lines, false);
760  m_wLines = 1;
761  m_wCylinders.resize(nberrors_cylinders, false);
762  m_wCylinders = 1;
763  m_wCircles.resize(nberrors_circles, false);
764  m_wCircles = 1;
765 
766  m_errorLines.resize(nberrors_lines, false);
767  m_errorCylinders.resize(nberrors_cylinders, false);
768  m_errorCircles.resize(nberrors_circles, false);
769 }
770 
772 {
773  throw vpException(vpException::fatalError, "vpMbEdgeTracker::"
774  "computeVVSInteractionMatrixAndR"
775  "esidu() should not be called!");
776 }
777 
779 {
783 
784  unsigned int n = 0;
785  unsigned int nlines = 0;
786  unsigned int ncylinders = 0;
787  unsigned int ncircles = 0;
788 
789  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
790  ++it) {
791  if ((*it)->isTracked()) {
792  l = *it;
794  for (unsigned int i = 0; i < l->nbFeatureTotal; i++) {
795  for (unsigned int j = 0; j < 6; j++) {
796  m_L_edge[n + i][j] = l->L[i][j];
797  m_error_edge[n + i] = l->error[i];
798  m_errorLines[nlines + i] = m_error_edge[n + i];
799  }
800  }
801  n += l->nbFeatureTotal;
802  nlines += l->nbFeatureTotal;
803  }
804  }
805 
806  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
807  it != cylinders[scaleLevel].end(); ++it) {
808  if ((*it)->isTracked()) {
809  cy = *it;
811  for (unsigned int i = 0; i < cy->nbFeature; i++) {
812  for (unsigned int j = 0; j < 6; j++) {
813  m_L_edge[n + i][j] = cy->L[i][j];
814  m_error_edge[n + i] = cy->error[i];
815  m_errorCylinders[ncylinders + i] = m_error_edge[n + i];
816  }
817  }
818 
819  n += cy->nbFeature;
820  ncylinders += cy->nbFeature;
821  }
822  }
823 
824  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
825  it != circles[scaleLevel].end(); ++it) {
826  if ((*it)->isTracked()) {
827  ci = *it;
829  for (unsigned int i = 0; i < ci->nbFeature; i++) {
830  for (unsigned int j = 0; j < 6; j++) {
831  m_L_edge[n + i][j] = ci->L[i][j];
832  m_error_edge[n + i] = ci->error[i];
833  m_errorCircles[ncircles + i] = m_error_edge[n + i];
834  }
835  }
836 
837  n += ci->nbFeature;
838  ncircles += ci->nbFeature;
839  }
840  }
841 }
842 
844 {
845  unsigned int nberrors_lines = m_errorLines.getRows(), nberrors_cylinders = m_errorCylinders.getRows(),
846  nberrors_circles = m_errorCircles.getRows();
847 
848  if (nberrors_lines > 0)
850  if (nberrors_cylinders > 0)
852  if (nberrors_circles > 0)
854 
858 }
859 
869 {
870  projectionError = 0.0;
871  unsigned int nbFeatures = 0;
872  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
873  ++it) {
874  vpMbtDistanceLine *l = *it;
875  if (l->isVisible() && l->isTracked()) {
876  for (unsigned int a = 0; a < l->meline.size(); a++) {
877  if (l->meline[a] != NULL) {
878  double lineNormGradient;
879  unsigned int lineNbFeatures;
880  l->meline[a]->computeProjectionError(_I, lineNormGradient, lineNbFeatures);
881  projectionError += lineNormGradient;
882  nbFeatures += lineNbFeatures;
883  }
884  }
885  }
886  }
887 
888  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
889  it != cylinders[scaleLevel].end(); ++it) {
890  vpMbtDistanceCylinder *cy = *it;
891  if (cy->isVisible() && cy->isTracked()) {
892  if (cy->meline1 != NULL) {
893  double cylinderNormGradient = 0;
894  unsigned int cylinderNbFeatures = 0;
895  cy->meline1->computeProjectionError(_I, cylinderNormGradient, cylinderNbFeatures);
896  projectionError += cylinderNormGradient;
897  nbFeatures += cylinderNbFeatures;
898  }
899 
900  if (cy->meline2 != NULL) {
901  double cylinderNormGradient = 0;
902  unsigned int cylinderNbFeatures = 0;
903  cy->meline2->computeProjectionError(_I, cylinderNormGradient, cylinderNbFeatures);
904  projectionError += cylinderNormGradient;
905  nbFeatures += cylinderNbFeatures;
906  }
907  }
908  }
909 
910  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
911  it != circles[scaleLevel].end(); ++it) {
912  vpMbtDistanceCircle *c = *it;
913  if (c->isVisible() && c->isTracked() && c->meEllipse != NULL) {
914  double circleNormGradient = 0;
915  unsigned int circleNbFeatures = 0;
916  c->meEllipse->computeProjectionError(_I, circleNormGradient, circleNbFeatures);
917  projectionError += circleNormGradient;
918  nbFeatures += circleNbFeatures;
919  }
920  }
921 
922  if (nbFeatures > 0) {
923  projectionError = vpMath::deg(projectionError / (double)nbFeatures);
924  } else {
925  projectionError = 90.0;
926  }
927 
929  // std::cout << "Norm Gradient = " << errorGradient << std::endl;
930 }
931 
938 {
939  int nbExpectedPoint = 0;
940  int nbGoodPoint = 0;
941  int nbBadPoint = 0;
942 
943  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
944  ++it) {
945  vpMbtDistanceLine *l = *it;
946  if (l->isVisible() && l->isTracked()) {
947  for (unsigned int a = 0; a < l->meline.size(); a++) {
948  if (l->meline[a] != NULL) {
949  nbExpectedPoint += (int)l->meline[a]->expecteddensity;
950  for (std::list<vpMeSite>::const_iterator itme = l->meline[a]->getMeList().begin();
951  itme != l->meline[a]->getMeList().end(); ++itme) {
952  vpMeSite pix = *itme;
953  if (pix.getState() == vpMeSite::NO_SUPPRESSION)
954  nbGoodPoint++;
955  else
956  nbBadPoint++;
957  }
958  }
959  }
960  }
961  }
962 
963  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
964  it != cylinders[scaleLevel].end(); ++it) {
965  vpMbtDistanceCylinder *cy = *it;
966  if ((cy->meline1 != NULL && cy->meline2 != NULL) && cy->isVisible() && cy->isTracked()) {
967  nbExpectedPoint += (int)cy->meline1->expecteddensity;
968  for (std::list<vpMeSite>::const_iterator itme1 = cy->meline1->getMeList().begin();
969  itme1 != cy->meline1->getMeList().end(); ++itme1) {
970  vpMeSite pix = *itme1;
971  if (pix.getState() == vpMeSite::NO_SUPPRESSION)
972  nbGoodPoint++;
973  else
974  nbBadPoint++;
975  }
976  nbExpectedPoint += (int)cy->meline2->expecteddensity;
977  for (std::list<vpMeSite>::const_iterator itme2 = cy->meline2->getMeList().begin();
978  itme2 != cy->meline2->getMeList().end(); ++itme2) {
979  vpMeSite pix = *itme2;
980  if (pix.getState() == vpMeSite::NO_SUPPRESSION)
981  nbGoodPoint++;
982  else
983  nbBadPoint++;
984  }
985  }
986  }
987 
988  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
989  it != circles[scaleLevel].end(); ++it) {
990  vpMbtDistanceCircle *ci = *it;
991  if (ci->isVisible() && ci->isTracked() && ci->meEllipse != NULL) {
992  nbExpectedPoint += ci->meEllipse->getExpectedDensity();
993  for (std::list<vpMeSite>::const_iterator itme = ci->meEllipse->getMeList().begin();
994  itme != ci->meEllipse->getMeList().end(); ++itme) {
995  vpMeSite pix = *itme;
996  if (pix.getState() == vpMeSite::NO_SUPPRESSION)
997  nbGoodPoint++;
998  else
999  nbBadPoint++;
1000  }
1001  }
1002  }
1003 
1004  // Compare the number of good points with the min between the number of
1005  // expected points and number of points that are tracked
1006  int nb_min = (int)vpMath::minimum(percentageGdPt * nbExpectedPoint, percentageGdPt * (nbGoodPoint + nbBadPoint));
1007  // int nb_min = (std::min)(val1, val2);
1008  if (nbGoodPoint < nb_min || nbExpectedPoint < 2) {
1009  std::ostringstream oss;
1010  oss << "Not enough moving edges (" << nbGoodPoint << ") to track the object: expected " << nb_min
1011  << ". Try to reduce the threshold=" << percentageGdPt
1012  << " using vpMbTracker::setGoodMovingEdgesRatioThreshold()";
1014  }
1015 }
1016 
1025 {
1026  initPyramid(I, Ipyramid);
1027 
1028  // for (int lvl = ((int)scales.size()-1); lvl >= 0; lvl -= 1)
1029  unsigned int lvl = (unsigned int)scales.size();
1030  do {
1031  lvl--;
1032 
1033  projectionError = 90.0;
1034 
1035  if (scales[lvl]) {
1036  vpHomogeneousMatrix cMo_1 = cMo;
1037  try {
1038  downScale(lvl);
1039 
1040  try {
1041  trackMovingEdge(*Ipyramid[lvl]);
1042  } catch (...) {
1043  vpTRACE("Error in moving edge tracking");
1044  throw;
1045  }
1046 
1047  // initialize the vector that contains the error and the matrix that
1048  // contains the interaction matrix AY: Useless as it is done in
1049  // coputeVVS()
1050  /*
1051  for(std::list<vpMbtDistanceLine*>::const_iterator
1052  it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){ l = *it; if
1053  (l->isVisible()){ l->initInteractionMatrixError();
1054  }
1055  }
1056 
1057  for(std::list<vpMbtDistanceCylinder*>::const_iterator
1058  it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){ cy = *it;
1059  if(cy->isVisible()) {
1060  cy->initInteractionMatrixError();
1061  }
1062  }
1063 
1064  for(std::list<vpMbtDistanceCircle*>::const_iterator
1065  it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){ ci = *it; if
1066  (ci->isVisible()){ ci->initInteractionMatrixError();
1067  }
1068  }
1069  */
1070 
1071  try {
1072  computeVVS(*Ipyramid[lvl], lvl);
1073  } catch (...) {
1074  covarianceMatrix = -1;
1075  throw; // throw the original exception
1076  }
1077 
1078  testTracking();
1079 
1080  if (displayFeatures) {
1081  displayFeaturesOnImage(I, lvl);
1082  }
1083 
1084  // Looking for new visible face
1085  bool newvisibleface = false;
1086  visibleFace(I, cMo, newvisibleface);
1087 
1088  // cam.computeFov(I.getWidth(), I.getHeight());
1089  if (useScanLine) {
1092  }
1093 
1094  updateMovingEdge(I);
1095 
1096  initMovingEdge(I, cMo);
1097  // Reinit the moving edge for the lines which need it.
1098  reinitMovingEdge(I, cMo);
1099 
1100  if (computeProjError)
1102 
1103  upScale(lvl);
1104  } catch (vpException &e) {
1105  if (lvl != 0) {
1106  cMo = cMo_1;
1107  reInitLevel(lvl);
1108  upScale(lvl);
1109  } else {
1110  upScale(lvl);
1111  throw(e);
1112  }
1113  }
1114  }
1115  } while (lvl != 0);
1116 
1118 }
1119 
1126 {
1127  if (!modelInitialised) {
1128  throw vpException(vpException::fatalError, "model not initialized");
1129  }
1130 
1131  bool a = false;
1132 
1133 #ifdef VISP_HAVE_OGRE
1134  if (useOgre) {
1135  if (!faces.isOgreInitialised()) {
1138  faces.initOgre(cam);
1139  // Turn off Ogre config dialog display for the next call to this
1140  // function since settings are saved in the ogre.cfg file and used
1141  // during the next call
1142  ogreShowConfigDialog = false;
1143  }
1144  }
1145 #endif
1146 
1147  if (clippingFlag > 2)
1148  cam.computeFov(I.getWidth(), I.getHeight());
1149 
1150  initPyramid(I, Ipyramid);
1151  visibleFace(I, cMo, a);
1152  unsigned int i = (unsigned int)scales.size();
1153 
1154  resetMovingEdge();
1155 
1156  if (useScanLine) {
1157  if (clippingFlag <= 2)
1158  cam.computeFov(I.getWidth(), I.getHeight());
1159 
1162  }
1163 
1164  do {
1165  i--;
1166  if (scales[i]) {
1167  downScale(i);
1168  initMovingEdge(*Ipyramid[i], cMo);
1169  upScale(i);
1170  }
1171  } while (i != 0);
1172 
1174 }
1175 
1184 {
1185  cMo = cdMo;
1186 
1187  init(I);
1188 }
1189 
1203 void vpMbEdgeTracker::loadConfigFile(const std::string &configFile)
1204 {
1205  vpMbEdgeTracker::loadConfigFile(configFile.c_str());
1206 }
1207 
1258 void vpMbEdgeTracker::loadConfigFile(const char *configFile)
1259 {
1260 #ifdef VISP_HAVE_XML2
1261  vpMbtXmlParser xmlp;
1262 
1263  xmlp.setCameraParameters(cam);
1266  xmlp.setMovingEdge(me);
1267 
1268  try {
1269  std::cout << " *********** Parsing XML for Mb Edge Tracker ************ " << std::endl;
1270  xmlp.parse(configFile);
1271  } catch (...) {
1272  throw vpException(vpException::ioError, "Cannot open XML file \"%s\"", configFile);
1273  }
1274 
1275  vpCameraParameters camera;
1276  vpMe meParser;
1277  xmlp.getCameraParameters(camera);
1278  xmlp.getMe(meParser);
1279 
1280  setCameraParameters(camera);
1281  setMovingEdge(meParser);
1284 
1285  if (xmlp.hasNearClippingDistance())
1287 
1288  if (xmlp.hasFarClippingDistance())
1290 
1291  if (xmlp.getFovClipping())
1293 
1294  useLodGeneral = xmlp.getLodState();
1297 
1298  applyLodSettingInConfig = false;
1299  if (this->getNbPolygon() > 0) {
1300  applyLodSettingInConfig = true;
1304  }
1305 
1306 #else
1307  vpTRACE("You need the libXML2 to read the config file %s", configFile);
1308 #endif
1309 }
1310 
1323  const vpCameraParameters &camera, const vpColor &col, const unsigned int thickness,
1324  const bool displayFullModel)
1325 {
1326  for (unsigned int i = 0; i < scales.size(); i += 1) {
1327  if (scales[i]) {
1328  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1329  ++it) {
1330  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1331  }
1332 
1333  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1334  it != cylinders[scaleLevel].end(); ++it) {
1335  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1336  }
1337 
1338  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1339  it != circles[scaleLevel].end(); ++it) {
1340  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1341  }
1342 
1343  break; // displaying model on one scale only
1344  }
1345  }
1346 
1347 #ifdef VISP_HAVE_OGRE
1348  if (useOgre)
1349  faces.displayOgre(cMo_);
1350 #endif
1351 }
1352 
1365  const vpCameraParameters &camera, const vpColor &col, const unsigned int thickness,
1366  const bool displayFullModel)
1367 {
1368  for (unsigned int i = 0; i < scales.size(); i += 1) {
1369  if (scales[i]) {
1370  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1371  ++it) {
1372  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1373  }
1374 
1375  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1376  it != cylinders[scaleLevel].end(); ++it) {
1377  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1378  }
1379 
1380  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1381  it != circles[scaleLevel].end(); ++it) {
1382  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1383  }
1384  break; // displaying model on one scale only
1385  }
1386  }
1387 
1388 #ifdef VISP_HAVE_OGRE
1389  if (useOgre)
1390  faces.displayOgre(cMo_);
1391 #endif
1392 }
1393 
1395 {
1396  if (lvl == 0) {
1397  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[lvl].begin(); it != lines[lvl].end(); ++it) {
1398  vpMbtDistanceLine *l = *it;
1399  if (l->isVisible() && l->isTracked()) {
1400  l->displayMovingEdges(I);
1401  }
1402  }
1403 
1404  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[lvl].begin(); it != cylinders[lvl].end();
1405  ++it) {
1406  vpMbtDistanceCylinder *cy = *it;
1407  if (cy->isVisible() && cy->isTracked()) {
1408  cy->displayMovingEdges(I);
1409  }
1410  }
1411 
1412  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[lvl].begin(); it != circles[lvl].end(); ++it) {
1413  vpMbtDistanceCircle *ci = *it;
1414  if (ci->isVisible() && ci->isTracked()) {
1415  ci->displayMovingEdges(I);
1416  }
1417  }
1418  }
1419 }
1420 
1430 {
1431  vpMbtDistanceLine *l;
1432 
1433  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1434  ++it) {
1435  l = *it;
1436  bool isvisible = false;
1437 
1438  for (std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex != l->Lindex_polygon.end();
1439  ++itindex) {
1440  int index = *itindex;
1441  if (index == -1)
1442  isvisible = true;
1443  else {
1444  if (l->hiddenface->isVisible((unsigned int)index))
1445  isvisible = true;
1446  }
1447  }
1448 
1449  // Si la ligne n'appartient a aucune face elle est tout le temps visible
1450  if (l->Lindex_polygon.empty())
1451  isvisible = true; // Not sure that this can occur
1452 
1453  if (isvisible) {
1454  l->setVisible(true);
1455  l->updateTracked();
1456  if (l->meline.size() == 0 && l->isTracked())
1457  l->initMovingEdge(I, _cMo);
1458  } else {
1459  l->setVisible(false);
1460  for (unsigned int a = 0; a < l->meline.size(); a++) {
1461  if (l->meline[a] != NULL)
1462  delete l->meline[a];
1463  if (a < l->nbFeature.size())
1464  l->nbFeature[a] = 0;
1465  }
1466  l->nbFeatureTotal = 0;
1467  l->meline.clear();
1468  l->nbFeature.clear();
1469  }
1470  }
1471 
1473  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1474  it != cylinders[scaleLevel].end(); ++it) {
1475  cy = *it;
1476 
1477  bool isvisible = false;
1478 
1479  int index = cy->index_polygon;
1480  if (index == -1)
1481  isvisible = true;
1482  else {
1483  if (cy->hiddenface->isVisible((unsigned int)index + 1) || cy->hiddenface->isVisible((unsigned int)index + 2) ||
1484  cy->hiddenface->isVisible((unsigned int)index + 3) || cy->hiddenface->isVisible((unsigned int)index + 4))
1485  isvisible = true;
1486  }
1487  // vpTRACE("cyl with index %d is visible: %d", index, isvisible);
1488 
1489  if (isvisible) {
1490  cy->setVisible(true);
1491  if (cy->meline1 == NULL || cy->meline2 == NULL) {
1492  if (cy->isTracked())
1493  cy->initMovingEdge(I, _cMo);
1494  }
1495  } else {
1496  cy->setVisible(false);
1497  if (cy->meline1 != NULL)
1498  delete cy->meline1;
1499  if (cy->meline2 != NULL)
1500  delete cy->meline2;
1501  cy->meline1 = NULL;
1502  cy->meline2 = NULL;
1503  cy->nbFeature = 0;
1504  cy->nbFeaturel1 = 0;
1505  cy->nbFeaturel2 = 0;
1506  }
1507  }
1508 
1509  vpMbtDistanceCircle *ci;
1510  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1511  it != circles[scaleLevel].end(); ++it) {
1512  ci = *it;
1513  bool isvisible = false;
1514 
1515  int index = ci->index_polygon;
1516  if (index == -1)
1517  isvisible = true;
1518  else {
1519  if (ci->hiddenface->isVisible((unsigned int)index))
1520  isvisible = true;
1521  }
1522 
1523  if (isvisible) {
1524  ci->setVisible(true);
1525  if (ci->meEllipse == NULL) {
1526  if (ci->isTracked())
1527  ci->initMovingEdge(I, _cMo);
1528  }
1529  } else {
1530  ci->setVisible(false);
1531  if (ci->meEllipse != NULL)
1532  delete ci->meEllipse;
1533  ci->meEllipse = NULL;
1534  ci->nbFeature = 0;
1535  }
1536  }
1537 }
1538 
1545 {
1546  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1547  ++it) {
1548  vpMbtDistanceLine *l = *it;
1549  if (l->isVisible() && l->isTracked()) {
1550  if (l->meline.size() == 0) {
1551  l->initMovingEdge(I, cMo);
1552  }
1553  l->trackMovingEdge(I, cMo);
1554  }
1555  }
1556 
1557  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1558  it != cylinders[scaleLevel].end(); ++it) {
1559  vpMbtDistanceCylinder *cy = *it;
1560  if (cy->isVisible() && cy->isTracked()) {
1561  if (cy->meline1 == NULL || cy->meline2 == NULL) {
1562  cy->initMovingEdge(I, cMo);
1563  }
1564  cy->trackMovingEdge(I, cMo);
1565  }
1566  }
1567 
1568  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1569  it != circles[scaleLevel].end(); ++it) {
1570  vpMbtDistanceCircle *ci = *it;
1571  if (ci->isVisible() && ci->isTracked()) {
1572  if (ci->meEllipse == NULL) {
1573  ci->initMovingEdge(I, cMo);
1574  }
1575  ci->trackMovingEdge(I, cMo);
1576  }
1577  }
1578 }
1579 
1586 {
1587  vpMbtDistanceLine *l;
1588  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1589  ++it) {
1590  if ((*it)->isTracked()) {
1591  l = *it;
1592  l->updateMovingEdge(I, cMo);
1593  if (l->nbFeatureTotal == 0 && l->isVisible()) {
1594  l->Reinit = true;
1595  }
1596  }
1597  }
1598 
1600  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1601  it != cylinders[scaleLevel].end(); ++it) {
1602  if ((*it)->isTracked()) {
1603  cy = *it;
1604  cy->updateMovingEdge(I, cMo);
1605  if ((cy->nbFeaturel1 == 0 || cy->nbFeaturel2 == 0) && cy->isVisible()) {
1606  cy->Reinit = true;
1607  }
1608  }
1609  }
1610 
1611  vpMbtDistanceCircle *ci;
1612  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1613  it != circles[scaleLevel].end(); ++it) {
1614  if ((*it)->isTracked()) {
1615  ci = *it;
1616  ci->updateMovingEdge(I, cMo);
1617  if (ci->nbFeature == 0 && ci->isVisible()) {
1618  ci->Reinit = true;
1619  }
1620  }
1621  }
1622 }
1623 
1625 {
1626  unsigned int n = 0;
1627 
1628  vpMbtDistanceLine *l;
1629  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1630  ++it) {
1631  if ((*it)->isTracked()) {
1632  l = *it;
1633  unsigned int indexLine = 0;
1634  double wmean = 0;
1635  for (unsigned int a = 0; a < l->meline.size(); a++) {
1636  if (l->nbFeature[a] > 0) {
1637  std::list<vpMeSite>::iterator itListLine;
1638  itListLine = l->meline[a]->getMeList().begin();
1639 
1640  for (unsigned int i = 0; i < l->nbFeature[a]; i++) {
1641  wmean += m_w_edge[n + indexLine];
1642  vpMeSite p = *itListLine;
1643  if (m_w_edge[n + indexLine] < 0.5) {
1645 
1646  *itListLine = p;
1647  }
1648 
1649  ++itListLine;
1650  indexLine++;
1651  }
1652  }
1653  }
1654  n += l->nbFeatureTotal;
1655 
1656  if (l->nbFeatureTotal != 0)
1657  wmean /= l->nbFeatureTotal;
1658  else
1659  wmean = 1;
1660 
1661  l->setMeanWeight(wmean);
1662 
1663  if (wmean < 0.8)
1664  l->Reinit = true;
1665  }
1666  }
1667 
1668  // Same thing with cylinders as with lines
1670  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1671  it != cylinders[scaleLevel].end(); ++it) {
1672  if ((*it)->isTracked()) {
1673  cy = *it;
1674  double wmean = 0;
1675  std::list<vpMeSite>::iterator itListCyl1;
1676  std::list<vpMeSite>::iterator itListCyl2;
1677 
1678  if (cy->nbFeature > 0) {
1679  itListCyl1 = cy->meline1->getMeList().begin();
1680  itListCyl2 = cy->meline2->getMeList().begin();
1681 
1682  for (unsigned int i = 0; i < cy->nbFeaturel1; i++) {
1683  wmean += m_w_edge[n + i];
1684  vpMeSite p = *itListCyl1;
1685  if (m_w_edge[n + i] < 0.5) {
1687 
1688  *itListCyl1 = p;
1689  }
1690 
1691  ++itListCyl1;
1692  }
1693  }
1694 
1695  if (cy->nbFeaturel1 != 0)
1696  wmean /= cy->nbFeaturel1;
1697  else
1698  wmean = 1;
1699 
1700  cy->setMeanWeight1(wmean);
1701 
1702  if (wmean < 0.8) {
1703  cy->Reinit = true;
1704  }
1705 
1706  wmean = 0;
1707  for (unsigned int i = cy->nbFeaturel1; i < cy->nbFeature; i++) {
1708  wmean += m_w_edge[n + i];
1709  vpMeSite p = *itListCyl2;
1710  if (m_w_edge[n + i] < 0.5) {
1712 
1713  *itListCyl2 = p;
1714  }
1715 
1716  ++itListCyl2;
1717  }
1718 
1719  if (cy->nbFeaturel2 != 0)
1720  wmean /= cy->nbFeaturel2;
1721  else
1722  wmean = 1;
1723 
1724  cy->setMeanWeight2(wmean);
1725 
1726  if (wmean < 0.8) {
1727  cy->Reinit = true;
1728  }
1729 
1730  n += cy->nbFeature;
1731  }
1732  }
1733 
1734  // Same thing with circles as with lines
1735  vpMbtDistanceCircle *ci;
1736  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1737  it != circles[scaleLevel].end(); ++it) {
1738  if ((*it)->isTracked()) {
1739  ci = *it;
1740  double wmean = 0;
1741  std::list<vpMeSite>::iterator itListCir;
1742 
1743  if (ci->nbFeature > 0) {
1744  itListCir = ci->meEllipse->getMeList().begin();
1745  }
1746 
1747  wmean = 0;
1748  for (unsigned int i = 0; i < ci->nbFeature; i++) {
1749  wmean += m_w_edge[n + i];
1750  vpMeSite p = *itListCir;
1751  if (m_w_edge[n + i] < 0.5) {
1753 
1754  *itListCir = p;
1755  }
1756 
1757  ++itListCir;
1758  }
1759 
1760  if (ci->nbFeature != 0)
1761  wmean /= ci->nbFeature;
1762  else
1763  wmean = 1;
1764 
1765  ci->setMeanWeight(wmean);
1766 
1767  if (wmean < 0.8) {
1768  ci->Reinit = true;
1769  }
1770 
1771  n += ci->nbFeature;
1772  }
1773  }
1774 }
1775 
1786 {
1787  vpMbtDistanceLine *l;
1788  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
1789  ++it) {
1790  if ((*it)->isTracked()) {
1791  l = *it;
1792  if (l->Reinit && l->isVisible())
1793  l->reinitMovingEdge(I, _cMo);
1794  }
1795  }
1796 
1798  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
1799  it != cylinders[scaleLevel].end(); ++it) {
1800  if ((*it)->isTracked()) {
1801  cy = *it;
1802  if (cy->Reinit && cy->isVisible())
1803  cy->reinitMovingEdge(I, _cMo);
1804  }
1805  }
1806 
1807  vpMbtDistanceCircle *ci;
1808  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
1809  it != circles[scaleLevel].end(); ++it) {
1810  if ((*it)->isTracked()) {
1811  ci = *it;
1812  if (ci->Reinit && ci->isVisible())
1813  ci->reinitMovingEdge(I, _cMo);
1814  }
1815  }
1816 }
1817 
1819 {
1820  for (unsigned int i = 0; i < scales.size(); i += 1) {
1821  if (scales[i]) {
1822  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
1823  for (unsigned int a = 0; a < (*it)->meline.size(); a++) {
1824  if ((*it)->meline[a] != NULL) {
1825  delete (*it)->meline[a];
1826  (*it)->meline[a] = NULL;
1827  }
1828  (*it)->meline.clear();
1829  (*it)->nbFeature.clear();
1830  (*it)->nbFeatureTotal = 0;
1831  }
1832  }
1833 
1834  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
1835  ++it) {
1836  if ((*it)->meline1 != NULL) {
1837  delete (*it)->meline1;
1838  (*it)->meline1 = NULL;
1839  }
1840  if ((*it)->meline2 != NULL) {
1841  delete (*it)->meline2;
1842  (*it)->meline2 = NULL;
1843  }
1844 
1845  (*it)->nbFeature = 0;
1846  (*it)->nbFeaturel1 = 0;
1847  (*it)->nbFeaturel2 = 0;
1848  }
1849 
1850  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
1851  if ((*it)->meEllipse != NULL) {
1852  delete (*it)->meEllipse;
1853  (*it)->meEllipse = NULL;
1854  }
1855  (*it)->nbFeature = 0;
1856  }
1857  }
1858  }
1859 }
1860 
1870 bool vpMbEdgeTracker::samePoint(const vpPoint &P1, const vpPoint &P2) const
1871 {
1872  double dx = fabs(P1.get_oX() - P2.get_oX());
1873  double dy = fabs(P1.get_oY() - P2.get_oY());
1874  double dz = fabs(P1.get_oZ() - P2.get_oZ());
1875 
1876  if (dx <= std::numeric_limits<double>::epsilon() && dy <= std::numeric_limits<double>::epsilon() &&
1877  dz <= std::numeric_limits<double>::epsilon())
1878  return true;
1879  else
1880  return false;
1881 }
1882 
1895 void vpMbEdgeTracker::addLine(vpPoint &P1, vpPoint &P2, int polygon, std::string name)
1896 {
1897  // suppress line already in the model
1898  bool already_here = false;
1899  vpMbtDistanceLine *l;
1900 
1901  for (unsigned int i = 0; i < scales.size(); i += 1) {
1902  if (scales[i]) {
1903  downScale(i);
1904  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
1905  l = *it;
1906  if ((samePoint(*(l->p1), P1) && samePoint(*(l->p2), P2)) ||
1907  (samePoint(*(l->p1), P2) && samePoint(*(l->p2), P1))) {
1908  already_here = true;
1909  l->addPolygon(polygon);
1910  l->hiddenface = &faces;
1911  }
1912  }
1913 
1914  if (!already_here) {
1915  l = new vpMbtDistanceLine;
1916 
1918  l->buildFrom(P1, P2);
1919  l->addPolygon(polygon);
1920  l->setMovingEdge(&me);
1921  l->hiddenface = &faces;
1922  l->useScanLine = useScanLine;
1923 
1924  l->setIndex(nline);
1925  l->setName(name);
1926 
1929 
1930  if ((clippingFlag & vpPolygon3D::NEAR_CLIPPING) == vpPolygon3D::NEAR_CLIPPING)
1932 
1933  if ((clippingFlag & vpPolygon3D::FAR_CLIPPING) == vpPolygon3D::FAR_CLIPPING)
1935 
1936  nline += 1;
1937  lines[i].push_back(l);
1938  }
1939  upScale(i);
1940  }
1941  }
1942 }
1943 
1949 void vpMbEdgeTracker::removeLine(const std::string &name)
1950 {
1951  vpMbtDistanceLine *l;
1952 
1953  for (unsigned int i = 0; i < scales.size(); i++) {
1954  if (scales[i]) {
1955  for (std::list<vpMbtDistanceLine *>::iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
1956  l = *it;
1957  if (name.compare(l->getName()) == 0) {
1958  lines[i].erase(it);
1959  break;
1960  }
1961  }
1962  }
1963  }
1964 }
1965 
1976 void vpMbEdgeTracker::addCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, const double r, int idFace,
1977  const std::string &name)
1978 {
1979  bool already_here = false;
1980  vpMbtDistanceCircle *ci;
1981 
1982  for (unsigned int i = 0; i < scales.size(); i += 1) {
1983  if (scales[i]) {
1984  downScale(i);
1985  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
1986  ci = *it;
1987  if ((samePoint(*(ci->p1), P1) && samePoint(*(ci->p2), P2) && samePoint(*(ci->p3), P3)) ||
1988  (samePoint(*(ci->p1), P1) && samePoint(*(ci->p2), P3) && samePoint(*(ci->p3), P2))) {
1989  already_here =
1990  (std::fabs(ci->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(ci->radius, r));
1991  }
1992  }
1993 
1994  if (!already_here) {
1995  ci = new vpMbtDistanceCircle;
1996 
1997  ci->setCameraParameters(cam);
1998  ci->buildFrom(P1, P2, P3, r);
1999  ci->setMovingEdge(&me);
2000  ci->setIndex(ncircle);
2001  ci->setName(name);
2002  ci->index_polygon = idFace;
2003  ci->hiddenface = &faces;
2004 
2005  // if(clippingFlag != vpPolygon3D::NO_CLIPPING)
2006  // ci->getPolygon().setClipping(clippingFlag);
2007 
2008  // if((clippingFlag & vpPolygon3D::NEAR_CLIPPING) ==
2009  // vpPolygon3D::NEAR_CLIPPING)
2010  // ci->getPolygon().setNearClippingDistance(distNearClip);
2011 
2012  // if((clippingFlag & vpPolygon3D::FAR_CLIPPING) ==
2013  // vpPolygon3D::FAR_CLIPPING)
2014  // ci->getPolygon().setFarClippingDistance(distFarClip);
2015 
2016  ncircle += 1;
2017  circles[i].push_back(ci);
2018  }
2019  upScale(i);
2020  }
2021  }
2022 }
2023 
2033 void vpMbEdgeTracker::addCylinder(const vpPoint &P1, const vpPoint &P2, const double r, int idFace,
2034  const std::string &name)
2035 {
2036  bool already_here = false;
2038 
2039  for (unsigned int i = 0; i < scales.size(); i += 1) {
2040  if (scales[i]) {
2041  downScale(i);
2042  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2043  ++it) {
2044  cy = *it;
2045  if ((samePoint(*(cy->p1), P1) && samePoint(*(cy->p2), P2)) ||
2046  (samePoint(*(cy->p1), P2) && samePoint(*(cy->p2), P1))) {
2047  already_here =
2048  (std::fabs(cy->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(cy->radius, r));
2049  }
2050  }
2051 
2052  if (!already_here) {
2053  cy = new vpMbtDistanceCylinder;
2054 
2055  cy->setCameraParameters(cam);
2056  cy->buildFrom(P1, P2, r);
2057  cy->setMovingEdge(&me);
2058  cy->setIndex(ncylinder);
2059  cy->setName(name);
2060  cy->index_polygon = idFace;
2061  cy->hiddenface = &faces;
2062  ncylinder += 1;
2063  cylinders[i].push_back(cy);
2064  }
2065  upScale(i);
2066  }
2067  }
2068 }
2069 
2075 void vpMbEdgeTracker::removeCylinder(const std::string &name)
2076 {
2078 
2079  for (unsigned int i = 0; i < scales.size(); i++) {
2080  if (scales[i]) {
2081  for (std::list<vpMbtDistanceCylinder *>::iterator it = cylinders[i].begin(); it != cylinders[i].end(); ++it) {
2082  cy = *it;
2083  if (name.compare(cy->getName()) == 0) {
2084  cylinders[i].erase(it);
2085  break;
2086  }
2087  }
2088  }
2089  }
2090 }
2091 
2097 void vpMbEdgeTracker::removeCircle(const std::string &name)
2098 {
2099  vpMbtDistanceCircle *ci;
2100 
2101  for (unsigned int i = 0; i < scales.size(); i++) {
2102  if (scales[i]) {
2103  for (std::list<vpMbtDistanceCircle *>::iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2104  ci = *it;
2105  if (name.compare(ci->getName()) == 0) {
2106  circles[i].erase(it);
2107  break;
2108  }
2109  }
2110  }
2111  }
2112 }
2113 
2120 {
2121  unsigned int nbpt = p.getNbPoint();
2122  if (nbpt > 0) {
2123  for (unsigned int i = 0; i < nbpt - 1; i++)
2124  addLine(p.p[i], p.p[i + 1], p.getIndex());
2125  addLine(p.p[nbpt - 1], p.p[0], p.getIndex());
2126  }
2127 }
2128 
2141  bool &newvisibleline)
2142 {
2143  unsigned int n;
2144  bool changed = false;
2145 
2146  if (!useOgre) {
2147  // n = faces.setVisible(_I, cam, _cMo, vpMath::rad(89), vpMath::rad(89),
2148  // changed);
2149  n = faces.setVisible(_I, cam, _cMo, angleAppears, angleDisappears, changed);
2150  } else {
2151 #ifdef VISP_HAVE_OGRE
2152  n = faces.setVisibleOgre(_I, cam, _cMo, angleAppears, angleDisappears, changed);
2153 #else
2154  n = faces.setVisible(_I, cam, _cMo, angleAppears, angleDisappears, changed);
2155 #endif
2156  }
2157 
2158  if (n > nbvisiblepolygone) {
2159  // cout << "une nouvelle face est visible " << endl;
2160  newvisibleline = true;
2161  } else
2162  newvisibleline = false;
2163 
2164  nbvisiblepolygone = n;
2165 }
2166 
2183 {
2184  unsigned int nbpt = polygon.getNbPoint();
2185  if (nbpt > 0) {
2186  for (unsigned int i = 0; i < nbpt - 1; i++)
2187  vpMbEdgeTracker::addLine(polygon.p[i], polygon.p[i + 1], polygon.getIndex(), polygon.getName());
2188  vpMbEdgeTracker::addLine(polygon.p[nbpt - 1], polygon.p[0], polygon.getIndex(), polygon.getName());
2189  }
2190 }
2207 {
2208  unsigned int nbpt = polygon.getNbPoint();
2209  if (nbpt > 0) {
2210  for (unsigned int i = 0; i < nbpt - 1; i++)
2211  vpMbEdgeTracker::addLine(polygon.p[i], polygon.p[i + 1], polygon.getIndex(), polygon.getName());
2212  }
2213 }
2214 
2215 unsigned int vpMbEdgeTracker::initMbtTracking(unsigned int &nberrors_lines, unsigned int &nberrors_cylinders,
2216  unsigned int &nberrors_circles)
2217 {
2218  unsigned int nbrow = 0;
2219  nberrors_lines = 0;
2220  nberrors_cylinders = 0;
2221  nberrors_circles = 0;
2222 
2223  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
2224  ++it) {
2225 
2226  vpMbtDistanceLine *l = *it;
2227 
2228  if (l->isTracked()) {
2230  nbrow += l->nbFeatureTotal;
2231  nberrors_lines += l->nbFeatureTotal;
2232  }
2233  }
2234 
2235  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
2236  it != cylinders[scaleLevel].end(); ++it) {
2237  vpMbtDistanceCylinder *cy = *it;
2238 
2239  if (cy->isTracked()) {
2241  nbrow += cy->nbFeature;
2242  nberrors_cylinders += cy->nbFeature;
2243  }
2244  }
2245 
2246  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
2247  it != circles[scaleLevel].end(); ++it) {
2248  vpMbtDistanceCircle *ci = *it;
2249 
2250  if (ci->isTracked()) {
2252  nbrow += ci->nbFeature;
2253  nberrors_circles += ci->nbFeature;
2254  }
2255  }
2256 
2257  return nbrow;
2258 }
2259 
2271 void vpMbEdgeTracker::initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, const double radius,
2272  const int idFace, const std::string &name)
2273 {
2274  addCircle(p1, p2, p3, radius, (int)idFace, name);
2275 }
2276 
2287 void vpMbEdgeTracker::initCylinder(const vpPoint &p1, const vpPoint &p2, const double radius, const int idFace,
2288  const std::string &name)
2289 {
2290  addCylinder(p1, p2, radius, (int)idFace, name);
2291 }
2292 
2299 {
2300  this->cMo.eye();
2301  vpMbtDistanceLine *l;
2303  vpMbtDistanceCircle *ci;
2304 
2305  for (unsigned int i = 0; i < scales.size(); i += 1) {
2306  if (scales[i]) {
2307  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2308  l = *it;
2309  if (l != NULL)
2310  delete l;
2311  l = NULL;
2312  }
2313 
2314  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2315  ++it) {
2316  cy = *it;
2317  if (cy != NULL)
2318  delete cy;
2319  cy = NULL;
2320  }
2321 
2322  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2323  ci = *it;
2324  if (ci != NULL)
2325  delete ci;
2326  ci = NULL;
2327  }
2328  lines[i].clear();
2329  cylinders[i].clear();
2330  circles[i].clear();
2331  }
2332  }
2333 
2334  faces.reset();
2335 
2336  useScanLine = false;
2337 
2338 #ifdef VISP_HAVE_OGRE
2339  useOgre = false;
2340 #endif
2341 
2342  m_computeInteraction = true;
2343  nline = 0;
2344  ncylinder = 0;
2345  m_lambda = 1.0;
2346  nbvisiblepolygone = 0;
2347  percentageGdPt = 0.4;
2348 
2349  angleAppears = vpMath::rad(89);
2352 
2354 
2355  // reinitialization of the scales.
2356  this->setScales(scales);
2357 }
2358 
2368 void vpMbEdgeTracker::reInitModel(const vpImage<unsigned char> &I, const std::string &cad_name,
2369  const vpHomogeneousMatrix &cMo_, const bool verbose)
2370 {
2371  reInitModel(I, cad_name.c_str(), cMo_, verbose);
2372 }
2373 
2383 void vpMbEdgeTracker::reInitModel(const vpImage<unsigned char> &I, const char *cad_name,
2384  const vpHomogeneousMatrix &cMo_, const bool verbose)
2385 {
2386  this->cMo.eye();
2387  vpMbtDistanceLine *l;
2389  vpMbtDistanceCircle *ci;
2390 
2391  for (unsigned int i = 0; i < scales.size(); i += 1) {
2392  if (scales[i]) {
2393  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2394  l = *it;
2395  if (l != NULL)
2396  delete l;
2397  l = NULL;
2398  }
2399 
2400  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2401  ++it) {
2402  cy = *it;
2403  if (cy != NULL)
2404  delete cy;
2405  cy = NULL;
2406  }
2407 
2408  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2409  ci = *it;
2410  if (ci != NULL)
2411  delete ci;
2412  ci = NULL;
2413  }
2414 
2415  lines[i].clear();
2416  cylinders[i].clear();
2417  circles[i].clear();
2418  }
2419  }
2420 
2421  faces.reset();
2422 
2423  // compute_interaction=1;
2424  nline = 0;
2425  ncylinder = 0;
2426  ncircle = 0;
2427  // lambda = 1;
2428  nbvisiblepolygone = 0;
2429 
2430  loadModel(cad_name, verbose);
2431  initFromPose(I, cMo_);
2432 }
2433 
2444 unsigned int vpMbEdgeTracker::getNbPoints(const unsigned int level) const
2445 {
2446  if ((level > scales.size()) || !scales[level]) {
2447  throw vpException(vpException::dimensionError, "Cannot get the number of points for level %d: level is not used",
2448  level);
2449  }
2450 
2451  unsigned int nbGoodPoints = 0;
2452  vpMbtDistanceLine *l;
2453  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[level].begin(); it != lines[level].end(); ++it) {
2454  l = *it;
2455  if (l->isVisible() && l->isTracked()) {
2456  for (unsigned int a = 0; a < l->meline.size(); a++) {
2457  if (l->nbFeature[a] != 0)
2458  for (std::list<vpMeSite>::const_iterator itme = l->meline[a]->getMeList().begin();
2459  itme != l->meline[a]->getMeList().end(); ++itme) {
2460  if (itme->getState() == vpMeSite::NO_SUPPRESSION)
2461  nbGoodPoints++;
2462  }
2463  }
2464  }
2465  }
2466 
2468  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[level].begin(); it != cylinders[level].end();
2469  ++it) {
2470  cy = *it;
2471  if (cy->isVisible() && cy->isTracked() && (cy->meline1 != NULL || cy->meline2 != NULL)) {
2472  for (std::list<vpMeSite>::const_iterator itme1 = cy->meline1->getMeList().begin();
2473  itme1 != cy->meline1->getMeList().end(); ++itme1) {
2474  if (itme1->getState() == vpMeSite::NO_SUPPRESSION)
2475  nbGoodPoints++;
2476  }
2477  for (std::list<vpMeSite>::const_iterator itme2 = cy->meline2->getMeList().begin();
2478  itme2 != cy->meline2->getMeList().end(); ++itme2) {
2479  if (itme2->getState() == vpMeSite::NO_SUPPRESSION)
2480  nbGoodPoints++;
2481  }
2482  }
2483  }
2484 
2485  vpMbtDistanceCircle *ci;
2486  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[level].begin(); it != circles[level].end(); ++it) {
2487  ci = *it;
2488  if (ci->isVisible() && ci->isTracked() && ci->meEllipse != NULL) {
2489  for (std::list<vpMeSite>::const_iterator itme = ci->meEllipse->getMeList().begin();
2490  itme != ci->meEllipse->getMeList().end(); ++itme) {
2491  if (itme->getState() == vpMeSite::NO_SUPPRESSION)
2492  nbGoodPoints++;
2493  }
2494  }
2495  }
2496 
2497  return nbGoodPoints;
2498 }
2499 
2521 void vpMbEdgeTracker::setScales(const std::vector<bool> &scale)
2522 {
2523  unsigned int nbActivatedLevels = 0;
2524  for (unsigned int i = 0; i < scale.size(); i++) {
2525  if (scale[i]) {
2526  nbActivatedLevels++;
2527  }
2528  }
2529 
2530  if (scale.empty() || (nbActivatedLevels == 0)) {
2531  vpERROR_TRACE(" !! WARNING : must use at least one level for the "
2532  "tracking. Use the global one");
2533  this->scales.resize(0);
2534  this->scales.push_back(true);
2535 
2536  lines.resize(1);
2537  lines[0].clear();
2538 
2539  cylinders.resize(1);
2540  cylinders[0].clear();
2541 
2542  circles.resize(1);
2543  circles[0].clear();
2544  } else {
2545  this->scales = scale;
2546 
2547  lines.resize(scale.size());
2548  cylinders.resize(scale.size());
2549  circles.resize(scale.size());
2550 
2551  for (unsigned int i = 0; i < lines.size(); i++) {
2552  lines[i].clear();
2553  cylinders[i].clear();
2554  circles[i].clear();
2555  }
2556  }
2557 }
2558 
2565 {
2566  if ((clippingFlag & vpPolygon3D::NEAR_CLIPPING) == vpPolygon3D::NEAR_CLIPPING && dist <= distNearClip)
2567  std::cerr << "Far clipping value cannot be inferior than near clipping "
2568  "value. Far clipping won't be considered."
2569  << std::endl;
2570  else if (dist < 0)
2571  std::cerr << "Far clipping value cannot be inferior than 0. Far clipping "
2572  "won't be considered."
2573  << std::endl;
2574  else {
2576  vpMbtDistanceLine *l;
2577 
2578  for (unsigned int i = 0; i < scales.size(); i += 1) {
2579  if (scales[i]) {
2580  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2581  l = *it;
2583  }
2584  }
2585  }
2586  }
2587 }
2588 
2595 {
2596  if ((clippingFlag & vpPolygon3D::FAR_CLIPPING) == vpPolygon3D::FAR_CLIPPING && dist >= distFarClip)
2597  std::cerr << "Near clipping value cannot be superior than far clipping "
2598  "value. Near clipping won't be considered."
2599  << std::endl;
2600  else if (dist < 0)
2601  std::cerr << "Near clipping value cannot be inferior than 0. Near "
2602  "clipping won't be considered."
2603  << std::endl;
2604  else {
2606  vpMbtDistanceLine *l;
2607 
2608  for (unsigned int i = 0; i < scales.size(); i += 1) {
2609  if (scales[i]) {
2610  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2611  l = *it;
2613  }
2614  }
2615  }
2616  }
2617 }
2618 
2626 void vpMbEdgeTracker::setClipping(const unsigned int &flags)
2627 {
2628  vpMbTracker::setClipping(flags);
2629 
2630  vpMbtDistanceLine *l;
2631 
2632  for (unsigned int i = 0; i < scales.size(); i += 1) {
2633  if (scales[i]) {
2634  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2635  l = *it;
2637  }
2638  }
2639  }
2640 }
2641 
2658  std::vector<const vpImage<unsigned char> *> &_pyramid)
2659 {
2660  _pyramid.resize(scales.size());
2661 
2662  if (scales[0]) {
2663  _pyramid[0] = &_I;
2664  } else {
2665  _pyramid[0] = NULL;
2666  }
2667 
2668  for (unsigned int i = 1; i < _pyramid.size(); i += 1) {
2669  if (scales[i]) {
2670  unsigned int cScale = static_cast<unsigned int>(pow(2., (int)i));
2671  vpImage<unsigned char> *I = new vpImage<unsigned char>(_I.getHeight() / cScale, _I.getWidth() / cScale);
2672 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x020408))
2673  IplImage *vpI0 = cvCreateImageHeader(cvSize((int)_I.getWidth(), (int)_I.getHeight()), IPL_DEPTH_8U, 1);
2674  vpI0->imageData = (char *)(_I.bitmap);
2675  IplImage *vpI =
2676  cvCreateImage(cvSize((int)(_I.getWidth() / cScale), (int)(_I.getHeight() / cScale)), IPL_DEPTH_8U, 1);
2677  cvResize(vpI0, vpI, CV_INTER_NN);
2678  vpImageConvert::convert(vpI, *I);
2679  cvReleaseImage(&vpI);
2680  vpI0->imageData = NULL;
2681  cvReleaseImageHeader(&vpI0);
2682 #else
2683  for (unsigned int k = 0, ii = 0; k < I->getHeight(); k += 1, ii += cScale) {
2684  for (unsigned int l = 0, jj = 0; l < I->getWidth(); l += 1, jj += cScale) {
2685  (*I)[k][l] = _I[ii][jj];
2686  }
2687  }
2688 #endif
2689  _pyramid[i] = I;
2690  } else {
2691  _pyramid[i] = NULL;
2692  }
2693  }
2694 }
2695 
2702 void vpMbEdgeTracker::cleanPyramid(std::vector<const vpImage<unsigned char> *> &_pyramid)
2703 {
2704  if (_pyramid.size() > 0) {
2705  _pyramid[0] = NULL;
2706  for (unsigned int i = 1; i < _pyramid.size(); i += 1) {
2707  if (_pyramid[i] != NULL) {
2708  delete _pyramid[i];
2709  _pyramid[i] = NULL;
2710  }
2711  }
2712  _pyramid.resize(0);
2713  }
2714 }
2715 
2726 void vpMbEdgeTracker::getLline(std::list<vpMbtDistanceLine *> &linesList, const unsigned int level) const
2727 {
2728  if (level > scales.size() || !scales[level]) {
2729  std::ostringstream oss;
2730  oss << level;
2731  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2732  throw vpException(vpException::dimensionError, errorMsg);
2733  }
2734 
2735  linesList = lines[level];
2736 }
2737 
2748 void vpMbEdgeTracker::getLcylinder(std::list<vpMbtDistanceCylinder *> &cylindersList, const unsigned int level) const
2749 {
2750  if (level > scales.size() || !scales[level]) {
2751  std::ostringstream oss;
2752  oss << level;
2753  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2754  throw vpException(vpException::dimensionError, errorMsg);
2755  }
2756 
2757  cylindersList = cylinders[level];
2758 }
2759 
2770 void vpMbEdgeTracker::getLcircle(std::list<vpMbtDistanceCircle *> &circlesList, const unsigned int level) const
2771 {
2772  if (level > scales.size() || !scales[level]) {
2773  std::ostringstream oss;
2774  oss << level;
2775  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2776  throw vpException(vpException::dimensionError, errorMsg);
2777  }
2778 
2779  circlesList = circles[level];
2780 }
2781 
2788 void vpMbEdgeTracker::downScale(const unsigned int _scale)
2789 {
2790  const double ratio = pow(2., (int)_scale);
2791  scaleLevel = _scale;
2792 
2793  vpMatrix K = cam.get_K();
2794 
2795  K[0][0] /= ratio;
2796  K[1][1] /= ratio;
2797  K[0][2] /= ratio;
2798  K[1][2] /= ratio;
2799 
2801 }
2802 
2809 void vpMbEdgeTracker::upScale(const unsigned int _scale)
2810 {
2811  const double ratio = pow(2., (int)_scale);
2812  scaleLevel = 0;
2813 
2814  vpMatrix K = cam.get_K();
2815 
2816  K[0][0] *= ratio;
2817  K[1][1] *= ratio;
2818  K[0][2] *= ratio;
2819  K[1][2] *= ratio;
2820 
2822 }
2823 
2831 void vpMbEdgeTracker::reInitLevel(const unsigned int _lvl)
2832 {
2833  unsigned int scaleLevel_1 = scaleLevel;
2834  scaleLevel = _lvl;
2835 
2836  vpMbtDistanceLine *l;
2837  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[scaleLevel].begin(); it != lines[scaleLevel].end();
2838  ++it) {
2839  if ((*it)->isTracked()) {
2840  l = *it;
2841  l->reinitMovingEdge(*Ipyramid[_lvl], cMo);
2842  }
2843  }
2844 
2846  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[scaleLevel].begin();
2847  it != cylinders[scaleLevel].end(); ++it) {
2848  if ((*it)->isTracked()) {
2849  cy = *it;
2850  cy->reinitMovingEdge(*Ipyramid[_lvl], cMo);
2851  }
2852  }
2853 
2854  vpMbtDistanceCircle *ci;
2855  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[scaleLevel].begin();
2856  it != circles[scaleLevel].end(); ++it) {
2857  if ((*it)->isTracked()) {
2858  ci = *it;
2859  ci->reinitMovingEdge(*Ipyramid[_lvl], cMo);
2860  }
2861  }
2862 
2863  trackMovingEdge(*Ipyramid[_lvl]);
2864  updateMovingEdge(*Ipyramid[_lvl]);
2865  scaleLevel = scaleLevel_1;
2866 }
2867 
2875 void vpMbEdgeTracker::setUseEdgeTracking(const std::string &name, const bool &useEdgeTracking)
2876 {
2877  for (unsigned int i = 0; i < scales.size(); i += 1) {
2878  if (scales[i]) {
2879  for (std::list<vpMbtDistanceLine *>::const_iterator it = lines[i].begin(); it != lines[i].end(); ++it) {
2880  /*(*it)->setTracked(useEdgeTracking);
2881  for(std::list<int>::const_iterator
2882  itpoly=(*it)->Lindex_polygon.begin();
2883  itpoly!=(*it)->Lindex_polygon.end(); ++itpoly){
2884  if(faces[(*itpoly)]->getName() != name){
2885  (*it)->setTracked(true);
2886  break;
2887  }
2888  }*/
2889 
2890  (*it)->setTracked(name, useEdgeTracking);
2891  }
2892 
2893  for (std::list<vpMbtDistanceCylinder *>::const_iterator it = cylinders[i].begin(); it != cylinders[i].end();
2894  ++it) {
2895  if (faces[(unsigned)(*it)->index_polygon]->getName() == name) {
2896  (*it)->setTracked(useEdgeTracking);
2897  }
2898  }
2899 
2900  for (std::list<vpMbtDistanceCircle *>::const_iterator it = circles[i].begin(); it != circles[i].end(); ++it) {
2901  if (faces[(unsigned)(*it)->index_polygon]->getName() == name) {
2902  (*it)->setTracked(useEdgeTracking);
2903  }
2904  }
2905  }
2906  }
2907 }
bool m_computeInteraction
Definition: vpMbTracker.h:187
void setWindowName(const Ogre::String &n)
Definition: vpAROgre.h:269
bool computeProjError
Definition: vpMbTracker.h:135
unsigned int ncylinder
std::string getName() const
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
void displayMovingEdges(const vpImage< unsigned char > &I)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Definition: vpMatrix.cpp:1931
vpMatrix covarianceMatrix
Covariance matrix.
Definition: vpMbTracker.h:132
void initFromCalibrationMatrix(const vpMatrix &_K)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void setMovingEdge(const vpMe &me)
bool getFovClipping() const
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.cpp:422
vpMeSiteState getState() const
Definition: vpMeSite.h:188
unsigned int nbFeature
The number of moving edges.
unsigned int nbFeatureTotal
The number of moving edges.
void setVisible(bool _isvisible)
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void setCameraParameters(const vpCameraParameters &camera)
vpColVector m_error_edge
(s - s*)
void upScale(const unsigned int _scale)
virtual void initFaceFromCorners(vpMbtPolygon &polygon)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpColVector m_weightedError_edge
Weighted error.
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Compute the weights according a residue vector and a PsiFunction.
Definition: vpRobust.cpp:176
int getIndex() const
Definition: vpMbtPolygon.h:101
vpPoint * p3
An other point on the plane containing the circle.
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
void addLine(vpPoint &p1, vpPoint &p2, int polygon=-1, std::string name="")
bool isAppearing(const unsigned int i)
double getAngleAppear() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
std::string getName() const
vpMbHiddenFaces< vpMbtPolygon > faces
Set of faces describing the object.
Definition: vpMbTracker.h:145
bool Reinit
Indicates if the line has to be reinitialized.
void setMeanWeight2(const double wmean)
Implementation of an homogeneous matrix and operations on such kind of matrices.
void init(const vpImage< unsigned char > &I)
void track(const vpImage< unsigned char > &I)
std::string getName() const
Definition: vpMbtPolygon.h:108
std::vector< std::list< vpMbtDistanceCylinder * > > cylinders
Vector of the tracked cylinders.
unsigned int scaleLevel
std::list< int > Lindex_polygon
Index of the faces which contain the line.
Type * bitmap
points toward the bitmap
Definition: vpImage.h:133
vpMatrix L
The interaction matrix.
bool isTracked() const
void setFarClippingDistance(const double &dist)
Definition: vpPolygon3D.h:194
void setCameraParameters(const vpCameraParameters &camera)
vpMatrix AtA() const
Definition: vpMatrix.cpp:524
Performs search in a given direction(normal) for a given distance(pixels) for a given &#39;site&#39;...
Definition: vpMeSite.h:71
void getMe(vpMe &_ecm) const
#define vpERROR_TRACE
Definition: vpDebug.h:393
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true, const bool recopy_=true)
Definition: vpArray2D.h:171
Class to define colors available for display functionnalities.
Definition: vpColor.h:120
Parse an Xml file to extract configuration parameters of a mbtConfig object.Data parser for the model...
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpColVector m_factor
Edge VVS variables.
void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w)
vpHomogeneousMatrix cMo
The current pose.
Definition: vpMbTracker.h:115
vpPoint * p1
The first extremity.
void displayMovingEdges(const vpImage< unsigned char > &I)
void setOgreShowConfigDialog(const bool showConfigDialog)
virtual ~vpMbEdgeTracker()
unsigned int ncircle
std::vector< const vpImage< unsigned char > * > Ipyramid
vpColVector error
The error vector.
virtual unsigned int getNbPoints(const unsigned int level=0) const
bool modelInitialised
Definition: vpMbTracker.h:125
vpColVector m_w_edge
Robust weights.
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const vpPoint &_p3, const double r)
vpColVector m_wCircles
error that can be emited by ViSP classes.
Definition: vpException.h:71
vpMbtMeEllipse * meEllipse
The moving edge containers.
Manage a cylinder used in the model-based tracker.
void reInitLevel(const unsigned int _lvl)
vpPoint * p
corners in the object frame
Definition: vpPolygon3D.h:81
unsigned int getRows() const
Definition: vpArray2D.h:156
Definition: vpMe.h:60
vpHomogeneousMatrix inverse() const
Manage the line of a polygon used in the model-based tracker.
unsigned int nbFeature
The number of moving edges.
void getCameraParameters(vpCameraParameters &_cam) const
virtual void setPose(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cdMo)
void removeCircle(const std::string &name)
bool useOgre
Use Ogre3d for visibility tests.
Definition: vpMbTracker.h:157
int index_polygon
Index of the faces which contain the line.
vpPoint * p2
A point on the plane containing the circle.
bool hasNearClippingDistance() const
void setIndex(const unsigned int i)
virtual void setCameraParameters(const vpCameraParameters &camera)
vpMatrix get_K() const
void displayFeaturesOnImage(const vpImage< unsigned char > &I, const unsigned int lvl)
void computeVVSFirstPhasePoseEstimation(const unsigned int iter, bool &isoJoIdentity_)
bool getLodState() const
void computeVVS(const vpImage< unsigned char > &_I, const unsigned int lvl)
virtual void initFromPose(const vpImage< unsigned char > &I, const std::string &initFile)
unsigned int setVisibleOgre(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
void removeCylinder(const std::string &name)
vpMbtPolygon & getPolygon()
bool computeCovariance
Flag used to specify if the covariance matrix has to be computed or not.
Definition: vpMbTracker.h:130
void loadConfigFile(const std::string &configFile)
vpMe me
The moving edges parameters.
void updateMovingEdge(const vpImage< unsigned char > &I)
vpPoint * p1
The first extremity on the axe.
double get_oX() const
Get the point X coordinate in the object frame.
Definition: vpPoint.cpp:420
void downScale(const unsigned int _scale)
Class that defines what is a point.
Definition: vpPoint.h:58
vpMatrix L
The interaction matrix.
vpCameraParameters cam
The camera parameters.
Definition: vpMbTracker.h:113
virtual void computeVVSWeights()
void computeClippedPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
unsigned int setVisible(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed)
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
double getAngleDisappear() const
virtual void setNearClippingDistance(const double &dist)
void initOgre(const vpCameraParameters &cam=vpCameraParameters())
unsigned int nbFeaturel1
The number of moving edges on line 1.
double distFarClip
Distance for near clipping.
Definition: vpMbTracker.h:153
double projectionError
Definition: vpMbTracker.h:138
vpAROgre * getOgreContext()
int index_polygon
Index of the face which contains the cylinder.
virtual void reInitModel(const vpImage< unsigned char > &I, const std::string &cad_name, const vpHomogeneousMatrix &cMo_, const bool verbose=false)
virtual void setMinPolygonAreaThresh(const double minPolygonAreaThresh, const std::string &name="")
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
Manage a circle used in the model-based tracker.
vpMatrix oJo
The Degrees of Freedom to estimate.
Definition: vpMbTracker.h:117
std::vector< bool > scales
Vector of scale level to use for the multi-scale tracking.
bool Reinit
Indicates if the circle has to be reinitialized.
Error that can be emited by the vpTracker class and its derivates.
Implementation of a polygon of the model used by the model-based tracker.
Definition: vpMbtPolygon.h:66
double getNearClippingDistance() const
void initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
void setName(const std::string &circle_name)
vpPoint * p2
The second extremity.
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
bool useScanLine
Use Scanline for visibility tests.
Definition: vpMbTracker.h:160
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
#define vpTRACE
Definition: vpDebug.h:416
double getFarClippingDistance() const
static double sqr(double x)
Definition: vpMath.h:108
double minLineLengthThresholdGeneral
Minimum line length threshold for LOD mode (general setting)
Definition: vpMbTracker.h:179
void setAngleDisappear(const double &adisappear)
vpColVector error
The error vector.
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
unsigned int nbFeaturesForProjErrorComputation
Number of features used in the computation of the projection error.
Generic class defining intrinsic camera parameters.
void cleanPyramid(std::vector< const vpImage< unsigned char > *> &_pyramid)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
unsigned int initMbtTracking(unsigned int &nberrors_lines, unsigned int &nberrors_cylinders, unsigned int &nberrors_circles)
void setIndex(const unsigned int i)
std::string getName() const
unsigned int getNbPoint() const
Definition: vpPolygon3D.h:132
virtual void computeVVSInteractionMatrixAndResidu()
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.cpp:424
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
double m_initialMu
Initial Mu for Levenberg Marquardt optimization loop.
Definition: vpMbTracker.h:195
vpMbtMeLine * meline1
The moving edge containers (first line of the cylinder)
void setVisible(bool _isvisible)
double m_lambda
Gain of the virtual visual servoing stage.
Definition: vpMbTracker.h:189
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
virtual void setFarClippingDistance(const double &dist)
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:145
vpMbtOptimizationMethod m_optimizationMethod
Optimization method used.
Definition: vpMbTracker.h:142
void setCameraParameters(const vpCameraParameters &_cam)
double angleAppears
Angle used to detect a face appearance.
Definition: vpMbTracker.h:147
vpColVector m_errorCylinders
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:174
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
vpColVector m_errorCircles
bool samePoint(const vpPoint &P1, const vpPoint &P2) const
void displayMovingEdges(const vpImage< unsigned char > &I)
unsigned int m_maxIter
Maximum number of iterations of the virtual visual servoing stage.
Definition: vpMbTracker.h:191
vpColVector m_wCylinders
vpRobust m_robustLines
static double rad(double deg)
Definition: vpMath.h:102
void addCylinder(const vpPoint &P1, const vpPoint &P2, const double r, int idFace=-1, const std::string &name="")
virtual void setMinLineLengthThresh(const double minLineLengthThresh, const std::string &name="")
void parse(const char *filename)
void setMeanWeight1(const double wmean)
std::vector< std::list< vpMbtDistanceCircle * > > circles
Vector of the tracked circles.
void getLline(std::list< vpMbtDistanceLine *> &linesList, const unsigned int level=0) const
void setClipping(const unsigned int &flags)
Definition: vpPolygon3D.h:187
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void computeProjectionError(const vpImage< unsigned char > &_I)
void setVisible(bool _isvisible)
void insert(unsigned int i, const vpColVector &v)
vpRobust m_robustCylinders
virtual void initFaceFromLines(vpMbtPolygon &polygon)
void getLcircle(std::list< vpMbtDistanceCircle *> &circlesList, const unsigned int level=0) const
vpRobust m_robustCircles
void setName(const std::string &line_name)
void setScales(const std::vector< bool > &_scales)
vpPoint * p2
The second extremity on the axe.
void setCameraParameters(const vpCameraParameters &camera)
virtual void initCylinder(const vpPoint &p1, const vpPoint &p2, const double radius, const int idFace=0, const std::string &name="")
bool closeToImageBorder(const vpImage< unsigned char > &I, const unsigned int threshold)
void setIndex(const unsigned int i)
bool isVisible() const
double minPolygonAreaThresholdGeneral
Minimum polygon area threshold for LOD mode (general setting)
Definition: vpMbTracker.h:181
static double deg(double rad)
Definition: vpMath.h:95
bool displayFeatures
If true, the features are displayed.
Definition: vpMbTracker.h:140
virtual void loadModel(const char *modelFile, const bool verbose=false)
unsigned int getHeight() const
Definition: vpImage.h:178
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const double r)
bool ogreShowConfigDialog
Definition: vpMbTracker.h:158
virtual unsigned int getNbPolygon() const
Definition: vpMbTracker.h:335
double getMinPolygonAreaThreshold() const
bool applyLodSettingInConfig
Definition: vpMbTracker.h:177
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
void setAngleAppear(const double &aappear)
void setMovingEdge(vpMe *Me)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
virtual void initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, const double radius, const int idFace=0, const std::string &name="")
virtual void computeVVSPoseEstimation(const bool isoJoIdentity_, const 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=NULL, vpColVector *const m_w_prev=NULL)
bool hasFarClippingDistance() const
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
static vpHomogeneousMatrix direct(const vpColVector &v)
virtual void computeCovarianceMatrixVVS(const bool isoJoIdentity_, const vpColVector &w_true, const vpHomogeneousMatrix &cMoPrev, const vpMatrix &L_true, const vpMatrix &LVJ_true, const vpColVector &error)
void setMeanWeight(const double _wmean)
bool isVisible(const unsigned int i)
unsigned int nbvisiblepolygone
Number of polygon (face) currently visible.
double angleDisappears
Angle used to detect a face disappearance.
Definition: vpMbTracker.h:149
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, const unsigned int thickness=1, const bool displayFullModel=false)
void visibleFace(const vpImage< unsigned char > &_I, const vpHomogeneousMatrix &_cMo, bool &newvisibleline)
virtual void computeVVSInit()
void addPolygon(const int &index)
void setNearClippingDistance(const double &dist)
Definition: vpPolygon3D.h:207
void setMeanWeight(const double w_mean)
vpColVector error
The error vector.
std::vector< std::list< vpMbtDistanceLine * > > lines
vpColVector m_wLines
virtual void setClipping(const unsigned int &flags)
bool Reinit
Indicates if the line has to be reinitialized.
double radius
The radius of the cylinder.
double getMinLineLengthThreshold() const
std::vector< vpMbtMeLine * > meline
The moving edge container.
unsigned int clippingFlag
Flags specifying which clipping to used.
Definition: vpMbTracker.h:155
vpMatrix m_L_edge
Interaction matrix.
unsigned int nline
void addPolygon(vpMbtPolygon &p)
void initPyramid(const vpImage< unsigned char > &_I, std::vector< const vpImage< unsigned char > *> &_pyramid)
void trackMovingEdge(const vpImage< unsigned char > &I)
void displayOgre(const vpHomogeneousMatrix &cMo)
virtual void setClipping(const unsigned int &flags)
unsigned int nbFeaturel2
The number of moving edges on line 2.
void setUseEdgeTracking(const std::string &name, const bool &useEdgeTracking)
void setThreshold(const double noise_threshold)
Definition: vpRobust.h:115
double radius
The radius of the circle.
virtual void setFarClippingDistance(const double &dist)
void computeVVSFirstPhase(const vpImage< unsigned char > &I, const unsigned int iter, double &count, const unsigned int lvl=0)
void setName(const std::string &cyl_name)
static int() sign(double x)
Definition: vpMath.h:262
vpColVector m_errorLines
void resize(unsigned int n_data)
Resize containers for sort methods.
Definition: vpRobust.cpp:128
vpMbtMeLine * meline2
The moving edge containers (second line of the cylinder)
void removeLine(const std::string &name)
unsigned int getWidth() const
Definition: vpImage.h:229
void computeVVSFirstPhaseFactor(const vpImage< unsigned char > &I, const unsigned int lvl=0)
void computeJTR(const vpMatrix &J, const vpColVector &R, vpColVector &JTR) const
double distNearClip
Distance for near clipping.
Definition: vpMbTracker.h:151
bool useLodGeneral
True if LOD mode is enabled.
Definition: vpMbTracker.h:174
void computeScanLineRender(const vpCameraParameters &cam, const unsigned int &w, const unsigned int &h)
vpMatrix L
The interaction matrix.
void addCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, const double r, int idFace=-1, const std::string &name="")
std::vector< unsigned int > nbFeature
The number of moving edges.
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo, const vpImage< unsigned char > &I)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void eye()
Definition: vpMatrix.cpp:360
virtual void computeVVSCheckLevenbergMarquardt(const unsigned int iter, vpColVector &error, const vpColVector &m_error_prev, const vpHomogeneousMatrix &cMoPrev, double &mu, bool &reStartFromLastIncrement, vpColVector *const w=NULL, const vpColVector *const m_w_prev=NULL)
void setMovingEdge(const vpMe &_ecm)
bool isoJoIdentity
Boolean to know if oJo is identity (for fast computation)
Definition: vpMbTracker.h:119
vpPoint * p1
The center of the circle.
bool useScanLine
Use scanline rendering.
void getLcylinder(std::list< vpMbtDistanceCylinder *> &cylindersList, const unsigned int level=0) const
void buildFrom(vpPoint &_p1, vpPoint &_p2)
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:241
virtual void setLod(const bool useLod, const std::string &name="")
virtual void setNearClippingDistance(const double &dist)
void computeFov(const unsigned int &w, const unsigned int &h)