Visual Servoing Platform  version 3.6.1 under development (2023-12-07)
vpDot.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  * Track a white dot.
33  *
34  * Authors:
35  * Aurelien Yol
36  *
37 *****************************************************************************/
38 
39 /*
40  \file vpDot.cpp
41  \brief Track a white dot
42 */
43 
44 #include <visp3/blob/vpDot.h>
45 #include <visp3/core/vpColor.h>
46 #include <visp3/core/vpDisplay.h>
47 #include <visp3/core/vpTrackingException.h>
48 
49 #include <vector>
50 
51 /*
52  \class vpDot
53  \brief Track a white dot
54 */
55 
56 /* spiral size for the dot search */
57 const unsigned int vpDot::SPIRAL_SEARCH_SIZE = 350;
58 
65 void vpDot::init()
66 {
67  cog.set_u(0);
68  cog.set_v(0);
69 
70  compute_moment = false;
71  graphics = false;
72  thickness = 1;
73  maxDotSizePercentage = 0.25; // 25 % of the image size
74 
75  mean_gray_level = 0;
76  gray_level_min = 128;
77  gray_level_max = 255;
78  grayLevelPrecision = 0.85;
79  gamma = 1.5;
80 
81  m00 = m11 = m02 = m20 = m10 = m01 = mu11 = mu02 = mu20 = 0;
82 
83  connexityType = CONNEXITY_4;
84 
85  u_min = u_max = v_min = v_max = 0;
86 
87  gray_level_out = 0;
88  nbMaxPoint = 0;
89 }
90 
92  : m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), ip_connexities_list(),
93  ip_edges_list(), connexityType(CONNEXITY_4), cog(), u_min(0), u_max(0), v_min(0), v_max(0), graphics(false),
94  thickness(1), maxDotSizePercentage(0.25), gray_level_out(0), mean_gray_level(0), gray_level_min(128),
95  gray_level_max(255), grayLevelPrecision(0.85), gamma(1.5), compute_moment(false), nbMaxPoint(0)
96 { }
97 
104  : m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), ip_connexities_list(),
105  ip_edges_list(), connexityType(CONNEXITY_4), cog(ip), u_min(0), u_max(0), v_min(0), v_max(0), graphics(false),
106  thickness(1), maxDotSizePercentage(0.25), gray_level_out(0), mean_gray_level(0), gray_level_min(128),
107  gray_level_max(255), grayLevelPrecision(0.85), gamma(1.5), compute_moment(false), nbMaxPoint(0)
108 { }
109 
114  : vpTracker(d), m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.),
115  ip_connexities_list(), ip_edges_list(), connexityType(CONNEXITY_4), cog(), u_min(0), u_max(0), v_min(0), v_max(0),
116  graphics(false), thickness(1), maxDotSizePercentage(0.25), gray_level_out(0), mean_gray_level(0),
117  gray_level_min(128), gray_level_max(255), grayLevelPrecision(0.85), gamma(1.5), compute_moment(false), nbMaxPoint(0)
118 {
119  *this = d;
120 }
121 
125 vpDot::~vpDot() { ip_connexities_list.clear(); }
126 
131 {
132  ip_edges_list = d.ip_edges_list;
133  ip_connexities_list = d.ip_connexities_list;
134  connexityType = d.connexityType;
135  cog = d.getCog();
136 
137  u_min = d.u_min;
138  v_min = d.v_min;
139  u_max = d.u_max;
140  v_max = d.v_max;
141 
142  graphics = d.graphics;
143  thickness = d.thickness;
144  maxDotSizePercentage = d.maxDotSizePercentage;
145  gray_level_out = d.gray_level_out;
146  mean_gray_level = d.mean_gray_level;
147  gray_level_min = d.gray_level_min;
148  gray_level_max = d.gray_level_max;
149  grayLevelPrecision = d.grayLevelPrecision;
150  gamma = d.gamma;
151  compute_moment = d.compute_moment;
152  nbMaxPoint = d.nbMaxPoint;
153 
154  m00 = d.m00;
155  m01 = d.m01;
156  m10 = d.m10;
157  m11 = d.m11;
158  m02 = d.m02;
159  m20 = d.m20;
160 
161  mu11 = d.mu11;
162  mu20 = d.mu20;
163  mu02 = d.mu02;
164 
165  return *this;
166 }
167 
168 bool vpDot::operator!=(const vpDot &d) const { return (cog != d.getCog()); }
169 
170 bool vpDot::operator==(const vpDot &d) const { return (cog == d.getCog()); }
171 
183 void vpDot::setGrayLevelOut()
184 {
185  if (gray_level_min == 0) {
186  if (gray_level_max == 255) {
187  // gray_level_min = 0 and gray_level_max = 255: this should not occur
188  // vpERROR_TRACE("Unable to choose a good \"out\" level") ;
189  throw(vpTrackingException(vpTrackingException::initializationError, "Unable to choose a good \"out\" level"));
190  }
191  gray_level_out = static_cast<unsigned char>(gray_level_max + 1u);
192  }
193 }
194 
212 bool vpDot::connexe(const vpImage<unsigned char> &I, unsigned int u, unsigned int v, double &mean_value, double &u_cog,
213  double &v_cog, double &n)
214 {
215  std::vector<bool> checkTab(I.getWidth() * I.getHeight(), false);
216  return connexe(I, u, v, mean_value, u_cog, v_cog, n, checkTab);
217 }
235 bool vpDot::connexe(const vpImage<unsigned char> &I, unsigned int u, unsigned int v, double &mean_value, double &u_cog,
236  double &v_cog, double &n, std::vector<bool> &checkTab)
237 {
238 
239  unsigned int width = I.getWidth();
240  unsigned int height = I.getHeight();
241 
242  // Test if we are in the image
243  if ((u >= width) || (v >= height)) {
244  // std::cout << "out of bound" << std::endl;
245  return false;
246  }
247 
248  if (checkTab[u + v * I.getWidth()])
249  return true;
250 
251  vpImagePoint ip;
252  ip.set_u(u);
253  ip.set_v(v);
254 
255  if (I[v][u] >= gray_level_min && I[v][u] <= gray_level_max) {
256  checkTab[v * I.getWidth() + u] = true;
257 
258  ip_connexities_list.push_back(ip);
259 
260  u_cog += u;
261  v_cog += v;
262  n += 1;
263 
264  if (n > nbMaxPoint) {
266  "Too many point %lf (%lf%% of image size). "
267  "This threshold can be modified using the setMaxDotSize() "
268  "method.",
269  n, n / (I.getWidth() * I.getHeight()), nbMaxPoint, maxDotSizePercentage));
270  }
271 
272  // Bounding box update
273  if (u < this->u_min)
274  this->u_min = u;
275  if (u > this->u_max)
276  this->u_max = u;
277  if (v < this->v_min)
278  this->v_min = v;
279  if (v > this->v_max)
280  this->v_max = v;
281 
282  // Mean value of the dot intensities
283  mean_value = (mean_value * (n - 1) + I[v][u]) / n;
284  if (compute_moment == true) {
285  m00++;
286  m10 += u;
287  m01 += v;
288  m11 += (u * v);
289  m20 += u * u;
290  m02 += v * v;
291  }
292  }
293  else {
294  // std::cout << "not in" << std::endl;
295  return false;
296  }
297 
298  bool edge = false;
299 
300  // if((int)u-1 >= 0)
301  if (u >= 1)
302  if (!checkTab[u - 1 + v * I.getWidth()])
303  if (!connexe(I, u - 1, v, mean_value, u_cog, v_cog, n, checkTab))
304  edge = true;
305 
306  if (u + 1 < I.getWidth())
307  if (!checkTab[u + 1 + v * I.getWidth()])
308  if (!connexe(I, u + 1, v, mean_value, u_cog, v_cog, n, checkTab))
309  edge = true;
310 
311  if (v >= 1)
312  if (!checkTab[u + (v - 1) * I.getWidth()])
313  if (!connexe(I, u, v - 1, mean_value, u_cog, v_cog, n, checkTab))
314  edge = true;
315 
316  if (v + 1 < I.getHeight())
317  if (!checkTab[u + (v + 1) * I.getWidth()])
318  if (!connexe(I, u, v + 1, mean_value, u_cog, v_cog, n, checkTab))
319  edge = true;
320 
321  if (connexityType == CONNEXITY_8) {
322  if (v >= 1 && u >= 1)
323  if (!checkTab[u - 1 + (v - 1) * I.getWidth()])
324  if (!connexe(I, u - 1, v - 1, mean_value, u_cog, v_cog, n, checkTab))
325  edge = true;
326 
327  if (v >= 1 && u + 1 < I.getWidth())
328  if (!checkTab[u + 1 + (v - 1) * I.getWidth()])
329  if (!connexe(I, u + 1, v - 1, mean_value, u_cog, v_cog, n, checkTab))
330  edge = true;
331 
332  if (v + 1 < I.getHeight() && u >= 1)
333  if (!checkTab[u - 1 + (v + 1) * I.getWidth()])
334  if (!connexe(I, u - 1, v + 1, mean_value, u_cog, v_cog, n, checkTab))
335  edge = true;
336 
337  if (v + 1 < I.getHeight() && u + 1 < I.getWidth())
338  if (!checkTab[u + 1 + (v + 1) * I.getWidth()])
339  if (!connexe(I, u + 1, v + 1, mean_value, u_cog, v_cog, n, checkTab))
340  edge = true;
341  }
342 
343  if (edge) {
344  ip_edges_list.push_back(ip);
345  if (graphics == true) {
346  vpImagePoint ip_(ip);
347  for (unsigned int t = 0; t < thickness; t++) {
348  ip_.set_u(ip.get_u() + t);
350  }
351  // vpDisplay::flush(I);
352  }
353  }
354 
355  return true;
356 }
357 
377 void vpDot::COG(const vpImage<unsigned char> &I, double &u, double &v)
378 {
379  // Set the maximal number of points considering the maximal dot size
380  // image percentage
381  nbMaxPoint = (I.getWidth() * I.getHeight()) * maxDotSizePercentage;
382 
383  // segmentation de l'image apres seuillage
384  // (etiquetage des composante connexe)
385  if (compute_moment)
386  m00 = m11 = m02 = m20 = m10 = m01 = mu11 = mu20 = mu02 = 0;
387 
388  double u_cog = 0;
389  double v_cog = 0;
390  double npoint = 0;
391  this->mean_gray_level = 0;
392 
393  ip_connexities_list.clear();
394  ip_edges_list.clear();
395 
396  // Initialise the boundig box
397  this->u_min = I.getWidth();
398  this->u_max = 0;
399  this->v_min = I.getHeight();
400  this->v_max = 0;
401 
402 #if 0
403  // Original version
404  if (connexe(I, (unsigned int)u, (unsigned int)v,
405  gray_level_min, gray_level_max,
406  mean_gray_level, u_cog, v_cog, npoint) == vpDot::out) {
407  bool sol = false;
408  unsigned int pas;
409  for (pas = 2; pas <= 25; pas++)if (sol==false) {
410  for (int k = -1; k <=1; k++) if (sol==false)
411  for (int l = -1; l <=1; l++) if (sol==false) {
412  u_cog = 0;
413  v_cog = 0;
414  ip_connexities_list.clear();
415 
416  this->mean_gray_level = 0;
417  if (connexe(I, (unsigned int)(u+k*pas), (unsigned int)(v+l*pas),
418  gray_level_min, gray_level_max,
419  mean_gray_level, u_cog, v_cog, npoint) != vpDot::out) {
420  sol = true; u += k*pas; v += l*pas;
421  }
422  }
423  }
424  if (sol == false) {
425  //vpERROR_TRACE("Dot has been lost") ;
427  "Dot has been lost"));
428  }
429  }
430 #else
431  // If the dot is not found, search around using a spiral
432  if (!connexe(I, (unsigned int)u, (unsigned int)v, mean_gray_level, u_cog, v_cog, npoint)) {
433  bool sol = false;
434 
435  unsigned int right = 1;
436  unsigned int botom = 1;
437  unsigned int left = 2;
438  unsigned int up = 2;
439  double u_ = u, v_ = v;
440  unsigned int k;
441 
442  // Spiral search from the center to find the nearest dot
443  while ((right < SPIRAL_SEARCH_SIZE) && (sol == false)) {
444  for (k = 1; k <= right; k++)
445  if (sol == false) {
446  u_cog = 0;
447  v_cog = 0;
448  ip_connexities_list.clear();
449  ip_edges_list.clear();
450 
451  this->mean_gray_level = 0;
452  if (connexe(I, (unsigned int)u_ + k, (unsigned int)(v_), mean_gray_level, u_cog, v_cog, npoint)) {
453  sol = true;
454  u = u_ + k;
455  v = v_;
456  }
457  }
458  u_ += k;
459  right += 2;
460 
461  for (k = 1; k <= botom; k++)
462  if (sol == false) {
463  u_cog = 0;
464  v_cog = 0;
465  ip_connexities_list.clear();
466  ip_edges_list.clear();
467 
468  this->mean_gray_level = 0;
469 
470  if (connexe(I, (unsigned int)(u_), (unsigned int)(v_ + k), mean_gray_level, u_cog, v_cog, npoint)) {
471  sol = true;
472  u = u_;
473  v = v_ + k;
474  }
475  }
476  v_ += k;
477  botom += 2;
478 
479  for (k = 1; k <= left; k++)
480  if (sol == false) {
481  u_cog = 0;
482  v_cog = 0;
483  ip_connexities_list.clear();
484  ip_edges_list.clear();
485 
486  this->mean_gray_level = 0;
487 
488  if (connexe(I, (unsigned int)(u_ - k), (unsigned int)(v_), mean_gray_level, u_cog, v_cog, npoint)) {
489  sol = true;
490  u = u_ - k;
491  v = v_;
492  }
493  }
494  u_ -= k;
495  left += 2;
496 
497  for (k = 1; k <= up; k++)
498  if (sol == false) {
499  u_cog = 0;
500  v_cog = 0;
501  ip_connexities_list.clear();
502  ip_edges_list.clear();
503 
504  this->mean_gray_level = 0;
505 
506  if (connexe(I, (unsigned int)(u_), (unsigned int)(v_ - k), mean_gray_level, u_cog, v_cog, npoint)) {
507  sol = true;
508  u = u_;
509  v = v_ - k;
510  }
511  }
512  v_ -= k;
513  up += 2;
514  }
515 
516  if (sol == false) {
517  // vpERROR_TRACE("Dot has been lost") ;
518  throw(vpTrackingException(vpTrackingException::featureLostError, "Dot has been lost"));
519  }
520  }
521 
522 #endif
523  /*
524  vpImagePoint ip;
525  unsigned int i, j;
526  std::list<vpImagePoint>::iterator it;
527  for (it = ip_connexities_list.begin(); it != ip_connexities_list.end(); it
528  ++) { ip = *it; i = (unsigned int) ip.get_i(); j = (unsigned int)
529  ip.get_j(); I[i][j] = 255 ;
530  }*/
531 
532  u_cog = u_cog / npoint;
533  v_cog = v_cog / npoint;
534 
535  u = u_cog;
536  v = v_cog;
537 
538  // Initialize the threshold for the next call to track()
539  double Ip = pow((double)this->mean_gray_level / 255, 1 / gamma);
540 
541  if (Ip - (1 - grayLevelPrecision) < 0) {
542  gray_level_min = 0;
543  }
544  else {
545  gray_level_min = (unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
546  if (gray_level_min > 255)
547  gray_level_min = 255;
548  }
549  gray_level_max = (unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
550  if (gray_level_max > 255)
551  gray_level_max = 255;
552 
553  // vpCTRACE << "gray_level_min: " << gray_level_min << std::endl;
554  // vpCTRACE << "gray_level_max: " << gray_level_max << std::endl;
555 
556  if (npoint < 5) {
557  // vpERROR_TRACE("Dot to small") ;
559  }
560 
561  if (npoint > nbMaxPoint) {
563  "Too many point %lf (%lf%%). Max allowed is "
564  "%lf (%lf%%). This threshold can be modified "
565  "using the setMaxDotSize() method.",
566  npoint, npoint / (I.getWidth() * I.getHeight()), nbMaxPoint, maxDotSizePercentage));
567  }
568 }
569 
582 void vpDot::setMaxDotSize(double percentage)
583 {
584  if (percentage <= 0.0 || percentage > 1.0) {
585  // print a warning. We keep the default percentage
586  vpTRACE("Max dot size percentage is requested to be set to %lf.",
587  "Value should be in ]0:1]. Value will be set to %lf.", percentage, maxDotSizePercentage);
588  }
589  else {
590  maxDotSizePercentage = percentage;
591  }
592 }
593 
618 {
619  while (vpDisplay::getClick(I, cog) != true)
620  ;
621 
622  unsigned int i = (unsigned int)cog.get_i();
623  unsigned int j = (unsigned int)cog.get_j();
624 
625  double Ip = pow((double)I[i][j] / 255, 1 / gamma);
626 
627  if (Ip - (1 - grayLevelPrecision) < 0) {
628  gray_level_min = 0;
629  }
630  else {
631  gray_level_min = (unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
632  if (gray_level_min > 255)
633  gray_level_min = 255;
634  }
635  gray_level_max = (unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
636  if (gray_level_max > 255)
637  gray_level_max = 255;
638 
639  try {
640  track(I);
641  }
642  catch (const vpException &e) {
643  throw(e);
644  }
645 }
646 
671 {
672 
673  cog = ip;
674 
675  unsigned int i = (unsigned int)cog.get_i();
676  unsigned int j = (unsigned int)cog.get_j();
677 
678  double Ip = pow((double)I[i][j] / 255, 1 / gamma);
679 
680  if (Ip - (1 - grayLevelPrecision) < 0) {
681  gray_level_min = 0;
682  }
683  else {
684  gray_level_min = (unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
685  if (gray_level_min > 255)
686  gray_level_min = 255;
687  }
688  gray_level_max = (unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
689  if (gray_level_max > 255)
690  gray_level_max = 255;
691  try {
692  track(I);
693  }
694  catch (const vpException &e) {
695  throw(e);
696  }
697 }
698 
726 void vpDot::initTracking(const vpImage<unsigned char> &I, const vpImagePoint &ip, unsigned int level_min,
727  unsigned int level_max)
728 {
729 
730  cog = ip;
731 
732  this->gray_level_min = level_min;
733  this->gray_level_max = level_max;
734 
735  try {
736  track(I);
737  }
738  catch (const vpException &e) {
739  throw(e);
740  }
741 }
742 
758 {
759  try {
760  setGrayLevelOut();
761  double u = this->cog.get_u();
762  double v = this->cog.get_v();
763 
764  COG(I, u, v);
765 
766  this->cog.set_u(u);
767  this->cog.set_v(v);
768 
769  if (compute_moment == true) {
770  mu11 = m11 - u * m01;
771  mu02 = m02 - v * m01;
772  mu20 = m20 - u * m10;
773  }
774 
775  if (graphics) {
776  // display a red cross at the center of gravity's location in the image.
777  vpDisplay::displayCross(I, this->cog, 3 * thickness + 8, vpColor::red, thickness);
778  }
779 
780  }
781  catch (const vpException &e) {
782  throw(e);
783  }
784 }
785 
801 {
802  track(I);
803 
804  ip = this->cog;
805 }
806 
814 void vpDot::display(const vpImage<unsigned char> &I, vpColor color, unsigned int thick) const
815 {
816  vpDisplay::displayCross(I, cog, 3 * thickness + 8, color, thick);
817  std::list<vpImagePoint>::const_iterator it;
818 
819  for (it = ip_edges_list.begin(); it != ip_edges_list.end(); ++it) {
820  vpDisplay::displayPoint(I, *it, color);
821  }
822 }
823 
842 void vpDot::setGrayLevelPrecision(const double &precision)
843 {
844  double epsilon = 0.05;
845  if (grayLevelPrecision < epsilon) {
846  this->grayLevelPrecision = epsilon;
847  }
848  else if (grayLevelPrecision > 1) {
849  this->grayLevelPrecision = 1.0;
850  }
851  else {
852  this->grayLevelPrecision = precision;
853  }
854 }
855 
870 void vpDot::display(const vpImage<unsigned char> &I, const vpImagePoint &cog, const std::list<vpImagePoint> &edges_list,
871  vpColor color, unsigned int thickness)
872 {
873  vpDisplay::displayCross(I, cog, 3 * thickness + 8, color, thickness);
874  std::list<vpImagePoint>::const_iterator it;
875 
876  for (it = edges_list.begin(); it != edges_list.end(); ++it) {
877  vpDisplay::displayPoint(I, *it, color);
878  }
879 }
880 
895 void vpDot::display(const vpImage<vpRGBa> &I, const vpImagePoint &cog, const std::list<vpImagePoint> &edges_list,
896  vpColor color, unsigned int thickness)
897 {
898  vpDisplay::displayCross(I, cog, 3 * thickness + 8, color, thickness);
899  std::list<vpImagePoint>::const_iterator it;
900 
901  for (it = edges_list.begin(); it != edges_list.end(); ++it) {
902  vpDisplay::displayPoint(I, *it, color);
903  }
904 }
905 
911 VISP_EXPORT std::ostream &operator<<(std::ostream &os, vpDot &d) { return (os << "(" << d.getCog() << ")"); };
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
Definition: vpArray2D.h:504
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:152
static const vpColor red
Definition: vpColor.h:211
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
This tracker is meant to track a dot (connected pixels with same gray level) on a vpImage.
Definition: vpDot.h:112
void setMaxDotSize(double percentage)
Definition: vpDot.cpp:582
double mu02
Definition: vpDot.h:184
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1) const
Definition: vpDot.cpp:814
double m10
Definition: vpDot.h:146
bool operator!=(const vpDot &d) const
Definition: vpDot.cpp:168
void initTracking(const vpImage< unsigned char > &I)
Definition: vpDot.cpp:617
double mu11
Definition: vpDot.h:174
double m01
Definition: vpDot.h:139
vpDot()
Definition: vpDot.cpp:91
vpDot & operator=(const vpDot &d)
Copy operator.
Definition: vpDot.cpp:130
double mu20
Definition: vpDot.h:179
void setGrayLevelPrecision(const double &grayLevelPrecision)
Definition: vpDot.cpp:842
virtual ~vpDot() override
Destructor.
Definition: vpDot.cpp:125
double m11
Definition: vpDot.h:153
double m02
Definition: vpDot.h:167
static const unsigned int SPIRAL_SEARCH_SIZE
Definition: vpDot.h:130
double m00
Definition: vpDot.h:132
double m20
Definition: vpDot.h:160
@ CONNEXITY_8
Definition: vpDot.h:121
@ CONNEXITY_4
Definition: vpDot.h:119
bool operator==(const vpDot &d) const
Definition: vpDot.cpp:170
void track(const vpImage< unsigned char > &I)
Definition: vpDot.cpp:757
error that can be emitted by ViSP classes.
Definition: vpException.h:59
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
double get_j() const
Definition: vpImagePoint.h:125
double get_u() const
Definition: vpImagePoint.h:136
void set_u(double u)
Definition: vpImagePoint.h:320
void set_v(double v)
Definition: vpImagePoint.h:331
double get_i() const
Definition: vpImagePoint.h:114
double get_v() const
Definition: vpImagePoint.h:147
unsigned int getWidth() const
Definition: vpImage.h:240
unsigned int getHeight() const
Definition: vpImage.h:182
Class that defines what is a feature generic tracker.
Definition: vpTracker.h:59
Error that can be emitted by the vpTracker class and its derivatives.
@ featureLostError
Tracker lost feature.
@ initializationError
Tracker initialization error.
#define vpTRACE
Definition: vpDebug.h:411