Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
vpMbtMeLine.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 https://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 
34 #include <visp3/core/vpConfig.h>
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36 
41 #include <algorithm> // (std::min)
42 #include <cmath> // std::fabs
43 #include <limits> // numeric_limits
44 
45 #include <visp3/core/vpDebug.h>
46 #include <visp3/core/vpRobust.h>
47 #include <visp3/core/vpTrackingException.h>
48 #include <visp3/mbt/vpMbtMeLine.h>
49 
50 BEGIN_VISP_NAMESPACE
52 static void normalizeAngle(double &delta)
53 {
54  while (delta > M_PI) {
55  delta -= M_PI;
56  }
57  while (delta < -M_PI) {
58  delta += M_PI;
59  }
60 }
61 
65 vpMbtMeLine::vpMbtMeLine()
66  : 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.),
67  imin(0), imax(0), jmin(0), jmax(0), expecteddensity(0.)
68 { }
69 
73 vpMbtMeLine::~vpMbtMeLine()
74 {
75  m_meList.clear();
76 }
77 
93 void vpMbtMeLine::initTracking(const vpImage<unsigned char> &I, const vpImagePoint &ip1, const vpImagePoint &ip2,
94  double rho, double theta, bool doNoTrack)
95 {
96  vpCDEBUG(1) << " begin vpMeLine::initTracking()" << std::endl;
97 
98  try {
99  // 1. On fait ce qui concerne les droites (peut etre vide)
100  // Points extremites
101  m_PExt[0].m_ifloat = (float)ip1.get_i();
102  m_PExt[0].m_jfloat = (float)ip1.get_j();
103  m_PExt[1].m_ifloat = (float)ip2.get_i();
104  m_PExt[1].m_jfloat = (float)ip2.get_j();
105 
106  m_rho = rho;
107  m_theta = theta;
108  m_theta_1 = theta;
109 
110  m_a = cos(m_theta);
111  m_b = sin(m_theta);
112  m_c = -m_rho;
113 
114  m_delta = -m_theta + M_PI / 2.0;
115  normalizeAngle(m_delta);
116  m_delta_1 = m_delta;
117 
118  sample(I, doNoTrack);
119  expecteddensity = (double)m_meList.size();
120 
121  if (!doNoTrack)
123  }
124  catch (...) {
125  throw; // throw the original exception
126  }
127  vpCDEBUG(1) << " end vpMeLine::initTracking()" << std::endl;
128 }
129 
137 void vpMbtMeLine::sample(const vpImage<unsigned char> &I, bool doNoTrack)
138 {
139  int nbrows = static_cast<int>(I.getHeight());
140  int nbcols = static_cast<int>(I.getWidth());
141  double n_sample;
142 
143  if (std::fabs(m_me->getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
144  throw(vpTrackingException(vpTrackingException::fatalError, "Function vpMbtMeLine::sample() called with "
145  "moving-edges sample step = 0"));
146  }
147 
148  // i, j portions of the line_p
149  double diffsi = m_PExt[0].m_ifloat - m_PExt[1].m_ifloat;
150  double diffsj = m_PExt[0].m_jfloat - m_PExt[1].m_jfloat;
151 
152  double length_p = sqrt((vpMath::sqr(diffsi) + vpMath::sqr(diffsj)));
153 
154  // number of samples along line_p
155  n_sample = length_p / (double)m_me->getSampleStep();
156 
157  double stepi = diffsi / (double)n_sample;
158  double stepj = diffsj / (double)n_sample;
159 
160  // Choose starting point
161  double is = m_PExt[1].m_ifloat;
162  double js = m_PExt[1].m_jfloat;
163 
164  // Delete old list
165  m_meList.clear();
166 
167  // sample positions at i*m_me->getSampleStep() interval along the
168  // line_p, starting at PSiteExt[0]
169 
170  for (int i = 0; i <= vpMath::round(n_sample); i++) {
171  vpImagePoint iP;
172  iP.set_i(is);
173  iP.set_j(js);
174  // If point is in the image, add to the sample list
175  if (!outOfImage(iP, (int)(m_me->getRange() + m_me->getMaskSize() + 1), nbrows, nbcols)) {
176  unsigned int is_uint = static_cast<unsigned int>(is);
177  unsigned int js_uint = static_cast<unsigned int>(js);
178  if (inRoiMask(m_mask, is_uint, js_uint) && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) {
179  vpMeSite pix;
180  pix.init(iP.get_i(), iP.get_j(), m_delta, 0, m_sign);
181  pix.setDisplay(m_selectDisplay);
183  const double marginRatio = m_me->getThresholdMarginRatio();
184  double convolution = pix.convolution(I, m_me);
185  double contrastThreshold = fabs(convolution) * marginRatio;
186  pix.setContrastThreshold(contrastThreshold, *m_me);
187 
188  if (!doNoTrack) {
189  pix.track(I, m_me, false);
190  }
191 
192  if (vpDEBUG_ENABLE(3)) {
194  }
195 
196  m_meList.push_back(pix);
197  }
198  }
199  is += stepi;
200  js += stepj;
201  }
202 
203  vpCDEBUG(1) << "end vpMeLine::sample() : ";
204  vpCDEBUG(1) << m_meList.size() << " point inserted in the list " << std::endl;
205 }
206 
212 void vpMbtMeLine::suppressPoints(const vpImage<unsigned char> &I)
213 {
214  for (std::list<vpMeSite>::iterator it = m_meList.begin(); it != m_meList.end();) {
215  vpMeSite s = *it; // current reference pixel
216 
217  if (fabs(sin(m_theta)) > 0.9) // Vertical line management
218  {
219  if ((s.m_i < imin) || (s.m_i > imax)) {
221  }
222  }
223 
224  else if (fabs(cos(m_theta)) > 0.9) // Horizontal line management
225  {
226  if ((s.m_j < jmin) || (s.m_j > jmax)) {
228  }
229  }
230 
231  else {
232  if ((s.m_i < imin) || (s.m_i > imax) || (s.m_j < jmin) || (s.m_j > jmax)) {
234  }
235  }
236 
237  if (outOfImage(s.m_i, s.m_j, (int)(m_me->getRange() + m_me->getMaskSize() + 1), (int)I.getHeight(), (int)I.getWidth())) {
239  }
240 
242  it = m_meList.erase(it);
243  else
244  ++it;
245  }
246 }
247 
254 void vpMbtMeLine::seekExtremities(const vpImage<unsigned char> &I)
255 {
256  vpCDEBUG(1) << "begin vpMeLine::sample() : " << std::endl;
257 
258  int rows = (int)I.getHeight();
259  int cols = (int)I.getWidth();
260  double n_sample;
261 
262  // if (m_me->getSampleStep()==0)
263  if (std::fabs(m_me->getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
264  throw(vpTrackingException(vpTrackingException::fatalError, "Function called with sample step = 0"));
265  }
266 
267  // i, j portions of the line_p
268  double diffsi = m_PExt[0].m_ifloat - m_PExt[1].m_ifloat;
269  double diffsj = m_PExt[0].m_jfloat - m_PExt[1].m_jfloat;
270 
271  double s = vpMath::sqr(diffsi) + vpMath::sqr(diffsj);
272 
273  double di = diffsi / sqrt(s); // pas de risque de /0 car d(P1,P2) >0
274  double dj = diffsj / sqrt(s);
275 
276  double length_p = sqrt(s); /*(vpMath::sqr(diffsi)+vpMath::sqr(diffsj))*/
277 
278  // number of samples along line_p
279  n_sample = length_p / (double)m_me->getSampleStep();
280  double sample_step = (double)m_me->getSampleStep();
281 
282  vpMeSite P;
283  P.init((int)m_PExt[0].m_ifloat, (int)m_PExt[0].m_jfloat, m_delta_1, 0, m_sign);
284  P.setDisplay(m_selectDisplay);
285 
286  unsigned int memory_range = m_me->getRange();
287  m_me->setRange(1);
288 
289  for (int i = 0; i < 3; i++) {
290  P.m_ifloat = P.m_ifloat + di * sample_step;
291  P.m_i = (int)P.m_ifloat;
292  P.m_jfloat = P.m_jfloat + dj * sample_step;
293  P.m_j = (int)P.m_jfloat;
294 
295  if ((P.m_i < imin) || (P.m_i > imax) || (P.m_j < jmin) || (P.m_j > jmax)) {
296  if (vpDEBUG_ENABLE(3))
298  }
299  else if (!outOfImage(P.m_i, P.m_j, (int)(m_me->getRange() + m_me->getMaskSize() + 1), (int)rows, (int)cols)) {
300  P.track(I, m_me, false);
301 
302  if (P.getState() == vpMeSite::NO_SUPPRESSION) {
303  m_meList.push_back(P);
304  if (vpDEBUG_ENABLE(3))
306  }
307  else if (vpDEBUG_ENABLE(3))
309  }
310  }
311 
312  P.init((int)m_PExt[1].m_ifloat, (int)m_PExt[1].m_jfloat, m_delta_1, 0, m_sign);
313  P.setDisplay(m_selectDisplay);
314  for (int i = 0; i < 3; i++) {
315  P.m_ifloat = P.m_ifloat - di * sample_step;
316  P.m_i = (int)P.m_ifloat;
317  P.m_jfloat = P.m_jfloat - dj * sample_step;
318  P.m_j = (int)P.m_jfloat;
319 
320  if ((P.m_i < imin) || (P.m_i > imax) || (P.m_j < jmin) || (P.m_j > jmax)) {
321  if (vpDEBUG_ENABLE(3))
323  }
324 
325  else if (!outOfImage(P.m_i, P.m_j, (int)(m_me->getRange() + m_me->getMaskSize() + 1), (int)rows, (int)cols)) {
326  P.track(I, m_me, false);
327 
328  if (P.getState() == vpMeSite::NO_SUPPRESSION) {
329  m_meList.push_back(P);
330  if (vpDEBUG_ENABLE(3))
332  }
333  else if (vpDEBUG_ENABLE(3))
335  }
336  }
337 
338  m_me->setRange(memory_range);
339 
340  vpCDEBUG(1) << "end vpMeLine::sample() : ";
341  vpCDEBUG(1) << n_sample << " point inserted in the list " << std::endl;
342 }
343 
358 void vpMbtMeLine::computeProjectionError(const vpImage<unsigned char> &_I, double &_sumErrorRad,
359  unsigned int &_nbFeatures, const vpMatrix &SobelX, const vpMatrix &SobelY,
360  bool display, unsigned int length, unsigned int thickness)
361 {
362  _sumErrorRad = 0;
363  _nbFeatures = 0;
364  double deltaNormalized = m_theta;
365  unsigned int iter = 0;
366 
367  while (deltaNormalized < 0) {
368  deltaNormalized += M_PI;
369  }
370  while (deltaNormalized > M_PI) {
371  deltaNormalized -= M_PI;
372  }
373 
374  vpColVector vecLine(2);
375  vecLine[0] = cos(deltaNormalized);
376  vecLine[1] = sin(deltaNormalized);
377  vecLine.normalize();
378 
379  double offset = std::floor(SobelX.getRows() / 2.0f);
380 
381  for (std::list<vpMeSite>::const_iterator it = m_meList.begin(); it != m_meList.end(); ++it) {
382  if (iter != 0 && iter + 1 != m_meList.size()) {
383  double gradientX = 0;
384  double gradientY = 0;
385 
386  double iSite = it->m_ifloat;
387  double jSite = it->m_jfloat;
388 
389  for (unsigned int i = 0; i < SobelX.getRows(); i++) {
390  double iImg = iSite + (i - offset);
391  for (unsigned int j = 0; j < SobelX.getCols(); j++) {
392  double jImg = jSite + (j - offset);
393 
394  if (iImg < 0)
395  iImg = 0.0;
396  if (jImg < 0)
397  jImg = 0.0;
398 
399  if (iImg > _I.getHeight() - 1)
400  iImg = _I.getHeight() - 1;
401  if (jImg > _I.getWidth() - 1)
402  jImg = _I.getWidth() - 1;
403 
404  gradientX += SobelX[i][j] * _I((unsigned int)iImg, (unsigned int)jImg);
405  }
406  }
407 
408  for (unsigned int i = 0; i < SobelY.getRows(); i++) {
409  double iImg = iSite + (i - offset);
410  for (unsigned int j = 0; j < SobelY.getCols(); j++) {
411  double jImg = jSite + (j - offset);
412 
413  if (iImg < 0)
414  iImg = 0.0;
415  if (jImg < 0)
416  jImg = 0.0;
417 
418  if (iImg > _I.getHeight() - 1)
419  iImg = _I.getHeight() - 1;
420  if (jImg > _I.getWidth() - 1)
421  jImg = _I.getWidth() - 1;
422 
423  gradientY += SobelY[i][j] * _I((unsigned int)iImg, (unsigned int)jImg);
424  }
425  }
426 
427  double angle = atan2(gradientX, gradientY);
428  while (angle < 0)
429  angle += M_PI;
430  while (angle > M_PI)
431  angle -= M_PI;
432 
433  vpColVector vecGrad(2);
434  vecGrad[0] = cos(angle);
435  vecGrad[1] = sin(angle);
436  vecGrad.normalize();
437 
438  double angle1 = acos(vecLine * vecGrad);
439  double angle2 = acos(vecLine * (-vecGrad));
440 
441  if (display) {
442  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(deltaNormalized)),
443  (int)(it->get_j() + length * sin(deltaNormalized)), vpColor::blue,
444  length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
445  if (angle1 < angle2) {
446  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(angle)),
447  (int)(it->get_j() + length * sin(angle)), vpColor::red, length >= 20 ? length / 5 : 4,
448  length >= 20 ? length / 10 : 2, thickness);
449  }
450  else {
451  vpDisplay::displayArrow(_I, it->get_i(), it->get_j(), (int)(it->get_i() + length * cos(angle + M_PI)),
452  (int)(it->get_j() + length * sin(angle + M_PI)), vpColor::red,
453  length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
454  }
455  }
456 
457  _sumErrorRad += std::min<double>(angle1, angle2);
458 
459  _nbFeatures++;
460  }
461  iter++;
462  }
463 }
464 
475 void vpMbtMeLine::reSample(const vpImage<unsigned char> &I)
476 {
477  unsigned int n = numberOfSignal();
478 
479  if ((double)n < 0.5 * expecteddensity && n > 0) {
480  double delta_new = m_delta;
481  m_delta = m_delta_1;
482  sample(I);
483  expecteddensity = (double)m_meList.size();
484  m_delta = delta_new;
485  // 2. On appelle ce qui n'est pas specifique
487  }
488 }
489 
502 void vpMbtMeLine::reSample(const vpImage<unsigned char> &I, const vpImagePoint &ip1, const vpImagePoint &ip2)
503 {
504  size_t n = m_meList.size();
505 
506  if ((double)n < 0.5 * expecteddensity /*&& n > 0*/) // n is always > 0
507  {
508  double delta_new = m_delta;
509  m_delta = m_delta_1;
510  m_PExt[0].m_ifloat = (float)ip1.get_i();
511  m_PExt[0].m_jfloat = (float)ip1.get_j();
512  m_PExt[1].m_ifloat = (float)ip2.get_i();
513  m_PExt[1].m_jfloat = (float)ip2.get_j();
514  sample(I);
515  expecteddensity = (double)m_meList.size();
516  m_delta = delta_new;
518  }
519 }
520 
524 void vpMbtMeLine::updateDelta()
525 {
526  vpMeSite p_me;
527 
528  double diff = 0;
529 
530  // if(fabs(theta) == M_PI )
531  if (std::fabs(std::fabs(m_theta) - M_PI) <=
532  vpMath::maximum(std::fabs(m_theta), (double)M_PI) * std::numeric_limits<double>::epsilon()) {
533  m_theta = 0;
534  }
535 
536  diff = fabs(m_theta - m_theta_1);
537  if (diff > M_PI / 2.0) {
538  m_sign *= -1;
539  }
540 
541  m_theta_1 = m_theta;
542 
543  m_delta = -m_theta + M_PI / 2.0;
544  normalizeAngle(m_delta);
545 
546  for (std::list<vpMeSite>::iterator it = m_meList.begin(); it != m_meList.end(); ++it) {
547  p_me = *it;
548  p_me.m_alpha = m_delta;
549  p_me.m_mask_sign = m_sign;
550  *it = p_me;
551  }
552  m_delta_1 = m_delta;
553 }
554 
560 void vpMbtMeLine::track(const vpImage<unsigned char> &I)
561 {
562  try {
564  if (m_mask != nullptr) {
565  // Expected density could be modified if some vpMeSite are no more tracked because they are outside the mask.
566  expecteddensity = (double)m_meList.size();
567  }
568  }
569  catch (...) {
570  throw; // throw the original exception
571  }
572 }
573 
582 void vpMbtMeLine::updateParameters(const vpImage<unsigned char> &I, double rho, double theta)
583 {
584  m_rho = rho;
585  m_theta = theta;
586  m_a = cos(m_theta);
587  m_b = sin(m_theta);
588  m_c = -m_rho;
589  // recherche de point aux extremite de la droites
590  // dans le cas d'un glissement
591  suppressPoints(I);
592  seekExtremities(I);
593  suppressPoints(I);
594  setExtremities();
595  // reechantillonage si necessaire
596  reSample(I);
597 
598  // remet a jour l'angle delta pour chaque point de la liste
599  updateDelta();
600 }
601 
612 void vpMbtMeLine::updateParameters(const vpImage<unsigned char> &I, const vpImagePoint &ip1, const vpImagePoint &ip2,
613  double rho, double theta)
614 {
615  m_rho = rho;
616  m_theta = theta;
617  m_a = cos(m_theta);
618  m_b = sin(m_theta);
619  m_c = -m_rho;
620  // recherche de point aux extremite de la droites
621  // dans le cas d'un glissement
622  suppressPoints(I);
623  seekExtremities(I);
624  suppressPoints(I);
625  setExtremities();
626  // reechantillonage si necessaire
627  reSample(I, ip1, ip2);
628 
629  // remet a jour l'angle delta pour chaque point de la liste
630  updateDelta();
631 }
632 
636 void vpMbtMeLine::setExtremities()
637 {
638  double i_min = +1e6;
639  double j_min = +1e6;
640  double i_max = -1;
641  double j_max = -1;
642 
643  // Loop through list of sites to track
644  for (std::list<vpMeSite>::const_iterator it = m_meList.begin(); it != m_meList.end(); ++it) {
645  vpMeSite s = *it; // current reference pixel
646  if (s.m_ifloat < i_min) {
647  i_min = s.m_ifloat;
648  j_min = s.m_jfloat;
649  }
650 
651  if (s.m_ifloat > i_max) {
652  i_max = s.m_ifloat;
653  j_max = s.m_jfloat;
654  }
655  }
656 
657  if (!m_meList.empty()) {
658  m_PExt[0].m_ifloat = i_min;
659  m_PExt[0].m_jfloat = j_min;
660  m_PExt[1].m_ifloat = i_max;
661  m_PExt[1].m_jfloat = j_max;
662  }
663 
664  if (fabs(i_min - i_max) < 25) {
665  for (std::list<vpMeSite>::const_iterator it = m_meList.begin(); it != m_meList.end(); ++it) {
666  vpMeSite s = *it; // current reference pixel
667  if (s.m_jfloat < j_min) {
668  i_min = s.m_ifloat;
669  j_min = s.m_jfloat;
670  }
671 
672  if (s.m_jfloat > j_max) {
673  i_max = s.m_ifloat;
674  j_max = s.m_jfloat;
675  }
676  }
677 
678  if (!m_meList.empty()) {
679  m_PExt[0].m_ifloat = i_min;
680  m_PExt[0].m_jfloat = j_min;
681  m_PExt[1].m_ifloat = i_max;
682  m_PExt[1].m_jfloat = j_max;
683  }
684  bubbleSortJ();
685  }
686 
687  else
688  bubbleSortI();
689 }
690 
691 static bool sortByI(const vpMeSite &s1, const vpMeSite &s2) { return (s1.m_ifloat > s2.m_ifloat); }
692 
693 void vpMbtMeLine::bubbleSortI()
694 {
695 #if 0
696  unsigned int nbElmt = m_meList.size();
697  for (unsigned int pass = 1; pass < nbElmt; pass++) {
698  m_meList.front();
699  for (unsigned int i = 0; i < nbElmt-pass; i++) {
700  vpMeSite s1 = m_meList.value();
701  vpMeSite s2 = m_meList.nextValue();
702  if (s1.m_ifloat > s2.m_ifloat)
703  m_meList.swapRight();
704  else
705  m_meList.next();
706  }
707  }
708 #endif
709  m_meList.sort(sortByI);
710 }
711 
712 static bool sortByJ(const vpMeSite &s1, const vpMeSite &s2) { return (s1.m_jfloat > s2.m_jfloat); }
713 
714 void vpMbtMeLine::bubbleSortJ()
715 {
716 #if 0
717  unsigned int nbElmt = m_meList.size();
718  for (unsigned int pass = 1; pass < nbElmt; pass++) {
719  m_meList.front();
720  for (unsigned int i = 0; i < nbElmt-pass; i++) {
721  vpMeSite s1 = m_meList.value();
722  vpMeSite s2 = m_meList.nextValue();
723  if (s1.m_jfloat > s2.m_jfloat)
724  m_meList.swapRight();
725  else
726  m_meList.next();
727  }
728  }
729 #endif
730  m_meList.sort(sortByJ);
731 }
732 END_VISP_NAMESPACE
733 #endif
unsigned int getCols() const
Definition: vpArray2D.h:337
unsigned int getRows() const
Definition: vpArray2D.h:347
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
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:82
void set_j(double jj)
Definition: vpImagePoint.h:309
double get_j() const
Definition: vpImagePoint.h:125
void set_i(double ii)
Definition: vpImagePoint.h:298
double get_i() const
Definition: vpImagePoint.h:114
unsigned int getWidth() const
Definition: vpImage.h:242
unsigned int getHeight() const
Definition: vpImage.h:181
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:254
static double sqr(double x)
Definition: vpMath.h:203
static int round(double x)
Definition: vpMath.h:410
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition: vpMeSite.h:68
int m_mask_sign
Mask sign.
Definition: vpMeSite.h:107
@ TOO_NEAR
Point not tracked anymore, since too near from its neighbor.
Definition: vpMeSite.h:93
@ CONTRAST
Point not tracked due to a contrast problem, but retained in the ME list.
Definition: vpMeSite.h:87
@ NO_SUPPRESSION
Point successfully tracked.
Definition: vpMeSite.h:86
void setDisplay(vpMeSiteDisplayType select)
Definition: vpMeSite.h:264
double m_ifloat
Subpixel coordinates along i of a site.
Definition: vpMeSite.h:103
double convolution(const vpImage< unsigned char > &ima, const vpMe *me)
Definition: vpMeSite.cpp:227
void init()
Definition: vpMeSite.cpp:70
double m_alpha
Angle of tangent at site.
Definition: vpMeSite.h:109
vpMeSiteState getState() const
Definition: vpMeSite.h:283
int m_j
Integer coordinates along j of a site.
Definition: vpMeSite.h:101
int m_i
Integer coordinate along i of a site.
Definition: vpMeSite.h:99
double m_jfloat
Subpixel coordinates along j of a site.
Definition: vpMeSite.h:105
void setContrastThreshold(const double &thresh, const vpMe &me)
Definition: vpMeSite.h:303
void track(const vpImage< unsigned char > &I, const vpMe *me, const bool &test_contrast=true)
Definition: vpMeSite.cpp:282
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:273
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.