ViSP  2.10.0
vpMbEdgeTracker.cpp
1 /****************************************************************************
2  *
3  * $Id: vpMbEdgeTracker.cpp 5285 2015-02-09 14:32:54Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Make the complete tracking of an object by using its CAD model
36  *
37  * Authors:
38  * Nicolas Melchior
39  * Romain Tallonneau
40  * Eric Marchand
41  *
42  *****************************************************************************/
43 
49 #include <visp/vpDebug.h>
50 #include <visp/vpPose.h>
51 #include <visp/vpExponentialMap.h>
52 #include <visp/vpPixelMeterConversion.h>
53 #include <visp/vpImageIo.h>
54 #include <visp/vpRobust.h>
55 #include <visp/vpDisplayOpenCV.h>
56 #include <visp/vpDisplayX.h>
57 #include <visp/vpDisplayGDI.h>
58 #include <visp/vpMatrixException.h>
59 #include <visp/vpMath.h>
60 #include <visp/vpException.h>
61 #include <visp/vpTrackingException.h>
62 #include <visp/vpMbEdgeTracker.h>
63 #include <visp/vpMbtDistanceLine.h>
64 #include <visp/vpMbtXmlParser.h>
65 #include <visp/vpMbtPolygon.h>
66 #include <visp/vpVelocityTwistMatrix.h>
67 
68 #include <limits>
69 #include <string>
70 #include <sstream>
71 #include <float.h>
72 #include <map>
73 
74 bool samePoint(const vpPoint &P1, const vpPoint &P2, double threshold);
75 
80  : compute_interaction(1), lambda(1), me(), lines(1), circles(1), cylinders(1), nline(0), ncircle(0), ncylinder(0),
81  nbvisiblepolygone(0), percentageGdPt(0.4), scales(1),
82  Ipyramid(0), scaleLevel(0)
83 {
86 
87  scales[0] = true;
88 
89 #ifdef VISP_HAVE_OGRE
90  faces.getOgreContext()->setWindowName("MBT Edge");
91 #endif
92 }
93 
98 {
102 
103  for (unsigned int i = 0; i < lines.size(); i += 1){
104  if(scales[i]){
105  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
106  l = *it;
107  if (l!=NULL){
108  delete l ;
109  }
110  l = NULL ;
111  }
112 
113  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
114  cy = *it;
115  if (cy!=NULL){
116  delete cy ;
117  }
118  cy = NULL ;
119  }
120 
121  lines[i].clear();
122  cylinders[i].clear();
123  }
124  }
125  for (unsigned int i = 0; i < circles.size(); i += 1){
126  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
127  ci = *it;
128  if (ci!=NULL){
129  delete ci ;
130  }
131  ci = NULL ;
132  }
133  circles[i].clear();
134  }
136 }
137 
143 void
145 {
146  this->me = p_me;
147 
148  for (unsigned int i = 0; i < scales.size(); i += 1){
149  if(scales[i]){
150  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
151  (*it)->setMovingEdge(&(this->me)) ;
152  }
153 
155  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
156  cy = *it;
157  cy->setMovingEdge(&(this->me)) ;
158  }
159 
161  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
162  ci = *it;
163  ci->setMovingEdge(&(this->me)) ;
164  }
165  }
166  }
167 }
168 
177 void
179 {
180  double residu_1 =1e3;
181  double r =1e3-1;
182  vpMatrix LTL;
183  vpColVector LTR;
184 
185  // compute the interaction matrix and its pseudo inverse
186  vpMbtDistanceLine *l ;
188  vpMbtDistanceCircle *ci ;
189 
190  //vpColVector w;
191  vpColVector factor;
192  //vpColVector error; // s-s*
193  vpColVector weighted_error; // Weighted error vector wi(s-s)*
195 
196  unsigned int iter = 0;
197 
198  //Nombre de moving edges
199  unsigned int nbrow = 0;
200  unsigned int nberrors_lines = 0;
201  unsigned int nberrors_cylinders = 0;
202  unsigned int nberrors_circles = 0;
203 
204  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
205  l = *it;
206  nbrow += l->nbFeature;
207  nberrors_lines+=l->nbFeature;
209  }
210 
211  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
212  cy = *it;
213  nbrow += cy->nbFeature ;
214  nberrors_cylinders += cy->nbFeature ;
216  }
217 
218  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
219  ci = *it;
220  nbrow += ci->nbFeature ;
221  nberrors_circles += ci->nbFeature ;
223  }
224 
225  if (nbrow==0){
226  throw vpTrackingException(vpTrackingException::notEnoughPointError, "No data found to compute the interaction matrix...");
227  }
228 
229  vpMatrix L(nbrow,6), Lp;
230 
231  // compute the error vector
232  m_error.resize(nbrow);
233  unsigned int nerror = m_error.getRows();
234  vpColVector v ;
235 
236  double limite = 3; //Une limite de 3 pixels
237  limite = limite / cam.get_px(); //Transformation limite pixel en limite metre.
238 
239  //Parametre pour la premiere phase d'asservissement
240  double e_prev = 0, e_cur, e_next;
241  bool reloop = true;
242  double count = 0;
243 
244  bool isoJoIdentity_ = isoJoIdentity; // Backup since it can be modified if L is not full rank
245 
246  /*** First phase ***/
247 
248  while ( reloop == true && iter<10)
249  {
250  if(iter==0)
251  {
252  weighted_error.resize(nerror) ;
253  m_w.resize(nerror);
254  m_w = 0;
255  factor.resize(nerror);
256  factor = 1;
257  }
258 
259  count = 0;
260 
261  unsigned int n = 0;
262  reloop = false;
263  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
264  l = *it;
266 
267  double fac = 1;
268  if (iter == 0)
269  {
270  for(std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex!=l->Lindex_polygon.end(); ++itindex){
271  int index = *itindex;
272  if (l->hiddenface->isAppearing((unsigned int)index))
273  {
274  fac = 0.2;
275  break;
276  }
277  if(l->closeToImageBorder(_I, 10))
278  {
279  fac = 0.1;
280  break;
281  }
282  }
283  }
284 
285  std::list<vpMeSite>::const_iterator itListLine;
286  if (iter == 0 && l->meline != NULL)
287  itListLine = l->meline->getMeList().begin();
288 
289  for (unsigned int i=0 ; i < l->nbFeature ; i++)
290  {
291  for (unsigned int j=0; j < 6 ; j++)
292  {
293  L[n+i][j] = l->L[i][j]; //On remplit la matrice d'interaction globale
294  }
295  m_error[n+i] = l->error[i]; //On remplit la matrice d'erreur
296 
297  if (m_error[n+i] <= limite) count = count+1.0; //Si erreur proche de 0 on incremente cur
298 
299  m_w[n+i] = 0;
300 
301  if (iter == 0)
302  {
303  factor[n+i] = fac;
304  vpMeSite site = *itListLine;
305  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
306  ++itListLine;
307  }
308 
309  //If pour la premiere extremite des moving edges
310  if (i == 0)
311  {
312  e_cur = l->error[0];
313  if (l->nbFeature > 1)
314  {
315  e_next = l->error[1];
316  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
317  {
318  m_w[n+i] = 1/*0.5*/;
319  }
320  e_prev = e_cur;
321  }
322  else m_w[n+i] = 1;
323  }
324 
325  //If pour la derniere extremite des moving edges
326  else if(i == l->nbFeature-1)
327  {
328  e_cur = l->error[i];
329  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
330  {
331  m_w[n+i] += 1/*0.5*/;
332  }
333  }
334 
335  else
336  {
337  e_cur = l->error[i];
338  e_next = l->error[i+1];
339  if ( fabs(e_cur - e_prev) < limite )
340  {
341  m_w[n+i] += 0.5;
342  }
343  if ( fabs(e_cur - e_next) < limite )
344  {
345  m_w[n+i] += 0.5;
346  }
347  e_prev = e_cur;
348  }
349  }
350 
351  n+= l->nbFeature ;
352  }
353  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
354  cy = *it;
356  double fac = 1.0;
357 
358  std::list<vpMeSite>::const_iterator itCyl1;
359  std::list<vpMeSite>::const_iterator itCyl2;
360  if (iter == 0 && (cy->meline1 != NULL || cy->meline2 != NULL)){
361  itCyl1 = cy->meline1->getMeList().begin();
362  itCyl2 = cy->meline2->getMeList().begin();
363  }
364 
365  for(unsigned int i=0 ; i < cy->nbFeature ; i++){
366  for(unsigned int j=0; j < 6 ; j++){
367  L[n+i][j] = cy->L[i][j]; //On remplit la matrice d'interaction globale
368  }
369  m_error[n+i] = cy->error[i]; //On remplit la matrice d'erreur
370 
371  if (m_error[n+i] <= limite) count = count+1.0; //Si erreur proche de 0 on incremente cur
372 
373  m_w[n+i] = 0;
374 
375  if (iter == 0)
376  {
377  factor[n+i] = fac;
378  vpMeSite site;
379  if(i<cy->nbFeaturel1) {
380  site= *itCyl1;
381  ++itCyl1;
382  }
383  else{
384  site= *itCyl2;
385  ++itCyl2;
386  }
387  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
388  }
389 
390  //If pour la premiere extremite des moving edges
391  if (i == 0)
392  {
393  e_cur = cy->error[0];
394  if (cy->nbFeature > 1)
395  {
396  e_next = cy->error[1];
397  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
398  {
399  m_w[n+i] = 1/*0.5*/;
400  }
401  e_prev = e_cur;
402  }
403  else m_w[n+i] = 1;
404  }
405  if (i == cy->nbFeaturel1)
406  {
407  e_cur = cy->error[i];
408  if (cy->nbFeaturel2 > 1)
409  {
410  e_next = cy->error[i+1];
411  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
412  {
413  m_w[n+i] = 1/*0.5*/;
414  }
415  e_prev = e_cur;
416  }
417  else m_w[n+i] = 1;
418  }
419 
420  //If pour la derniere extremite des moving edges
421  else if(i == cy->nbFeaturel1-1)
422  {
423  e_cur = cy->error[i];
424  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
425  {
426  m_w[n+i] += 1/*0.5*/;
427  }
428  }
429  //If pour la derniere extremite des moving edges
430  else if(i == cy->nbFeature-1)
431  {
432  e_cur = cy->error[i];
433  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
434  {
435  m_w[n+i] += 1/*0.5*/;
436  }
437  }
438 
439  else
440  {
441  e_cur = cy->error[i];
442  e_next = cy->error[i+1];
443  if ( fabs(e_cur - e_prev) < limite ){
444  m_w[n+i] += 0.5;
445  }
446  if ( fabs(e_cur - e_next) < limite ){
447  m_w[n+i] += 0.5;
448  }
449  e_prev = e_cur;
450  }
451  }
452 
453  n+= cy->nbFeature ;
454  }
455 
456  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
457  ci = *it;
459  double fac = 1.0;
460 
461  std::list<vpMeSite>::const_iterator itCir;
462  if (iter == 0 && (ci->meEllipse != NULL)) {
463  itCir = ci->meEllipse->getMeList().begin();
464  }
465 
466  for(unsigned int i=0 ; i < ci->nbFeature ; i++){
467  for(unsigned int j=0; j < 6 ; j++){
468  L[n+i][j] = ci->L[i][j]; //On remplit la matrice d'interaction globale
469  }
470  m_error[n+i] = ci->error[i]; //On remplit la matrice d'erreur
471 
472  if (m_error[n+i] <= limite) count = count+1.0; //Si erreur proche de 0 on incremente cur
473 
474  m_w[n+i] = 0;
475 
476  if (iter == 0)
477  {
478  factor[n+i] = fac;
479  vpMeSite site = *itCir;
480  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
481  ++itCir;
482  }
483 
484  //If pour la premiere extremite des moving edges
485  if (i == 0)
486  {
487  e_cur = ci->error[0];
488  if (ci->nbFeature > 1)
489  {
490  e_next = ci->error[1];
491  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
492  {
493  m_w[n+i] = 1/*0.5*/;
494  }
495  e_prev = e_cur;
496  }
497  else m_w[n+i] = 1;
498  }
499 
500  //If pour la derniere extremite des moving edges
501  else if(i == ci->nbFeature-1)
502  {
503  e_cur = ci->error[i];
504  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
505  {
506  m_w[n+i] += 1/*0.5*/;
507  }
508  }
509 
510  else
511  {
512  e_cur = ci->error[i];
513  e_next = ci->error[i+1];
514  if ( fabs(e_cur - e_prev) < limite ){
515  m_w[n+i] += 0.5;
516  }
517  if ( fabs(e_cur - e_next) < limite ){
518  m_w[n+i] += 0.5;
519  }
520  e_prev = e_cur;
521  }
522  }
523 
524  n+= ci->nbFeature ;
525  }
526 
527  count = count / (double)nbrow;
528  if (count < 0.85){
529  reloop = true;
530  }
531 
532  double num=0;
533  double den=0;
534 
535  double wi ; double eri ;
536  for(unsigned int i = 0; i < nerror; i++){
537  wi = m_w[i]*factor[i];
538  eri = m_error[i];
539  num += wi*vpMath::sqr(eri);
540  den += wi ;
541 
542  weighted_error[i] = wi*eri ;
543  }
544 
545  if((iter==0) || compute_interaction){
546  for (unsigned int i=0 ; i < nerror ; i++){
547  for (unsigned int j=0 ; j < 6 ; j++){
548  L[i][j] = m_w[i]*factor[i]*L[i][j] ;
549  }
550  }
551  }
552 
553  // If all the 6 dof should be estimated, we check if the interaction matrix is full rank.
554  // If not we remove automatically the dof that cannot be estimated
555  // This is particularly useful when consering circles (rank 5) and cylinders (rank 4)
556  if (isoJoIdentity_) {
557  cVo.buildFrom(cMo);
558 
559  vpMatrix K; // kernel
560  unsigned int rank = (L*cVo).kernel(K);
561  if(rank == 0) {
562  throw vpException(vpException::fatalError, "Rank=0, cannot estimate the pose !");
563  }
564  if (rank != 6) {
565  vpMatrix I; // Identity
566  I.eye(6);
567  oJo = I-K.AtA();
568 
569  isoJoIdentity_ = false;
570  }
571  }
572 
573  if(isoJoIdentity_){
574  LTL = L.AtA();
575  computeJTR(L, weighted_error, LTR);
576  v = -0.7*LTL.pseudoInverse(LTL.getRows()*std::numeric_limits<double>::epsilon())*LTR;
577  }
578  else{
579  cVo.buildFrom(cMo);
580  vpMatrix LVJ = (L*cVo*oJo);
581  vpMatrix LVJTLVJ = (LVJ).AtA();
582  vpMatrix LVJTR;
583  computeJTR(LVJ, weighted_error, LVJTR);
584  v = -0.7*LVJTLVJ.pseudoInverse(LVJTLVJ.getRows()*std::numeric_limits<double>::epsilon())*LVJTR;
585  v = cVo * v;
586  }
587 
589 
590  iter++;
591  }
592 
593 // std::cout << "\t First minimization in " << iter << " iteration give as initial cMo: \n" << cMo << std::endl ;
594 
595 
596 /*** Second phase ***/
597 
598  vpRobust robust_lines(nberrors_lines);
599  vpRobust robust_cylinders(nberrors_cylinders);
600  vpRobust robust_circles(nberrors_circles);
601  robust_lines.setIteration(0) ;
602  robust_cylinders.setIteration(0) ;
603  robust_circles.setIteration(0) ;
604  iter = 0;
605  vpColVector w_lines(nberrors_lines);
606  vpColVector w_cylinders(nberrors_cylinders);
607  vpColVector w_circles(nberrors_circles);
608  vpColVector error_lines(nberrors_lines);
609  vpColVector error_cylinders(nberrors_cylinders);
610  vpColVector error_circles(nberrors_circles);
611 
612  vpHomogeneousMatrix cMoPrev;
613  vpColVector W_true;
614  vpMatrix L_true;
615  vpMatrix LVJ_true;
616 
617  while ( ((int)((residu_1 - r)*1e8) !=0 ) && (iter<30))
618  {
619  unsigned int n = 0 ;
620  unsigned int nlines = 0;
621  unsigned int ncylinders = 0;
622  unsigned int ncircles = 0;
623  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
624  l = *it;
626  for (unsigned int i=0 ; i < l->nbFeature ; i++){
627  for (unsigned int j=0; j < 6 ; j++){
628  L[n+i][j] = l->L[i][j];
629  m_error[n+i] = l->error[i];
630  error_lines[nlines+i] = m_error[n+i];
631  }
632  }
633  n+= l->nbFeature;
634  nlines+= l->nbFeature;
635  }
636 
637  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
638  cy = *it;
640  for(unsigned int i=0 ; i < cy->nbFeature ; i++){
641  for(unsigned int j=0; j < 6 ; j++){
642  L[n+i][j] = cy->L[i][j];
643  m_error[n+i] = cy->error[i];
644  error_cylinders[ncylinders+i] = m_error[n+i];
645  }
646  }
647 
648  n+= cy->nbFeature ;
649  ncylinders+= cy->nbFeature ;
650  }
651 
652  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
653  ci = *it;
655  for(unsigned int i=0 ; i < ci->nbFeature ; i++){
656  for(unsigned int j=0; j < 6 ; j++){
657  L[n+i][j] = ci->L[i][j];
658  m_error[n+i] = ci->error[i];
659  error_circles[ncircles+i] = m_error[n+i];
660  }
661  }
662 
663  n+= ci->nbFeature ;
664  ncircles+= ci->nbFeature ;
665  }
666 
667  if(iter==0)
668  {
669  weighted_error.resize(nerror);
670  m_w.resize(nerror);
671  m_w = 1;
672  w_lines.resize(nberrors_lines);
673  w_lines = 1;
674  w_cylinders.resize(nberrors_cylinders);
675  w_cylinders = 1;
676  w_circles.resize(nberrors_circles);
677  w_circles = 1;
678 
679  robust_lines.setThreshold(2/cam.get_px());
680  robust_cylinders.setThreshold(2/cam.get_px());
681  robust_circles.setThreshold(vpMath::sqr(2/cam.get_px()));
682  if(nberrors_lines > 0)
683  robust_lines.MEstimator(vpRobust::TUKEY, error_lines,w_lines);
684  if(nberrors_cylinders > 0)
685  robust_cylinders.MEstimator(vpRobust::TUKEY, error_cylinders,w_cylinders);
686  if(nberrors_circles > 0)
687  robust_circles.MEstimator(vpRobust::TUKEY, error_circles,w_circles);
688  }
689  else
690  {
691  robust_lines.setIteration(iter);
692  robust_cylinders.setIteration(iter);
693  robust_circles.setIteration(iter);
694  if(nberrors_lines > 0)
695  robust_lines.MEstimator(vpRobust::TUKEY, error_lines, w_lines);
696  if(nberrors_cylinders > 0)
697  robust_cylinders.MEstimator(vpRobust::TUKEY, error_cylinders,w_cylinders);
698  if(nberrors_circles > 0)
699  robust_circles.MEstimator(vpRobust::TUKEY, error_circles,w_circles);
700  }
701 
702  unsigned int cpt = 0;
703  while(cpt<nbrow){
704  if(cpt<nberrors_lines){
705  m_w[cpt] = w_lines[cpt];
706  }
707  else if (cpt<nberrors_lines+nberrors_cylinders){
708  m_w[cpt] = w_cylinders[cpt-nberrors_lines];
709  }
710  else {
711  m_w[cpt] = w_circles[cpt-nberrors_lines-nberrors_cylinders];
712  }
713  cpt++;
714  }
715 
716  residu_1 = r;
717 
718  double num=0;
719  double den=0;
720  double wi;
721  double eri;
722 
723  L_true = L;
724  W_true = vpColVector(nerror);
725 
726  if(computeCovariance){
727  L_true = L;
728  if(!isoJoIdentity_){
729  cVo.buildFrom(cMo);
730  LVJ_true = (L*cVo*oJo);
731  }
732  }
733 
734  for(unsigned int i=0; i<nerror; i++){
735  wi = m_w[i]*factor[i];
736  W_true[i] = wi;
737  eri = m_error[i];
738  num += wi*vpMath::sqr(eri);
739  den += wi;
740 
741  weighted_error[i] = wi*eri ;
742  }
743 
744  r = sqrt(num/den); //Le critere d'arret prend en compte le poids
745 
746  if((iter==0)|| compute_interaction){
747  for (unsigned int i=0 ; i < nerror ; i++){
748  for (unsigned int j=0 ; j < 6 ; j++){
749  L[i][j] = m_w[i]*factor[i]*L[i][j];
750  }
751  }
752  }
753 
754  if(isoJoIdentity_){
755  LTL = L.AtA();
756  computeJTR(L, weighted_error, LTR);
757  v = -lambda*LTL.pseudoInverse(LTL.getRows()*std::numeric_limits<double>::epsilon())*LTR;
758  }
759  else{
760  cVo.buildFrom(cMo);
761  vpMatrix LVJ = (L*cVo*oJo);
762  vpMatrix LVJTLVJ = (LVJ).AtA();
763  vpMatrix LVJTR;
764  computeJTR(LVJ, weighted_error, LVJTR);
765  v = -lambda*LVJTLVJ.pseudoInverse(LVJTLVJ.getRows()*std::numeric_limits<double>::epsilon())*LVJTR;
766  v = cVo * v;
767  }
768 
769  cMoPrev = cMo;
771 
772  iter++;
773  }
774 
775  // std::cout << "VVS estimate pose cMo:\n" << cMo << std::endl;
776  if(computeCovariance){
777  vpMatrix D;
778  D.diag(W_true);
779 
780  // Note that here the covariance is computed on cMoPrev for time computation efficiency
781  if(isoJoIdentity_){
782  computeCovarianceMatrix(cMoPrev,m_error,L_true,D);
783  }
784  else{
785  computeCovarianceMatrix(cMoPrev,m_error,LVJ_true,D);
786  }
787  }
788 
789  unsigned int n =0 ;
790  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
791  l = *it;
792  {
793  double wmean = 0 ;
794  std::list<vpMeSite>::iterator itListLine;
795  if (l->nbFeature > 0) itListLine = l->meline->getMeList().begin();
796 
797  for (unsigned int i=0 ; i < l->nbFeature ; i++){
798  wmean += m_w[n+i] ;
799  vpMeSite p = *itListLine;
800  if (m_w[n+i] < 0.5){
802 
803  *itListLine = p;
804  }
805 
806  ++itListLine;
807  }
808  n+= l->nbFeature ;
809 
810  if (l->nbFeature!=0)
811  wmean /= l->nbFeature ;
812  else
813  wmean = 1;
814 
815  l->setMeanWeight(wmean);
816 
817  if (wmean < 0.8)
818  l->Reinit = true;
819  }
820  }
821 
822  // Same thing with cylinders as with lines
823  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
824  cy = *it;
825  double wmean = 0 ;
826  std::list<vpMeSite>::iterator itListCyl1;
827  std::list<vpMeSite>::iterator itListCyl2;
828 
829  if (cy->nbFeature > 0){
830  itListCyl1 = cy->meline1->getMeList().begin();
831  itListCyl2 = cy->meline2->getMeList().begin();
832  }
833 
834  wmean = 0;
835  for(unsigned int i=0 ; i < cy->nbFeaturel1 ; i++){
836  wmean += m_w[n+i] ;
837  vpMeSite p = *itListCyl1;
838  if (m_w[n+i] < 0.5){
840 
841  *itListCyl1 = p;
842  }
843 
844  ++itListCyl1;
845  }
846 
847  if (cy->nbFeaturel1!=0)
848  wmean /= cy->nbFeaturel1 ;
849  else
850  wmean = 1;
851 
852  cy->setMeanWeight1(wmean);
853 
854  if (wmean < 0.8){
855  cy->Reinit = true;
856  }
857 
858  wmean = 0;
859  for(unsigned int i=cy->nbFeaturel1 ; i < cy->nbFeature ; i++){
860  wmean += m_w[n+i] ;
861  vpMeSite p = *itListCyl2;
862  if (m_w[n+i] < 0.5){
864 
865  *itListCyl2 = p;
866  }
867 
868  ++itListCyl2;
869  }
870 
871  if (cy->nbFeaturel2!=0)
872  wmean /= cy->nbFeaturel2 ;
873  else
874  wmean = 1;
875 
876  cy->setMeanWeight2(wmean);
877 
878  if (wmean < 0.8){
879  cy->Reinit = true;
880  }
881 
882  n+= cy->nbFeature ;
883  }
884 
885  // Same thing with circles as with lines
886  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
887  ci = *it;
888  double wmean = 0 ;
889  std::list<vpMeSite>::iterator itListCir;
890 
891  if (ci->nbFeature > 0){
892  itListCir = ci->meEllipse->getMeList().begin();
893  }
894 
895  wmean = 0;
896  for(unsigned int i=0 ; i < ci->nbFeature ; i++){
897  wmean += m_w[n+i] ;
898  vpMeSite p = *itListCir;
899  if (m_w[n+i] < 0.5){
901 
902  *itListCir = p;
903  }
904 
905  ++itListCir;
906  }
907 
908  if (ci->nbFeature!=0)
909  wmean /= ci->nbFeature ;
910  else
911  wmean = 1;
912 
913  ci->setMeanWeight(wmean);
914 
915  if (wmean < 0.8){
916  ci->Reinit = true;
917  }
918 
919  n+= ci->nbFeature ;
920  }
921 }
922 
928 void
930 {
931  int nbExpectedPoint = 0;
932  int nbGoodPoint = 0;
933  int nbBadPoint = 0;
934 
935  vpMbtDistanceLine *l ;
936  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
937  l = *it;
938  if (l->isVisible() && l->meline != NULL)
939  {
940  nbExpectedPoint += (int)l->meline->expecteddensity;
941  for(std::list<vpMeSite>::const_iterator itme=l->meline->getMeList().begin(); itme!=l->meline->getMeList().end(); ++itme){
942  vpMeSite pix = *itme;
943  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
944  else nbBadPoint++;
945  }
946  }
947  }
948 
950  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
951  cy = *it;
952  if ((cy->meline1 !=NULL && cy->meline2 != NULL) && cy->isVisible())
953  {
954  nbExpectedPoint += (int)cy->meline1->expecteddensity;
955  for(std::list<vpMeSite>::const_iterator itme1=cy->meline1->getMeList().begin(); itme1!=cy->meline1->getMeList().end(); ++itme1){
956  vpMeSite pix = *itme1;
957  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
958  else nbBadPoint++;
959  }
960  nbExpectedPoint += (int)cy->meline2->expecteddensity;
961  for(std::list<vpMeSite>::const_iterator itme2=cy->meline2->getMeList().begin(); itme2!=cy->meline2->getMeList().end(); ++itme2){
962  vpMeSite pix = *itme2;
963  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
964  else nbBadPoint++;
965  }
966  }
967  }
968 
969  vpMbtDistanceCircle *ci ;
970  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
971  ci = *it;
972  if (ci->isVisible() && ci->meEllipse !=NULL)
973  {
974  nbExpectedPoint += ci->meEllipse->getExpectedDensity();
975  for(std::list<vpMeSite>::const_iterator itme=ci->meEllipse->getMeList().begin(); itme!=ci->meEllipse->getMeList().end(); ++itme){
976  vpMeSite pix = *itme;
977  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
978  else nbBadPoint++;
979  }
980  }
981  }
982 
983  // Compare the number of good points with the min between the number of expected points and
984  // number of points that are tracked
985  int nb_min = (int)vpMath::minimum(percentageGdPt *nbExpectedPoint, percentageGdPt *(nbGoodPoint + nbBadPoint) );
986  //int nb_min = std::min(val1, val2);
987  if (nbGoodPoint < nb_min || nbExpectedPoint < 2) {
988  std::ostringstream oss;
989  oss << "Not enough moving edges ("
990  << nbGoodPoint
991  << ") to track the object: expected "
992  << nb_min
993  << ". Try to reduce the threshold="
994  << percentageGdPt
995  << " using vpMbTracker::setGoodMovingEdgesRatioThreshold()";
997  }
998 }
999 
1007 void
1009 {
1010  initPyramid(I, Ipyramid);
1011 
1012 // for (int lvl = ((int)scales.size()-1); lvl >= 0; lvl -= 1)
1013  unsigned int lvl = (unsigned int)scales.size();
1014  do{
1015  lvl--;
1016  if(scales[lvl]){
1017  vpHomogeneousMatrix cMo_1 = cMo;
1018  try
1019  {
1020  downScale(lvl);
1021 
1022  try
1023  {
1024  trackMovingEdge(*Ipyramid[lvl]);
1025  }
1026  catch(...)
1027  {
1028  vpTRACE("Error in moving edge tracking") ;
1029  throw ;
1030  }
1031 
1032  // initialize the vector that contains the error and the matrix that contains
1033  // the interaction matrix
1034  vpMbtDistanceLine *l ;
1035  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
1036  l = *it;
1037  if (l->isVisible()){
1039  }
1040  }
1041 
1042  vpMbtDistanceCylinder *cy ;
1043  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){
1044  cy = *it;
1045  if(cy->isVisible()) {
1047  }
1048  }
1049 
1050  vpMbtDistanceCircle *ci ;
1051  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){
1052  ci = *it;
1053  if (ci->isVisible()){
1055  }
1056  }
1057 
1058  try
1059  {
1060  computeVVS(*Ipyramid[lvl]);
1061  }
1062  catch(vpException &e)
1063  {
1064  covarianceMatrix = -1;
1065  throw e;
1066  }
1067 
1068  try
1069  {
1070  testTracking();
1071  }
1072  catch(vpException &e)
1073  {
1074  throw e;
1075  }
1076 
1077  if (displayFeatures)
1078  {
1079  if(lvl == 0){
1080  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
1081  l = *it;
1082  if (l->isVisible()){
1083  l->displayMovingEdges(I);
1084  }
1085  }
1086 
1087  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){
1088  cy = *it;
1089  if(cy->isVisible()) {
1090  cy->displayMovingEdges(I);
1091  }
1092  }
1093 
1094  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){
1095  ci = *it;
1096  if (ci->isVisible()){
1097  ci->displayMovingEdges(I);
1098  }
1099  }
1100  }
1101  }
1102 
1103  try
1104  {
1105  updateMovingEdge(I);
1106  }
1107  catch(vpException &e)
1108  {
1109  throw e;
1110  }
1111 
1112  // Looking for new visible face
1113  bool newvisibleface = false ;
1114  visibleFace(I, cMo, newvisibleface) ;
1115  initMovingEdge(I,cMo) ;
1116 
1117  // Reinit the moving edge for the lines which need it.
1118  reinitMovingEdge(I,cMo);
1119  upScale(lvl);
1120  }
1121  catch(vpException &e)
1122  {
1123  if(lvl != 0){
1124  cMo = cMo_1;
1125  reInitLevel(lvl);
1126  upScale(lvl);
1127  }
1128  else{
1129  upScale(lvl);
1130  throw(e) ;
1131  }
1132  }
1133  }
1134  } while(lvl != 0);
1135 
1137 }
1138 
1145 {
1146  if(!modelInitialised){
1147  throw vpException(vpException::fatalError, "model not initialized");
1148  }
1149 
1150  bool a = false;
1151 
1152 #ifdef VISP_HAVE_OGRE
1153  if(useOgre){
1154  if(!faces.isOgreInitialised()){
1156  faces.initOgre(cam);
1157  }
1158  }
1159 #endif
1160 
1161 
1162  initPyramid(I, Ipyramid);
1163  visibleFace(I, cMo, a);
1164  unsigned int i = (unsigned int)scales.size();
1165 
1166  do {
1167  i--;
1168  if(scales[i]){
1169  downScale(i);
1170  initMovingEdge(*Ipyramid[i], cMo);
1171  upScale(i);
1172  }
1173  } while(i != 0);
1174 
1176 }
1177 
1187 void
1189 {
1190  cMo = cdMo;
1191 
1192  if (! lines[scaleLevel].empty()) {
1193  lines[scaleLevel].front() ;
1194  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1195  if((*it)->meline != NULL){
1196  delete (*it)->meline;
1197  (*it)->meline = NULL;
1198  }
1199  }
1200  }
1201 
1202  if (! cylinders[scaleLevel].empty()) {
1203  cylinders[scaleLevel].front() ;
1204  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1205  if((*it)->meline1 != NULL){
1206  delete (*it)->meline1;
1207  (*it)->meline1 = NULL;
1208  }
1209  if((*it)->meline2 != NULL){
1210  delete (*it)->meline2;
1211  (*it)->meline2 = NULL;
1212  }
1213  }
1214  }
1215 
1216  if (! circles[scaleLevel].empty()) {
1217  circles[scaleLevel].front() ;
1218  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1219  if((*it)->meEllipse != NULL){
1220  delete (*it)->meEllipse;
1221  (*it)->meEllipse = NULL;
1222  }
1223  }
1224  }
1225 
1226  init(I);
1227 }
1228 
1240 void
1241 vpMbEdgeTracker::loadConfigFile(const std::string& configFile)
1242 {
1243  vpMbEdgeTracker::loadConfigFile(configFile.c_str());
1244 }
1245 
1296 void
1297 vpMbEdgeTracker::loadConfigFile(const char* configFile)
1298 {
1299 #ifdef VISP_HAVE_XML2
1300  vpMbtXmlParser xmlp;
1301 
1302  xmlp.setCameraParameters(cam);
1305  xmlp.setMovingEdge(me);
1306 
1307  try{
1308  std::cout << " *********** Parsing XML for Mb Edge Tracker ************ " << std::endl;
1309  xmlp.parse(configFile);
1310  }
1311  catch(...){
1312  throw vpException(vpException::ioError, "Cannot open XML file \"%s\"", configFile);
1313  }
1314 
1315  vpCameraParameters camera;
1316  vpMe meParser;
1317  xmlp.getCameraParameters(camera);
1318  xmlp.getMe(meParser);
1319 
1320  setCameraParameters(camera);
1321  setMovingEdge(meParser);
1324 
1325  if(xmlp.hasNearClippingDistance())
1327 
1328  if(xmlp.hasFarClippingDistance())
1330 
1331  if(xmlp.getFovClipping())
1333 
1334  useLodGeneral = xmlp.getLodState();
1337 
1338  applyLodSettingInConfig = false;
1339  if(this->getNbPolygon() > 0) {
1340  applyLodSettingInConfig = true;
1344  }
1345 
1346 #else
1347  vpTRACE("You need the libXML2 to read the config file %s", configFile);
1348 #endif
1349 }
1350 
1351 
1362 void
1364  const vpCameraParameters &camera, const vpColor& col,
1365  const unsigned int thickness, const bool displayFullModel)
1366 {
1367  for (unsigned int i = 0; i < scales.size(); i += 1){
1368  if(scales[i]){
1369  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1370  (*it)->display(I,cMo_, camera, col, thickness, displayFullModel);
1371  }
1372 
1373  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1374  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1375  }
1376 
1377  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1378  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1379  }
1380 
1381  break ; //displaying model on one scale only
1382  }
1383  }
1384 
1385 #ifdef VISP_HAVE_OGRE
1386  if(useOgre)
1387  faces.displayOgre(cMo_);
1388 #endif
1389 }
1390 
1401 void
1403  const vpCameraParameters &camera, const vpColor& col,
1404  const unsigned int thickness, const bool displayFullModel)
1405 {
1406  for (unsigned int i = 0; i < scales.size(); i += 1){
1407  if(scales[i]){
1408  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1409  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel) ;
1410  }
1411 
1412  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1413  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel) ;
1414  }
1415 
1416  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1417  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1418  }
1419  break ; //displaying model on one scale only
1420  }
1421  }
1422 
1423 #ifdef VISP_HAVE_OGRE
1424  if(useOgre)
1425  faces.displayOgre(cMo_);
1426 #endif
1427 }
1428 
1429 
1437 void
1439 {
1440  vpMbtDistanceLine *l ;
1441 
1442  lines[scaleLevel].front() ;
1443  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1444  l = *it;
1445  bool isvisible = false ;
1446 
1447  for(std::list<int>::const_iterator itindex=l->Lindex_polygon.begin(); itindex!=l->Lindex_polygon.end(); ++itindex){
1448  int index = *itindex;
1449  if (index ==-1) isvisible =true ;
1450  else
1451  {
1452  if (l->hiddenface->isVisible((unsigned int)index)) isvisible = true ;
1453  }
1454  }
1455 
1456  //Si la ligne n'appartient a aucune face elle est tout le temps visible
1457  if (l->Lindex_polygon.empty()) isvisible = true; // Not sure that this can occur
1458 
1459  if (isvisible)
1460  {
1461  l->setVisible(true) ;
1462  if (l->meline==NULL)
1463  {
1464 // std::cout << "init me line "<< l->getIndex() << std::endl ;
1465  l->initMovingEdge(I, _cMo) ;
1466  }
1467  }
1468  else
1469  {
1470  l->setVisible(false) ;
1471  if (l->meline!=NULL) delete l->meline;
1472  l->meline=NULL;
1473  }
1474  }
1475 
1476  vpMbtDistanceCylinder *cy ;
1477  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1478  cy = *it;
1479 
1480  bool isvisible = false ;
1481 
1482  int index = cy->index_polygon;
1483  if (index ==-1) isvisible =true ;
1484  else
1485  {
1486  if (cy->hiddenface->isVisible((unsigned int)index)) isvisible = true ;
1487  }
1488 // vpTRACE("cyl with index %d is visible: %d", index, isvisible);
1489 
1490  if (isvisible)
1491  {
1492  cy->setVisible(true) ;
1493  if (cy->meline1==NULL || cy->meline2==NULL){
1494  cy->initMovingEdge(I, _cMo) ;
1495  }
1496  }
1497  else
1498  {
1499  cy->setVisible(false) ;
1500  if (cy->meline1!=NULL) delete cy->meline1;
1501  if (cy->meline2!=NULL) delete cy->meline2;
1502  cy->meline1=NULL;
1503  cy->meline2=NULL;
1504  }
1505  }
1506 
1507  vpMbtDistanceCircle *ci ;
1508  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1509  ci = *it;
1510  bool isvisible = false ;
1511 
1512  int index = ci->index_polygon;
1513  if (index ==-1) isvisible =true ;
1514  else
1515  {
1516  if (ci->hiddenface->isVisible((unsigned int)index)) isvisible = true ;
1517  }
1518 
1519  if (isvisible)
1520  {
1521  ci->setVisible(true) ;
1522  if (ci->meEllipse==NULL)
1523  {
1524  ci->initMovingEdge(I, _cMo) ;
1525  }
1526  }
1527  else
1528  {
1529  ci->setVisible(false) ;
1530  if (ci->meEllipse!=NULL) delete ci->meEllipse;
1531  ci->meEllipse=NULL;
1532  }
1533  }
1534 }
1535 
1536 
1542 void
1544 {
1545  vpMbtDistanceLine *l ;
1546  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1547  l = *it;
1548  if(l->isVisible() == true){
1549  if(l->meline == NULL){
1550  l->initMovingEdge(I, cMo);
1551  }
1552  l->trackMovingEdge(I, cMo) ;
1553  }
1554  }
1555 
1557  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1558  cy = *it;
1559  if(cy->isVisible()) {
1560  if(cy->meline1 == NULL || cy->meline2 == NULL){
1561  cy->initMovingEdge(I, cMo);
1562  }
1563  cy->trackMovingEdge(I, cMo) ;
1564  }
1565  }
1566 
1567  vpMbtDistanceCircle *ci;
1568  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1569  ci = *it;
1570  if(ci->isVisible() == true){
1571  if(ci->meEllipse == NULL){
1572  ci->initMovingEdge(I, cMo);
1573  }
1574  ci->trackMovingEdge(I, cMo) ;
1575  }
1576  }
1577 }
1578 
1579 
1585 void
1587 {
1588  vpMbtDistanceLine *l ;
1589  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1590  l = *it;
1591  l->updateMovingEdge(I, cMo) ;
1592  if (l->nbFeature == 0 && l->isVisible()){
1593  l->Reinit = true;
1594  }
1595  }
1596 
1597  vpMbtDistanceCylinder *cy ;
1598  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1599  cy = *it;
1600  cy->updateMovingEdge(I, cMo) ;
1601  if((cy->nbFeaturel1 == 0 || cy->nbFeaturel2 == 0) && cy->isVisible()){
1602  cy->Reinit = true;
1603  }
1604  }
1605 
1606  vpMbtDistanceCircle *ci ;
1607  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1608  ci = *it;
1609  ci->updateMovingEdge(I, cMo) ;
1610  if(ci->nbFeature == 0 && ci->isVisible()){
1611  ci->Reinit = true;
1612  }
1613  }
1614 }
1615 
1616 
1625 void
1627 {
1628  vpMbtDistanceLine *l ;
1629  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1630  l = *it;
1631  if (l->Reinit && l->isVisible())
1632  l->reinitMovingEdge(I, _cMo);
1633  }
1634 
1636  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1637  cy = *it;
1638  if (cy->Reinit && cy->isVisible())
1639  cy->reinitMovingEdge(I, _cMo);
1640  }
1641 
1643  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1644  ci = *it;
1645  if (ci->Reinit && ci->isVisible())
1646  ci->reinitMovingEdge(I, _cMo);
1647  }
1648 }
1649 
1650 
1659 bool
1661 {
1662  double dx = fabs(P1.get_oX() - P2.get_oX());
1663  double dy = fabs(P1.get_oY() - P2.get_oY());
1664  double dz = fabs(P1.get_oZ() - P2.get_oZ());
1665 
1666  if (dx <= std::numeric_limits<double>::epsilon() && dy <= std::numeric_limits<double>::epsilon() && dz <= std::numeric_limits<double>::epsilon())
1667  return true ;
1668  else
1669  return false ;
1670 }
1671 
1672 
1683 void
1684 vpMbEdgeTracker::addLine(vpPoint &P1, vpPoint &P2, int polygon, std::string name)
1685 {
1686  //suppress line already in the model
1687  bool already_here = false ;
1688  vpMbtDistanceLine *l ;
1689 
1690  for (unsigned int i = 0; i < scales.size(); i += 1){
1691  if(scales[i]){
1692  downScale(i);
1693  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
1694  l = *it;
1695  if((samePoint(*(l->p1),P1) && samePoint(*(l->p2),P2)) ||
1696  (samePoint(*(l->p1),P2) && samePoint(*(l->p2),P1)) ){
1697  already_here = true ;
1698  l->Lindex_polygon.push_back(polygon);
1699  l->hiddenface = &faces ;
1700  }
1701  }
1702 
1703  if (!already_here){
1704  l = new vpMbtDistanceLine ;
1705 
1706  l->setCameraParameters(cam) ;
1707  l->buildFrom(P1,P2) ;
1708  l->Lindex_polygon.push_back(polygon);
1709  l->setMovingEdge(&me) ;
1710  l->hiddenface = &faces ;
1711 
1712  l->setIndex(nline) ;
1713  l->setName(name);
1714 
1717 
1718  if((clippingFlag & vpMbtPolygon::NEAR_CLIPPING) == vpMbtPolygon::NEAR_CLIPPING)
1720 
1721  if((clippingFlag & vpMbtPolygon::FAR_CLIPPING) == vpMbtPolygon::FAR_CLIPPING)
1723 
1724  nline +=1 ;
1725  lines[i].push_back(l);
1726  }
1727  upScale(i);
1728  }
1729  }
1730 }
1731 
1737 void
1738 vpMbEdgeTracker::removeLine(const std::string& name)
1739 {
1740  vpMbtDistanceLine *l;
1741 
1742  for(unsigned int i=0; i<scales.size(); i++){
1743  if(scales[i]){
1744  for(std::list<vpMbtDistanceLine*>::iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
1745  l = *it;
1746  if (name.compare(l->getName()) == 0){
1747  lines[i].erase(it);
1748  break;
1749  }
1750  }
1751  }
1752  }
1753 }
1754 
1765 void
1766 vpMbEdgeTracker::addCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, const double r, int idFace, const std::string& name)
1767 {
1768  bool already_here = false ;
1769  vpMbtDistanceCircle *ci ;
1770 
1771  for (unsigned int i = 0; i < scales.size(); i += 1){
1772  if(scales[i]){
1773  downScale(i);
1774  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
1775  ci = *it;
1776  if((samePoint(*(ci->p1),P1) && samePoint(*(ci->p2),P2) && samePoint(*(ci->p3),P3)) ||
1777  (samePoint(*(ci->p1),P1) && samePoint(*(ci->p2),P3) && samePoint(*(ci->p3),P2)) ){
1778  already_here = (std::fabs(ci->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(ci->radius, r));
1779  }
1780  }
1781 
1782  if (!already_here){
1783  ci = new vpMbtDistanceCircle ;
1784 
1785  ci->setCameraParameters(cam);
1786  ci->buildFrom(P1, P2, P3, r);
1787  ci->setMovingEdge(&me);
1788  ci->setIndex(ncircle);
1789  ci->setName(name);
1790  ci->index_polygon = idFace;
1791  ci->hiddenface = &faces ;
1792 
1793 // if(clippingFlag != vpMbtPolygon::NO_CLIPPING)
1794 // ci->getPolygon().setClipping(clippingFlag);
1795 
1796 // if((clippingFlag & vpMbtPolygon::NEAR_CLIPPING) == vpMbtPolygon::NEAR_CLIPPING)
1797 // ci->getPolygon().setNearClippingDistance(distNearClip);
1798 
1799 // if((clippingFlag & vpMbtPolygon::FAR_CLIPPING) == vpMbtPolygon::FAR_CLIPPING)
1800 // ci->getPolygon().setFarClippingDistance(distFarClip);
1801 
1802  ncircle +=1;
1803  circles[i].push_back(ci);
1804  }
1805  upScale(i);
1806  }
1807  }
1808 }
1809 
1819 void
1820 vpMbEdgeTracker::addCylinder(const vpPoint &P1, const vpPoint &P2, const double r, int idFace, const std::string& name)
1821 {
1822  bool already_here = false ;
1823  vpMbtDistanceCylinder *cy ;
1824 
1825  for (unsigned int i = 0; i < scales.size(); i += 1){
1826  if(scales[i]){
1827  downScale(i);
1828  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
1829  cy = *it;
1830  if((samePoint(*(cy->p1),P1) && samePoint(*(cy->p2),P2)) ||
1831  (samePoint(*(cy->p1),P2) && samePoint(*(cy->p2),P1)) ){
1832  already_here = (std::fabs(cy->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(cy->radius, r));
1833  }
1834  }
1835 
1836  if (!already_here){
1837  cy = new vpMbtDistanceCylinder ;
1838 
1839  cy->setCameraParameters(cam);
1840  cy->buildFrom(P1, P2, r);
1841  cy->setMovingEdge(&me);
1842  cy->setIndex(ncylinder);
1843  cy->setName(name);
1844  cy->index_polygon = idFace;
1845  cy->hiddenface = &faces ;
1846  ncylinder +=1;
1847  cylinders[i].push_back(cy);
1848  }
1849  upScale(i);
1850  }
1851  }
1852 }
1853 
1859 void
1860 vpMbEdgeTracker::removeCylinder(const std::string& name)
1861 {
1863 
1864  for(unsigned int i=0; i<scales.size(); i++){
1865  if(scales[i]){
1866  for(std::list<vpMbtDistanceCylinder*>::iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
1867  cy = *it;
1868  if (name.compare(cy->getName()) == 0){
1869  cylinders[i].erase(it);
1870  break;
1871  }
1872  }
1873  }
1874  }
1875 }
1876 
1882 void
1883 vpMbEdgeTracker::removeCircle(const std::string& name)
1884 {
1885  vpMbtDistanceCircle *ci;
1886 
1887  for(unsigned int i=0; i<scales.size(); i++){
1888  if(scales[i]){
1889  for(std::list<vpMbtDistanceCircle*>::iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
1890  ci = *it;
1891  if (name.compare(ci->getName()) == 0){
1892  circles[i].erase(it);
1893  break;
1894  }
1895  }
1896  }
1897  }
1898 }
1899 
1905 void
1907 {
1908  unsigned int nbpt = p.getNbPoint() ;
1909  if(nbpt > 0){
1910  for (unsigned int i=0 ; i < nbpt-1 ; i++)
1911  addLine(p.p[i], p.p[i+1], p.getIndex()) ;
1912  addLine(p.p[nbpt-1], p.p[0], p.getIndex()) ;
1913  }
1914 }
1915 
1916 
1917 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1918 
1929 void
1930 vpMbEdgeTracker::visibleFace(const vpHomogeneousMatrix &_cMo, bool &newvisibleline)
1931 {
1932  unsigned int n ;
1933 
1934  if(!useOgre)
1935  n = faces.setVisible(_cMo) ;
1936  else{
1937 #ifdef VISP_HAVE_OGRE
1938  bool changed = false;
1939  n = faces.setVisibleOgre(_cMo, vpMath::rad(70), vpMath::rad(70), changed);
1940 #else
1941  n = faces.setVisible(_cMo) ;
1942 #endif
1943  }
1944 
1945 // cout << "visible face " << n << endl ;
1946  if (n > nbvisiblepolygone)
1947  {
1948  //cout << "une nouvelle face est visible " << endl ;
1949  newvisibleline = true ;
1950  }
1951  else
1952  newvisibleline = false ;
1953 
1954  nbvisiblepolygone= n ;
1955 }
1956 #endif //VISP_BUILD_DEPRECATED_FUNCTIONS
1957 
1968 void
1970  const vpHomogeneousMatrix &_cMo, bool &newvisibleline)
1971 {
1972  unsigned int n ;
1973  bool changed = false;
1974 
1975  if(!useOgre) {
1976  //n = faces.setVisible(_I, cam, _cMo, vpMath::rad(89), vpMath::rad(89), changed) ;
1977  n = faces.setVisible(_I, cam, _cMo, angleAppears, angleDisappears, changed) ;
1978  }
1979  else{
1980 #ifdef VISP_HAVE_OGRE
1981  n = faces.setVisibleOgre(_I, cam, _cMo, angleAppears, angleDisappears, changed);
1982 #else
1983  n = faces.setVisible(_I, cam, _cMo, angleAppears, angleDisappears, changed) ;
1984 #endif
1985  }
1986 
1987  if (n > nbvisiblepolygone)
1988  {
1989  //cout << "une nouvelle face est visible " << endl ;
1990  newvisibleline = true ;
1991  }
1992  else
1993  newvisibleline = false ;
1994 
1995  nbvisiblepolygone= n ;
1996 }
1997 
2010 void
2012 {
2013  unsigned int nbpt = polygon.getNbPoint() ;
2014  if(nbpt > 0){
2015  for (unsigned int i=0 ; i < nbpt-1 ; i++)
2016  addLine(polygon.p[i], polygon.p[i+1], polygon.getIndex(), polygon.getName());
2017  addLine(polygon.p[nbpt-1], polygon.p[0], polygon.getIndex(), polygon.getName());
2018  }
2019 }
2032 void
2034 {
2035  unsigned int nbpt = polygon.getNbPoint() ;
2036  if(nbpt > 0){
2037  for (unsigned int i=0 ; i < nbpt-1 ; i++)
2038  addLine(polygon.p[i], polygon.p[i+1], polygon.getIndex(), polygon.getName());
2039  }
2040 }
2041 
2053 void
2054 vpMbEdgeTracker::initCircle(const vpPoint& p1, const vpPoint &p2, const vpPoint &p3, const double radius,
2055  const int idFace, const std::string &name)
2056 {
2057  addCircle(p1, p2, p3, radius, (int)idFace, name);
2058 }
2059 
2070 void
2071 vpMbEdgeTracker::initCylinder(const vpPoint& p1, const vpPoint &p2, const double radius, const int idFace,
2072  const std::string &name)
2073 {
2074  addCylinder(p1, p2, radius, (int)idFace, name);
2075 }
2076 
2082 void
2084 {
2085  this->cMo.setIdentity();
2086  vpMbtDistanceLine *l;
2088  vpMbtDistanceCircle *ci;
2089 
2090  for (unsigned int i = 0; i < scales.size(); i += 1){
2091  if(scales[i]){
2092  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2093  l = *it;
2094  if (l!=NULL) delete l ;
2095  l = NULL ;
2096  }
2097 
2098  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
2099  cy = *it;
2100  if (cy!=NULL) delete cy;
2101  cy = NULL;
2102  }
2103 
2104  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
2105  ci = *it;
2106  if (ci!=NULL) delete ci;
2107  ci = NULL;
2108  }
2109  lines[i].clear();
2110  cylinders[i].clear();
2111  circles[i].clear();
2112  }
2113  }
2114 
2115  faces.reset();
2116 
2117 #ifdef VISP_HAVE_OGRE
2118  useOgre = false;
2119 #endif
2120 
2122  nline = 0;
2123  ncylinder = 0;
2124  lambda = 1;
2125  nbvisiblepolygone = 0;
2126  percentageGdPt = 0.4;
2127 
2128  angleAppears = vpMath::rad(89);
2131 
2132  // reinitialization of the scales.
2133  this->setScales(scales);
2134 }
2135 
2145 void
2146 vpMbEdgeTracker::reInitModel(const vpImage<unsigned char>& I, const std::string &cad_name,
2147  const vpHomogeneousMatrix& cMo_, const bool verbose)
2148 {
2149  reInitModel(I, cad_name.c_str(), cMo_, verbose);
2150 }
2151 
2161 void
2163  const vpHomogeneousMatrix& cMo_, const bool verbose)
2164 {
2165  this->cMo.setIdentity();
2166  vpMbtDistanceLine *l;
2168  vpMbtDistanceCircle *ci;
2169 
2170  for (unsigned int i = 0; i < scales.size(); i += 1){
2171  if(scales[i]){
2172  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2173  l = *it;
2174  if (l!=NULL) delete l ;
2175  l = NULL ;
2176  }
2177 
2178  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
2179  cy = *it;
2180  if (cy!=NULL) delete cy;
2181  cy = NULL;
2182  }
2183 
2184  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
2185  ci = *it;
2186  if (ci!=NULL) delete ci;
2187  ci = NULL;
2188  }
2189 
2190  lines[i].clear();
2191  cylinders[i].clear();
2192  circles[i].clear();
2193  }
2194  }
2195 
2196  faces.reset();
2197 
2198  //compute_interaction=1;
2199  nline = 0;
2200  ncylinder = 0;
2201  ncircle = 0;
2202  //lambda = 1;
2203  nbvisiblepolygone = 0;
2204 
2205  loadModel(cad_name, verbose);
2206  initFromPose(I, cMo_);
2207 }
2208 
2219 unsigned int
2220 vpMbEdgeTracker::getNbPoints(const unsigned int level) const
2221 {
2222  if((level > scales.size()) || !scales[level]){
2223  throw vpException(vpException::dimensionError, "Cannot get the number of points for level %d: level is not used", level);
2224  }
2225 
2226  unsigned int nbGoodPoints = 0;
2227  vpMbtDistanceLine *l ;
2228  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[level].begin(); it!=lines[level].end(); ++it){
2229  l = *it;
2230  if (l->isVisible() && l->meline != NULL)
2231  {
2232  for(std::list<vpMeSite>::const_iterator itme=l->meline->getMeList().begin(); itme!=l->meline->getMeList().end(); ++itme){
2233  if (itme->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
2234  }
2235  }
2236  }
2237 
2238  vpMbtDistanceCylinder *cy ;
2239  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[level].begin(); it!=cylinders[level].end(); ++it){
2240  cy = *it;
2241  if (cy->isVisible() && (cy->meline1 != NULL || cy->meline2 != NULL))
2242  {
2243  for(std::list<vpMeSite>::const_iterator itme1=cy->meline1->getMeList().begin(); itme1!=cy->meline1->getMeList().end(); ++itme1){
2244  if (itme1->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
2245  }
2246  for(std::list<vpMeSite>::const_iterator itme2=cy->meline2->getMeList().begin(); itme2!=cy->meline2->getMeList().end(); ++itme2){
2247  if (itme2->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
2248  }
2249  }
2250  }
2251 
2252  vpMbtDistanceCircle *ci ;
2253  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[level].begin(); it!=circles[level].end(); ++it){
2254  ci = *it;
2255  if (ci->isVisible() && ci->meEllipse != NULL)
2256  {
2257  for(std::list<vpMeSite>::const_iterator itme=ci->meEllipse->getMeList().begin(); itme!=ci->meEllipse->getMeList().end(); ++itme){
2258  if (itme->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
2259  }
2260  }
2261  }
2262 
2263  return nbGoodPoints;
2264 }
2265 
2286 void
2287 vpMbEdgeTracker::setScales(const std::vector<bool>& scale)
2288 {
2289  unsigned int nbActivatedLevels = 0;
2290  for (unsigned int i = 0; i < scale.size(); i += 1){
2291  if(scale[i]){
2292  nbActivatedLevels++;
2293  }
2294  }
2295  if((scale.size() < 1) || (nbActivatedLevels == 0)){
2296  vpERROR_TRACE(" !! WARNING : must use at least one level for the tracking. Use the global one");
2297  this->scales.resize(0);
2298  this->scales.push_back(true);
2299  lines.resize(1);
2300  lines[0].clear();
2301  cylinders.resize(1);
2302  cylinders[0].clear();
2303  }
2304  else{
2305  this->scales = scale;
2306  lines.resize(scale.size());
2307  cylinders.resize(scale.size());
2308  for (unsigned int i = 0; i < lines.size(); i += 1){
2309  lines[i].clear();
2310  cylinders[i].clear();
2311  }
2312  }
2313 }
2314 
2320 void
2322 {
2323  if( (clippingFlag & vpMbtPolygon::NEAR_CLIPPING) == vpMbtPolygon::NEAR_CLIPPING && dist <= distNearClip)
2324  vpTRACE("Far clipping value cannot be inferior than near clipping value. Far clipping won't be considered.");
2325  else if ( dist < 0 )
2326  vpTRACE("Far clipping value cannot be inferior than 0. Far clipping won't be considered.");
2327  else{
2329  vpMbtDistanceLine *l;
2330 
2331  for (unsigned int i = 0; i < scales.size(); i += 1){
2332  if(scales[i]){
2333  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2334  l = *it;
2336  }
2337  }
2338  }
2339  }
2340 }
2341 
2347 void
2349 {
2350  if( (clippingFlag & vpMbtPolygon::FAR_CLIPPING) == vpMbtPolygon::FAR_CLIPPING && dist >= distFarClip)
2351  vpTRACE("Near clipping value cannot be superior than far clipping value. Near clipping won't be considered.");
2352  else if ( dist < 0 )
2353  vpTRACE("Near clipping value cannot be inferior than 0. Near clipping won't be considered.");
2354  else{
2356  vpMbtDistanceLine *l;
2357 
2358  for (unsigned int i = 0; i < scales.size(); i += 1){
2359  if(scales[i]){
2360  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2361  l = *it;
2363  }
2364  }
2365  }
2366  }
2367 }
2368 
2376 void
2377 vpMbEdgeTracker::setClipping(const unsigned int &flags)
2378 {
2379  vpMbTracker::setClipping(flags);
2380 
2381  vpMbtDistanceLine *l;
2382 
2383  for (unsigned int i = 0; i < scales.size(); i += 1){
2384  if(scales[i]){
2385  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2386  l = *it;
2388  }
2389  }
2390  }
2391 }
2392 
2407 void
2409 {
2410  _pyramid.resize(scales.size());
2411 
2412  if(scales[0]){
2413  _pyramid[0] = &_I;
2414  }
2415  else{
2416  _pyramid[0] = NULL;
2417  }
2418 
2419  for(unsigned int i=1; i<_pyramid.size(); i += 1){
2420  if(scales[i]){
2421  unsigned int cScale = static_cast<unsigned int>(pow(2., (int)i));
2422  vpImage<unsigned char>* I = new vpImage<unsigned char>(_I.getHeight() / cScale, _I.getWidth() / cScale);
2423 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x020408))
2424  IplImage* vpI0 = cvCreateImageHeader(cvSize((int)_I.getWidth(), (int)_I.getHeight()), IPL_DEPTH_8U, 1);
2425  vpI0->imageData = (char*)(_I.bitmap);
2426  IplImage* vpI = cvCreateImage(cvSize((int)(_I.getWidth() / cScale), (int)(_I.getHeight() / cScale)), IPL_DEPTH_8U, 1);
2427  cvResize(vpI0, vpI, CV_INTER_NN);
2428  vpImageConvert::convert(vpI, *I);
2429  cvReleaseImage(&vpI);
2430  vpI0->imageData = NULL;
2431  cvReleaseImageHeader(&vpI0);
2432 #else
2433  for (unsigned int k = 0, ii = 0; k < I->getHeight(); k += 1, ii += cScale){
2434  for (unsigned int l = 0, jj = 0; l < I->getWidth(); l += 1, jj += cScale){
2435  (*I)[k][l] = _I[ii][jj];
2436  }
2437  }
2438 #endif
2439  _pyramid[i] = I;
2440  }
2441  else{
2442  _pyramid[i] = NULL;
2443  }
2444  }
2445 }
2446 
2453 void
2455 {
2456  if(_pyramid.size() > 0){
2457  _pyramid[0] = NULL;
2458  for (unsigned int i = 1; i < _pyramid.size(); i += 1){
2459  if(_pyramid[i] != NULL){
2460  delete _pyramid[i];
2461  _pyramid[i] = NULL;
2462  }
2463  }
2464  _pyramid.resize(0);
2465  }
2466 }
2467 
2478 void
2479 vpMbEdgeTracker::getLline(std::list<vpMbtDistanceLine *>& linesList, const unsigned int level)
2480 {
2481  if(level > scales.size() || !scales[level]){
2482  std::ostringstream oss;
2483  oss << level;
2484  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2485  throw vpException(vpException::dimensionError, errorMsg);
2486  }
2487 
2488  linesList = lines[level];
2489 }
2490 
2491 
2502 void
2503 vpMbEdgeTracker::getLcylinder(std::list<vpMbtDistanceCylinder *>& cylindersList, const unsigned int level)
2504 {
2505  if(level > scales.size() || !scales[level]){
2506  std::ostringstream oss;
2507  oss << level;
2508  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2509  throw vpException(vpException::dimensionError, errorMsg);
2510  }
2511 
2512  cylindersList = cylinders[level];
2513 }
2514 
2515 
2526 void
2527 vpMbEdgeTracker::getLcircle(std::list<vpMbtDistanceCircle *>& circlesList, const unsigned int level)
2528 {
2529  if(level > scales.size() || !scales[level]){
2530  std::ostringstream oss;
2531  oss << level;
2532  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2533  throw vpException(vpException::dimensionError, errorMsg);
2534  }
2535 
2536  circlesList = circles[level];
2537 }
2538 
2545 void
2546 vpMbEdgeTracker::downScale(const unsigned int _scale)
2547 {
2548  const double ratio = pow(2., (int)_scale);
2549  scaleLevel = _scale;
2550 
2551  vpMatrix K = cam.get_K();
2552 
2553  K[0][0] /= ratio;
2554  K[1][1] /= ratio;
2555  K[0][2] /= ratio;
2556  K[1][2] /= ratio;
2557 
2559 }
2560 
2567 void
2568 vpMbEdgeTracker::upScale(const unsigned int _scale)
2569 {
2570  const double ratio = pow(2., (int)_scale);
2571  scaleLevel = 0;
2572 
2573  vpMatrix K = cam.get_K();
2574 
2575  K[0][0] *= ratio;
2576  K[1][1] *= ratio;
2577  K[0][2] *= ratio;
2578  K[1][2] *= ratio;
2579 
2580 
2582 }
2583 
2591 void
2592 vpMbEdgeTracker::reInitLevel(const unsigned int _lvl)
2593 {
2594  unsigned int scaleLevel_1 = scaleLevel;
2595  scaleLevel = _lvl;
2596 
2597  vpMbtDistanceLine *l;
2598  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
2599  l = *it;
2600  l->reinitMovingEdge(*Ipyramid[_lvl], cMo);
2601  }
2602 
2604  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
2605  cy = *it;
2606  cy->reinitMovingEdge(*Ipyramid[_lvl], cMo);
2607  }
2608 
2609  vpMbtDistanceCircle *ci;
2610  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
2611  ci = *it;
2612  ci->reinitMovingEdge(*Ipyramid[_lvl], cMo);
2613  }
2614 
2615  trackMovingEdge(*Ipyramid[_lvl]);
2616  updateMovingEdge(*Ipyramid[_lvl]);
2617  scaleLevel = scaleLevel_1;
2618 }
2619 
void setWindowName(const Ogre::String &n)
Definition: vpAROgre.h:268
unsigned int ncylinder
Index of the cylinder to add, and total number of cylinders extracted so far.
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
void displayMovingEdges(const vpImage< unsigned char > &I)
vpMatrix covarianceMatrix
Covariance matrix.
Definition: vpMbTracker.h:126
void initFromCalibrationMatrix(const vpMatrix &_K)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void setFarClippingDistance(const double &dist)
Definition: vpMbtPolygon.h:226
void setMovingEdge(const vpMe &me)
void setClipping(const unsigned int &flags)
Definition: vpMbtPolygon.h:219
unsigned int nbFeature
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)
void upScale(const unsigned int _scale)
std::string getName() const
virtual void initFaceFromCorners(vpMbtPolygon &polygon)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Compute the weights according a residue vector and a PsiFunction.
Definition: vpRobust.cpp:136
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)
unsigned int getWidth() const
Definition: vpImage.h:161
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
void getCameraParameters(vpCameraParameters &_cam) const
vpMbHiddenFaces< vpMbtPolygon > faces
Set of faces describing the object.
Definition: vpMbTracker.h:135
bool Reinit
Indicates if the line has to be reinitialized.
void setMeanWeight2(const double wmean)
void computeVVS(const vpImage< unsigned char > &_I)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpERROR_TRACE
Definition: vpDebug.h:395
void init(const vpImage< unsigned char > &I)
void track(const vpImage< unsigned char > &I)
#define vpTRACE
Definition: vpDebug.h:418
double lambda
The gain of the virtual visual servoing stage.
unsigned int scaleLevel
Current scale level used. This attribute must not be modified outside of the downScale() and upScale(...
std::list< int > Lindex_polygon
Index of the faces which contain the line.
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
vpMatrix L
The interaction matrix.
void setCameraParameters(const vpCameraParameters &camera)
void setIdentity()
Basic initialisation (identity)
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'...
Definition: vpMeSite.h:76
std::vector< std::list< vpMbtDistanceCircle * > > circles
Vector of the tracked circles.
Class to define colors available for display functionnalities.
Definition: vpColor.h:125
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)
void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w)
vpHomogeneousMatrix cMo
The current pose.
Definition: vpMbTracker.h:112
vpPoint * p1
The first extremity.
void displayMovingEdges(const vpImage< unsigned char > &I)
double getNearClippingDistance() const
virtual ~vpMbEdgeTracker()
unsigned int ncircle
Index of the circle to add, and total number of circles extracted so far.
vpColVector error
The error vector.
bool modelInitialised
Flag used to ensure that the CAD model is loaded before the initialisation.
Definition: vpMbTracker.h:120
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.h:129
void getMe(vpMe &_ecm) const
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const vpPoint &_p3, const double r)
error that can be emited by ViSP classes.
Definition: vpException.h:76
void computeJTR(const vpMatrix &J, const vpColVector &R, vpMatrix &JTR)
vpMbtMeEllipse * meEllipse
Polygon describing the circle bbox.
Manage a cylinder used in the model-based tracker.
void reInitLevel(const unsigned int _lvl)
Contains predetermined masks for sites and holds moving edges tracking parameters.
Definition: vpMe.h:70
Manage the line of a polygon used in the model-based tracker.
unsigned int nbFeature
The number of moving edges.
virtual void setPose(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cdMo)
std::vector< const vpImage< unsigned char > * > Ipyramid
Pyramid of image associated to the current image. This pyramid is computed in the init() and in the t...
void removeCircle(const std::string &name)
bool useOgre
Use Ogre3d for visibility tests.
Definition: vpMbTracker.h:147
int index_polygon
Index of the faces which contain the line.
vpPoint * p2
A point on the plane containing the circle.
void getLcylinder(std::list< vpMbtDistanceCylinder * > &cylindersList, const unsigned int level=0)
void setIndex(const unsigned int i)
virtual void setCameraParameters(const vpCameraParameters &camera)
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:124
void loadConfigFile(const std::string &configFile)
vpMe me
The moving edges parameters.
void updateMovingEdge(const vpImage< unsigned char > &I)
std::vector< std::list< vpMbtDistanceLine * > > lines
Vector of list of all the lines tracked (each line is linked to a list of moving edges). Each element of the vector is for a scale (element 0 = level 0 = no subsampling).
unsigned int getNbPoints(const unsigned int level=0) const
void setNearClippingDistance(const double &dist)
Definition: vpMbtPolygon.h:280
vpPoint * p1
The first extremity on the axe.
unsigned int nbFeature
The number of moving edges.
void downScale(const unsigned int _scale)
bool hasNearClippingDistance() const
Class that defines what is a point.
Definition: vpPoint.h:65
vpMatrix L
The interaction matrix.
vpMeSiteState getState() const
Definition: vpMeSite.h:202
vpCameraParameters cam
The camera parameters.
Definition: vpMbTracker.h:110
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
virtual void setNearClippingDistance(const double &dist)
double getFarClippingDistance() const
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:143
bool hasFarClippingDistance() const
vpAROgre * getOgreContext()
int index_polygon
Index of the face which contains the cylinder.
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:114
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.
bool getLodState() const
void getLline(std::list< vpMbtDistanceLine * > &linesList, const unsigned int level=0)
Error that can be emited by the vpTracker class and its derivates.
double getAngleDisappear() const
Implementation of a polygon of the model used by the model-based tracker.
Definition: vpMbtPolygon.h:67
void initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
void setName(const std::string &circle_name)
std::string getName() const
Definition: vpMbtPolygon.h:164
vpMatrix AtA() const
Definition: vpMatrix.cpp:1479
vpPoint * p2
The second extremity.
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
static double sqr(double x)
Definition: vpMath.h:106
double minLineLengthThresholdGeneral
Minimum line length threshold for LOD mode (general setting)
Definition: vpMbTracker.h:165
void setAngleDisappear(const double &adisappear)
vpColVector error
The error vector.
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpColVector m_error
Error s-s*.
Definition: vpMbTracker.h:132
int getIndex() const
Definition: vpMbtPolygon.h:157
double getMinPolygonAreaThreshold() const
bool isVisible() const
Generic class defining intrinsic camera parameters.
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.h:131
void setIndex(const unsigned int i)
double percentageGdPt
Percentage of good points over total number of points below which tracking is supposed to have failed...
void initPyramid(const vpImage< unsigned char > &_I, std::vector< const vpImage< unsigned char > * > &_pyramid)
void cleanPyramid(std::vector< const vpImage< unsigned char > * > &_pyramid)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpMbtMeLine * meline1
The moving edge containers (first line of the cylinder)
void setVisible(bool _isvisible)
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:148
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
void setCameraParameters(const vpCameraParameters &_cam)
double angleAppears
Angle used to detect a face appearance.
Definition: vpMbTracker.h:137
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:189
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
void displayMovingEdges(const vpImage< unsigned char > &I)
double get_px() const
std::string getName() const
static double rad(double deg)
Definition: vpMath.h:100
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)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void diag(const vpColVector &A)
Definition: vpMatrix.cpp:2841
void setVisible(bool _isvisible)
void computeCovarianceMatrix(const vpHomogeneousMatrix &cMoPrev, const vpColVector &deltaS, const vpMatrix &Ls, const vpMatrix &W)
bool samePoint(const vpPoint &P1, const vpPoint &P2)
virtual void initFaceFromLines(vpMbtPolygon &polygon)
void setScales(const std::vector< bool > &_scales)
vpPoint * p2
The second extremity on the axe.
void getLcircle(std::list< vpMbtDistanceCircle * > &circlesList, const unsigned int level=0)
void eye(unsigned int n)
Definition: vpMatrix.cpp:1252
void setCameraParameters(const vpCameraParameters &camera)
double get_oX() const
Get the point X coordinate in the object frame.
Definition: vpPoint.h:127
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)
double minPolygonAreaThresholdGeneral
Minimum polygon area threshold for LOD mode (general setting)
Definition: vpMbTracker.h:167
vpMatrix get_K() const
static double deg(double rad)
Definition: vpMath.h:93
bool displayFeatures
If true, the features are displayed.
Definition: vpMbTracker.h:128
virtual void loadModel(const char *modelFile, const bool verbose=false)
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const double r)
bool applyLodSettingInConfig
True if the CAO model is loaded before the call to loadConfigFile, (deduced by the number of polygons...
Definition: vpMbTracker.h:163
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
std::vector< std::list< vpMbtDistanceCylinder * > > cylinders
Vector of the tracked cylinders.
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="")
vpHomogeneousMatrix inverse() const
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
static vpHomogeneousMatrix direct(const vpColVector &v)
void setMeanWeight(const double _wmean)
bool isVisible(const unsigned int i)
Contains an M-Estimator and various influence function.
Definition: vpRobust.h:63
unsigned int nbvisiblepolygone
Number of polygon (face) currently visible.
double angleDisappears
Angle used to detect a face disappearance.
Definition: vpMbTracker.h:139
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)
virtual unsigned int getNbPolygon() const
Definition: vpMbTracker.h:290
void visibleFace(const vpImage< unsigned char > &_I, const vpHomogeneousMatrix &_cMo, bool &newvisibleline)
unsigned int getHeight() const
Definition: vpImage.h:152
void setMeanWeight(const double w_mean)
vpColVector error
The error vector.
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1932
virtual void setClipping(const unsigned int &flags)
bool Reinit
Indicates if the line has to be reinitialized.
double radius
The radius of the cylinder.
unsigned int clippingFlag
Flags specifying which clipping to used.
Definition: vpMbTracker.h:145
unsigned int getNbPoint() const
Definition: vpMbtPolygon.h:171
unsigned int nline
Index of the polygon to add, and total number of polygon extracted so far.
void addPolygon(vpMbtPolygon &p)
void setName(const std::string line_name)
void trackMovingEdge(const vpImage< unsigned char > &I)
void displayOgre(const vpHomogeneousMatrix &cMo)
double getAngleAppear() const
virtual void setClipping(const unsigned int &flags)
unsigned int nbFeaturel2
The number of moving edges on line 2.
void setThreshold(const double noise_threshold)
Definition: vpRobust.h:128
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:161
double radius
The radius of the circle.
virtual void setFarClippingDistance(const double &dist)
void setName(const std::string &cyl_name)
static int sign(double x)
Definition: vpMath.h:248
vpMbtMeLine * meline2
The moving edge containers (second line of the cylinder)
void removeLine(const std::string &name)
bool getFovClipping() const
void setIteration(const unsigned int iter)
Set iteration.
Definition: vpRobust.h:122
double distNearClip
Distance for near clipping.
Definition: vpMbTracker.h:141
bool useLodGeneral
True if LOD mode is enabled.
Definition: vpMbTracker.h:161
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="")
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo, const vpImage< unsigned char > &I)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void setMovingEdge(const vpMe &_ecm)
bool isoJoIdentity
Boolean to know if oJo is identity (for fast computation)
Definition: vpMbTracker.h:116
std::string getName() const
vpMbtMeLine * meline
The moving edge container.
vpPoint * p1
The center of the circle.
void buildFrom(vpPoint &_p1, vpPoint &_p2)
double getMinLineLengthThreshold() const
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:98
vpColVector m_w
Weights used in the robust scheme.
Definition: vpMbTracker.h:130
virtual void setLod(const bool useLod, const std::string &name="")
virtual void setNearClippingDistance(const double &dist)
vpPoint * p
corners in the object frame
Definition: vpMbtPolygon.h:95