Visual Servoing Platform  version 3.5.1 under development (2022-09-25)
vpMbtMeLine.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Make the complete tracking of an object by using its CAD model
33  *
34  * Authors:
35  * Nicolas Melchior
36  * Romain Tallonneau
37  * Eric Marchand
38  *
39  *****************************************************************************/
40 #include <visp3/core/vpConfig.h>
41 #ifndef DOXYGEN_SHOULD_SKIP_THIS
42 
47 #include <algorithm> // (std::min)
48 #include <cmath> // std::fabs
49 #include <limits> // numeric_limits
50 
51 #include <visp3/core/vpRobust.h>
52 #include <visp3/core/vpTrackingException.h>
53 #include <visp3/mbt/vpMbtMeLine.h>
54 
56 static void normalizeAngle(double &delta)
57 {
58  while (delta > M_PI) {
59  delta -= M_PI;
60  }
61  while (delta < -M_PI) {
62  delta += M_PI;
63  }
64 }
65 
69 vpMbtMeLine::vpMbtMeLine()
70  : rho(0.), theta(0.), theta_1(M_PI / 2), delta(0.), delta_1(0), sign(1), a(0.), b(0.), c(0.), imin(0), imax(0),
71  jmin(0), jmax(0), expecteddensity(0.)
72 {
73 }
74 
78 vpMbtMeLine::~vpMbtMeLine() { list.clear(); }
79 
95 void vpMbtMeLine::initTracking(const vpImage<unsigned char> &I, const vpImagePoint &ip1, const vpImagePoint &ip2,
96  double rho_, double theta_, bool doNoTrack)
97 {
98  vpCDEBUG(1) << " begin vpMeLine::initTracking()" << std::endl;
99 
100  try {
101  // 1. On fait ce qui concerne les droites (peut etre vide)
102  // Points extremites
103  PExt[0].ifloat = (float)ip1.get_i();
104  PExt[0].jfloat = (float)ip1.get_j();
105  PExt[1].ifloat = (float)ip2.get_i();
106  PExt[1].jfloat = (float)ip2.get_j();
107 
108  this->rho = rho_;
109  this->theta = theta_;
110  theta_1 = theta_;
111 
112  a = cos(theta);
113  b = sin(theta);
114  c = -rho;
115 
116  delta = -theta + M_PI / 2.0;
117  normalizeAngle(delta);
118  delta_1 = delta;
119 
120  sample(I, doNoTrack);
121  expecteddensity = (double)list.size();
122 
123  if (!doNoTrack)
125  } catch (...) {
126  throw; // throw the original exception
127  }
128  vpCDEBUG(1) << " end vpMeLine::initTracking()" << std::endl;
129 }
130 
138 void vpMbtMeLine::sample(const vpImage<unsigned char> &I, bool doNoTrack)
139 {
140  int rows = (int)I.getHeight();
141  int cols = (int)I.getWidth();
142  double n_sample;
143 
144  // if (me->getSampleStep==0)
145  if (std::fabs(me->getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
146  throw(vpTrackingException(vpTrackingException::fatalError, "Function vpMbtMeLine::sample() called with "
147  "moving-edges sample step = 0"));
148  }
149 
150  // i, j portions of the line_p
151  double diffsi = PExt[0].ifloat - PExt[1].ifloat;
152  double diffsj = PExt[0].jfloat - PExt[1].jfloat;
153 
154  double length_p = sqrt((vpMath::sqr(diffsi) + vpMath::sqr(diffsj)));
155 
156  // number of samples along line_p
157  n_sample = length_p / (double)me->getSampleStep();
158 
159  double stepi = diffsi / (double)n_sample;
160  double stepj = diffsj / (double)n_sample;
161 
162  // Choose starting point
163  double is = PExt[1].ifloat;
164  double js = PExt[1].jfloat;
165 
166  // Delete old list
167  list.clear();
168 
169  // sample positions at i*me->getSampleStep() interval along the
170  // line_p, starting at PSiteExt[0]
171 
172  vpImagePoint ip;
173  for (int i = 0; i <= vpMath::round(n_sample); i++) {
174  // If point is in the image, add to the sample list
175  if (!outOfImage(vpMath::round(is), vpMath::round(js), (int)(me->getRange() + me->getMaskSize() + 1), (int)rows,
176  (int)cols) &&
177  vpMeTracker::inMask(m_mask, vpMath::round(is), vpMath::round(js))) {
178  vpMeSite pix; //= list.value();
179  pix.init((int)is, (int)js, delta, 0, sign);
180 
181  if (!doNoTrack)
182  pix.track(I, me, false);
183 
184  pix.setDisplay(selectDisplay);
185 
186  if (vpDEBUG_ENABLE(3)) {
187  ip.set_i(is);
188  ip.set_j(js);
190  }
191 
192  list.push_back(pix);
193  }
194  is += stepi;
195  js += stepj;
196  }
197 
198  vpCDEBUG(1) << "end vpMeLine::sample() : ";
199  vpCDEBUG(1) << list.size() << " point inserted in the list " << std::endl;
200 }
201 
207 void vpMbtMeLine::suppressPoints(const vpImage<unsigned char> &I)
208 {
209  for (std::list<vpMeSite>::iterator it = list.begin(); it != list.end();) {
210  vpMeSite s = *it; // current reference pixel
211 
212  if (fabs(sin(theta)) > 0.9) // Vertical line management
213  {
214  if ((s.i < imin) || (s.i > imax)) {
216  }
217  }
218 
219  else if (fabs(cos(theta)) > 0.9) // Horizontal line management
220  {
221  if ((s.j < jmin) || (s.j > jmax)) {
223  }
224  }
225 
226  else {
227  if ((s.i < imin) || (s.i > imax) || (s.j < jmin) || (s.j > jmax)) {
229  }
230  }
231 
232  if (outOfImage(s.i, s.j, (int)(me->getRange() + me->getMaskSize() + 1), (int)I.getHeight(), (int)I.getWidth())) {
234  }
235 
237  it = list.erase(it);
238  else
239  ++it;
240  }
241 }
242 
249 void vpMbtMeLine::seekExtremities(const vpImage<unsigned char> &I)
250 {
251  vpCDEBUG(1) << "begin vpMeLine::sample() : " << std::endl;
252 
253  int rows = (int)I.getHeight();
254  int cols = (int)I.getWidth();
255  double n_sample;
256 
257  // if (me->getSampleStep()==0)
258  if (std::fabs(me->getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
259  throw(vpTrackingException(vpTrackingException::fatalError, "Function called with sample step = 0"));
260  }
261 
262  // i, j portions of the line_p
263  double diffsi = PExt[0].ifloat - PExt[1].ifloat;
264  double diffsj = PExt[0].jfloat - PExt[1].jfloat;
265 
266  double s = vpMath::sqr(diffsi) + vpMath::sqr(diffsj);
267 
268  double di = diffsi / sqrt(s); // pas de risque de /0 car d(P1,P2) >0
269  double dj = diffsj / sqrt(s);
270 
271  double length_p = sqrt(s); /*(vpMath::sqr(diffsi)+vpMath::sqr(diffsj))*/
272 
273  // number of samples along line_p
274  n_sample = length_p / (double)me->getSampleStep();
275  double sample_step = (double)me->getSampleStep();
276 
277  vpMeSite P;
278  P.init((int)PExt[0].ifloat, (int)PExt[0].jfloat, delta_1, 0, sign);
279  P.setDisplay(selectDisplay);
280 
281  unsigned int memory_range = me->getRange();
282  me->setRange(1);
283 
284  for (int i = 0; i < 3; i++) {
285  P.ifloat = P.ifloat + di * sample_step;
286  P.i = (int)P.ifloat;
287  P.jfloat = P.jfloat + dj * sample_step;
288  P.j = (int)P.jfloat;
289 
290  if ((P.i < imin) || (P.i > imax) || (P.j < jmin) || (P.j > jmax)) {
291  if (vpDEBUG_ENABLE(3))
293  } else if (!outOfImage(P.i, P.j, (int)(me->getRange() + me->getMaskSize() + 1), (int)rows, (int)cols)) {
294  P.track(I, me, false);
295 
296  if (P.getState() == vpMeSite::NO_SUPPRESSION) {
297  list.push_back(P);
298  if (vpDEBUG_ENABLE(3))
300  } else if (vpDEBUG_ENABLE(3))
302  }
303  }
304 
305  P.init((int)PExt[1].ifloat, (int)PExt[1].jfloat, delta_1, 0, sign);
306  P.setDisplay(selectDisplay);
307  for (int i = 0; i < 3; i++) {
308  P.ifloat = P.ifloat - di * sample_step;
309  P.i = (int)P.ifloat;
310  P.jfloat = P.jfloat - dj * sample_step;
311  P.j = (int)P.jfloat;
312 
313  if ((P.i < imin) || (P.i > imax) || (P.j < jmin) || (P.j > jmax)) {
314  if (vpDEBUG_ENABLE(3))
316  }
317 
318  else if (!outOfImage(P.i, P.j, (int)(me->getRange() + me->getMaskSize() + 1), (int)rows, (int)cols)) {
319  P.track(I, me, false);
320 
321  if (P.getState() == vpMeSite::NO_SUPPRESSION) {
322  list.push_back(P);
323  if (vpDEBUG_ENABLE(3))
325  } else if (vpDEBUG_ENABLE(3))
327  }
328  }
329 
330  me->setRange(memory_range);
331 
332  vpCDEBUG(1) << "end vpMeLine::sample() : ";
333  vpCDEBUG(1) << n_sample << " point inserted in the list " << std::endl;
334 }
335 
350 void vpMbtMeLine::computeProjectionError(const vpImage<unsigned char> &_I, double &_sumErrorRad,
351  unsigned int &_nbFeatures, const vpMatrix &SobelX, const vpMatrix &SobelY,
352  bool display, unsigned int length, unsigned int thickness)
353 {
354  _sumErrorRad = 0;
355  _nbFeatures = 0;
356  double deltaNormalized = theta;
357  unsigned int iter = 0;
358 
359  while (deltaNormalized < 0)
360  deltaNormalized += M_PI;
361  while (deltaNormalized > M_PI)
362  deltaNormalized -= M_PI;
363 
364  vpColVector vecLine(2);
365  vecLine[0] = cos(deltaNormalized);
366  vecLine[1] = sin(deltaNormalized);
367  vecLine.normalize();
368 
369  double offset = std::floor(SobelX.getRows() / 2.0f);
370 
371  for (std::list<vpMeSite>::const_iterator it = list.begin(); it != list.end(); ++it) {
372  if (iter != 0 && iter + 1 != list.size()) {
373  double gradientX = 0;
374  double gradientY = 0;
375 
376  double iSite = it->ifloat;
377  double jSite = it->jfloat;
378 
379  for (unsigned int i = 0; i < SobelX.getRows(); i++) {
380  double iImg = iSite + (i - offset);
381  for (unsigned int j = 0; j < SobelX.getCols(); j++) {
382  double jImg = jSite + (j - offset);
383 
384  if (iImg < 0)
385  iImg = 0.0;
386  if (jImg < 0)
387  jImg = 0.0;
388 
389  if (iImg > _I.getHeight() - 1)
390  iImg = _I.getHeight() - 1;
391  if (jImg > _I.getWidth() - 1)
392  jImg = _I.getWidth() - 1;
393 
394  gradientX += SobelX[i][j] * _I((unsigned int)iImg, (unsigned int)jImg);
395  }
396  }
397 
398  for (unsigned int i = 0; i < SobelY.getRows(); i++) {
399  double iImg = iSite + (i - offset);
400  for (unsigned int j = 0; j < SobelY.getCols(); j++) {
401  double jImg = jSite + (j - offset);
402 
403  if (iImg < 0)
404  iImg = 0.0;
405  if (jImg < 0)
406  jImg = 0.0;
407 
408  if (iImg > _I.getHeight() - 1)
409  iImg = _I.getHeight() - 1;
410  if (jImg > _I.getWidth() - 1)
411  jImg = _I.getWidth() - 1;
412 
413  gradientY += SobelY[i][j] * _I((unsigned int)iImg, (unsigned int)jImg);
414  }
415  }
416 
417  double angle = atan2(gradientX, gradientY);
418  while (angle < 0)
419  angle += M_PI;
420  while (angle > M_PI)
421  angle -= M_PI;
422 
423  vpColVector vecGrad(2);
424  vecGrad[0] = cos(angle);
425  vecGrad[1] = sin(angle);
426  vecGrad.normalize();
427 
428  double angle1 = acos(vecLine * vecGrad);
429  double angle2 = acos(vecLine * (-vecGrad));
430 
431  if (display) {
432  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(deltaNormalized)),
433  (int)(it->get_j() + length * sin(deltaNormalized)), vpColor::blue,
434  length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
435  if (angle1 < angle2) {
436  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(angle)),
437  (int)(it->get_j() + length * sin(angle)), vpColor::red, length >= 20 ? length / 5 : 4,
438  length >= 20 ? length / 10 : 2, thickness);
439  } else {
440  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(angle + M_PI)),
441  (int)(it->get_j() + length * sin(angle + M_PI)), vpColor::red,
442  length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
443  }
444  }
445 
446  // double angle1 = sqrt(vpMath::sqr(deltaNormalized-angle));
447  // double angle2 = sqrt(vpMath::sqr(deltaNormalized-
448  // (angle-M_PI)));
449 
450  _sumErrorRad += (std::min)(angle1, angle2);
451 
452  // if(std::fabs(deltaNormalized-angle) > M_PI / 2)
453  // {
454  // sumErrorRad += sqrt(vpMath::sqr(deltaNormalized-angle)) - M_PI
455  // / 2;
456  // } else {
457  // sumErrorRad += sqrt(vpMath::sqr(deltaNormalized-angle));
458  // }
459 
460  _nbFeatures++;
461  }
462  iter++;
463  }
464 }
465 
476 void vpMbtMeLine::reSample(const vpImage<unsigned char> &I)
477 {
478  unsigned int n = numberOfSignal();
479 
480  if ((double)n < 0.5 * expecteddensity && n > 0) {
481  double delta_new = delta;
482  delta = delta_1;
483  sample(I);
484  expecteddensity = (double)list.size();
485  delta = delta_new;
486  // 2. On appelle ce qui n'est pas specifique
487  {
489  }
490  }
491 }
492 
505 void vpMbtMeLine::reSample(const vpImage<unsigned char> &I, const vpImagePoint &ip1, const vpImagePoint &ip2)
506 {
507  size_t n = list.size();
508 
509  if ((double)n < 0.5 * expecteddensity /*&& n > 0*/) // n is always > 0
510  {
511  double delta_new = delta;
512  delta = delta_1;
513  PExt[0].ifloat = (float)ip1.get_i();
514  PExt[0].jfloat = (float)ip1.get_j();
515  PExt[1].ifloat = (float)ip2.get_i();
516  PExt[1].jfloat = (float)ip2.get_j();
517  sample(I);
518  expecteddensity = (double)list.size();
519  delta = delta_new;
521  }
522 }
523 
527 void vpMbtMeLine::updateDelta()
528 {
529  vpMeSite p_me;
530 
531  double diff = 0;
532 
533  // if(fabs(theta) == M_PI )
534  if (std::fabs(std::fabs(theta) - M_PI) <=
535  vpMath::maximum(std::fabs(theta), (double)M_PI) * std::numeric_limits<double>::epsilon()) {
536  theta = 0;
537  }
538 
539  diff = fabs(theta - theta_1);
540  if (diff > M_PI / 2.0)
541  sign *= -1;
542 
543  theta_1 = theta;
544 
545  delta = -theta + M_PI / 2.0;
546  normalizeAngle(delta);
547 
548  for (std::list<vpMeSite>::iterator it = list.begin(); it != list.end(); ++it) {
549  p_me = *it;
550  p_me.alpha = delta;
551  p_me.mask_sign = sign;
552  *it = p_me;
553  }
554  delta_1 = delta;
555 }
556 
562 void vpMbtMeLine::track(const vpImage<unsigned char> &I)
563 {
564  try {
566  if (m_mask != NULL) {
567  // Expected density could be modified if some vpMeSite are no more tracked because they are outside the mask.
568  expecteddensity = (double)list.size();
569  }
570  } catch (...) {
571  throw; // throw the original exception
572  }
573 }
574 
583 void vpMbtMeLine::updateParameters(const vpImage<unsigned char> &I, double rho_, double theta_)
584 {
585  this->rho = rho_;
586  this->theta = theta_;
587  a = cos(theta);
588  b = sin(theta);
589  c = -rho;
590  // recherche de point aux extremite de la droites
591  // dans le cas d'un glissement
592  suppressPoints(I);
593  seekExtremities(I);
594  suppressPoints(I);
595  setExtremities();
596  // reechantillonage si necessaire
597  reSample(I);
598 
599  // remet a jour l'angle delta pour chaque point de la liste
600  updateDelta();
601 }
602 
613 void vpMbtMeLine::updateParameters(const vpImage<unsigned char> &I, const vpImagePoint &ip1, const vpImagePoint &ip2,
614  double rho_, double theta_)
615 {
616  this->rho = rho_;
617  this->theta = theta_;
618  a = cos(theta);
619  b = sin(theta);
620  c = -rho;
621  // recherche de point aux extremite de la droites
622  // dans le cas d'un glissement
623  suppressPoints(I);
624  seekExtremities(I);
625  suppressPoints(I);
626  setExtremities();
627  // reechantillonage si necessaire
628  reSample(I, ip1, ip2);
629 
630  // remet a jour l'angle delta pour chaque point de la liste
631  updateDelta();
632 }
633 
637 void vpMbtMeLine::setExtremities()
638 {
639  double i_min = +1e6;
640  double j_min = +1e6;
641  double i_max = -1;
642  double j_max = -1;
643 
644  // Loop through list of sites to track
645  for (std::list<vpMeSite>::const_iterator it = list.begin(); it != list.end(); ++it) {
646  vpMeSite s = *it; // current reference pixel
647  if (s.ifloat < i_min) {
648  i_min = s.ifloat;
649  j_min = s.jfloat;
650  }
651 
652  if (s.ifloat > i_max) {
653  i_max = s.ifloat;
654  j_max = s.jfloat;
655  }
656  }
657 
658  if (!list.empty()) {
659  PExt[0].ifloat = i_min;
660  PExt[0].jfloat = j_min;
661  PExt[1].ifloat = i_max;
662  PExt[1].jfloat = j_max;
663  }
664 
665  if (fabs(i_min - i_max) < 25) {
666  for (std::list<vpMeSite>::const_iterator it = list.begin(); it != list.end(); ++it) {
667  vpMeSite s = *it; // current reference pixel
668  if (s.jfloat < j_min) {
669  i_min = s.ifloat;
670  j_min = s.jfloat;
671  }
672 
673  if (s.jfloat > j_max) {
674  i_max = s.ifloat;
675  j_max = s.jfloat;
676  }
677  }
678 
679  if (!list.empty()) {
680  PExt[0].ifloat = i_min;
681  PExt[0].jfloat = j_min;
682  PExt[1].ifloat = i_max;
683  PExt[1].jfloat = j_max;
684  }
685  bubbleSortJ();
686  }
687 
688  else
689  bubbleSortI();
690 }
691 
692 static bool sortByI(const vpMeSite &s1, const vpMeSite &s2) { return (s1.ifloat > s2.ifloat); }
693 
694 void vpMbtMeLine::bubbleSortI()
695 {
696 #if 0
697  unsigned int nbElmt = list.size();
698  for (unsigned int pass = 1; pass < nbElmt; pass++)
699  {
700  list.front();
701  for (unsigned int i=0; i < nbElmt-pass; i++)
702  {
703  vpMeSite s1 = list.value();
704  vpMeSite s2 = list.nextValue();
705  if (s1.ifloat > s2.ifloat)
706  list.swapRight();
707  else
708  list.next();
709  }
710  }
711 #endif
712  list.sort(sortByI);
713 }
714 
715 static bool sortByJ(const vpMeSite &s1, const vpMeSite &s2) { return (s1.jfloat > s2.jfloat); }
716 
717 void vpMbtMeLine::bubbleSortJ()
718 {
719 #if 0
720  unsigned int nbElmt = list.size();
721  for(unsigned int pass=1; pass < nbElmt; pass++)
722  {
723  list.front();
724  for (unsigned int i=0; i < nbElmt-pass; i++)
725  {
726  vpMeSite s1 = list.value();
727  vpMeSite s2 = list.nextValue();
728  if (s1.jfloat > s2.jfloat)
729  list.swapRight();
730  else
731  list.next();
732  }
733  }
734 #endif
735  list.sort(sortByJ);
736 }
737 
738 #endif
unsigned int getCols() const
Definition: vpArray2D.h:281
unsigned int getRows() const
Definition: vpArray2D.h:291
Implementation of column vector and the associated operations.
Definition: vpColVector.h:131
static const vpColor red
Definition: vpColor.h:217
static const vpColor cyan
Definition: vpColor.h:226
static const vpColor blue
Definition: vpColor.h:223
static const vpColor green
Definition: vpColor.h:220
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void displayArrow(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:89
void set_j(double jj)
Definition: vpImagePoint.h:309
double get_j() const
Definition: vpImagePoint.h:132
void set_i(double ii)
Definition: vpImagePoint.h:298
double get_i() const
Definition: vpImagePoint.h:121
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:188
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:171
static double sqr(double x)
Definition: vpMath.h:123
static int round(double x)
Definition: vpMath.h:318
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:154
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition: vpMeSite.h:72
int j
Definition: vpMeSite.h:87
@ CONSTRAST
Point removed due to a contrast problem.
Definition: vpMeSite.h:79
@ TOO_NEAR
Point removed because too near image borders.
Definition: vpMeSite.h:82
@ NO_SUPPRESSION
Point used by the tracker.
Definition: vpMeSite.h:78
void setDisplay(vpMeSiteDisplayType select)
Definition: vpMeSite.h:139
void track(const vpImage< unsigned char > &im, const vpMe *me, bool test_contraste=true)
Definition: vpMeSite.cpp:355
double ifloat
Definition: vpMeSite.h:89
int i
Definition: vpMeSite.h:87
int mask_sign
Definition: vpMeSite.h:91
double alpha
Definition: vpMeSite.h:93
void init()
Definition: vpMeSite.cpp:66
double jfloat
Definition: vpMeSite.h:89
vpMeSiteState getState() const
Definition: vpMeSite.h:190
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:176
void initTracking(const vpImage< unsigned char > &I)
void track(const vpImage< unsigned char > &I)
Track sampled pixels.
static bool inMask(const vpImage< bool > *mask, unsigned int i, unsigned int j)
Error that can be emited by the vpTracker class and its derivates.
#define vpCDEBUG(level)
Definition: vpDebug.h:511
#define vpDEBUG_ENABLE(level)
Definition: vpDebug.h:538