Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpMbEdgeTracker.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Make the complete tracking of an object by using its CAD model
32  *
33  * Authors:
34  * Nicolas Melchior
35  * Romain Tallonneau
36  * Eric Marchand
37  *
38  *****************************************************************************/
39 
45 #include <visp3/core/vpDebug.h>
46 #include <visp3/vision/vpPose.h>
47 #include <visp3/core/vpExponentialMap.h>
48 #include <visp3/core/vpPixelMeterConversion.h>
49 #include <visp3/core/vpRobust.h>
50 #include <visp3/core/vpMatrixException.h>
51 #include <visp3/core/vpMath.h>
52 #include <visp3/core/vpException.h>
53 #include <visp3/core/vpTrackingException.h>
54 #include <visp3/mbt/vpMbEdgeTracker.h>
55 #include <visp3/mbt/vpMbtDistanceLine.h>
56 #include <visp3/mbt/vpMbtXmlParser.h>
57 #include <visp3/core/vpPolygon3D.h>
58 #include <visp3/core/vpVelocityTwistMatrix.h>
59 
60 #include <limits>
61 #include <string>
62 #include <sstream>
63 #include <float.h>
64 #include <map>
65 
66 
71  : compute_interaction(1), lambda(1), me(), lines(1), circles(1), cylinders(1), nline(0), ncircle(0), ncylinder(0),
72  nbvisiblepolygone(0), percentageGdPt(0.4), scales(1),
73  Ipyramid(0), scaleLevel(0), nbFeaturesForProjErrorComputation(0)
74 {
77 
78  scales[0] = true;
79 
80 #ifdef VISP_HAVE_OGRE
81  faces.getOgreContext()->setWindowName("MBT Edge");
82 #endif
83 }
84 
89 {
93 
94  for (unsigned int i = 0; i < scales.size(); i += 1){
95  if(scales[i]){
96  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
97  l = *it;
98  if (l!=NULL){
99  delete l ;
100  }
101  l = NULL ;
102  }
103 
104  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
105  cy = *it;
106  if (cy!=NULL){
107  delete cy ;
108  }
109  cy = NULL ;
110  }
111 
112  lines[i].clear();
113  cylinders[i].clear();
114  }
115  }
116  for (unsigned int i = 0; i < circles.size(); i += 1){
117  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
118  ci = *it;
119  if (ci!=NULL){
120  delete ci ;
121  }
122  ci = NULL ;
123  }
124  circles[i].clear();
125  }
127 }
128 
134 void
136 {
137  this->me = p_me;
138 
139  for (unsigned int i = 0; i < scales.size(); i += 1){
140  if(scales[i]){
141  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
142  vpMbtDistanceLine *l = *it;
143  l->setMovingEdge(&(this->me)) ;
144  }
145 
146  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
147  vpMbtDistanceCylinder *cy = *it;
148  cy->setMovingEdge(&(this->me)) ;
149  }
150 
151  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
152  vpMbtDistanceCircle *ci = *it;
153  ci->setMovingEdge(&(this->me)) ;
154  }
155  }
156  }
157 }
158 
168 void
169 vpMbEdgeTracker::computeVVS(const vpImage<unsigned char>& _I, const unsigned int lvl)
170 {
171  double residu_1 = 1e3;
172  double r = 1e3-1;
173 
174  //vpColVector w;
175  vpColVector factor;
176  //vpColVector error; // s-s*
177  vpColVector weighted_error; // Weighted error vector wi(s-s)*
178 
179  unsigned int iter = 0;
180 
181  //Nombre de moving edges
182  unsigned int nbrow = 0;
183  unsigned int nberrors_lines = 0;
184  unsigned int nberrors_cylinders = 0;
185  unsigned int nberrors_circles = 0;
186 
187  nbrow = initMbtTracking(nberrors_lines, nberrors_cylinders, nberrors_circles);
188 
189  if (nbrow==0){
190  throw vpTrackingException(vpTrackingException::notEnoughPointError, "No data found to compute the interaction matrix...");
191  }
192 
193  vpMatrix L(nbrow,6);
194 
195  // compute the error vector
196  m_error.resize(nbrow);
197  unsigned int nerror = m_error.getRows();
198 
199  bool reloop = true;
200 
201  bool isoJoIdentity_ = isoJoIdentity; // Backup since it can be modified if L is not full rank
202  if (isoJoIdentity_)
203  oJo.eye();
204 
205  /*** First phase ***/
206 
207  while ( reloop == true && iter<10)
208  {
209  if(iter==0)
210  {
211  weighted_error.resize(nerror);
212  m_w.resize(nerror);
213  m_w = 0;
214  factor.resize(nerror);
215  factor = 1;
216  }
217 
218  double count = 0;
219 
220  reloop = false;
221 
222  computeVVSFirstPhase(_I, iter, L, factor, count, m_error, m_w, lvl);
223 
224  count = count / (double)nbrow;
225  if (count < 0.85){
226  reloop = true;
227  }
228 
229  computeVVSFirstPhasePoseEstimation(nerror, iter, factor, weighted_error, L, isoJoIdentity_);
230 
231  iter++;
232  }
233 
234 // std::cout << "\t First minimization in " << iter << " iteration give as initial cMo: \n" << cMo << std::endl ;
235 
236 
237 /*** Second phase ***/
238 
239  vpRobust robust_lines(nberrors_lines);
240  vpRobust robust_cylinders(nberrors_cylinders);
241  vpRobust robust_circles(nberrors_circles);
242  robust_lines.setIteration(0);
243  robust_cylinders.setIteration(0);
244  robust_circles.setIteration(0);
245  iter = 0;
246  vpColVector w_lines(nberrors_lines);
247  vpColVector w_cylinders(nberrors_cylinders);
248  vpColVector w_circles(nberrors_circles);
249  vpColVector error_lines(nberrors_lines);
250  vpColVector error_cylinders(nberrors_cylinders);
251  vpColVector error_circles(nberrors_circles);
252 
253  vpHomogeneousMatrix cMoPrev;
254  vpColVector W_true;
255  vpMatrix L_true;
256  vpMatrix LVJ_true;
257 
258  double mu = 0.01;
259  vpColVector m_error_prev(nbrow);
260  vpColVector m_w_prev(nbrow);
261 
262  //while ( ((int)((residu_1 - r)*1e8) !=0 ) && (iter<30))
263  while(std::fabs((residu_1 - r)*1e8) > std::numeric_limits<double>::epsilon() && (iter<30))
264  {
265  computeVVSSecondPhase(_I, L, error_lines, error_cylinders, error_circles, m_error, lvl);
266 
267  bool reStartFromLastIncrement = false;
268 
269  computeVVSSecondPhaseCheckLevenbergMarquardt(iter, nbrow, m_error_prev, m_w_prev, cMoPrev, mu, reStartFromLastIncrement);
270 
271  if(!reStartFromLastIncrement){
272  computeVVSSecondPhaseWeights(iter, nerror, nbrow, weighted_error, robust_lines, robust_cylinders, robust_circles,
273  w_lines, w_cylinders, w_circles, error_lines, error_cylinders, error_circles, nberrors_lines, nberrors_cylinders,
274  nberrors_circles);
275 
276  computeVVSSecondPhasePoseEstimation(nerror, L, L_true, LVJ_true, W_true, factor, iter, isoJoIdentity_,
277  weighted_error, mu, m_error_prev, m_w_prev, cMoPrev, residu_1, r);
278 
279  } // endif(!restartFromLast)
280 
281  iter++;
282  }
283 
284 // std::cout << "VVS estimate pose cMo:\n" << cMo << std::endl;
285  if(computeCovariance){
286  vpMatrix D;
287  D.diag(W_true);
288 
289  // Note that here the covariance is computed on cMoPrev for time computation efficiency
290  if(isoJoIdentity_){
292  }
293  else{
295  }
296  }
297 
299 }
300 
301 void
303  vpColVector &factor, double &count, vpColVector &error, vpColVector &w_mbt, const unsigned int lvl) {
307 
308  double limite = 3; //Une limite de 3 pixels
309  limite = limite / cam.get_px(); //Transformation limite pixel en limite metre.
310 
311  unsigned int n = 0;
312 
313  //Parametre pour la premiere phase d'asservissement
314  double e_prev = 0, e_cur, e_next;
315 
316  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
317  if((*it)->isTracked())
318  {
319  l = *it;
321 
322  double fac = 1;
323  if (iter == 0)
324  {
325  for(std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex!=l->Lindex_polygon.end(); ++itindex) {
326  int index = *itindex;
327  if (l->hiddenface->isAppearing((unsigned int)index))
328  {
329  fac = 0.2;
330  break;
331  }
332  if(l->closeToImageBorder(_I, 10))
333  {
334  fac = 0.1;
335  break;
336  }
337  }
338  }
339 
340  std::list<vpMeSite>::const_iterator itListLine;
341 
342  unsigned int indexFeature = 0;
343 
344  for(unsigned int a = 0 ; a < l->meline.size() ; a++)
345  {
346  if (iter == 0 && l->meline[a] != NULL)
347  itListLine = l->meline[a]->getMeList().begin();
348 
349  for (unsigned int i=0 ; i < l->nbFeature[a] ; i++)
350  {
351  for (unsigned int j=0; j < 6 ; j++)
352  {
353  L[n+i][j] = l->L[indexFeature][j]; //On remplit la matrice d'interaction globale
354  }
355  error[n+i] = l->error[indexFeature]; //On remplit la matrice d'erreur
356 
357  if (error[n+i] <= limite) count = count+1.0; //Si erreur proche de 0 on incremente cur
358 
359  w_mbt[n+i] = 0;
360 
361  if (iter == 0)
362  {
363  factor[n+i] = fac;
364  vpMeSite site = *itListLine;
365  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
366  ++itListLine;
367  }
368 
369  //If pour la premiere extremite des moving edges
370  if (indexFeature == 0)
371  {
372  e_cur = l->error[0];
373  if (l->nbFeature[a] > 1)
374  {
375  e_next = l->error[1];
376  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
377  {
378  w_mbt[n+i] = 1/*0.5*/;
379  }
380  e_prev = e_cur;
381  }
382  else w_mbt[n+i] = 1;
383  }
384 
385  //If pour la derniere extremite des moving edges
386  else if(indexFeature == l->nbFeatureTotal-1)
387  {
388  e_cur = l->error[indexFeature];
389  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
390  {
391  w_mbt[n+i] += 1/*0.5*/;
392  }
393  }
394 
395  else
396  {
397  e_cur = l->error[indexFeature];
398  e_next = l->error[indexFeature+1];
399  if ( fabs(e_cur - e_prev) < limite )
400  {
401  w_mbt[n+i] += 0.5;
402  }
403  if ( fabs(e_cur - e_next) < limite )
404  {
405  w_mbt[n+i] += 0.5;
406  }
407  e_prev = e_cur;
408  }
409  indexFeature++;
410  }
411  n += l->nbFeature[a] ;
412  }
413  }
414  }
415 
416  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it) {
417  if((*it)->isTracked())
418  {
419  cy = *it;
421  double fac = 1.0;
422 
423  std::list<vpMeSite>::const_iterator itCyl1;
424  std::list<vpMeSite>::const_iterator itCyl2;
425  if (iter == 0 && (cy->meline1 != NULL || cy->meline2 != NULL)){
426  itCyl1 = cy->meline1->getMeList().begin();
427  itCyl2 = cy->meline2->getMeList().begin();
428  }
429 
430  for(unsigned int i=0 ; i < cy->nbFeature ; i++){
431  for(unsigned int j=0; j < 6 ; j++){
432  L[n+i][j] = cy->L[i][j]; //On remplit la matrice d'interaction globale
433  }
434  error[n+i] = cy->error[i]; //On remplit la matrice d'erreur
435 
436  if (error[n+i] <= limite) count = count+1.0; //Si erreur proche de 0 on incremente cur
437 
438  w_mbt[n+i] = 0;
439 
440  if (iter == 0)
441  {
442  factor[n+i] = fac;
443  vpMeSite site;
444  if(i<cy->nbFeaturel1) {
445  site= *itCyl1;
446  ++itCyl1;
447  }
448  else{
449  site= *itCyl2;
450  ++itCyl2;
451  }
452  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
453  }
454 
455  //If pour la premiere extremite des moving edges
456  if (i == 0)
457  {
458  e_cur = cy->error[0];
459  if (cy->nbFeature > 1)
460  {
461  e_next = cy->error[1];
462  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
463  {
464  w_mbt[n+i] = 1/*0.5*/;
465  }
466  e_prev = e_cur;
467  }
468  else w_mbt[n+i] = 1;
469  }
470  if (i == cy->nbFeaturel1)
471  {
472  e_cur = cy->error[i];
473  if (cy->nbFeaturel2 > 1)
474  {
475  e_next = cy->error[i+1];
476  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
477  {
478  w_mbt[n+i] = 1/*0.5*/;
479  }
480  e_prev = e_cur;
481  }
482  else w_mbt[n+i] = 1;
483  }
484 
485  //If pour la derniere extremite des moving edges
486  else if(i == cy->nbFeaturel1-1)
487  {
488  e_cur = cy->error[i];
489  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
490  {
491  w_mbt[n+i] += 1/*0.5*/;
492  }
493  }
494  //If pour la derniere extremite des moving edges
495  else if(i == cy->nbFeature-1)
496  {
497  e_cur = cy->error[i];
498  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
499  {
500  w_mbt[n+i] += 1/*0.5*/;
501  }
502  }
503 
504  else
505  {
506  e_cur = cy->error[i];
507  e_next = cy->error[i+1];
508  if ( fabs(e_cur - e_prev) < limite ){
509  w_mbt[n+i] += 0.5;
510  }
511  if ( fabs(e_cur - e_next) < limite ){
512  w_mbt[n+i] += 0.5;
513  }
514  e_prev = e_cur;
515  }
516  }
517 
518  n+= cy->nbFeature ;
519  }
520  }
521 
522  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[lvl].begin(); it!=circles[lvl].end(); ++it) {
523  if((*it)->isTracked())
524  {
525  ci = *it;
527  double fac = 1.0;
528 
529  std::list<vpMeSite>::const_iterator itCir;
530  if (iter == 0 && (ci->meEllipse != NULL)) {
531  itCir = ci->meEllipse->getMeList().begin();
532  }
533 
534  for(unsigned int i=0 ; i < ci->nbFeature ; i++){
535  for(unsigned int j=0; j < 6 ; j++){
536  L[n+i][j] = ci->L[i][j]; //On remplit la matrice d'interaction globale
537  }
538  error[n+i] = ci->error[i]; //On remplit la matrice d'erreur
539 
540  if (error[n+i] <= limite) count = count+1.0; //Si erreur proche de 0 on incremente cur
541 
542  w_mbt[n+i] = 0;
543 
544  if (iter == 0)
545  {
546  factor[n+i] = fac;
547  vpMeSite site = *itCir;
548  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
549  ++itCir;
550  }
551 
552  //If pour la premiere extremite des moving edges
553  if (i == 0)
554  {
555  e_cur = ci->error[0];
556  if (ci->nbFeature > 1)
557  {
558  e_next = ci->error[1];
559  if ( fabs(e_cur - e_next) < limite && vpMath::sign(e_cur) == vpMath::sign(e_next) )
560  {
561  w_mbt[n+i] = 1/*0.5*/;
562  }
563  e_prev = e_cur;
564  }
565  else w_mbt[n+i] = 1;
566  }
567 
568  //If pour la derniere extremite des moving edges
569  else if(i == ci->nbFeature-1)
570  {
571  e_cur = ci->error[i];
572  if ( fabs(e_cur - e_prev) < limite && vpMath::sign(e_cur) == vpMath::sign(e_prev) )
573  {
574  w_mbt[n+i] += 1/*0.5*/;
575  }
576  }
577 
578  else
579  {
580  e_cur = ci->error[i];
581  e_next = ci->error[i+1];
582  if ( fabs(e_cur - e_prev) < limite ){
583  w_mbt[n+i] += 0.5;
584  }
585  if ( fabs(e_cur - e_next) < limite ){
586  w_mbt[n+i] += 0.5;
587  }
588  e_prev = e_cur;
589  }
590  }
591 
592  n+= ci->nbFeature ;
593  }
594  }
595 }
596 
597 void
602 
603  unsigned int n = 0;
604  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
605  if((*it)->isTracked()){
606  l = *it;
608 
609  double fac = 1;
610  for(std::list<int>::const_iterator itindex = l->Lindex_polygon.begin(); itindex!=l->Lindex_polygon.end(); ++itindex){
611  int index = *itindex;
612  if (l->hiddenface->isAppearing((unsigned int)index)) {
613  fac = 0.2;
614  break;
615  }
616  if(l->closeToImageBorder(I, 10)){
617  fac = 0.1;
618  break;
619  }
620  }
621 
622  unsigned int indexFeature = 0;
623  for(unsigned int a = 0 ; a < l->meline.size(); a++){
624  std::list<vpMeSite>::const_iterator itListLine;
625  if (l->meline[a] != NULL)
626  {
627  itListLine = l->meline[a]->getMeList().begin();
628 
629  for (unsigned int i=0 ; i < l->nbFeature[a] ; i++){
630  factor[n+i] = fac;
631  vpMeSite site = *itListLine;
632  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
633  ++itListLine;
634  indexFeature++;
635  }
636  n+= l->nbFeature[a] ;
637  }
638  }
639  }
640  }
641 
642  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){
643  if((*it)->isTracked()){
644  cy = *it;
646 
647  std::list<vpMeSite>::const_iterator itCyl1;
648  std::list<vpMeSite>::const_iterator itCyl2;
649  if ((cy->meline1 != NULL || cy->meline2 != NULL)){
650  itCyl1 = cy->meline1->getMeList().begin();
651  itCyl2 = cy->meline2->getMeList().begin();
652 
653  double fac = 1.0;
654  for(unsigned int i=0 ; i < cy->nbFeature ; i++){
655  factor[n+i] = fac;
656  vpMeSite site;
657  if(i<cy->nbFeaturel1) {
658  site= *itCyl1;
659  ++itCyl1;
660  }
661  else{
662  site= *itCyl2;
663  ++itCyl2;
664  }
665  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
666  }
667  n+= cy->nbFeature ;
668  }
669  }
670  }
671 
672  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){
673  if((*it)->isTracked()){
674  ci = *it;
676 
677  std::list<vpMeSite>::const_iterator itCir;
678  if (ci->meEllipse != NULL) {
679  itCir = ci->meEllipse->getMeList().begin();
680  double fac = 1.0;
681 
682  for(unsigned int i=0 ; i < ci->nbFeature ; i++){
683  factor[n+i] = fac;
684  vpMeSite site = *itCir;
685  if (site.getState() != vpMeSite::NO_SUPPRESSION) factor[n+i] = 0.2;
686  ++itCir;
687  }
688  n+= ci->nbFeature ;
689  }
690  }
691  }
692 }
693 
694 void
695 vpMbEdgeTracker::computeVVSFirstPhasePoseEstimation(const unsigned int nerror, const unsigned int iter, const vpColVector &factor,
696  vpColVector &weighted_error, vpMatrix &L, bool &isoJoIdentity_) {
697 
698  double wi, eri;
699  if((iter==0) || compute_interaction) {
700  for (unsigned int i = 0; i < nerror; i++) {
701  wi = m_w[i]*factor[i];
702  eri = m_error[i];
703 
704  weighted_error[i] = wi*eri;
705 
706  for (unsigned int j = 0; j < 6; j++) {
707  L[i][j] = wi*L[i][j];
708  }
709  }
710  } else {
711  for(unsigned int i = 0; i < nerror; i++) {
712  wi = m_w[i]*factor[i];
713  eri = m_error[i];
714 
715  weighted_error[i] = wi*eri;
716  }
717  }
718 
720 
721  // If all the 6 dof should be estimated, we check if the interaction matrix is full rank.
722  // If not we remove automatically the dof that cannot be estimated
723  // This is particularly useful when consering circles (rank 5) and cylinders (rank 4)
724  if (isoJoIdentity_) {
725  cVo.buildFrom(cMo);
726 
727  vpMatrix K; // kernel
728  unsigned int rank = (L*cVo).kernel(K);
729  if(rank == 0) {
730  throw vpException(vpException::fatalError, "Rank=0, cannot estimate the pose !");
731  }
732  if (rank != 6) {
733  vpMatrix I; // Identity
734  I.eye(6);
735  oJo = I-K.AtA();
736 
737  isoJoIdentity_ = false;
738  }
739  }
740 
741  vpColVector v;
742  vpMatrix LTL;
743  vpColVector LTR;
744 
745  if(isoJoIdentity_){
746  LTL = L.AtA();
747  computeJTR(L, weighted_error, LTR);
748  v = -0.7*LTL.pseudoInverse(LTL.getRows()*std::numeric_limits<double>::epsilon())*LTR;
749  }
750  else{
751  cVo.buildFrom(cMo);
752  vpMatrix LVJ = (L*cVo*oJo);
753  vpMatrix LVJTLVJ = (LVJ).AtA();
754  vpColVector LVJTR;
755  computeJTR(LVJ, weighted_error, LVJTR);
756  v = -0.7*LVJTLVJ.pseudoInverse(LVJTLVJ.getRows()*std::numeric_limits<double>::epsilon())*LVJTR;
757  v = cVo * v;
758  }
759 
761 }
762 
763 void
765  vpColVector &error_cylinders, vpColVector &error_circles, vpColVector &error, const unsigned int lvl) {
769 
770  unsigned int n = 0;
771  unsigned int nlines = 0;
772  unsigned int ncylinders = 0;
773  unsigned int ncircles = 0;
774 
775  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
776  if((*it)->isTracked()){
777  l = *it;
779  for (unsigned int i=0 ; i < l->nbFeatureTotal ; i++){
780  for (unsigned int j=0; j < 6 ; j++){
781  L[n+i][j] = l->L[i][j];
782  error[n+i] = l->error[i];
783  error_lines[nlines+i] = error[n+i];
784  }
785  }
786  n+= l->nbFeatureTotal;
787  nlines+= l->nbFeatureTotal;
788  }
789  }
790 
791  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){
792  if((*it)->isTracked()){
793  cy = *it;
795  for(unsigned int i=0 ; i < cy->nbFeature ; i++){
796  for(unsigned int j=0; j < 6 ; j++){
797  L[n+i][j] = cy->L[i][j];
798  error[n+i] = cy->error[i];
799  error_cylinders[ncylinders+i] = error[n+i];
800  }
801  }
802 
803  n+= cy->nbFeature ;
804  ncylinders+= cy->nbFeature ;
805  }
806  }
807 
808  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){
809  if((*it)->isTracked()){
810  ci = *it;
812  for(unsigned int i=0 ; i < ci->nbFeature ; i++){
813  for(unsigned int j=0; j < 6 ; j++){
814  L[n+i][j] = ci->L[i][j];
815  error[n+i] = ci->error[i];
816  error_circles[ncircles+i] = error[n+i];
817  }
818  }
819 
820  n+= ci->nbFeature ;
821  ncircles+= ci->nbFeature ;
822  }
823  }
824 }
825 
826 void
827 vpMbEdgeTracker::computeVVSSecondPhaseCheckLevenbergMarquardt(const unsigned int iter, const unsigned int nbrow,
828  const vpColVector &m_error_prev, const vpColVector &m_w_prev, const vpHomogeneousMatrix &cMoPrev,
829  double &mu, bool &reStartFromLastIncrement) {
831  if(m_error.sumSquare()/(double)nbrow > m_error_prev.sumSquare()/(double)nbrow){
832  mu *= 10.0;
833 
834  if(mu > 1.0)
835  throw vpTrackingException(vpTrackingException::fatalError, "Optimization diverged");
836 
837  cMo = cMoPrev;
838  m_error = m_error_prev;
839  m_w = m_w_prev;
840  reStartFromLastIncrement = true;
841  }
842  }
843 }
844 
845 void
847  vpMatrix &LVJ_true, vpColVector &W_true, const vpColVector &factor, const unsigned int iter, const bool isoJoIdentity_,
848  vpColVector &weighted_error, double &mu, vpColVector &m_error_prev, vpColVector &m_w_prev,
849  vpHomogeneousMatrix &cMoPrev, double &residu_1, double &r) {
850  double num=0;
851  double den=0;
852  double wi;
853  double eri;
854 
855  vpMatrix LTL;
856  vpColVector LTR;
857 
858  L_true = L;
859  W_true = vpColVector(nerror);
860 
862  if(computeCovariance){
863  L_true = L;
864  if(!isoJoIdentity_){
865  cVo.buildFrom(cMo);
866  LVJ_true = (L*cVo*oJo);
867  }
868  }
869 
870  if((iter==0)|| compute_interaction) {
871  for (unsigned int i = 0; i < nerror; i++) {
872  wi = m_w[i]*factor[i];
873  W_true[i] = wi;
874  eri = m_error[i];
875  num += wi*vpMath::sqr(eri);
876  den += wi;
877 
878  weighted_error[i] = wi*eri ;
879 
880  for (unsigned int j = 0; j < 6; j++) {
881  L[i][j] = wi*L[i][j];
882  }
883  }
884  } else {
885  for(unsigned int i = 0; i < nerror; i++) {
886  wi = m_w[i]*factor[i];
887  W_true[i] = wi;
888  eri = m_error[i];
889  num += wi*vpMath::sqr(eri);
890  den += wi;
891 
892  weighted_error[i] = wi*eri ;
893  }
894  }
895 
896  vpColVector v;
897  if(isoJoIdentity_){
898  LTL = L.AtA();
899  computeJTR(L, weighted_error, LTR);
900 
901  switch(m_optimizationMethod){
903  {
904  vpMatrix LMA(LTL.getRows(), LTL.getCols());
905  LMA.eye();
906  vpMatrix LTLmuI = LTL + (LMA*mu);
907  v = -lambda*LTLmuI.pseudoInverse(LTLmuI.getRows()*std::numeric_limits<double>::epsilon())*LTR;
908 
909  if(iter != 0)
910  mu /= 10.0;
911 
912  m_error_prev = m_error;
913  m_w_prev = m_w;
914  break;
915  }
917  default:
918  v = -lambda*LTL.pseudoInverse(LTL.getRows()*std::numeric_limits<double>::epsilon())*LTR;
919  }
920  }
921  else{
922  cVo.buildFrom(cMo);
923  vpMatrix LVJ = (L*cVo*oJo);
924  vpMatrix LVJTLVJ = (LVJ).AtA();
925  vpColVector LVJTR;
926  computeJTR(LVJ, weighted_error, LVJTR);
927 
928  switch(m_optimizationMethod){
930  {
931  vpMatrix LMA(LVJTLVJ.getRows(), LVJTLVJ.getCols());
932  LMA.eye();
933  vpMatrix LTLmuI = LVJTLVJ + (LMA*mu);
934  v = -lambda*LTLmuI.pseudoInverse(LTLmuI.getRows()*std::numeric_limits<double>::epsilon())*LVJTR;
935  v = cVo * v;
936 
937  if(iter != 0)
938  mu /= 10.0;
939 
940  m_error_prev = m_error;
941  m_w_prev = m_w;
942  break;
943  }
945  default:
946  {
947  v = -lambda*LVJTLVJ.pseudoInverse(LVJTLVJ.getRows()*std::numeric_limits<double>::epsilon())*LVJTR;
948  v = cVo * v;
949  break;
950  }
951  }
952  }
953 
954  residu_1 = r;
955  r = sqrt(num/den); //Le critere d'arret prend en compte le poids
956 
957  cMoPrev = cMo;
959 }
960 
961 void
962 vpMbEdgeTracker::computeVVSSecondPhaseWeights(const unsigned int iter, const unsigned int nerror,
963  const unsigned int nbrow, vpColVector &weighted_error,
964  vpRobust &robust_lines, vpRobust &robust_cylinders, vpRobust &robust_circles,
965  vpColVector &w_lines, vpColVector &w_cylinders, vpColVector &w_circles,
966  vpColVector &error_lines, vpColVector &error_cylinders, vpColVector &error_circles,
967  const unsigned int nberrors_lines, const unsigned int nberrors_cylinders, const unsigned int nberrors_circles) {
968  if(iter==0)
969  {
970  weighted_error.resize(nerror);
971  m_w.resize(nerror);
972  m_w = 1;
973  w_lines.resize(nberrors_lines);
974  w_lines = 1;
975  w_cylinders.resize(nberrors_cylinders);
976  w_cylinders = 1;
977  w_circles.resize(nberrors_circles);
978  w_circles = 1;
979 
980  robust_lines.setThreshold(2/cam.get_px());
981  robust_cylinders.setThreshold(2/cam.get_px());
982  robust_circles.setThreshold(vpMath::sqr(2/cam.get_px()));
983  if(nberrors_lines > 0)
984  robust_lines.MEstimator(vpRobust::TUKEY, error_lines,w_lines);
985  if(nberrors_cylinders > 0)
986  robust_cylinders.MEstimator(vpRobust::TUKEY, error_cylinders,w_cylinders);
987  if(nberrors_circles > 0)
988  robust_circles.MEstimator(vpRobust::TUKEY, error_circles,w_circles);
989  }
990  else
991  {
992  robust_lines.setIteration(iter);
993  robust_cylinders.setIteration(iter);
994  robust_circles.setIteration(iter);
995  if(nberrors_lines > 0)
996  robust_lines.MEstimator(vpRobust::TUKEY, error_lines, w_lines);
997  if(nberrors_cylinders > 0)
998  robust_cylinders.MEstimator(vpRobust::TUKEY, error_cylinders,w_cylinders);
999  if(nberrors_circles > 0)
1000  robust_circles.MEstimator(vpRobust::TUKEY, error_circles,w_circles);
1001  }
1002 
1003  unsigned int cpt = 0;
1004  while(cpt<nbrow){
1005  if(cpt<nberrors_lines){
1006  m_w[cpt] = w_lines[cpt];
1007  }
1008  else if (cpt<nberrors_lines+nberrors_cylinders){
1009  m_w[cpt] = w_cylinders[cpt-nberrors_lines];
1010  }
1011  else {
1012  m_w[cpt] = w_circles[cpt-nberrors_lines-nberrors_cylinders];
1013  }
1014  cpt++;
1015  }
1016 }
1017 
1025 void
1027 {
1028  projectionError = 0.0;
1029  unsigned int nbFeatures = 0;
1030  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1031  vpMbtDistanceLine *l = *it;
1032  if (l->isVisible() && l->isTracked())
1033  {
1034  for(unsigned int a = 0 ; a < l->meline.size() ; a++){
1035  if(l->meline[a] != NULL){
1036  double lineNormGradient;
1037  unsigned int lineNbFeatures;
1038  l->meline[a]->computeProjectionError(_I, lineNormGradient, lineNbFeatures);
1039  projectionError += lineNormGradient;
1040  nbFeatures += lineNbFeatures;
1041  }
1042  }
1043  }
1044  }
1045 
1046  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1047  vpMbtDistanceCylinder *cy = *it;
1048  if (cy->isVisible() && cy->isTracked())
1049  {
1050  if(cy->meline1 != NULL)
1051  {
1052  double cylinderNormGradient = 0;
1053  unsigned int cylinderNbFeatures = 0;
1054  cy->meline1->computeProjectionError(_I, cylinderNormGradient, cylinderNbFeatures);
1055  projectionError += cylinderNormGradient;
1056  nbFeatures += cylinderNbFeatures;
1057  }
1058 
1059  if(cy->meline2 != NULL)
1060  {
1061  double cylinderNormGradient = 0;
1062  unsigned int cylinderNbFeatures = 0;
1063  cy->meline2->computeProjectionError(_I, cylinderNormGradient, cylinderNbFeatures);
1064  projectionError += cylinderNormGradient;
1065  nbFeatures += cylinderNbFeatures;
1066  }
1067  }
1068  }
1069 
1070  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1071  vpMbtDistanceCircle *c = *it;
1072  if (c->isVisible() && c->isTracked() && c->meEllipse != NULL)
1073  {
1074  double circleNormGradient = 0;
1075  unsigned int circleNbFeatures = 0;
1076  c->meEllipse->computeProjectionError(_I, circleNormGradient, circleNbFeatures);
1077  projectionError += circleNormGradient;
1078  nbFeatures += circleNbFeatures;
1079  }
1080  }
1081 
1082  if(nbFeatures > 0) {
1083  projectionError = vpMath::deg(projectionError/(double)nbFeatures);
1084  }
1085  else {
1086  projectionError = 90.0;
1087  }
1088 
1089  nbFeaturesForProjErrorComputation = nbFeatures;
1090 // std::cout << "Norm Gradient = " << errorGradient << std::endl;
1091 }
1092 
1098 void
1100 {
1101  int nbExpectedPoint = 0;
1102  int nbGoodPoint = 0;
1103  int nbBadPoint = 0;
1104 
1105  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1106  vpMbtDistanceLine *l = *it;
1107  if (l->isVisible() && l->isTracked())
1108  {
1109  for(unsigned int a = 0 ; a < l->meline.size() ; a++){
1110  if(l->meline[a] != NULL){
1111  nbExpectedPoint += (int)l->meline[a]->expecteddensity;
1112  for(std::list<vpMeSite>::const_iterator itme=l->meline[a]->getMeList().begin(); itme!=l->meline[a]->getMeList().end(); ++itme){
1113  vpMeSite pix = *itme;
1114  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
1115  else nbBadPoint++;
1116  }
1117  }
1118  }
1119  }
1120  }
1121 
1122  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1123  vpMbtDistanceCylinder *cy = *it;
1124  if ((cy->meline1 !=NULL && cy->meline2 != NULL) && cy->isVisible() && cy->isTracked())
1125  {
1126  nbExpectedPoint += (int)cy->meline1->expecteddensity;
1127  for(std::list<vpMeSite>::const_iterator itme1=cy->meline1->getMeList().begin(); itme1!=cy->meline1->getMeList().end(); ++itme1){
1128  vpMeSite pix = *itme1;
1129  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
1130  else nbBadPoint++;
1131  }
1132  nbExpectedPoint += (int)cy->meline2->expecteddensity;
1133  for(std::list<vpMeSite>::const_iterator itme2=cy->meline2->getMeList().begin(); itme2!=cy->meline2->getMeList().end(); ++itme2){
1134  vpMeSite pix = *itme2;
1135  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
1136  else nbBadPoint++;
1137  }
1138  }
1139  }
1140 
1141  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1142  vpMbtDistanceCircle *ci = *it;
1143  if (ci->isVisible() && ci->isTracked() && ci->meEllipse !=NULL)
1144  {
1145  nbExpectedPoint += ci->meEllipse->getExpectedDensity();
1146  for(std::list<vpMeSite>::const_iterator itme=ci->meEllipse->getMeList().begin(); itme!=ci->meEllipse->getMeList().end(); ++itme){
1147  vpMeSite pix = *itme;
1148  if (pix.getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoint++;
1149  else nbBadPoint++;
1150  }
1151  }
1152  }
1153 
1154  // Compare the number of good points with the min between the number of expected points and
1155  // number of points that are tracked
1156  int nb_min = (int)vpMath::minimum(percentageGdPt *nbExpectedPoint, percentageGdPt *(nbGoodPoint + nbBadPoint) );
1157  //int nb_min = std::min(val1, val2);
1158  if (nbGoodPoint < nb_min || nbExpectedPoint < 2) {
1159  std::ostringstream oss;
1160  oss << "Not enough moving edges ("
1161  << nbGoodPoint
1162  << ") to track the object: expected "
1163  << nb_min
1164  << ". Try to reduce the threshold="
1165  << percentageGdPt
1166  << " using vpMbTracker::setGoodMovingEdgesRatioThreshold()";
1168  }
1169 }
1170 
1178 void
1180 {
1181  initPyramid(I, Ipyramid);
1182 
1183 // for (int lvl = ((int)scales.size()-1); lvl >= 0; lvl -= 1)
1184  unsigned int lvl = (unsigned int)scales.size();
1185  do{
1186  lvl--;
1187 
1188  projectionError = 90.0;
1189 
1190  if(scales[lvl]){
1191  vpHomogeneousMatrix cMo_1 = cMo;
1192  try
1193  {
1194  downScale(lvl);
1195 
1196  try
1197  {
1198  trackMovingEdge(*Ipyramid[lvl]);
1199  }
1200  catch(...)
1201  {
1202  vpTRACE("Error in moving edge tracking") ;
1203  throw ;
1204  }
1205 
1206  // initialize the vector that contains the error and the matrix that contains
1207  // the interaction matrix
1208  // AY: Useless as it is done in coputeVVS()
1209  /*
1210  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
1211  l = *it;
1212  if (l->isVisible()){
1213  l->initInteractionMatrixError() ;
1214  }
1215  }
1216 
1217  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){
1218  cy = *it;
1219  if(cy->isVisible()) {
1220  cy->initInteractionMatrixError();
1221  }
1222  }
1223 
1224  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){
1225  ci = *it;
1226  if (ci->isVisible()){
1227  ci->initInteractionMatrixError();
1228  }
1229  }
1230  */
1231 
1232  try
1233  {
1234  computeVVS(*Ipyramid[lvl], lvl);
1235  }
1236  catch(...)
1237  {
1238  covarianceMatrix = -1;
1239  throw; // throw the original exception
1240  }
1241 
1242  try
1243  {
1244  testTracking();
1245  }
1246  catch(...)
1247  {
1248  throw; // throw the original exception
1249  }
1250 
1251  if (displayFeatures)
1252  {
1253  displayFeaturesOnImage(I, lvl);
1254  }
1255 
1256  // Looking for new visible face
1257  bool newvisibleface = false ;
1258  visibleFace(I, cMo, newvisibleface) ;
1259 
1260  //cam.computeFov(I.getWidth(), I.getHeight());
1261  if(useScanLine){
1264  }
1265 
1266  try
1267  {
1268  updateMovingEdge(I);
1269  }
1270  catch(...)
1271  {
1272  throw; // throw the original exception
1273  }
1274 
1275  initMovingEdge(I,cMo) ;
1276  // Reinit the moving edge for the lines which need it.
1277  reinitMovingEdge(I,cMo);
1278 
1279  if(computeProjError)
1281 
1282  upScale(lvl);
1283  }
1284  catch(vpException &e)
1285  {
1286  if(lvl != 0){
1287  cMo = cMo_1;
1288  reInitLevel(lvl);
1289  upScale(lvl);
1290  }
1291  else{
1292  upScale(lvl);
1293  throw(e) ;
1294  }
1295  }
1296  }
1297  } while(lvl != 0);
1298 
1300 }
1301 
1308 {
1309  if(!modelInitialised){
1310  throw vpException(vpException::fatalError, "model not initialized");
1311  }
1312 
1313  bool a = false;
1314 
1315 #ifdef VISP_HAVE_OGRE
1316  if(useOgre){
1317  if(!faces.isOgreInitialised()){
1320  faces.initOgre(cam);
1321  // Turn off Ogre config dialog display for the next call to this function
1322  // since settings are saved in the ogre.cfg file and used during the next
1323  // call
1324  ogreShowConfigDialog = false;
1325  }
1326  }
1327 #endif
1328 
1329  if(clippingFlag > 2)
1330  cam.computeFov(I.getWidth(), I.getHeight());
1331 
1332  initPyramid(I, Ipyramid);
1333  visibleFace(I, cMo, a);
1334  unsigned int i = (unsigned int)scales.size();
1335 
1336  resetMovingEdge();
1337 
1338  if(useScanLine){
1339  if(clippingFlag <= 2)
1340  cam.computeFov(I.getWidth(), I.getHeight());
1341 
1344  }
1345 
1346  do {
1347  i--;
1348  if(scales[i]){
1349  downScale(i);
1350  initMovingEdge(*Ipyramid[i], cMo);
1351  upScale(i);
1352  }
1353  } while(i != 0);
1354 
1356 }
1357 
1365 void
1367 {
1368  cMo = cdMo;
1369 
1370  init(I);
1371 }
1372 
1384 void
1385 vpMbEdgeTracker::loadConfigFile(const std::string& configFile)
1386 {
1387  vpMbEdgeTracker::loadConfigFile(configFile.c_str());
1388 }
1389 
1439 void
1440 vpMbEdgeTracker::loadConfigFile(const char* configFile)
1441 {
1442 #ifdef VISP_HAVE_XML2
1443  vpMbtXmlParser xmlp;
1444 
1445  xmlp.setCameraParameters(cam);
1448  xmlp.setMovingEdge(me);
1449 
1450  try{
1451  std::cout << " *********** Parsing XML for Mb Edge Tracker ************ " << std::endl;
1452  xmlp.parse(configFile);
1453  }
1454  catch(...){
1455  throw vpException(vpException::ioError, "Cannot open XML file \"%s\"", configFile);
1456  }
1457 
1458  vpCameraParameters camera;
1459  vpMe meParser;
1460  xmlp.getCameraParameters(camera);
1461  xmlp.getMe(meParser);
1462 
1463  setCameraParameters(camera);
1464  setMovingEdge(meParser);
1467 
1468  if(xmlp.hasNearClippingDistance())
1470 
1471  if(xmlp.hasFarClippingDistance())
1473 
1474  if(xmlp.getFovClipping())
1476 
1477  useLodGeneral = xmlp.getLodState();
1480 
1481  applyLodSettingInConfig = false;
1482  if(this->getNbPolygon() > 0) {
1483  applyLodSettingInConfig = true;
1487  }
1488 
1489 #else
1490  vpTRACE("You need the libXML2 to read the config file %s", configFile);
1491 #endif
1492 }
1493 
1494 
1505 void
1507  const vpCameraParameters &camera, const vpColor& col,
1508  const unsigned int thickness, const bool displayFullModel)
1509 {
1510  for (unsigned int i = 0; i < scales.size(); i += 1){
1511  if(scales[i]){
1512  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1513  (*it)->display(I,cMo_, camera, col, thickness, displayFullModel);
1514  }
1515 
1516  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1517  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1518  }
1519 
1520  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1521  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1522  }
1523 
1524  break ; //displaying model on one scale only
1525  }
1526  }
1527 
1528 #ifdef VISP_HAVE_OGRE
1529  if(useOgre)
1530  faces.displayOgre(cMo_);
1531 #endif
1532 }
1533 
1544 void
1546  const vpCameraParameters &camera, const vpColor& col,
1547  const unsigned int thickness, const bool displayFullModel)
1548 {
1549  for (unsigned int i = 0; i < scales.size(); i += 1){
1550  if(scales[i]){
1551  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1552  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel) ;
1553  }
1554 
1555  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1556  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel) ;
1557  }
1558 
1559  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1560  (*it)->display(I, cMo_, camera, col, thickness, displayFullModel);
1561  }
1562  break ; //displaying model on one scale only
1563  }
1564  }
1565 
1566 #ifdef VISP_HAVE_OGRE
1567  if(useOgre)
1568  faces.displayOgre(cMo_);
1569 #endif
1570 }
1571 
1572 void
1574 {
1575  if(lvl == 0){
1576  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[lvl].begin(); it!=lines[lvl].end(); ++it){
1577  vpMbtDistanceLine *l = *it;
1578  if (l->isVisible() && l->isTracked()){
1579  l->displayMovingEdges(I);
1580  }
1581  }
1582 
1583  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[lvl].begin(); it!=cylinders[lvl].end(); ++it){
1584  vpMbtDistanceCylinder *cy = *it;
1585  if(cy->isVisible() && cy->isTracked()) {
1586  cy->displayMovingEdges(I);
1587  }
1588  }
1589 
1590  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[lvl].begin(); it!=circles[lvl].end(); ++it){
1591  vpMbtDistanceCircle *ci = *it;
1592  if (ci->isVisible() && ci->isTracked()){
1593  ci->displayMovingEdges(I);
1594  }
1595  }
1596  }
1597 }
1598 
1599 
1607 void
1609 {
1610  vpMbtDistanceLine *l ;
1611 
1612  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1613  l = *it;
1614  bool isvisible = false ;
1615 
1616  for(std::list<int>::const_iterator itindex=l->Lindex_polygon.begin(); itindex!=l->Lindex_polygon.end(); ++itindex){
1617  int index = *itindex;
1618  if (index ==-1) isvisible =true ;
1619  else
1620  {
1621  if (l->hiddenface->isVisible((unsigned int)index)) isvisible = true ;
1622  }
1623  }
1624 
1625  //Si la ligne n'appartient a aucune face elle est tout le temps visible
1626  if (l->Lindex_polygon.empty()) isvisible = true; // Not sure that this can occur
1627 
1628  if (isvisible)
1629  {
1630  l->setVisible(true) ;
1631  l->updateTracked();
1632  if (l->meline.size() == 0 && l->isTracked())
1633  l->initMovingEdge(I, _cMo) ;
1634  }
1635  else
1636  {
1637  l->setVisible(false) ;
1638  for(unsigned int a = 0 ; a < l->meline.size() ; a++){
1639  if (l->meline[a] != NULL) delete l->meline[a] ;
1640  l->nbFeature[a] = 0;
1641  }
1642  l->nbFeatureTotal = 0;
1643  l->meline.clear();
1644  }
1645  }
1646 
1647  vpMbtDistanceCylinder *cy ;
1648  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1649  cy = *it;
1650 
1651  bool isvisible = false ;
1652 
1653  int index = cy->index_polygon;
1654  if (index ==-1) isvisible =true ;
1655  else
1656  {
1657  if (cy->hiddenface->isVisible((unsigned int)index +1 ) ||
1658  cy->hiddenface->isVisible((unsigned int)index +2 ) ||
1659  cy->hiddenface->isVisible((unsigned int)index +3 ) ||
1660  cy->hiddenface->isVisible((unsigned int)index +4 ))
1661  isvisible = true ;
1662  }
1663 // vpTRACE("cyl with index %d is visible: %d", index, isvisible);
1664 
1665  if (isvisible)
1666  {
1667  cy->setVisible(true) ;
1668  if (cy->meline1==NULL || cy->meline2==NULL){
1669  if(cy->isTracked())
1670  cy->initMovingEdge(I, _cMo) ;
1671  }
1672  }
1673  else
1674  {
1675  cy->setVisible(false) ;
1676  if (cy->meline1!=NULL) delete cy->meline1;
1677  if (cy->meline2!=NULL) delete cy->meline2;
1678  cy->meline1=NULL;
1679  cy->meline2=NULL;
1680  cy->nbFeature = 0;
1681  cy->nbFeaturel1 = 0;
1682  cy->nbFeaturel2= 0;
1683  }
1684  }
1685 
1686  vpMbtDistanceCircle *ci ;
1687  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1688  ci = *it;
1689  bool isvisible = false ;
1690 
1691  int index = ci->index_polygon;
1692  if (index ==-1) isvisible =true ;
1693  else
1694  {
1695  if (ci->hiddenface->isVisible((unsigned int)index)) isvisible = true ;
1696  }
1697 
1698  if (isvisible)
1699  {
1700  ci->setVisible(true) ;
1701  if (ci->meEllipse==NULL)
1702  {
1703  if(ci->isTracked())
1704  ci->initMovingEdge(I, _cMo) ;
1705  }
1706  }
1707  else
1708  {
1709  ci->setVisible(false) ;
1710  if (ci->meEllipse!=NULL) delete ci->meEllipse;
1711  ci->meEllipse=NULL;
1712  ci->nbFeature = 0;
1713  }
1714  }
1715 }
1716 
1717 
1723 void
1725 {
1726  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1727  vpMbtDistanceLine *l = *it;
1728  if(l->isVisible() && l->isTracked()){
1729  if(l->meline.size() == 0){
1730  l->initMovingEdge(I, cMo);
1731  }
1732  l->trackMovingEdge(I, cMo) ;
1733  }
1734  }
1735 
1736  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1737  vpMbtDistanceCylinder *cy = *it;
1738  if(cy->isVisible() && cy->isTracked()) {
1739  if(cy->meline1 == NULL || cy->meline2 == NULL){
1740  cy->initMovingEdge(I, cMo);
1741  }
1742  cy->trackMovingEdge(I, cMo) ;
1743  }
1744  }
1745 
1746  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1747  vpMbtDistanceCircle *ci = *it;
1748  if(ci->isVisible() && ci->isTracked()){
1749  if(ci->meEllipse == NULL){
1750  ci->initMovingEdge(I, cMo);
1751  }
1752  ci->trackMovingEdge(I, cMo) ;
1753  }
1754  }
1755 }
1756 
1757 
1763 void
1765 {
1766  vpMbtDistanceLine *l ;
1767  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1768  if((*it)->isTracked()){
1769  l = *it;
1770  l->updateMovingEdge(I, cMo) ;
1771  if (l->nbFeatureTotal == 0 && l->isVisible()){
1772  l->Reinit = true;
1773  }
1774  }
1775  }
1776 
1777  vpMbtDistanceCylinder *cy ;
1778  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1779  if((*it)->isTracked()){
1780  cy = *it;
1781  cy->updateMovingEdge(I, cMo) ;
1782  if((cy->nbFeaturel1 == 0 || cy->nbFeaturel2 == 0) && cy->isVisible()){
1783  cy->Reinit = true;
1784  }
1785  }
1786  }
1787 
1788  vpMbtDistanceCircle *ci ;
1789  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1790  if((*it)->isTracked()){
1791  ci = *it;
1792  ci->updateMovingEdge(I, cMo) ;
1793  if(ci->nbFeature == 0 && ci->isVisible()){
1794  ci->Reinit = true;
1795  }
1796  }
1797  }
1798 }
1799 
1800 void
1802  unsigned int n = 0;
1803 
1804  vpMbtDistanceLine *l;
1805  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1806  if((*it)->isTracked()){
1807  l = *it;
1808  unsigned int indexLine = 0;
1809  double wmean = 0 ;
1810  for(unsigned int a = 0 ; a < l->meline.size() ; a++)
1811  {
1812  if (l->nbFeature[a] > 0) {
1813  std::list<vpMeSite>::iterator itListLine;
1814  itListLine = l->meline[a]->getMeList().begin();
1815 
1816  for (unsigned int i=0 ; i < l->nbFeature[a] ; i++){
1817  wmean += m_w[n+indexLine] ;
1818  vpMeSite p = *itListLine;
1819  if (m_w[n+indexLine] < 0.5){
1821 
1822  *itListLine = p;
1823  }
1824 
1825  ++itListLine;
1826  indexLine++;
1827  }
1828  }
1829  }
1830  n+= l->nbFeatureTotal ;
1831 
1832  if (l->nbFeatureTotal!=0)
1833  wmean /= l->nbFeatureTotal ;
1834  else
1835  wmean = 1;
1836 
1837  l->setMeanWeight(wmean);
1838 
1839  if (wmean < 0.8)
1840  l->Reinit = true;
1841  }
1842  }
1843 
1844  // Same thing with cylinders as with lines
1846  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1847  if((*it)->isTracked()){
1848  cy = *it;
1849  double wmean = 0 ;
1850  std::list<vpMeSite>::iterator itListCyl1;
1851  std::list<vpMeSite>::iterator itListCyl2;
1852 
1853  if (cy->nbFeature > 0){
1854  itListCyl1 = cy->meline1->getMeList().begin();
1855  itListCyl2 = cy->meline2->getMeList().begin();
1856 
1857  for(unsigned int i=0 ; i < cy->nbFeaturel1 ; i++){
1858  wmean += m_w[n+i] ;
1859  vpMeSite p = *itListCyl1;
1860  if (m_w[n+i] < 0.5){
1862 
1863  *itListCyl1 = p;
1864  }
1865 
1866  ++itListCyl1;
1867  }
1868  }
1869 
1870  if (cy->nbFeaturel1!=0)
1871  wmean /= cy->nbFeaturel1 ;
1872  else
1873  wmean = 1;
1874 
1875  cy->setMeanWeight1(wmean);
1876 
1877  if (wmean < 0.8){
1878  cy->Reinit = true;
1879  }
1880 
1881  wmean = 0;
1882  for(unsigned int i=cy->nbFeaturel1 ; i < cy->nbFeature ; i++){
1883  wmean += m_w[n+i] ;
1884  vpMeSite p = *itListCyl2;
1885  if (m_w[n+i] < 0.5){
1887 
1888  *itListCyl2 = p;
1889  }
1890 
1891  ++itListCyl2;
1892  }
1893 
1894  if (cy->nbFeaturel2!=0)
1895  wmean /= cy->nbFeaturel2 ;
1896  else
1897  wmean = 1;
1898 
1899  cy->setMeanWeight2(wmean);
1900 
1901  if (wmean < 0.8){
1902  cy->Reinit = true;
1903  }
1904 
1905  n+= cy->nbFeature ;
1906  }
1907  }
1908 
1909  // Same thing with circles as with lines
1910  vpMbtDistanceCircle *ci;
1911  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1912  if((*it)->isTracked()){
1913  ci = *it;
1914  double wmean = 0 ;
1915  std::list<vpMeSite>::iterator itListCir;
1916 
1917  if (ci->nbFeature > 0){
1918  itListCir = ci->meEllipse->getMeList().begin();
1919  }
1920 
1921  wmean = 0;
1922  for(unsigned int i=0 ; i < ci->nbFeature ; i++){
1923  wmean += m_w[n+i] ;
1924  vpMeSite p = *itListCir;
1925  if (m_w[n+i] < 0.5){
1927 
1928  *itListCir = p;
1929  }
1930 
1931  ++itListCir;
1932  }
1933 
1934  if (ci->nbFeature!=0)
1935  wmean /= ci->nbFeature ;
1936  else
1937  wmean = 1;
1938 
1939  ci->setMeanWeight(wmean);
1940 
1941  if (wmean < 0.8){
1942  ci->Reinit = true;
1943  }
1944 
1945  n+= ci->nbFeature ;
1946  }
1947  }
1948 }
1949 
1950 
1959 void
1961 {
1962  vpMbtDistanceLine *l ;
1963  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
1964  if((*it)->isTracked()){
1965  l = *it;
1966  if (l->Reinit && l->isVisible())
1967  l->reinitMovingEdge(I, _cMo);
1968  }
1969  }
1970 
1972  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
1973  if((*it)->isTracked()){
1974  cy = *it;
1975  if (cy->Reinit && cy->isVisible())
1976  cy->reinitMovingEdge(I, _cMo);
1977  }
1978  }
1979 
1981  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
1982  if((*it)->isTracked()){
1983  ci = *it;
1984  if (ci->Reinit && ci->isVisible())
1985  ci->reinitMovingEdge(I, _cMo);
1986  }
1987  }
1988 }
1989 
1990 void
1992  for (unsigned int i = 0; i < scales.size(); i += 1){
1993  if (scales[i]) {
1994  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
1995  for(unsigned int a = 0 ; a < (*it)->meline.size() ; a++){
1996  if((*it)->meline[a] != NULL){
1997  delete (*it)->meline[a];
1998  (*it)->meline[a] = NULL;
1999  }
2000  (*it)->meline.clear();
2001  (*it)->nbFeature.clear();
2002  (*it)->nbFeatureTotal = 0;
2003  }
2004  }
2005 
2006  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
2007  if((*it)->meline1 != NULL){
2008  delete (*it)->meline1;
2009  (*it)->meline1 = NULL;
2010  }
2011  if((*it)->meline2 != NULL){
2012  delete (*it)->meline2;
2013  (*it)->meline2 = NULL;
2014  }
2015 
2016  (*it)->nbFeature = 0;
2017  (*it)->nbFeaturel1 = 0;
2018  (*it)->nbFeaturel2 = 0;
2019  }
2020 
2021  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
2022  if((*it)->meEllipse != NULL){
2023  delete (*it)->meEllipse;
2024  (*it)->meEllipse = NULL;
2025  }
2026  (*it)->nbFeature = 0;
2027  }
2028  }
2029  }
2030 }
2031 
2040 bool
2041 vpMbEdgeTracker::samePoint(const vpPoint &P1, const vpPoint &P2) const
2042 {
2043  double dx = fabs(P1.get_oX() - P2.get_oX());
2044  double dy = fabs(P1.get_oY() - P2.get_oY());
2045  double dz = fabs(P1.get_oZ() - P2.get_oZ());
2046 
2047  if (dx <= std::numeric_limits<double>::epsilon() && dy <= std::numeric_limits<double>::epsilon() && dz <= std::numeric_limits<double>::epsilon())
2048  return true ;
2049  else
2050  return false ;
2051 }
2052 
2053 
2064 void
2065 vpMbEdgeTracker::addLine(vpPoint &P1, vpPoint &P2, int polygon, std::string name)
2066 {
2067  //suppress line already in the model
2068  bool already_here = false ;
2069  vpMbtDistanceLine *l ;
2070 
2071  for (unsigned int i = 0; i < scales.size(); i += 1){
2072  if(scales[i]){
2073  downScale(i);
2074  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2075  l = *it;
2076  if((samePoint(*(l->p1),P1) && samePoint(*(l->p2),P2)) ||
2077  (samePoint(*(l->p1),P2) && samePoint(*(l->p2),P1)) ){
2078  already_here = true ;
2079  l->addPolygon(polygon);
2080  l->hiddenface = &faces ;
2081  }
2082  }
2083 
2084  if (!already_here){
2085  l = new vpMbtDistanceLine ;
2086 
2087  l->setCameraParameters(cam) ;
2088  l->buildFrom(P1,P2) ;
2089  l->addPolygon(polygon);
2090  l->setMovingEdge(&me) ;
2091  l->hiddenface = &faces ;
2092  l->useScanLine = useScanLine;
2093 
2094  l->setIndex(nline) ;
2095  l->setName(name);
2096 
2099 
2100  if((clippingFlag & vpPolygon3D::NEAR_CLIPPING) == vpPolygon3D::NEAR_CLIPPING)
2102 
2103  if((clippingFlag & vpPolygon3D::FAR_CLIPPING) == vpPolygon3D::FAR_CLIPPING)
2105 
2106  nline +=1 ;
2107  lines[i].push_back(l);
2108  }
2109  upScale(i);
2110  }
2111  }
2112 }
2113 
2119 void
2120 vpMbEdgeTracker::removeLine(const std::string& name)
2121 {
2122  vpMbtDistanceLine *l;
2123 
2124  for(unsigned int i=0; i<scales.size(); i++){
2125  if(scales[i]){
2126  for(std::list<vpMbtDistanceLine*>::iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2127  l = *it;
2128  if (name.compare(l->getName()) == 0){
2129  lines[i].erase(it);
2130  break;
2131  }
2132  }
2133  }
2134  }
2135 }
2136 
2147 void
2148 vpMbEdgeTracker::addCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, const double r, int idFace, const std::string& name)
2149 {
2150  bool already_here = false ;
2151  vpMbtDistanceCircle *ci ;
2152 
2153  for (unsigned int i = 0; i < scales.size(); i += 1){
2154  if(scales[i]){
2155  downScale(i);
2156  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
2157  ci = *it;
2158  if((samePoint(*(ci->p1),P1) && samePoint(*(ci->p2),P2) && samePoint(*(ci->p3),P3)) ||
2159  (samePoint(*(ci->p1),P1) && samePoint(*(ci->p2),P3) && samePoint(*(ci->p3),P2)) ){
2160  already_here = (std::fabs(ci->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(ci->radius, r));
2161  }
2162  }
2163 
2164  if (!already_here){
2165  ci = new vpMbtDistanceCircle ;
2166 
2167  ci->setCameraParameters(cam);
2168  ci->buildFrom(P1, P2, P3, r);
2169  ci->setMovingEdge(&me);
2170  ci->setIndex(ncircle);
2171  ci->setName(name);
2172  ci->index_polygon = idFace;
2173  ci->hiddenface = &faces ;
2174 
2175 // if(clippingFlag != vpPolygon3D::NO_CLIPPING)
2176 // ci->getPolygon().setClipping(clippingFlag);
2177 
2178 // if((clippingFlag & vpPolygon3D::NEAR_CLIPPING) == vpPolygon3D::NEAR_CLIPPING)
2179 // ci->getPolygon().setNearClippingDistance(distNearClip);
2180 
2181 // if((clippingFlag & vpPolygon3D::FAR_CLIPPING) == vpPolygon3D::FAR_CLIPPING)
2182 // ci->getPolygon().setFarClippingDistance(distFarClip);
2183 
2184  ncircle +=1;
2185  circles[i].push_back(ci);
2186  }
2187  upScale(i);
2188  }
2189  }
2190 }
2191 
2201 void
2202 vpMbEdgeTracker::addCylinder(const vpPoint &P1, const vpPoint &P2, const double r, int idFace, const std::string& name)
2203 {
2204  bool already_here = false ;
2205  vpMbtDistanceCylinder *cy ;
2206 
2207  for (unsigned int i = 0; i < scales.size(); i += 1){
2208  if(scales[i]){
2209  downScale(i);
2210  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
2211  cy = *it;
2212  if((samePoint(*(cy->p1),P1) && samePoint(*(cy->p2),P2)) ||
2213  (samePoint(*(cy->p1),P2) && samePoint(*(cy->p2),P1)) ){
2214  already_here = (std::fabs(cy->radius - r) < std::numeric_limits<double>::epsilon() * vpMath::maximum(cy->radius, r));
2215  }
2216  }
2217 
2218  if (!already_here){
2219  cy = new vpMbtDistanceCylinder ;
2220 
2221  cy->setCameraParameters(cam);
2222  cy->buildFrom(P1, P2, r);
2223  cy->setMovingEdge(&me);
2224  cy->setIndex(ncylinder);
2225  cy->setName(name);
2226  cy->index_polygon = idFace;
2227  cy->hiddenface = &faces ;
2228  ncylinder +=1;
2229  cylinders[i].push_back(cy);
2230  }
2231  upScale(i);
2232  }
2233  }
2234 }
2235 
2241 void
2242 vpMbEdgeTracker::removeCylinder(const std::string& name)
2243 {
2245 
2246  for(unsigned int i=0; i<scales.size(); i++){
2247  if(scales[i]){
2248  for(std::list<vpMbtDistanceCylinder*>::iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
2249  cy = *it;
2250  if (name.compare(cy->getName()) == 0){
2251  cylinders[i].erase(it);
2252  break;
2253  }
2254  }
2255  }
2256  }
2257 }
2258 
2264 void
2265 vpMbEdgeTracker::removeCircle(const std::string& name)
2266 {
2267  vpMbtDistanceCircle *ci;
2268 
2269  for(unsigned int i=0; i<scales.size(); i++){
2270  if(scales[i]){
2271  for(std::list<vpMbtDistanceCircle*>::iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
2272  ci = *it;
2273  if (name.compare(ci->getName()) == 0){
2274  circles[i].erase(it);
2275  break;
2276  }
2277  }
2278  }
2279  }
2280 }
2281 
2287 void
2289 {
2290  unsigned int nbpt = p.getNbPoint() ;
2291  if(nbpt > 0){
2292  for (unsigned int i=0 ; i < nbpt-1 ; i++)
2293  addLine(p.p[i], p.p[i+1], p.getIndex()) ;
2294  addLine(p.p[nbpt-1], p.p[0], p.getIndex()) ;
2295  }
2296 }
2297 
2308 void
2310  const vpHomogeneousMatrix &_cMo, bool &newvisibleline)
2311 {
2312  unsigned int n ;
2313  bool changed = false;
2314 
2315  if(!useOgre) {
2316  //n = faces.setVisible(_I, cam, _cMo, vpMath::rad(89), vpMath::rad(89), changed) ;
2317  n = faces.setVisible(_I, cam, _cMo, angleAppears, angleDisappears, changed) ;
2318  }
2319  else{
2320 #ifdef VISP_HAVE_OGRE
2321  n = faces.setVisibleOgre(_I, cam, _cMo, angleAppears, angleDisappears, changed);
2322 #else
2323  n = faces.setVisible(_I, cam, _cMo, angleAppears, angleDisappears, changed) ;
2324 #endif
2325  }
2326 
2327  if (n > nbvisiblepolygone)
2328  {
2329  //cout << "une nouvelle face est visible " << endl ;
2330  newvisibleline = true ;
2331  }
2332  else
2333  newvisibleline = false ;
2334 
2335  nbvisiblepolygone= n ;
2336 }
2337 
2350 void
2352 {
2353  unsigned int nbpt = polygon.getNbPoint() ;
2354  if(nbpt > 0){
2355  for (unsigned int i=0 ; i < nbpt-1 ; i++)
2356  addLine(polygon.p[i], polygon.p[i+1], polygon.getIndex(), polygon.getName());
2357  addLine(polygon.p[nbpt-1], polygon.p[0], polygon.getIndex(), polygon.getName());
2358  }
2359 }
2372 void
2374 {
2375  unsigned int nbpt = polygon.getNbPoint() ;
2376  if(nbpt > 0){
2377  for (unsigned int i=0 ; i < nbpt-1 ; i++)
2378  addLine(polygon.p[i], polygon.p[i+1], polygon.getIndex(), polygon.getName());
2379  }
2380 }
2381 
2382 unsigned int
2383 vpMbEdgeTracker::initMbtTracking(unsigned int &nberrors_lines,
2384  unsigned int &nberrors_cylinders, unsigned int &nberrors_circles) {
2385  unsigned int nbrow = 0;
2386  nberrors_lines = 0;
2387  nberrors_cylinders = 0;
2388  nberrors_circles = 0;
2389 
2390  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
2391 
2392  vpMbtDistanceLine *l = *it;
2393 
2394  if(l->isVisible() && l->isTracked())
2395  {
2396  nbrow += l->nbFeatureTotal;
2397  nberrors_lines+=l->nbFeatureTotal;
2399  }
2400  }
2401 
2402  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
2403  vpMbtDistanceCylinder *cy = *it;
2404 
2405  if(cy->isVisible() && cy->isTracked())
2406  {
2407  nbrow += cy->nbFeature ;
2408  nberrors_cylinders += cy->nbFeature ;
2410  }
2411  }
2412 
2413  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
2414  vpMbtDistanceCircle *ci = *it;
2415 
2416  if(ci->isVisible() && ci->isTracked())
2417  {
2418  nbrow += ci->nbFeature ;
2419  nberrors_circles += ci->nbFeature ;
2421  }
2422  }
2423 
2424  return nbrow;
2425 }
2426 
2438 void
2439 vpMbEdgeTracker::initCircle(const vpPoint& p1, const vpPoint &p2, const vpPoint &p3, const double radius,
2440  const int idFace, const std::string &name)
2441 {
2442  addCircle(p1, p2, p3, radius, (int)idFace, name);
2443 }
2444 
2455 void
2456 vpMbEdgeTracker::initCylinder(const vpPoint& p1, const vpPoint &p2, const double radius, const int idFace,
2457  const std::string &name)
2458 {
2459  addCylinder(p1, p2, radius, (int)idFace, name);
2460 }
2461 
2467 void
2469 {
2470  this->cMo.eye();
2471  vpMbtDistanceLine *l;
2473  vpMbtDistanceCircle *ci;
2474 
2475  for (unsigned int i = 0; i < scales.size(); i += 1){
2476  if(scales[i]){
2477  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2478  l = *it;
2479  if (l!=NULL) delete l ;
2480  l = NULL ;
2481  }
2482 
2483  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
2484  cy = *it;
2485  if (cy!=NULL) delete cy;
2486  cy = NULL;
2487  }
2488 
2489  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
2490  ci = *it;
2491  if (ci!=NULL) delete ci;
2492  ci = NULL;
2493  }
2494  lines[i].clear();
2495  cylinders[i].clear();
2496  circles[i].clear();
2497  }
2498  }
2499 
2500  faces.reset();
2501 
2502  useScanLine = false;
2503 
2504 #ifdef VISP_HAVE_OGRE
2505  useOgre = false;
2506 #endif
2507 
2509  nline = 0;
2510  ncylinder = 0;
2511  lambda = 1;
2512  nbvisiblepolygone = 0;
2513  percentageGdPt = 0.4;
2514 
2515  angleAppears = vpMath::rad(89);
2518 
2520 
2521  // reinitialization of the scales.
2522  this->setScales(scales);
2523 }
2524 
2534 void
2535 vpMbEdgeTracker::reInitModel(const vpImage<unsigned char>& I, const std::string &cad_name,
2536  const vpHomogeneousMatrix& cMo_, const bool verbose)
2537 {
2538  reInitModel(I, cad_name.c_str(), cMo_, verbose);
2539 }
2540 
2550 void
2552  const vpHomogeneousMatrix& cMo_, const bool verbose)
2553 {
2554  this->cMo.eye();
2555  vpMbtDistanceLine *l;
2557  vpMbtDistanceCircle *ci;
2558 
2559  for (unsigned int i = 0; i < scales.size(); i += 1){
2560  if(scales[i]){
2561  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2562  l = *it;
2563  if (l!=NULL) delete l ;
2564  l = NULL ;
2565  }
2566 
2567  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
2568  cy = *it;
2569  if (cy!=NULL) delete cy;
2570  cy = NULL;
2571  }
2572 
2573  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
2574  ci = *it;
2575  if (ci!=NULL) delete ci;
2576  ci = NULL;
2577  }
2578 
2579  lines[i].clear();
2580  cylinders[i].clear();
2581  circles[i].clear();
2582  }
2583  }
2584 
2585  faces.reset();
2586 
2587  //compute_interaction=1;
2588  nline = 0;
2589  ncylinder = 0;
2590  ncircle = 0;
2591  //lambda = 1;
2592  nbvisiblepolygone = 0;
2593 
2594  loadModel(cad_name, verbose);
2595  initFromPose(I, cMo_);
2596 }
2597 
2608 unsigned int
2609 vpMbEdgeTracker::getNbPoints(const unsigned int level) const
2610 {
2611  if((level > scales.size()) || !scales[level]){
2612  throw vpException(vpException::dimensionError, "Cannot get the number of points for level %d: level is not used", level);
2613  }
2614 
2615  unsigned int nbGoodPoints = 0;
2616  vpMbtDistanceLine *l ;
2617  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[level].begin(); it!=lines[level].end(); ++it){
2618  l = *it;
2619  if (l->isVisible() && l->isTracked())
2620  {
2621  for(unsigned int a = 0 ; a < l->meline.size() ; a++){
2622  if(l->nbFeature[a] != 0)
2623  for(std::list<vpMeSite>::const_iterator itme=l->meline[a]->getMeList().begin(); itme!=l->meline[a]->getMeList().end(); ++itme){
2624  if (itme->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
2625  }
2626  }
2627  }
2628  }
2629 
2630  vpMbtDistanceCylinder *cy ;
2631  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[level].begin(); it!=cylinders[level].end(); ++it){
2632  cy = *it;
2633  if (cy->isVisible() && cy->isTracked() && (cy->meline1 != NULL || cy->meline2 != NULL))
2634  {
2635  for(std::list<vpMeSite>::const_iterator itme1=cy->meline1->getMeList().begin(); itme1!=cy->meline1->getMeList().end(); ++itme1){
2636  if (itme1->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
2637  }
2638  for(std::list<vpMeSite>::const_iterator itme2=cy->meline2->getMeList().begin(); itme2!=cy->meline2->getMeList().end(); ++itme2){
2639  if (itme2->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
2640  }
2641  }
2642  }
2643 
2644  vpMbtDistanceCircle *ci ;
2645  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[level].begin(); it!=circles[level].end(); ++it){
2646  ci = *it;
2647  if (ci->isVisible() && ci->isTracked() && ci->meEllipse != NULL)
2648  {
2649  for(std::list<vpMeSite>::const_iterator itme=ci->meEllipse->getMeList().begin(); itme!=ci->meEllipse->getMeList().end(); ++itme){
2650  if (itme->getState() == vpMeSite::NO_SUPPRESSION) nbGoodPoints++;
2651  }
2652  }
2653  }
2654 
2655  return nbGoodPoints;
2656 }
2657 
2678 void
2679 vpMbEdgeTracker::setScales(const std::vector<bool>& scale)
2680 {
2681  unsigned int nbActivatedLevels = 0;
2682  for (unsigned int i = 0; i < scale.size(); i += 1){
2683  if(scale[i]){
2684  nbActivatedLevels++;
2685  }
2686  }
2687  if((scale.size() < 1) || (nbActivatedLevels == 0)){
2688  vpERROR_TRACE(" !! WARNING : must use at least one level for the tracking. Use the global one");
2689  this->scales.resize(0);
2690  this->scales.push_back(true);
2691  lines.resize(1);
2692  lines[0].clear();
2693  cylinders.resize(1);
2694  cylinders[0].clear();
2695  }
2696  else{
2697  this->scales = scale;
2698  lines.resize(scale.size());
2699  cylinders.resize(scale.size());
2700  for (unsigned int i = 0; i < lines.size(); i += 1){
2701  lines[i].clear();
2702  cylinders[i].clear();
2703  }
2704  }
2705 }
2706 
2712 void
2714 {
2715  if( (clippingFlag & vpPolygon3D::NEAR_CLIPPING) == vpPolygon3D::NEAR_CLIPPING && dist <= distNearClip)
2716  vpTRACE("Far clipping value cannot be inferior than near clipping value. Far clipping won't be considered.");
2717  else if ( dist < 0 )
2718  vpTRACE("Far clipping value cannot be inferior than 0. Far clipping won't be considered.");
2719  else{
2721  vpMbtDistanceLine *l;
2722 
2723  for (unsigned int i = 0; i < scales.size(); i += 1){
2724  if(scales[i]){
2725  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2726  l = *it;
2728  }
2729  }
2730  }
2731  }
2732 }
2733 
2739 void
2741 {
2742  if( (clippingFlag & vpPolygon3D::FAR_CLIPPING) == vpPolygon3D::FAR_CLIPPING && dist >= distFarClip)
2743  vpTRACE("Near clipping value cannot be superior than far clipping value. Near clipping won't be considered.");
2744  else if ( dist < 0 )
2745  vpTRACE("Near clipping value cannot be inferior than 0. Near clipping won't be considered.");
2746  else{
2748  vpMbtDistanceLine *l;
2749 
2750  for (unsigned int i = 0; i < scales.size(); i += 1){
2751  if(scales[i]){
2752  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2753  l = *it;
2755  }
2756  }
2757  }
2758  }
2759 }
2760 
2768 void
2769 vpMbEdgeTracker::setClipping(const unsigned int &flags)
2770 {
2771  vpMbTracker::setClipping(flags);
2772 
2773  vpMbtDistanceLine *l;
2774 
2775  for (unsigned int i = 0; i < scales.size(); i += 1){
2776  if(scales[i]){
2777  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
2778  l = *it;
2780  }
2781  }
2782  }
2783 }
2784 
2799 void
2801 {
2802  _pyramid.resize(scales.size());
2803 
2804  if(scales[0]){
2805  _pyramid[0] = &_I;
2806  }
2807  else{
2808  _pyramid[0] = NULL;
2809  }
2810 
2811  for(unsigned int i=1; i<_pyramid.size(); i += 1){
2812  if(scales[i]){
2813  unsigned int cScale = static_cast<unsigned int>(pow(2., (int)i));
2814  vpImage<unsigned char>* I = new vpImage<unsigned char>(_I.getHeight() / cScale, _I.getWidth() / cScale);
2815 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x020408))
2816  IplImage* vpI0 = cvCreateImageHeader(cvSize((int)_I.getWidth(), (int)_I.getHeight()), IPL_DEPTH_8U, 1);
2817  vpI0->imageData = (char*)(_I.bitmap);
2818  IplImage* vpI = cvCreateImage(cvSize((int)(_I.getWidth() / cScale), (int)(_I.getHeight() / cScale)), IPL_DEPTH_8U, 1);
2819  cvResize(vpI0, vpI, CV_INTER_NN);
2820  vpImageConvert::convert(vpI, *I);
2821  cvReleaseImage(&vpI);
2822  vpI0->imageData = NULL;
2823  cvReleaseImageHeader(&vpI0);
2824 #else
2825  for (unsigned int k = 0, ii = 0; k < I->getHeight(); k += 1, ii += cScale){
2826  for (unsigned int l = 0, jj = 0; l < I->getWidth(); l += 1, jj += cScale){
2827  (*I)[k][l] = _I[ii][jj];
2828  }
2829  }
2830 #endif
2831  _pyramid[i] = I;
2832  }
2833  else{
2834  _pyramid[i] = NULL;
2835  }
2836  }
2837 }
2838 
2845 void
2847 {
2848  if(_pyramid.size() > 0){
2849  _pyramid[0] = NULL;
2850  for (unsigned int i = 1; i < _pyramid.size(); i += 1){
2851  if(_pyramid[i] != NULL){
2852  delete _pyramid[i];
2853  _pyramid[i] = NULL;
2854  }
2855  }
2856  _pyramid.resize(0);
2857  }
2858 }
2859 
2870 void
2871 vpMbEdgeTracker::getLline(std::list<vpMbtDistanceLine *>& linesList, const unsigned int level) const
2872 {
2873  if(level > scales.size() || !scales[level]){
2874  std::ostringstream oss;
2875  oss << level;
2876  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2877  throw vpException(vpException::dimensionError, errorMsg);
2878  }
2879 
2880  linesList = lines[level];
2881 }
2882 
2883 
2894 void
2895 vpMbEdgeTracker::getLcylinder(std::list<vpMbtDistanceCylinder *>& cylindersList, const unsigned int level) const
2896 {
2897  if(level > scales.size() || !scales[level]){
2898  std::ostringstream oss;
2899  oss << level;
2900  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2901  throw vpException(vpException::dimensionError, errorMsg);
2902  }
2903 
2904  cylindersList = cylinders[level];
2905 }
2906 
2907 
2918 void
2919 vpMbEdgeTracker::getLcircle(std::list<vpMbtDistanceCircle *>& circlesList, const unsigned int level) const
2920 {
2921  if(level > scales.size() || !scales[level]){
2922  std::ostringstream oss;
2923  oss << level;
2924  std::string errorMsg = "level " + oss.str() + " is not used, cannot get its distance lines.";
2925  throw vpException(vpException::dimensionError, errorMsg);
2926  }
2927 
2928  circlesList = circles[level];
2929 }
2930 
2937 void
2938 vpMbEdgeTracker::downScale(const unsigned int _scale)
2939 {
2940  const double ratio = pow(2., (int)_scale);
2941  scaleLevel = _scale;
2942 
2943  vpMatrix K = cam.get_K();
2944 
2945  K[0][0] /= ratio;
2946  K[1][1] /= ratio;
2947  K[0][2] /= ratio;
2948  K[1][2] /= ratio;
2949 
2951 }
2952 
2959 void
2960 vpMbEdgeTracker::upScale(const unsigned int _scale)
2961 {
2962  const double ratio = pow(2., (int)_scale);
2963  scaleLevel = 0;
2964 
2965  vpMatrix K = cam.get_K();
2966 
2967  K[0][0] *= ratio;
2968  K[1][1] *= ratio;
2969  K[0][2] *= ratio;
2970  K[1][2] *= ratio;
2971 
2972 
2974 }
2975 
2983 void
2984 vpMbEdgeTracker::reInitLevel(const unsigned int _lvl)
2985 {
2986  unsigned int scaleLevel_1 = scaleLevel;
2987  scaleLevel = _lvl;
2988 
2989  vpMbtDistanceLine *l;
2990  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[scaleLevel].begin(); it!=lines[scaleLevel].end(); ++it){
2991  if((*it)->isTracked()){
2992  l = *it;
2993  l->reinitMovingEdge(*Ipyramid[_lvl], cMo);
2994  }
2995  }
2996 
2998  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[scaleLevel].begin(); it!=cylinders[scaleLevel].end(); ++it){
2999  if((*it)->isTracked()){
3000  cy = *it;
3001  cy->reinitMovingEdge(*Ipyramid[_lvl], cMo);
3002  }
3003  }
3004 
3005  vpMbtDistanceCircle *ci;
3006  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[scaleLevel].begin(); it!=circles[scaleLevel].end(); ++it){
3007  if((*it)->isTracked()){
3008  ci = *it;
3009  ci->reinitMovingEdge(*Ipyramid[_lvl], cMo);
3010  }
3011  }
3012 
3013  trackMovingEdge(*Ipyramid[_lvl]);
3014  updateMovingEdge(*Ipyramid[_lvl]);
3015  scaleLevel = scaleLevel_1;
3016 }
3017 
3024 void
3025 vpMbEdgeTracker::setUseEdgeTracking(const std::string &name, const bool &useEdgeTracking)
3026 {
3027  for (unsigned int i = 0; i < scales.size(); i += 1){
3028  if(scales[i]){
3029  for(std::list<vpMbtDistanceLine*>::const_iterator it=lines[i].begin(); it!=lines[i].end(); ++it){
3030  /*(*it)->setTracked(useEdgeTracking);
3031  for(std::list<int>::const_iterator itpoly=(*it)->Lindex_polygon.begin(); itpoly!=(*it)->Lindex_polygon.end(); ++itpoly){
3032  if(faces[(*itpoly)]->getName() != name){
3033  (*it)->setTracked(true);
3034  break;
3035  }
3036  }*/
3037 
3038  (*it)->setTracked(name,useEdgeTracking);
3039  }
3040 
3041  for(std::list<vpMbtDistanceCylinder*>::const_iterator it=cylinders[i].begin(); it!=cylinders[i].end(); ++it){
3042  if(faces[(unsigned)(*it)->index_polygon]->getName() == name){
3043  (*it)->setTracked(useEdgeTracking);
3044  }
3045  }
3046 
3047  for(std::list<vpMbtDistanceCircle*>::const_iterator it=circles[i].begin(); it!=circles[i].end(); ++it){
3048  if(faces[(unsigned)(*it)->index_polygon]->getName() == name){
3049  (*it)->setTracked(useEdgeTracking);
3050  }
3051  }
3052  }
3053  }
3054 }
void setWindowName(const Ogre::String &n)
Definition: vpAROgre.h:266
bool computeProjError
Flag used to specify if the gradient error criteria has to be computed or not.
Definition: vpMbTracker.h:131
void getLline(std::list< vpMbtDistanceLine * > &linesList, const unsigned int level=0) const
unsigned int ncylinder
Index of the cylinder to add, and total number of cylinders extracted so far.
void computeVVSFirstPhasePoseEstimation(const unsigned int nerror, const unsigned int iter, const vpColVector &factor, vpColVector &weighted_error, vpMatrix &L, bool &isoJoIdentity_)
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
void displayMovingEdges(const vpImage< unsigned char > &I)
vpMatrix covarianceMatrix
Covariance matrix.
Definition: vpMbTracker.h:129
void initFromCalibrationMatrix(const vpMatrix &_K)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void setMovingEdge(const vpMe &me)
static vpMatrix computeCovarianceMatrixVVS(const vpHomogeneousMatrix &cMo, const vpColVector &deltaS, const vpMatrix &Ls, const vpMatrix &W)
unsigned int nbFeature
The number of moving edges.
unsigned int nbFeatureTotal
The number of moving edges.
void setVisible(bool _isvisible)
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void setCameraParameters(const vpCameraParameters &camera)
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:182
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:226
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:144
bool Reinit
Indicates if the line has to be reinitialized.
void setMeanWeight2(const double wmean)
Implementation of an homogeneous matrix and operations on such kind of matrices.
void init(const vpImage< unsigned char > &I)
void track(const vpImage< unsigned char > &I)
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:134
vpMatrix L
The interaction matrix.
void setFarClippingDistance(const double &dist)
Definition: vpPolygon3D.h:196
void setCameraParameters(const vpCameraParameters &camera)
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'...
Definition: vpMeSite.h:72
#define vpERROR_TRACE
Definition: vpDebug.h:391
std::vector< std::list< vpMbtDistanceCircle * > > circles
Vector of the tracked circles.
void getLcircle(std::list< vpMbtDistanceCircle * > &circlesList, const unsigned int level=0) const
Class to define colors available for display functionnalities.
Definition: vpColor.h:121
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:115
vpPoint * p1
The first extremity.
void displayMovingEdges(const vpImage< unsigned char > &I)
double getNearClippingDistance() const
void setOgreShowConfigDialog(const bool showConfigDialog)
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:123
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.cpp:449
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:73
vpMbtMeEllipse * meEllipse
The moving edge containers.
Manage a cylinder used in the model-based tracker.
void reInitLevel(const unsigned int _lvl)
vpPoint * p
corners in the object frame
Definition: vpPolygon3D.h:81
Definition: vpMe.h:59
Manage the line of a polygon used in the model-based tracker.
void computeVVSSecondPhaseWeights(const unsigned int iter, const unsigned int nerror, const unsigned int nbrow, vpColVector &weighted_error, vpRobust &robust_lines, vpRobust &robust_cylinders, vpRobust &robust_circles, vpColVector &w_lines, vpColVector &w_cylinders, vpColVector &w_circles, vpColVector &error_lines, vpColVector &error_cylinders, vpColVector &error_circles, const unsigned int nberrors_lines, const unsigned int nberrors_cylinders, const unsigned int nberrors_circles)
unsigned int nbFeature
The number of moving edges.
virtual void setPose(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cdMo)
bool samePoint(const vpPoint &P1, const vpPoint &P2) const
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:156
unsigned int getCols() const
Return the number of columns of the 2D array.
Definition: vpArray2D.h:154
bool getLodState() const
int index_polygon
Index of the faces which contain the line.
vpPoint * p2
A point on the plane containing the circle.
void setIndex(const unsigned int i)
virtual void setCameraParameters(const vpCameraParameters &camera)
void displayFeaturesOnImage(const vpImage< unsigned char > &I, const unsigned int lvl)
void computeVVS(const vpImage< unsigned char > &_I, const unsigned int lvl)
virtual void initFromPose(const vpImage< unsigned char > &I, const std::string &initFile)
unsigned int setVisibleOgre(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
void removeCylinder(const std::string &name)
vpMbtPolygon & getPolygon()
bool computeCovariance
Flag used to specify if the covariance matrix has to be computed or not.
Definition: vpMbTracker.h:127
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).
virtual unsigned int getNbPoints(const unsigned int level=0) const
vpPoint * p1
The first extremity on the axe.
void downScale(const unsigned int _scale)
void computeVVSSecondPhasePoseEstimation(const unsigned int nerror, vpMatrix &L, vpMatrix &L_true, vpMatrix &LVJ_true, vpColVector &W_true, const vpColVector &factor, const unsigned int iter, const bool isoJoIdentity_, vpColVector &weighted_error, double &mu, vpColVector &m_error_prev, vpColVector &m_w_prev, vpHomogeneousMatrix &cMoPrev, double &residu_1, double &r)
bool hasNearClippingDistance() const
Class that defines what is a point.
Definition: vpPoint.h:59
vpMatrix L
The interaction matrix.
vpMeSiteState getState() const
Definition: vpMeSite.h:198
vpCameraParameters cam
The camera parameters.
Definition: vpMbTracker.h:113
void computeClippedPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
unsigned int setVisible(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed)
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:140
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:152
void computeJTR(const vpMatrix &J, const vpColVector &R, vpColVector &JTR) const
double projectionError
Error angle between the gradient direction of the model features projected at the resulting pose and ...
Definition: vpMbTracker.h:133
bool hasFarClippingDistance() const
vpAROgre * getOgreContext()
std::vector< vpMbtMeLine * > meline
The moving edge container.
int index_polygon
Index of the face which contains the cylinder.
virtual void reInitModel(const vpImage< unsigned char > &I, const std::string &cad_name, const vpHomogeneousMatrix &cMo_, const bool verbose=false)
virtual void setMinPolygonAreaThresh(const double minPolygonAreaThresh, const std::string &name="")
void getLcylinder(std::list< vpMbtDistanceCylinder * > &cylindersList, const unsigned int level=0) const
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
Manage a circle used in the model-based tracker.
vpMatrix oJo
The Degrees of Freedom to estimate.
Definition: vpMbTracker.h:117
std::vector< bool > scales
Vector of scale level to use for the multi-scale tracking.
bool Reinit
Indicates if the circle has to be reinitialized.
Error that can be emited by the vpTracker class and its derivates.
double getAngleDisappear() const
Implementation of a polygon of the model used by the model-based tracker.
Definition: vpMbtPolygon.h:64
void initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo)
void setName(const std::string &circle_name)
std::string getName() const
Definition: vpMbtPolygon.h:101
vpMatrix AtA() const
Definition: vpMatrix.cpp:376
vpPoint * p2
The second extremity.
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void diag(const double &val=1.0)
Definition: vpMatrix.cpp:524
bool useScanLine
Use Scanline for visibility tests.
Definition: vpMbTracker.h:159
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
#define vpTRACE
Definition: vpDebug.h:414
static double sqr(double x)
Definition: vpMath.h:110
double minLineLengthThresholdGeneral
Minimum line length threshold for LOD mode (general setting)
Definition: vpMbTracker.h:177
void computeVVSSecondPhaseCheckLevenbergMarquardt(const unsigned int iter, const unsigned int nbrow, const vpColVector &m_error_prev, const vpColVector &m_w_prev, const vpHomogeneousMatrix &cMoPrev, double &mu, bool &reStartFromLastIncrement)
void setAngleDisappear(const double &adisappear)
double getMinPolygonAreaThreshold() const
vpColVector error
The error vector.
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpColVector m_error
Error s-s*.
Definition: vpMbTracker.h:139
int getIndex() const
Definition: vpMbtPolygon.h:94
bool isVisible() const
unsigned int nbFeaturesForProjErrorComputation
Number of features used in the computation of the projection error.
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.cpp:451
unsigned int initMbtTracking(unsigned int &nberrors_lines, unsigned int &nberrors_cylinders, unsigned int &nberrors_circles)
bool isTracked() const
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:151
Implementation of a velocity twist matrix and operations on such kind of matrices.
vpMbtOptimizationMethod m_optimizationMethod
Optimization method used.
Definition: vpMbTracker.h:141
unsigned int getRows() const
Return the number of rows of the 2D array.
Definition: vpArray2D.h:152
void setCameraParameters(const vpCameraParameters &_cam)
void computeVVSFirstPhase(const vpImage< unsigned char > &I, const unsigned int iter, vpMatrix &L, vpColVector &factor, double &count, vpColVector &error, vpColVector &w_mbt, const unsigned int lvl=0)
double angleAppears
Angle used to detect a face appearance.
Definition: vpMbTracker.h:146
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:185
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:104
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)
void setClipping(const unsigned int &flags)
Definition: vpPolygon3D.h:189
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void computeProjectionError(const vpImage< unsigned char > &_I)
void setVisible(bool _isvisible)
virtual void initFaceFromLines(vpMbtPolygon &polygon)
double getMinLineLengthThreshold() const
double sumSquare() const
void setScales(const std::vector< bool > &_scales)
vpPoint * p2
The second extremity on the axe.
void setCameraParameters(const vpCameraParameters &camera)
double get_oX() const
Get the point X coordinate in the object frame.
Definition: vpPoint.cpp:447
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:179
vpMatrix get_K() const
static double deg(double rad)
Definition: vpMath.h:97
bool displayFeatures
If true, the features are displayed.
Definition: vpMbTracker.h:135
virtual void loadModel(const char *modelFile, const bool verbose=false)
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const double r)
bool ogreShowConfigDialog
Definition: vpMbTracker.h:157
bool applyLodSettingInConfig
True if the CAO model is loaded before the call to loadConfigFile, (deduced by the number of polygons...
Definition: vpMbTracker.h:175
Implementation of column vector and the associated operations.
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:60
unsigned int nbvisiblepolygone
Number of polygon (face) currently visible.
double angleDisappears
Angle used to detect a face disappearance.
Definition: vpMbTracker.h:148
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:286
void visibleFace(const vpImage< unsigned char > &_I, const vpHomogeneousMatrix &_cMo, bool &newvisibleline)
void addPolygon(const int &index)
void setNearClippingDistance(const double &dist)
Definition: vpPolygon3D.h:205
unsigned int getHeight() const
Definition: vpImage.h:175
unsigned int getNbPoint() const
Definition: vpPolygon3D.h:135
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:1741
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:154
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 computeVVSFirstPhaseFactor(const vpImage< unsigned char > &I, vpColVector &factor, const unsigned int lvl=0)
void setUseEdgeTracking(const std::string &name, const bool &useEdgeTracking)
void setThreshold(const double noise_threshold)
Definition: vpRobust.h:129
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:275
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:123
double distNearClip
Distance for near clipping.
Definition: vpMbTracker.h:150
bool useLodGeneral
True if LOD mode is enabled.
Definition: vpMbTracker.h:173
void computeScanLineRender(const vpCameraParameters &cam, const unsigned int &w, const unsigned int &h)
vpMatrix L
The interaction matrix.
void addCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, const double r, int idFace=-1, const std::string &name="")
std::vector< unsigned int > nbFeature
The number of moving edges.
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo, const vpImage< unsigned char > &I)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void eye()
Definition: vpMatrix.cpp:194
void setMovingEdge(const vpMe &_ecm)
bool isoJoIdentity
Boolean to know if oJo is identity (for fast computation)
Definition: vpMbTracker.h:119
std::string getName() const
vpPoint * p1
The center of the circle.
void computeVVSSecondPhase(const vpImage< unsigned char > &I, vpMatrix &L, vpColVector &error_lines, vpColVector &error_cylinders, vpColVector &error_circles, vpColVector &error, const unsigned int lvl)
bool useScanLine
Use scanline rendering.
void buildFrom(vpPoint &_p1, vpPoint &_p2)
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:225
vpColVector m_w
Weights used in the robust scheme.
Definition: vpMbTracker.h:137
virtual void setLod(const bool useLod, const std::string &name="")
virtual void setNearClippingDistance(const double &dist)
void computeFov(const unsigned int &w, const unsigned int &h)