Visual Servoing Platform  version 3.6.1 under development (2024-04-26)
vpMbtMeLine.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 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 https://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  * Romain Tallonneau
36  *
37 *****************************************************************************/
38 #include <visp3/core/vpConfig.h>
39 #ifndef DOXYGEN_SHOULD_SKIP_THIS
40 
45 #include <algorithm> // (std::min)
46 #include <cmath> // std::fabs
47 #include <limits> // numeric_limits
48 
49 #include <visp3/core/vpRobust.h>
50 #include <visp3/core/vpTrackingException.h>
51 #include <visp3/mbt/vpMbtMeLine.h>
52 
54 static void normalizeAngle(double &delta)
55 {
56  while (delta > M_PI) {
57  delta -= M_PI;
58  }
59  while (delta < -M_PI) {
60  delta += M_PI;
61  }
62 }
63 
67 vpMbtMeLine::vpMbtMeLine()
68  : m_rho(0.), m_theta(0.), m_theta_1(M_PI / 2), m_delta(0.), m_delta_1(0), m_sign(1), m_a(0.), m_b(0.), m_c(0.),
69  imin(0), imax(0), jmin(0), jmax(0), expecteddensity(0.)
70 { }
71 
75 vpMbtMeLine::~vpMbtMeLine()
76 {
77  m_meList.clear();
78 }
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  m_PExt[0].m_ifloat = (float)ip1.get_i();
104  m_PExt[0].m_jfloat = (float)ip1.get_j();
105  m_PExt[1].m_ifloat = (float)ip2.get_i();
106  m_PExt[1].m_jfloat = (float)ip2.get_j();
107 
108  m_rho = rho;
109  m_theta = theta;
110  m_theta_1 = theta;
111 
112  m_a = cos(m_theta);
113  m_b = sin(m_theta);
114  m_c = -m_rho;
115 
116  m_delta = -m_theta + M_PI / 2.0;
117  normalizeAngle(m_delta);
118  m_delta_1 = m_delta;
119 
120  sample(I, doNoTrack);
121  expecteddensity = (double)m_meList.size();
122 
123  if (!doNoTrack)
125  }
126  catch (...) {
127  throw; // throw the original exception
128  }
129  vpCDEBUG(1) << " end vpMeLine::initTracking()" << std::endl;
130 }
131 
139 void vpMbtMeLine::sample(const vpImage<unsigned char> &I, bool doNoTrack)
140 {
141  int nbrows = static_cast<int>(I.getHeight());
142  int nbcols = static_cast<int>(I.getWidth());
143  double n_sample;
144 
145  if (std::fabs(m_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 = m_PExt[0].m_ifloat - m_PExt[1].m_ifloat;
152  double diffsj = m_PExt[0].m_jfloat - m_PExt[1].m_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)m_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 = m_PExt[1].m_ifloat;
164  double js = m_PExt[1].m_jfloat;
165 
166  // Delete old list
167  m_meList.clear();
168 
169  // sample positions at i*m_me->getSampleStep() interval along the
170  // line_p, starting at PSiteExt[0]
171 
172  for (int i = 0; i <= vpMath::round(n_sample); i++) {
173  vpImagePoint iP;
174  iP.set_i(is);
175  iP.set_j(js);
176  unsigned int is_uint = static_cast<unsigned int>(is);
177  unsigned int js_uint = static_cast<unsigned int>(js);
178  // If point is in the image, add to the sample list
179  if ((!outOfImage(iP, (int)(m_me->getRange() + m_me->getMaskSize() + 1), nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint)
180  && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) {
181  vpMeSite pix;
182  pix.init(iP.get_i(), iP.get_j(), m_delta, 0, m_sign);
183  pix.setDisplay(m_selectDisplay);
185  const double marginRatio = m_me->getThresholdMarginRatio();
186  double convolution = pix.convolution(I, m_me);
187  double contrastThreshold = fabs(convolution) * marginRatio;
188  pix.setContrastThreshold(contrastThreshold, *m_me);
189 
190  if (!doNoTrack) {
191  pix.track(I, m_me, false);
192  }
193 
194  if (vpDEBUG_ENABLE(3)) {
196  }
197 
198  m_meList.push_back(pix);
199  }
200  is += stepi;
201  js += stepj;
202  }
203 
204  vpCDEBUG(1) << "end vpMeLine::sample() : ";
205  vpCDEBUG(1) << m_meList.size() << " point inserted in the list " << std::endl;
206 }
207 
213 void vpMbtMeLine::suppressPoints(const vpImage<unsigned char> &I)
214 {
215  for (std::list<vpMeSite>::iterator it = m_meList.begin(); it != m_meList.end();) {
216  vpMeSite s = *it; // current reference pixel
217 
218  if (fabs(sin(m_theta)) > 0.9) // Vertical line management
219  {
220  if ((s.m_i < imin) || (s.m_i > imax)) {
222  }
223  }
224 
225  else if (fabs(cos(m_theta)) > 0.9) // Horizontal line management
226  {
227  if ((s.m_j < jmin) || (s.m_j > jmax)) {
229  }
230  }
231 
232  else {
233  if ((s.m_i < imin) || (s.m_i > imax) || (s.m_j < jmin) || (s.m_j > jmax)) {
235  }
236  }
237 
238  if (outOfImage(s.m_i, s.m_j, (int)(m_me->getRange() + m_me->getMaskSize() + 1), (int)I.getHeight(), (int)I.getWidth())) {
240  }
241 
243  it = m_meList.erase(it);
244  else
245  ++it;
246  }
247 }
248 
255 void vpMbtMeLine::seekExtremities(const vpImage<unsigned char> &I)
256 {
257  vpCDEBUG(1) << "begin vpMeLine::sample() : " << std::endl;
258 
259  int rows = (int)I.getHeight();
260  int cols = (int)I.getWidth();
261  double n_sample;
262 
263  // if (m_me->getSampleStep()==0)
264  if (std::fabs(m_me->getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
265  throw(vpTrackingException(vpTrackingException::fatalError, "Function called with sample step = 0"));
266  }
267 
268  // i, j portions of the line_p
269  double diffsi = m_PExt[0].m_ifloat - m_PExt[1].m_ifloat;
270  double diffsj = m_PExt[0].m_jfloat - m_PExt[1].m_jfloat;
271 
272  double s = vpMath::sqr(diffsi) + vpMath::sqr(diffsj);
273 
274  double di = diffsi / sqrt(s); // pas de risque de /0 car d(P1,P2) >0
275  double dj = diffsj / sqrt(s);
276 
277  double length_p = sqrt(s); /*(vpMath::sqr(diffsi)+vpMath::sqr(diffsj))*/
278 
279  // number of samples along line_p
280  n_sample = length_p / (double)m_me->getSampleStep();
281  double sample_step = (double)m_me->getSampleStep();
282 
283  vpMeSite P;
284  P.init((int)m_PExt[0].m_ifloat, (int)m_PExt[0].m_jfloat, m_delta_1, 0, m_sign);
285  P.setDisplay(m_selectDisplay);
286 
287  unsigned int memory_range = m_me->getRange();
288  m_me->setRange(1);
289 
290  for (int i = 0; i < 3; i++) {
291  P.m_ifloat = P.m_ifloat + di * sample_step;
292  P.m_i = (int)P.m_ifloat;
293  P.m_jfloat = P.m_jfloat + dj * sample_step;
294  P.m_j = (int)P.m_jfloat;
295 
296  if ((P.m_i < imin) || (P.m_i > imax) || (P.m_j < jmin) || (P.m_j > jmax)) {
297  if (vpDEBUG_ENABLE(3))
299  }
300  else if (!outOfImage(P.m_i, P.m_j, (int)(m_me->getRange() + m_me->getMaskSize() + 1), (int)rows, (int)cols)) {
301  P.track(I, m_me, false);
302 
303  if (P.getState() == vpMeSite::NO_SUPPRESSION) {
304  m_meList.push_back(P);
305  if (vpDEBUG_ENABLE(3))
307  }
308  else if (vpDEBUG_ENABLE(3))
310  }
311  }
312 
313  P.init((int)m_PExt[1].m_ifloat, (int)m_PExt[1].m_jfloat, m_delta_1, 0, m_sign);
314  P.setDisplay(m_selectDisplay);
315  for (int i = 0; i < 3; i++) {
316  P.m_ifloat = P.m_ifloat - di * sample_step;
317  P.m_i = (int)P.m_ifloat;
318  P.m_jfloat = P.m_jfloat - dj * sample_step;
319  P.m_j = (int)P.m_jfloat;
320 
321  if ((P.m_i < imin) || (P.m_i > imax) || (P.m_j < jmin) || (P.m_j > jmax)) {
322  if (vpDEBUG_ENABLE(3))
324  }
325 
326  else if (!outOfImage(P.m_i, P.m_j, (int)(m_me->getRange() + m_me->getMaskSize() + 1), (int)rows, (int)cols)) {
327  P.track(I, m_me, false);
328 
329  if (P.getState() == vpMeSite::NO_SUPPRESSION) {
330  m_meList.push_back(P);
331  if (vpDEBUG_ENABLE(3))
333  }
334  else if (vpDEBUG_ENABLE(3))
336  }
337  }
338 
339  m_me->setRange(memory_range);
340 
341  vpCDEBUG(1) << "end vpMeLine::sample() : ";
342  vpCDEBUG(1) << n_sample << " point inserted in the list " << std::endl;
343 }
344 
359 void vpMbtMeLine::computeProjectionError(const vpImage<unsigned char> &_I, double &_sumErrorRad,
360  unsigned int &_nbFeatures, const vpMatrix &SobelX, const vpMatrix &SobelY,
361  bool display, unsigned int length, unsigned int thickness)
362 {
363  _sumErrorRad = 0;
364  _nbFeatures = 0;
365  double deltaNormalized = m_theta;
366  unsigned int iter = 0;
367 
368  while (deltaNormalized < 0) {
369  deltaNormalized += M_PI;
370  }
371  while (deltaNormalized > M_PI) {
372  deltaNormalized -= M_PI;
373  }
374 
375  vpColVector vecLine(2);
376  vecLine[0] = cos(deltaNormalized);
377  vecLine[1] = sin(deltaNormalized);
378  vecLine.normalize();
379 
380  double offset = std::floor(SobelX.getRows() / 2.0f);
381 
382  for (std::list<vpMeSite>::const_iterator it = m_meList.begin(); it != m_meList.end(); ++it) {
383  if (iter != 0 && iter + 1 != m_meList.size()) {
384  double gradientX = 0;
385  double gradientY = 0;
386 
387  double iSite = it->m_ifloat;
388  double jSite = it->m_jfloat;
389 
390  for (unsigned int i = 0; i < SobelX.getRows(); i++) {
391  double iImg = iSite + (i - offset);
392  for (unsigned int j = 0; j < SobelX.getCols(); j++) {
393  double jImg = jSite + (j - offset);
394 
395  if (iImg < 0)
396  iImg = 0.0;
397  if (jImg < 0)
398  jImg = 0.0;
399 
400  if (iImg > _I.getHeight() - 1)
401  iImg = _I.getHeight() - 1;
402  if (jImg > _I.getWidth() - 1)
403  jImg = _I.getWidth() - 1;
404 
405  gradientX += SobelX[i][j] * _I((unsigned int)iImg, (unsigned int)jImg);
406  }
407  }
408 
409  for (unsigned int i = 0; i < SobelY.getRows(); i++) {
410  double iImg = iSite + (i - offset);
411  for (unsigned int j = 0; j < SobelY.getCols(); j++) {
412  double jImg = jSite + (j - offset);
413 
414  if (iImg < 0)
415  iImg = 0.0;
416  if (jImg < 0)
417  jImg = 0.0;
418 
419  if (iImg > _I.getHeight() - 1)
420  iImg = _I.getHeight() - 1;
421  if (jImg > _I.getWidth() - 1)
422  jImg = _I.getWidth() - 1;
423 
424  gradientY += SobelY[i][j] * _I((unsigned int)iImg, (unsigned int)jImg);
425  }
426  }
427 
428  double angle = atan2(gradientX, gradientY);
429  while (angle < 0)
430  angle += M_PI;
431  while (angle > M_PI)
432  angle -= M_PI;
433 
434  vpColVector vecGrad(2);
435  vecGrad[0] = cos(angle);
436  vecGrad[1] = sin(angle);
437  vecGrad.normalize();
438 
439  double angle1 = acos(vecLine * vecGrad);
440  double angle2 = acos(vecLine * (-vecGrad));
441 
442  if (display) {
443  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(deltaNormalized)),
444  (int)(it->get_j() + length * sin(deltaNormalized)), vpColor::blue,
445  length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
446  if (angle1 < angle2) {
447  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(angle)),
448  (int)(it->get_j() + length * sin(angle)), vpColor::red, length >= 20 ? length / 5 : 4,
449  length >= 20 ? length / 10 : 2, thickness);
450  }
451  else {
452  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(angle + M_PI)),
453  (int)(it->get_j() + length * sin(angle + M_PI)), vpColor::red,
454  length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
455  }
456  }
457 
458  _sumErrorRad += std::min<double>(angle1, angle2);
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 = m_delta;
482  m_delta = m_delta_1;
483  sample(I);
484  expecteddensity = (double)m_meList.size();
485  m_delta = delta_new;
486  // 2. On appelle ce qui n'est pas specifique
488  }
489 }
490 
503 void vpMbtMeLine::reSample(const vpImage<unsigned char> &I, const vpImagePoint &ip1, const vpImagePoint &ip2)
504 {
505  size_t n = m_meList.size();
506 
507  if ((double)n < 0.5 * expecteddensity /*&& n > 0*/) // n is always > 0
508  {
509  double delta_new = m_delta;
510  m_delta = m_delta_1;
511  m_PExt[0].m_ifloat = (float)ip1.get_i();
512  m_PExt[0].m_jfloat = (float)ip1.get_j();
513  m_PExt[1].m_ifloat = (float)ip2.get_i();
514  m_PExt[1].m_jfloat = (float)ip2.get_j();
515  sample(I);
516  expecteddensity = (double)m_meList.size();
517  m_delta = delta_new;
519  }
520 }
521 
525 void vpMbtMeLine::updateDelta()
526 {
527  vpMeSite p_me;
528 
529  double diff = 0;
530 
531  // if(fabs(theta) == M_PI )
532  if (std::fabs(std::fabs(m_theta) - M_PI) <=
533  vpMath::maximum(std::fabs(m_theta), (double)M_PI) * std::numeric_limits<double>::epsilon()) {
534  m_theta = 0;
535  }
536 
537  diff = fabs(m_theta - m_theta_1);
538  if (diff > M_PI / 2.0) {
539  m_sign *= -1;
540  }
541 
542  m_theta_1 = m_theta;
543 
544  m_delta = -m_theta + M_PI / 2.0;
545  normalizeAngle(m_delta);
546 
547  for (std::list<vpMeSite>::iterator it = m_meList.begin(); it != m_meList.end(); ++it) {
548  p_me = *it;
549  p_me.m_alpha = m_delta;
550  p_me.m_mask_sign = m_sign;
551  *it = p_me;
552  }
553  m_delta_1 = m_delta;
554 }
555 
561 void vpMbtMeLine::track(const vpImage<unsigned char> &I)
562 {
563  try {
565  if (m_mask != nullptr) {
566  // Expected density could be modified if some vpMeSite are no more tracked because they are outside the mask.
567  expecteddensity = (double)m_meList.size();
568  }
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  m_rho = rho;
586  m_theta = theta;
587  m_a = cos(m_theta);
588  m_b = sin(m_theta);
589  m_c = -m_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  m_rho = rho;
617  m_theta = theta;
618  m_a = cos(m_theta);
619  m_b = sin(m_theta);
620  m_c = -m_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 = m_meList.begin(); it != m_meList.end(); ++it) {
646  vpMeSite s = *it; // current reference pixel
647  if (s.m_ifloat < i_min) {
648  i_min = s.m_ifloat;
649  j_min = s.m_jfloat;
650  }
651 
652  if (s.m_ifloat > i_max) {
653  i_max = s.m_ifloat;
654  j_max = s.m_jfloat;
655  }
656  }
657 
658  if (!m_meList.empty()) {
659  m_PExt[0].m_ifloat = i_min;
660  m_PExt[0].m_jfloat = j_min;
661  m_PExt[1].m_ifloat = i_max;
662  m_PExt[1].m_jfloat = j_max;
663  }
664 
665  if (fabs(i_min - i_max) < 25) {
666  for (std::list<vpMeSite>::const_iterator it = m_meList.begin(); it != m_meList.end(); ++it) {
667  vpMeSite s = *it; // current reference pixel
668  if (s.m_jfloat < j_min) {
669  i_min = s.m_ifloat;
670  j_min = s.m_jfloat;
671  }
672 
673  if (s.m_jfloat > j_max) {
674  i_max = s.m_ifloat;
675  j_max = s.m_jfloat;
676  }
677  }
678 
679  if (!m_meList.empty()) {
680  m_PExt[0].m_ifloat = i_min;
681  m_PExt[0].m_jfloat = j_min;
682  m_PExt[1].m_ifloat = i_max;
683  m_PExt[1].m_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.m_ifloat > s2.m_ifloat); }
693 
694 void vpMbtMeLine::bubbleSortI()
695 {
696 #if 0
697  unsigned int nbElmt = m_meList.size();
698  for (unsigned int pass = 1; pass < nbElmt; pass++) {
699  m_meList.front();
700  for (unsigned int i = 0; i < nbElmt-pass; i++) {
701  vpMeSite s1 = m_meList.value();
702  vpMeSite s2 = m_meList.nextValue();
703  if (s1.m_ifloat > s2.m_ifloat)
704  m_meList.swapRight();
705  else
706  m_meList.next();
707  }
708  }
709 #endif
710  m_meList.sort(sortByI);
711 }
712 
713 static bool sortByJ(const vpMeSite &s1, const vpMeSite &s2) { return (s1.m_jfloat > s2.m_jfloat); }
714 
715 void vpMbtMeLine::bubbleSortJ()
716 {
717 #if 0
718  unsigned int nbElmt = m_meList.size();
719  for (unsigned int pass = 1; pass < nbElmt; pass++) {
720  m_meList.front();
721  for (unsigned int i = 0; i < nbElmt-pass; i++) {
722  vpMeSite s1 = m_meList.value();
723  vpMeSite s2 = m_meList.nextValue();
724  if (s1.m_jfloat > s2.m_jfloat)
725  m_meList.swapRight();
726  else
727  m_meList.next();
728  }
729  }
730 #endif
731  m_meList.sort(sortByJ);
732 }
733 
734 #endif
unsigned int getCols() const
Definition: vpArray2D.h:327
unsigned int getRows() const
Definition: vpArray2D.h:337
Implementation of column vector and the associated operations.
Definition: vpColVector.h:163
static const vpColor red
Definition: vpColor.h:211
static const vpColor cyan
Definition: vpColor.h:220
static const vpColor blue
Definition: vpColor.h:217
static const vpColor green
Definition: vpColor.h:214
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:82
void set_j(double jj)
Definition: vpImagePoint.h:304
double get_j() const
Definition: vpImagePoint.h:125
void set_i(double ii)
Definition: vpImagePoint.h:293
double get_i() const
Definition: vpImagePoint.h:114
unsigned int getWidth() const
Definition: vpImage.h:245
unsigned int getHeight() const
Definition: vpImage.h:184
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:252
static double sqr(double x)
Definition: vpMath.h:201
static int round(double x)
Definition: vpMath.h:403
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:146
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition: vpMeSite.h:65
int m_mask_sign
Mask sign.
Definition: vpMeSite.h:104
@ TOO_NEAR
Point not tracked anymore, since too near from its neighbor.
Definition: vpMeSite.h:90
@ CONTRAST
Point not tracked due to a contrast problem, but retained in the ME list.
Definition: vpMeSite.h:84
@ NO_SUPPRESSION
Point successfully tracked.
Definition: vpMeSite.h:83
void setDisplay(vpMeSiteDisplayType select)
Definition: vpMeSite.h:247
double m_ifloat
Subpixel coordinates along i of a site.
Definition: vpMeSite.h:100
double convolution(const vpImage< unsigned char > &ima, const vpMe *me)
Definition: vpMeSite.cpp:212
double m_alpha
Angle of tangent at site.
Definition: vpMeSite.h:106
void init()
Definition: vpMeSite.cpp:55
vpMeSiteState getState() const
Definition: vpMeSite.h:266
int m_j
Integer coordinates along j of a site.
Definition: vpMeSite.h:98
int m_i
Integer coordinate along i of a site.
Definition: vpMeSite.h:96
double m_jfloat
Subpixel coordinates along j of a site.
Definition: vpMeSite.h:102
void setContrastThreshold(const double &thresh, const vpMe &me)
Definition: vpMeSite.h:286
void track(const vpImage< unsigned char > &I, const vpMe *me, const bool &test_contrast=true)
Definition: vpMeSite.cpp:267
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:256
void initTracking(const vpImage< unsigned char > &I)
void track(const vpImage< unsigned char > &I)
Error that can be emitted by the vpTracker class and its derivatives.
@ fatalError
Tracker fatal error.
#define vpCDEBUG(level)
Definition: vpDebug.h:497
#define vpDEBUG_ENABLE(level)
Definition: vpDebug.h:524