ViSP  2.6.2
vpMbEdgeTracker.cpp
1 /****************************************************************************
2  *
3  * $Id: vpMbEdgeTracker.cpp 2807 2010-09-14 10:14:54Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2012 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 
51 #include <visp/vpDebug.h>
52 #include <visp/vpPose.h>
53 #include <visp/vpExponentialMap.h>
54 #include <visp/vpPixelMeterConversion.h>
55 #include <visp/vpImageIo.h>
56 #include <visp/vpRobust.h>
57 #include <visp/vpDisplayOpenCV.h>
58 #include <visp/vpDisplayX.h>
59 #include <visp/vpDisplayGDI.h>
60 #include <visp/vpMatrixException.h>
61 #include <visp/vpMath.h>
62 #include <visp/vpException.h>
63 #include <visp/vpTrackingException.h>
64 #include <visp/vpMbEdgeTracker.h>
65 #include <visp/vpMbtDistanceLine.h>
66 #include <visp/vpMbtXmlParser.h>
67 
68 #include <limits>
69 #include <string>
70 #include <sstream>
71 #include <float.h>
72 
77 {
78  index_polygon =0;
80  nline = 0;
81  ncylinder = 0;
82  lambda = 1;
84  percentageGdPt = 0.4;
85  displayMe = false;
86  computeCovariance = false;
87 
88  lines.resize(1);
89  cylinders.resize(1);
90  scales.resize(1);
91  scales[0] = true;
92  lines[0].clear();
93  cylinders[0].clear();
94  Ipyramid.resize(0);
95 }
96 
101 {
102  vpMbtDistanceLine *l ;
103  vpMbtDistanceCylinder *c;
104 
105  for (unsigned int i = 0; i < lines.size(); i += 1){
106  if(scales[i]){
107  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
108  l = *it;
109  if (l!=NULL){
110  delete l ;
111  }
112  l = NULL ;
113  }
114 
115  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
116  c = *it;
117  if (c!=NULL){
118  delete c ;
119  }
120  c = NULL ;
121  }
122 
123  lines[i].clear();
124  cylinders[i].clear();
125  }
126  }
128 }
129 
135 void
137 {
138  this->me = _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  (*it)->setMovingEdge(&me) ;
144  }
145 
146  vpMbtDistanceCylinder *cy;
147  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
148  cy = *it;
149  cy->setMovingEdge(&me) ;
150  }
151  }
152  }
153 }
154 
155 
164 void
166 {
167  double residu_1 =1e3;
168  double r =1e3-1;
169  vpMatrix LTL;
170  vpColVector LTR;
171 
172  // compute the interaction matrix and its pseudo inverse
173  vpMbtDistanceLine *l ;
174  vpMbtDistanceCylinder *cy ;
175 
176  vpColVector w;
177  vpColVector weighted_error;
178  vpColVector factor;
179 
180  unsigned int iter = 0;
181 
182  //Nombre de moving edges
183  unsigned int nbrow = 0;
184  unsigned int nberrors_lines = 0;
185  unsigned int nberrors_cylinders = 0;
186 
187  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
188  l = *it;
189  nbrow += l->nbFeature ;
190  nberrors_lines+=l->nbFeature;
191  l->initInteractionMatrixError() ;
192  }
193 
194  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
195  cy = *it;
196  nbrow += cy->nbFeature ;
197  nberrors_cylinders += cy->nbFeature ;
198  cy->initInteractionMatrixError() ;
199  }
200 
201  if (nbrow==0){
202  vpERROR_TRACE("\n\t\t Error-> not enough data in the interaction matrix...") ;
203  throw vpTrackingException(vpTrackingException::notEnoughPointError, "\n\t\t Error-> not enough data in the interaction matrix...");
204  }
205 
206  vpMatrix L(nbrow,6), Lp;
207 
208  // compute the error vector
209  vpColVector error(nbrow);
210  unsigned int nerror = error.getRows();
211  vpColVector v ;
212 
213  double limite = 3; //Une limite de 3 pixels
214  limite = limite / cam.get_px(); //Transformation limite pixel en limite metre.
215 
216  //Parametre pour la premiere phase d'asservissement
217  double e_prev = 0, e_cur, e_next;
218  bool reloop = true;
219  double count = 0;
220 
221  /*** First phase ***/
222 
223  while ( reloop == true && iter<10)
224  {
225  if(iter==0)
226  {
227  weighted_error.resize(nerror) ;
228  w.resize(nerror);
229  w = 0;
230  factor.resize(nerror);
231  factor = 1;
232  }
233 
234  count = 0;
235 
236  unsigned int n = 0;
237  reloop = false;
238  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
239  l = *it;
240  l->computeInteractionMatrixError(cMo);
241 
242  double fac = 1;
243  if (iter == 0)
244  {
245  for(std::list<int>::const_iterator it = l->Lindex_polygon.begin(); it!=l->Lindex_polygon.end(); ++it){
246  int index = *it;
247  if (l->hiddenface->isAppearing(index))
248  {
249  fac = 0.2;
250  break;
251  }
252  if(l->closeToImageBorder(_I, 10))
253  {
254  fac = 0.1;
255  break;
256  }
257  }
258  }
259 
260  std::list<vpMeSite>::const_iterator itListLine;
261  if (iter == 0 && l->meline != NULL)
262  itListLine = l->meline->getMeList().begin();
263 
264  for (unsigned int i=0 ; i < l->nbFeature ; i++)
265  {
266  for (unsigned int j=0; j < 6 ; j++)
267  {
268  L[n+i][j] = l->L[i][j]; //On remplit la matrice d'interaction globale
269  }
270  error[n+i] = l->error[i]; //On remplit la matrice d'erreur
271 
272  if (error[n+i] <= limite) count = count+1.0; //Si erreur proche de 0 on incremente cur
273 
274  w[n+i] = 0;
275 
276  if (iter == 0)
277  {
278  factor[n+i] = fac;
279  vpMeSite site = *itListLine;
280  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
281  ++itListLine;
282  }
283 
284  //If pour la premiere extremite des moving edges
285  if (i == 0)
286  {
287  e_cur = l->error[0];
288  if (l->nbFeature > 1)
289  {
290  e_next = l->error[1];
291  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
292  {
293  w[n+i] = 1/*0.5*/;
294  }
295  e_prev = e_cur;
296  }
297  else w[n+i] = 1;
298  }
299 
300  //If pour la derniere extremite des moving edges
301  else if(i == l->nbFeature-1)
302  {
303  e_cur = l->error[i];
304  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
305  {
306  w[n+i] += 1/*0.5*/;
307  }
308  }
309 
310  else
311  {
312  e_cur = l->error[i];
313  e_next = l->error[i+1];
314  if ( fabs(e_cur - e_prev) < limite )
315  {
316  w[n+i] += 0.5;
317  }
318  if ( fabs(e_cur - e_next) < limite )
319  {
320  w[n+i] += 0.5;
321  }
322  e_prev = e_cur;
323  }
324  }
325 
326  n+= l->nbFeature ;
327  }
328 
329 
330  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
331  cy = *it;
332  cy->computeInteractionMatrixError(cMo, _I);
333  double fac = 0.2;
334 
335  std::list<vpMeSite>::const_iterator itCyl1;
336  std::list<vpMeSite>::const_iterator itCyl2;
337  if (iter == 0 && (cy->meline1 != NULL || cy->meline2 != NULL)){
338  itCyl1 = cy->meline1->getMeList().begin();
339  itCyl2 = cy->meline2->getMeList().begin();
340  }
341 
342  for(unsigned int i=0 ; i < cy->nbFeature ; i++){
343  for(unsigned int j=0; j < 6 ; j++){
344  L[n+i][j] = cy->L[i][j]; //On remplit la matrice d'interaction globale
345  }
346  error[n+i] = cy->error[i]; //On remplit la matrice d'erreur
347 
348  if (error[n+i] <= limite) count = count+1.0; //Si erreur proche de 0 on incremente cur
349 
350  w[n+i] = 0;
351 
352  if (iter == 0)
353  {
354  factor[n+i] = fac;
355  vpMeSite site;
356  if(i<cy->nbFeaturel1) {
357  site= *itCyl1;
358  ++itCyl1;
359  }
360  else{
361  site= *itCyl2;
362  ++itCyl2;
363  }
364  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
365  }
366 
367  //If pour la premiere extremite des moving edges
368  if (i == 0)
369  {
370  e_cur = cy->error[0];
371  if (cy->nbFeature > 1)
372  {
373  e_next = cy->error[1];
374  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
375  {
376  w[n+i] = 1/*0.5*/;
377  }
378  e_prev = e_cur;
379  }
380  else w[n+i] = 1;
381  }
382  if (i == cy->nbFeaturel1)
383  {
384  e_cur = cy->error[i];
385  if (cy->nbFeaturel2 > 1)
386  {
387  e_next = cy->error[i+1];
388  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
389  {
390  w[n+i] = 1/*0.5*/;
391  }
392  e_prev = e_cur;
393  }
394  else w[n+i] = 1;
395  }
396 
397  //If pour la derniere extremite des moving edges
398  else if(i == cy->nbFeaturel1-1)
399  {
400  e_cur = cy->error[i];
401  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
402  {
403  w[n+i] += 1/*0.5*/;
404  }
405  }
406  //If pour la derniere extremite des moving edges
407  else if(i == cy->nbFeature-1)
408  {
409  e_cur = cy->error[i];
410  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
411  {
412  w[n+i] += 1/*0.5*/;
413  }
414  }
415 
416  else
417  {
418  e_cur = cy->error[i];
419  e_next = cy->error[i+1];
420  if ( fabs(e_cur - e_prev) < limite ){
421  w[n+i] += 0.5;
422  }
423  if ( fabs(e_cur - e_next) < limite ){
424  w[n+i] += 0.5;
425  }
426  e_prev = e_cur;
427  }
428  }
429 
430  n+= cy->nbFeature ;
431  }
432 
433  count = count / (double)nbrow;
434  if (count < 0.85){
435  reloop = true;
436  }
437 
438  double num=0;
439  double den=0;
440 
441  double wi ; double eri ;
442  for(unsigned int i = 0; i < nerror; i++){
443  wi = w[i]*factor[i];
444  eri = error[i];
445  num += wi*vpMath::sqr(eri);
446  den += wi ;
447 
448  weighted_error[i] = wi*eri ;
449  }
450 
451  if((iter==0) || compute_interaction){
452  for (unsigned int i=0 ; i < nerror ; i++){
453  for (unsigned int j=0 ; j < 6 ; j++){
454  L[i][j] = w[i]*factor[i]*L[i][j] ;
455  }
456  }
457  }
458 
459  LTL = L.AtA();
460  computeJTR(L, weighted_error, LTR);
461  v = -0.7*LTL.pseudoInverse(LTL.getRows()*DBL_EPSILON)*LTR;
463 
464  iter++;
465  }
466 // cout << "\t First minimization in " << iter << " iteration " << endl ;
467 
468 /*** Second phase ***/
469 
470  vpRobust robust_lines(nberrors_lines);
471  vpRobust robust_cylinders(nberrors_cylinders);
472  robust_lines.setIteration(0) ;
473  robust_cylinders.setIteration(0) ;
474  iter = 0;
475  vpColVector w_lines(nberrors_lines);
476  vpColVector w_cylinders(nberrors_cylinders);
477  vpColVector error_lines(nberrors_lines);
478  vpColVector error_cylinders(nberrors_cylinders);
479 
480  vpColVector error_vec;
481  vpColVector W_true;
482  vpMatrix L_true;
483 
484  while ( ((int)((residu_1 - r)*1e8) !=0 ) && (iter<30))
485  {
486  unsigned int n = 0 ;
487  unsigned int nlines = 0;
488  unsigned int ncylinders = 0;
489  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
490  l = *it;
491  l->computeInteractionMatrixError(cMo) ;
492  for (unsigned int i=0 ; i < l->nbFeature ; i++){
493  for (unsigned int j=0; j < 6 ; j++){
494  L[n+i][j] = l->L[i][j];
495  error[n+i] = l->error[i];
496  error_lines[nlines+i] = error[n+i];
497  }
498  }
499  n+= l->nbFeature;
500  nlines+= l->nbFeature;
501  }
502 
503  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
504  cy = *it;
505  cy->computeInteractionMatrixError(cMo, _I) ;
506  for(unsigned int i=0 ; i < cy->nbFeature ; i++){
507  for(unsigned int j=0; j < 6 ; j++){
508  L[n+i][j] = cy->L[i][j];
509  error[n+i] = cy->error[i];
510  error_cylinders[ncylinders+i] = error[n+i];
511  }
512  }
513 
514  n+= cy->nbFeature ;
515  ncylinders+= cy->nbFeature ;
516  }
517 
518  if(iter==0)
519  {
520  weighted_error.resize(nerror);
521  w.resize(nerror);
522  w = 1;
523  w_lines.resize(nberrors_lines);
524  w_lines = 1;
525  w_cylinders.resize(nberrors_cylinders);
526  w_cylinders = 1;
527 
528  robust_lines.setThreshold(2/cam.get_px());
529  robust_cylinders.setThreshold(2/cam.get_px());
530  if(nberrors_lines > 0)
531  robust_lines.MEstimator(vpRobust::TUKEY, error_lines,w_lines);
532  if(nberrors_cylinders > 0){
533  robust_cylinders.MEstimator(vpRobust::TUKEY, error_cylinders,w_cylinders);
534  }
535  }
536  else
537  {
538  robust_lines.setIteration(iter);
539  robust_cylinders.setIteration(iter);
540  if(nberrors_lines > 0)
541  robust_lines.MEstimator(vpRobust::TUKEY, error_lines, w_lines);
542  if(nberrors_cylinders > 0){
543  robust_cylinders.MEstimator(vpRobust::TUKEY, error_cylinders,w_cylinders);
544  }
545  }
546 
547  unsigned int cpt = 0;
548  while(cpt<nbrow){
549  if(cpt<nberrors_lines){
550  w[cpt] = w_lines[cpt];
551  }
552  else{
553  w[cpt] = w_cylinders[cpt-nberrors_lines];
554  }
555  cpt++;
556  }
557 
558  residu_1 = r;
559 
560  double num=0;
561  double den=0;
562  double wi;
563  double eri;
564 
565  L_true = L;
566  W_true = vpColVector(nerror);
567 
568  for(unsigned int i=0; i<nerror; i++){
569  wi = w[i]*factor[i];
570  W_true[i] = wi*wi;
571  eri = error[i];
572  num += wi*vpMath::sqr(eri);
573  den += wi;
574 
575  weighted_error[i] = wi*eri ;
576  }
577 
578  r = sqrt(num/den); //Le critere d'arret prend en compte le poids
579 
580  if((iter==0)|| compute_interaction){
581  for (unsigned int i=0 ; i < nerror ; i++){
582  for (unsigned int j=0 ; j < 6 ; j++){
583  L[i][j] = w[i]*factor[i]*L[i][j];
584  }
585  }
586  }
587 
588  LTL = L.AtA();
589  computeJTR(L, weighted_error, LTR);
590  v = -lambda*LTL.pseudoInverse(LTL.getRows()*DBL_EPSILON)*LTR;
592 
593  iter++;
594  }
595 
596  vpMatrix D; //Should be the M.diag(wi) * M.diag(wi).transpose() = (M.diag(wi^2)) which is more efficient
597  D.diag(W_true);
598 
599  if(computeCovariance){
601  }
602 
603  unsigned int n =0 ;
604  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
605  l = *it;
606  {
607  double wmean = 0 ;
608  std::list<vpMeSite>::iterator itListLine;
609  if (l->nbFeature > 0) itListLine = l->meline->getMeList().begin();
610 
611  for (unsigned int i=0 ; i < l->nbFeature ; i++){
612  wmean += w[n+i] ;
613  vpMeSite p = *itListLine;
614  if (w[n+i] < 0.5){
616 
617  *itListLine = p;
618  }
619 
620  ++itListLine;
621  }
622  n+= l->nbFeature ;
623 
624  if (l->nbFeature!=0)
625  wmean /= l->nbFeature ;
626  else
627  wmean = 1;
628 
629  l->setMeanWeight(wmean);
630 
631  if (wmean < 0.8)
632  l->Reinit = true;
633  }
634  }
635 
636 
637  // Same thing with cylinders as with lines
638  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
639  cy = *it;
640  double wmean = 0 ;
641  std::list<vpMeSite>::iterator itListCyl1;
642  std::list<vpMeSite>::iterator itListCyl2;
643  if (cy->nbFeature > 0){
644  itListCyl1 = cy->meline1->getMeList().begin();
645  itListCyl2 = cy->meline2->getMeList().begin();
646  }
647 
648  wmean = 0;
649  for(unsigned int i=0 ; i < cy->nbFeaturel1 ; i++){
650  wmean += w[n+i] ;
651  vpMeSite p = *itListCyl1;
652  if (w[n+i] < 0.5){
654 
655  *itListCyl1 = p;
656  }
657 
658  ++itListCyl1;
659  }
660 
661  if (cy->nbFeaturel1!=0)
662  wmean /= cy->nbFeaturel1 ;
663  else
664  wmean = 1;
665 
666  cy->setMeanWeight1(wmean);
667 
668  if (wmean < 0.8){
669  cy->Reinit = true;
670  }
671 
672  wmean = 0;
673  for(unsigned int i=cy->nbFeaturel1 ; i < cy->nbFeature ; i++){
674  wmean += w[n+i] ;
675  vpMeSite p = *itListCyl2;
676  if (w[n+i] < 0.5){
678 
679  *itListCyl2 = p;
680  }
681 
682  ++itListCyl2;
683  }
684 
685  if (cy->nbFeaturel2!=0)
686  wmean /= cy->nbFeaturel2 ;
687  else
688  wmean = 1;
689 
690  cy->setMeanWeight2(wmean);
691 
692  if (wmean < 0.8){
693  cy->Reinit = true;
694  }
695 
696  n+= cy->nbFeature ;
697  }
698 }
699 
705 void
707 {
708  int nbExpectedPoint = 0;
709  int nbGoodPoint = 0;
710  int nbBadPoint = 0;
711 
712  vpMbtDistanceLine *l ;
713  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
714  l = *it;
715  if (l->isVisible() && l->meline != NULL)
716  {
717  nbExpectedPoint += (int)l->meline->expecteddensity;
718  for(std::list<vpMeSite>::const_iterator it=l->meline->getMeList().begin(); it!=l->meline->getMeList().end(); ++it){
719  vpMeSite pix = *it;
720  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
721  else nbBadPoint++;
722  }
723  }
724  }
725 
726 
727  vpMbtDistanceCylinder *cy ;
728  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
729  cy = *it;
730  if (cy->meline1 !=NULL && cy->meline2 != NULL)
731  {
732  nbExpectedPoint += (int)cy->meline1->expecteddensity;
733  for(std::list<vpMeSite>::const_iterator it=cy->meline1->getMeList().begin(); it!=cy->meline1->getMeList().end(); ++it){
734  vpMeSite pix = *it;
735  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
736  else nbBadPoint++;
737  }
738  nbExpectedPoint += (int)cy->meline2->expecteddensity;
739  for(std::list<vpMeSite>::const_iterator it=cy->meline2->getMeList().begin(); it!=cy->meline2->getMeList().end(); ++it){
740  vpMeSite pix = *it;
741  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
742  else nbBadPoint++;
743  }
744  }
745  }
746 
747  if (nbGoodPoint < percentageGdPt *(nbGoodPoint+nbBadPoint) || nbExpectedPoint < 2)
748  {
749  std::cout << "nbGoodPoint :" << nbGoodPoint << std::endl;
750  std::cout << "nbBadPoint :" << nbBadPoint << std::endl;
751  std::cout << "nbExpectedPoint :" << nbExpectedPoint << std::endl;
752  std::cout << "percentageGdPt: " << percentageGdPt << std::endl;
753  throw vpTrackingException(vpTrackingException::fatalError, "test Tracking fail");
754  }
755 }
756 
757 
765 void
767 {
768  initPyramid(I, Ipyramid);
769 
770 // for (int lvl = ((int)scales.size()-1); lvl >= 0; lvl -= 1)
771  unsigned int lvl = scales.size();
772  do{
773  lvl--;
774  if(scales[lvl]){
775  vpHomogeneousMatrix cMo_1 = cMo;
776  try
777  {
778  downScale(lvl);
779 
780  try
781  {
782  trackMovingEdge(*Ipyramid[lvl]);
783  }
784  catch(...)
785  {
786  vpTRACE("Error in moving edge tracking") ;
787  throw ;
788  }
789 
790  // initialize the vector that contains the error and the matrix that contains
791  // the interaction matrix
792  vpMbtDistanceLine *l ;
793  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
794  l = *it;
795  if (l->isVisible()){
796  l->initInteractionMatrixError() ;
797  }
798  }
799 
800  vpMbtDistanceCylinder *cy ;
801  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){
802  cy = *it;
803  cy->initInteractionMatrixError();
804  }
805 
806  try
807  {
808  computeVVS(*Ipyramid[lvl]);
809  }
810  catch(...)
811  {
812  vpTRACE("Error in computeVVS") ;
813  throw vpException(vpException::fatalError, "Error in computeVVS");
814  }
815 
816  try
817  {
818  testTracking();
819  }
820  catch(...)
821  {
822  throw vpTrackingException(vpTrackingException::fatalError, "test Tracking fail");
823  }
824 
825  if (displayMe)
826  {
827  if(lvl == 0){
828  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
829  l = *it;
830  if (l->isVisible()){
831  l->displayMovingEdges(I);
832  }
833  }
834 
835  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){
836  cy = *it;
837  cy->displayMovingEdges(I);
838  }
839  }
840  }
841 
842  try
843  {
844  updateMovingEdge(I);
845  }
846  catch(...)
847  {
848  vpTRACE("Error in moving edge updating") ;
849  throw ;
850  }
851 
852  // Looking for new visible face
853  bool newvisibleface = false ;
854  visibleFace(cMo, newvisibleface) ;
855  initMovingEdge(I,cMo) ;
856 
857  // Reinit the moving edge for the lines which need it.
859  upScale(lvl);
860  }
861  catch(...)
862  {
863  if(lvl != 0){
864  cMo = cMo_1;
865  reInitLevel(lvl);
866  upScale(lvl);
867  }
868  else{
869  upScale(lvl);
870  throw ;
871  }
872  }
873  }
874  } while(lvl != 0);
875 
877 }
878 
884 void vpMbEdgeTracker::init(const vpImage<unsigned char>& I)
885 {
886  bool a = false;
887 
888  initPyramid(I, Ipyramid);
889  visibleFace(cMo, a);
890  unsigned int i=scales.size();
891  do {
892  i--;
893  if(scales[i]){
894  downScale(i);
896  upScale(i);
897  }
898  } while(i != 0);
899 
901 }
902 
912 void
913 vpMbEdgeTracker::loadConfigFile(const std::string& _filename)
914 {
915  loadConfigFile(_filename.c_str());
916 }
917 
932 void
933 vpMbEdgeTracker::loadConfigFile(const char* filename)
934 {
935 #ifdef VISP_HAVE_XML2
936  vpMbtXmlParser xmlp;
937 
938  try{
939  xmlp.parse(filename);
940  }
941  catch(...){
942  vpERROR_TRACE("Can't open XML file \"%s\"\n ",filename);
943  throw vpException(vpException::ioError, "problem to parse configuration file.");
944  }
945 
946  vpCameraParameters camera;
947  vpMe meParser;
948  xmlp.getCameraParameters(camera);
949  xmlp.getMe(meParser);
950  setCameraParameters(camera);
951  setMovingEdge(meParser);
952 #else
953  vpTRACE("You need the libXML2 to read the config file %s", filename);
954 #endif
955 }
956 
957 
968 void
970  const vpColor& col,
971  const unsigned int thickness, const bool displayFullModel)
972 {
973  vpMbtDistanceLine *l ;
974 
975  for (unsigned int i = 0; i < scales.size(); i += 1){
976  if(scales[i]){
977  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
978  l = *it;
979  l->display(I,_cMo, cam, col, thickness, displayFullModel);
980  }
981 
982  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
983  (*it)->display(I, _cMo, cam, col, thickness);
984  }
985 
986  break ; //displaying model on one scale only
987  }
988  }
989 }
990 
1001 void
1003  const vpColor& col,
1004  const unsigned int thickness, const bool displayFullModel)
1005 {
1006  vpMbtDistanceLine *l ;
1007 
1008  for (unsigned int i = 0; i < scales.size(); i += 1){
1009  if(scales[i]){
1010  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1011  l = *it;
1012  l->display(I,_cMo, cam, col, thickness, displayFullModel) ;
1013  }
1014 
1015  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1016  (*it)->display(I, _cMo, cam, col, thickness) ;
1017  }
1018 
1019  break ; //displaying model on one scale only
1020  }
1021  }
1022 }
1023 
1024 
1032 void
1034 {
1035  vpMbtDistanceLine *l ;
1036 
1037  lines[scaleLevel].front() ;
1038  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1039  l = *it;
1040  bool isvisible = false ;
1041 
1042  for(std::list<int>::const_iterator it=l->Lindex_polygon.begin(); it!=l->Lindex_polygon.end(); ++it){
1043  int index = *it;
1044  if (index ==-1) isvisible =true ;
1045  else
1046  {
1047  if (l->hiddenface->isVisible(index)) isvisible = true ;
1048  }
1049  }
1050 
1051  //Si la ligne n'appartient a aucune face elle est tout le temps visible
1052  if (l->Lindex_polygon.empty()) isvisible = true;
1053 
1054  if (isvisible)
1055  {
1056  l->setVisible(true) ;
1057  if (l->meline==NULL)
1058  {
1059  //cout << "init me line "<< l->getIndex() <<endl ;
1060  l->initMovingEdge(I, _cMo) ;
1061  }
1062  }
1063  else
1064  {
1065  l->setVisible(false) ;
1066  if (l->meline!=NULL) delete l->meline;
1067  l->meline=NULL;
1068  }
1069  }
1070 
1071 
1072  vpMbtDistanceCylinder *cy ;
1073  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1074  cy = *it;
1075  if (cy->meline1==NULL || cy->meline2==NULL){
1076  cy->initMovingEdge(I, _cMo) ;
1077  }
1078  }
1079 }
1080 
1081 
1087 void
1089 {
1090  vpMbtDistanceLine *l ;
1091  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1092  l = *it;
1093  if(l->isVisible() == true){
1094  if(l->meline == NULL){
1095  l->initMovingEdge(I, cMo);
1096  }
1097  l->trackMovingEdge(I, cMo) ;
1098  }
1099  }
1100 
1101  vpMbtDistanceCylinder *cy;
1102  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1103  cy = *it;
1104  if(cy->meline1 == NULL || cy->meline2 == NULL){
1105  cy->initMovingEdge(I, cMo);
1106  }
1107  cy->trackMovingEdge(I, cMo) ;
1108  }
1109 }
1110 
1111 
1117 void
1119 {
1120  vpMbtDistanceLine *l ;
1121  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1122  l = *it;
1123  l->updateMovingEdge(I, cMo) ;
1124  if (l->nbFeature == 0 && l->isVisible()){
1125  l->Reinit = true;
1126  }
1127  }
1128 
1129 
1130  vpMbtDistanceCylinder *cy ;
1131  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1132  cy = *it;
1133  cy->updateMovingEdge(I, cMo) ;
1134  if(cy->nbFeaturel1 == 0 || cy->nbFeaturel2 == 0){
1135  cy->Reinit = true;
1136  }
1137  }
1138 }
1139 
1140 
1149 void
1151 {
1152  vpMbtDistanceLine *l ;
1153  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1154  l = *it;
1155  if (l->Reinit && l->isVisible())
1156  l->reinitMovingEdge(I, _cMo);
1157  }
1158 
1159  vpMbtDistanceCylinder*cy;
1160  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1161  cy = *it;
1162  if (cy->Reinit)
1163  cy->reinitMovingEdge(I, _cMo);
1164  }
1165 }
1166 
1167 
1177 bool samePoint(const vpPoint &P1, const vpPoint &P2, double threshold=1e-5)
1178 {
1179  double d = vpMath::sqr(P1.get_oX() - P2.get_oX())+
1180  vpMath::sqr(P1.get_oY() - P2.get_oY())+
1181  vpMath::sqr(P1.get_oZ() - P2.get_oZ()) ;
1182  if (d < threshold)
1183  return true ;
1184  else
1185  return false ;
1186 }
1187 
1188 
1199 void
1200 vpMbEdgeTracker::addLine(vpPoint &P1, vpPoint &P2, int polygone, std::string name)
1201 {
1202  //suppress line already in the model
1203 
1204  bool already_here = false ;
1205  vpMbtDistanceLine *l ;
1206 
1207  for (unsigned int i = 0; i < scales.size(); i += 1){
1208  if(scales[i]){
1209  downScale(i);
1210  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
1211  l = *it;
1212  if((samePoint(*(l->p1),P1) && samePoint(*(l->p2),P2)) ||
1213  (samePoint(*(l->p1),P2) && samePoint(*(l->p2),P1)) ){
1214  already_here = true ;
1215  l->Lindex_polygon.push_back(polygone);
1216  l->hiddenface = &faces ;
1217  }
1218  }
1219 
1220  if (!already_here){
1221  l = new vpMbtDistanceLine ;
1222 
1223  l->setCameraParameters(cam) ;
1224  l->buildFrom(P1,P2) ;
1225  l->Lindex_polygon.push_back(polygone);
1226  l->setMovingEdge(&me) ;
1227  l->hiddenface = &faces ;
1228  l->setIndex(nline) ;
1229  l->setName(name);
1230  nline +=1 ;
1231  lines[i].push_back(l);
1232  }
1233  upScale(i);
1234  }
1235  }
1236 }
1237 
1243 void
1244 vpMbEdgeTracker::removeLine(const std::string& name)
1245 {
1246  vpMbtDistanceLine *l;
1247 
1248  for(unsigned int i=0; i<scales.size(); i++){
1249  if(scales[i]){
1250  for(std::list<vpMbtDistanceLine*>::iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
1251  l = *it;
1252  if (name.compare(l->getName()) == 0){
1253  lines[i].erase(it);
1254  break;
1255  }
1256  }
1257  }
1258  }
1259 }
1260 
1261 
1262 
1263 
1272 void
1273 vpMbEdgeTracker::addCylinder(const vpPoint &P1, const vpPoint &P2, const double r, const std::string& name)
1274 {
1275  bool already_here = false ;
1276  vpMbtDistanceCylinder *cy ;
1277 
1278  for (unsigned int i = 0; i < scales.size(); i += 1){
1279  if(scales[i]){
1280  downScale(i);
1281  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
1282  cy = *it;
1283  if((samePoint(*(cy->p1),P1) && samePoint(*(cy->p2),P2)) ||
1284  (samePoint(*(cy->p1),P2) && samePoint(*(cy->p2),P1)) ){
1285  already_here = (std::fabs(cy->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(cy->radius, r));
1286  }
1287  }
1288 
1289  if (!already_here){
1290  cy = new vpMbtDistanceCylinder ;
1291 
1292  cy->setCameraParameters(cam);
1293  cy->buildFrom(P1, P2, r);
1294  cy->setMovingEdge(&me);
1295  cy->setIndex(ncylinder);
1296  cy->setName(name);
1297  ncylinder +=1;
1298  cylinders[i].push_back(cy);
1299  }
1300  upScale(i);
1301  }
1302  }
1303 }
1304 
1305 
1311 void
1312 vpMbEdgeTracker::removeCylinder(const std::string& name)
1313 {
1314  vpMbtDistanceCylinder *cy;
1315 
1316  for(unsigned int i=0; i<scales.size(); i++){
1317  if(scales[i]){
1318  for(std::list<vpMbtDistanceCylinder*>::iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
1319  cy = *it;
1320  if (name.compare(cy->getName()) == 0){
1321  cylinders[i].erase(it);
1322  break;
1323  }
1324  }
1325  }
1326  }
1327 }
1328 
1334 void
1336 {
1337  p.setIndex(index_polygon) ;
1338  faces.addPolygon(&p) ;
1339 
1340  unsigned int nbpt = p.getNbPoint() ;
1341  if(nbpt > 0){
1342  for (unsigned int i=0 ; i < nbpt-1 ; i++)
1343  addLine(p.p[i], p.p[i+1], index_polygon) ;
1344  addLine(p.p[nbpt-1], p.p[0], index_polygon) ;
1345  }
1346 
1347  index_polygon++ ;
1348 }
1349 
1350 
1360 void
1361 vpMbEdgeTracker::visibleFace(const vpHomogeneousMatrix &cMo, bool &newvisibleline)
1362 {
1363  unsigned int n ;
1364 
1365  n = faces.setVisible(cMo) ;
1366 // cout << "visible face " << n << endl ;
1367  if (n > nbvisiblepolygone)
1368  {
1369  //cout << "une nouvelle face est visible " << endl ;
1370  newvisibleline = true ;
1371  }
1372  else
1373  newvisibleline = false ;
1374 
1375  nbvisiblepolygone= n ;
1376 }
1377 
1378 
1387 void
1389 {
1390  std::string model(file);
1391  vpMbTracker::loadModel(model);
1392 }
1393 
1402 void
1403 vpMbEdgeTracker::loadModel(const std::string &file)
1404 {
1405  vpMbTracker::loadModel(file);
1406 }
1407 
1416 void
1417 vpMbEdgeTracker::initFaceFromCorners(const std::vector<vpPoint>& _corners, const unsigned int _indexFace)
1418 {
1419  vpMbtPolygon *polygon = NULL;
1420  polygon = new vpMbtPolygon;
1421  polygon->setNbPoint(_corners.size());
1422  polygon->setIndex((int)_indexFace);
1423  for(unsigned int j = 0; j < _corners.size(); j++) {
1424  polygon->addPoint(j, _corners[j]);
1425  }
1426  addPolygon(*polygon);
1427 
1428  delete polygon;
1429  polygon = NULL;
1430 }
1431 
1441 void
1442 vpMbEdgeTracker::initCylinder(const vpPoint& _p1, const vpPoint _p2, const double _radius, const unsigned int _indexCylinder)
1443 {
1444  if(_indexCylinder != 0){
1445  ncylinder = _indexCylinder;
1446  }
1447  addCylinder(_p1, _p2, _radius);
1448 }
1449 
1455 void
1457 {
1458  this->cMo.setIdentity();
1459  vpMbtDistanceLine *l;
1460  vpMbtDistanceCylinder *cy;
1461 
1462  for (unsigned int i = 0; i < scales.size(); i += 1){
1463  if(scales[i]){
1464  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
1465  l = *it;
1466  if (l!=NULL) delete l ;
1467  l = NULL ;
1468  }
1469 
1470  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
1471  cy = *it;
1472  if (cy!=NULL) delete cy;
1473  cy = NULL;
1474  }
1475  lines[i].clear();
1476  cylinders[i].clear();
1477  }
1478  }
1479 
1480  faces.reset();
1481 
1482  index_polygon =0;
1484  nline = 0;
1485  ncylinder = 0;
1486  lambda = 1;
1487  nbvisiblepolygone = 0;
1488  percentageGdPt = 0.4;
1489 
1490  // reinitialisation of the scales.
1491  this->setScales(scales);
1492 }
1493 
1494 
1495 
1503 void
1504 vpMbEdgeTracker::reInitModel(const vpImage<unsigned char>& _I, const char* _cad_name, const vpHomogeneousMatrix& _cMo)
1505 {
1506  resetTracker();
1507  loadModel(_cad_name);
1508  initFromPose(_I, _cMo);
1509 }
1510 
1521 unsigned int
1522 vpMbEdgeTracker::getNbPoints(const unsigned int _level)
1523 {
1524  if((_level > scales.size()) || !scales[_level]){
1525  throw vpException(vpException::dimensionError, "Level is not used");
1526  }
1527 
1528  unsigned int nbGoodPoints = 0;
1529  vpMbtDistanceLine *l ;
1530  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[_level].begin(); it!=lines[_level].end(); ++it){
1531  l = *it;
1532  if (l->isVisible() && l->meline != NULL)
1533  {
1534  for(std::list<vpMeSite>::const_iterator it=l->meline->getMeList().begin(); it!=l->meline->getMeList().end(); ++it){
1535  if (it->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
1536  }
1537  }
1538  }
1539 
1540  vpMbtDistanceCylinder *cy ;
1541  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[_level].begin(); it!=cylinders[_level].end(); ++it){
1542  cy = *it;
1543  if (cy->meline1 != NULL || cy->meline2 != NULL)
1544  {
1545  for(std::list<vpMeSite>::const_iterator it=cy->meline1->getMeList().begin(); it!=cy->meline1->getMeList().end(); ++it){
1546  if (it->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
1547  }
1548  for(std::list<vpMeSite>::const_iterator it=cy->meline2->getMeList().begin(); it!=cy->meline2->getMeList().end(); ++it){
1549  if (it->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
1550  }
1551  }
1552  }
1553 
1554  return nbGoodPoints;
1555 }
1556 
1557 
1567 vpMbtPolygon*
1568 vpMbEdgeTracker::getPolygon(const unsigned int _index)
1569 {
1570  if(_index >= static_cast<unsigned int>(faces.getPolygon().size()) ){
1571  throw vpException(vpException::dimensionError, "index out of range");
1572  }
1573  std::list<vpMbtPolygon*>::const_iterator it = faces.getPolygon().begin();
1574  std::advance(it, _index);
1575  return *it;
1576 }
1577 
1583 unsigned int
1585 {
1586  return static_cast<unsigned int>(faces.getPolygon().size());
1587 }
1588 
1609 void
1610 vpMbEdgeTracker::setScales(const std::vector<bool>& _scales)
1611 {
1612  unsigned int nbActivatedLevels = 0;
1613  for (unsigned int i = 0; i < _scales.size(); i += 1){
1614  if(_scales[i]){
1615  nbActivatedLevels++;
1616  }
1617  }
1618  if((_scales.size() < 1) || (nbActivatedLevels == 0)){
1619  vpERROR_TRACE(" !! WARNING : must use at least one level for the tracking. Use the global one");
1620  scales.resize(0);
1621  scales.push_back(true);
1622  lines.resize(1);
1623  lines[0].clear();
1624  cylinders.resize(1);
1625  cylinders[0].clear();
1626  }
1627  else{
1628  scales = _scales;
1629  lines.resize(_scales.size());
1630  cylinders.resize(_scales.size());
1631  for (unsigned int i = 0; i < lines.size(); i += 1){
1632  lines[i].clear();
1633  cylinders[i].clear();
1634  }
1635  }
1636 }
1637 
1652 void
1654 {
1655  _pyramid.resize(scales.size());
1656 
1657  if(scales[0]){
1658  _pyramid[0] = &_I;
1659  }
1660  else{
1661  _pyramid[0] = NULL;
1662  }
1663 
1664  for(unsigned int i=1; i<_pyramid.size(); i += 1){
1665  if(scales[i]){
1666  unsigned int cScale = static_cast<unsigned int>(pow(2., (int)i));
1667  vpImage<unsigned char>* I = new vpImage<unsigned char>(_I.getHeight() / cScale, _I.getWidth() / cScale);
1668 #ifdef VISP_HAVE_OPENCV
1669  IplImage* vpI0 = cvCreateImageHeader(cvSize((int)_I.getWidth(), (int)_I.getHeight()), IPL_DEPTH_8U, 1);
1670  vpI0->imageData = (char*)(_I.bitmap);
1671  IplImage* vpI = cvCreateImage(cvSize((int)(_I.getWidth() / cScale), (int)(_I.getHeight() / cScale)), IPL_DEPTH_8U, 1);
1672  cvResize(vpI0, vpI, CV_INTER_NN);
1673  vpImageConvert::convert(vpI, *I);
1674  cvReleaseImage(&vpI);
1675  vpI0->imageData = NULL;
1676  cvReleaseImageHeader(&vpI0);
1677 #else
1678  for (unsigned int k = 0, ii = 0; k < I->getHeight(); k += 1, ii += cScale){
1679  for (unsigned int l = 0, jj = 0; l < I->getWidth(); l += 1, jj += cScale){
1680  (*I)[k][l] = _I[ii][jj];
1681  }
1682  }
1683 #endif
1684  _pyramid[i] = I;
1685  }
1686  else{
1687  _pyramid[i] = NULL;
1688  }
1689  }
1690 }
1691 
1698 void
1700 {
1701  if(_pyramid.size() > 0){
1702  _pyramid[0] = NULL;
1703  for (unsigned int i = 1; i < _pyramid.size(); i += 1){
1704  if(_pyramid[i] != NULL){
1705  delete _pyramid[i];
1706  _pyramid[i] = NULL;
1707  }
1708  }
1709  _pyramid.resize(0);
1710  }
1711 }
1712 
1713 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1714 
1726 vp_deprecated vpList<vpMbtDistanceLine *>*
1727 vpMbEdgeTracker::getLline(const unsigned int _level)
1728 {
1729  if(_level > scales.size() || !scales[_level]){
1730  std::ostringstream oss;
1731  oss << _level;
1732  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
1733  throw vpException(vpException::dimensionError, errorMsg);
1734  }
1735 
1737  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[_level].begin(); it!=lines[_level].end(); ++it){
1738  l->addRight(*it);
1739  }
1740 
1741  return l;
1742 }
1743 
1744 
1757 vp_deprecated vpList<vpMbtDistanceCylinder *>*
1758 vpMbEdgeTracker::getLcylinder(const unsigned int _level)
1759 {
1760  if(_level > scales.size() || !scales[_level]){
1761  std::ostringstream oss;
1762  oss << _level;
1763  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
1764  throw vpException(vpException::dimensionError, errorMsg);
1765  }
1766 
1768  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[_level].begin(); it!=cylinders[_level].end(); ++it){
1769  c->addRight(*it);
1770  }
1771 
1772  return c;
1773 }
1774 
1781 vp_deprecated void
1782 vpMbEdgeTracker::init(const vpImage<unsigned char>& I, const vpHomogeneousMatrix &_cMo)
1783 {
1784  this->cMo = _cMo;
1785  init(I);
1786 }
1787 #endif
1788 
1799 void
1800 vpMbEdgeTracker::getLline(std::list<vpMbtDistanceLine *>& linesList, const unsigned int _level)
1801 {
1802  if(_level > scales.size() || !scales[_level]){
1803  std::ostringstream oss;
1804  oss << _level;
1805  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
1806  throw vpException(vpException::dimensionError, errorMsg);
1807  }
1808 
1809  linesList = lines[_level];
1810 }
1811 
1812 
1823 void
1824 vpMbEdgeTracker::getLcylinder(std::list<vpMbtDistanceCylinder *>& cylindersList, const unsigned int _level)
1825 {
1826  if(_level > scales.size() || !scales[_level]){
1827  std::ostringstream oss;
1828  oss << _level;
1829  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
1830  throw vpException(vpException::dimensionError, errorMsg);
1831  }
1832 
1833  cylindersList = cylinders[_level];
1834 }
1835 
1836 
1843 void
1844 vpMbEdgeTracker::downScale(const unsigned int _scale)
1845 {
1846  const double ratio = pow(2., (int)_scale);
1847  scaleLevel = _scale;
1848 
1849  vpMatrix K = cam.get_K();
1850 
1851  K[0][0] /= ratio;
1852  K[1][1] /= ratio;
1853  K[0][2] /= ratio;
1854  K[1][2] /= ratio;
1855 
1857 }
1858 
1865 void
1866 vpMbEdgeTracker::upScale(const unsigned int _scale)
1867 {
1868  const double ratio = pow(2., (int)_scale);
1869  scaleLevel = 0;
1870 
1871  vpMatrix K = cam.get_K();
1872 
1873  K[0][0] *= ratio;
1874  K[1][1] *= ratio;
1875  K[0][2] *= ratio;
1876  K[1][2] *= ratio;
1877 
1879 }
1880 
1888 void
1889 vpMbEdgeTracker::reInitLevel(const unsigned int _lvl)
1890 {
1891  unsigned int scaleLevel_1 = scaleLevel;
1892  scaleLevel = _lvl;
1893 
1894  vpMbtDistanceLine *l;
1895  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1896  l = *it;
1897  l->reinitMovingEdge(*Ipyramid[_lvl], cMo);
1898  }
1899 
1900 
1901  vpMbtDistanceCylinder *cy;
1902  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1903  cy = *it;
1904  cy->reinitMovingEdge(*Ipyramid[_lvl], cMo);
1905  }
1906 
1907  trackMovingEdge(*Ipyramid[_lvl]);
1908  updateMovingEdge(*Ipyramid[_lvl]);
1909  scaleLevel = scaleLevel_1;
1910 }
1911 
unsigned int ncylinder
Index of the cylinder to add, and total number of polygon extracted so far.
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
vpMatrix covarianceMatrix
Covariance matrix.
Definition: vpMbTracker.h:115
void initFromCalibrationMatrix(const vpMatrix &_K)
virtual void loadModel(const std::string &_modelFile)
void upScale(const unsigned int _scale)
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Compute the weights according a residue vector and a PsiFunction.
Definition: vpRobust.cpp:138
unsigned int getWidth() const
Definition: vpImage.h:154
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
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:379
void loadConfigFile(const std::string &filename)
void track(const vpImage< unsigned char > &I)
#define vpTRACE
Definition: vpDebug.h:401
Provide simple list management.
Definition: vpList.h:112
double lambda
The gain of the virtual visual servoing stage.
unsigned int scaleLevel
Current scale level used. This attribute must not be modified outsied of the downScale() and upScale(...
Type * bitmap
points toward the bitmap
Definition: vpImage.h:115
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
virtual void setCameraParameters(const vpCameraParameters &_cam)
Class to define colors available for display functionnalities.
Definition: vpColor.h:123
vpHomogeneousMatrix cMo
The current pose.
Definition: vpMbTracker.h:101
virtual void initFromPose(const vpImage< unsigned char > &_I, const std::string &_initFile)
unsigned int getNbPolygon()
void getLcylinder(std::list< vpMbtDistanceCylinder * > &cylindersList, const unsigned int _level=0)
void computeJTR(const vpMatrix &_J, const vpColVector &_R, vpMatrix &_JTR)
virtual ~vpMbEdgeTracker()
bool displayMe
If true, the moving edges are displayed during the track() method.
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.h:136
void reInitLevel(const unsigned int _lvl)
Contains predetermined masks for sites and holds moving edges tracking parameters.
Definition: vpMe.h:70
std::vector< const vpImage< unsigned char > * > Ipyramid
Pyramid of image associated to the current image. This pyramid is compted in the init() and in the tr...
void removeCylinder(const std::string &name)
bool computeCovariance
Flag used to specify if the covariance matrix has to be computed or not.
Definition: vpMbTracker.h:113
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).
void visibleFace(const vpHomogeneousMatrix &cMo, bool &newvisibleline)
static vpMatrix computeCovarianceMatrix(const vpMatrix &A, const vpColVector &x, const vpColVector &b)
void downScale(const unsigned int _scale)
vpMbtHiddenFaces faces
Set of faces describing the object.
Class that defines what is a point.
Definition: vpPoint.h:65
vpMeSiteState getState() const
Definition: vpMeSite.h:202
void addLine(vpPoint &p1, vpPoint &p2, int polygone=-1, std::string name="")
vpCameraParameters cam
The camera parameters.
Definition: vpMbTracker.h:99
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
int index_polygon
Index of the polygon to add, and total number of polygon extracted so far. Cannot be unsigned because...
std::vector< bool > scales
Vector of scale level to use for the multi-scale tracking.
Error that can be emited by the vpTracker class and its derivates.
void initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
static double sqr(double x)
Definition: vpMath.h:106
virtual void initCylinder(const vpPoint &_p1, const vpPoint _p2, const double _radius, const unsigned int _indexCylinder=0)
Generic class defining intrinsic camera parameters.
void addRight(const type &el)
add a new element in the list, at the right of the current one
Definition: vpList.h:480
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.h:138
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)
virtual void initFaceFromCorners(const std::vector< vpPoint > &_corners, const unsigned int _indexFace=-1)
void reInitModel(const vpImage< unsigned char > &I, const char *cad_name, const vpHomogeneousMatrix &_cMo)
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:189
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
vpMbtPolygon * getPolygon(const unsigned int _index)
double get_px() const
void diag(const vpColVector &A)
Definition: vpMatrix.cpp:2521
void setScales(const std::vector< bool > &_scales)
double get_oX() const
Get the point X coordinate in the object frame.
Definition: vpPoint.h:134
vpMatrix get_K() const
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.
vpHomogeneousMatrix inverse() const
static vpHomogeneousMatrix direct(const vpColVector &v)
void addCylinder(const vpPoint &P1, const vpPoint &P2, const double r, const std::string &name="")
Contains an M-Estimator and various influence function.
Definition: vpRobust.h:63
unsigned int nbvisiblepolygone
Number of polygon (face) currently visible.
unsigned int getHeight() const
Definition: vpImage.h:145
void getLline(std::list< vpMbtDistanceLine * > &linesList, const unsigned int _level=0)
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, const unsigned int l=1, const bool displayFullModel=false)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1810
unsigned int nline
Index of the polygon to add, and total number of polygon extracted so far.
void addPolygon(vpMbtPolygon &p)
unsigned int getNbPoints(const unsigned int _level=0)
void trackMovingEdge(const vpImage< unsigned char > &I)
void loadModel(const std::string &cad_name)
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:157
static int sign(double x)
Definition: vpMath.h:248
void removeLine(const std::string &name)
void setIteration(const unsigned int iter)
Set iteration.
Definition: vpRobust.h:122
void setMovingEdge(const vpMe &_me)
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94