Visual Servoing Platform  version 3.6.1 under development (2024-04-25)
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 = 0;
82  m11 = 0;
83  m02 = 0;
84  m20 = 0;
85  m10 = 0;
86  m01 = 0;
87  mu11 = 0;
88  mu02 = 0;
89  mu20 = 0;
90 
91  connexityType = CONNEXITY_4;
92 
93  u_min = 0;
94  u_max = 0;
95  v_min = 0;
96  v_max = 0;
97 
98  gray_level_out = 0;
99  nbMaxPoint = 0;
100 }
101 
103  : m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), ip_connexities_list(),
104  ip_edges_list(), connexityType(CONNEXITY_4), cog(), u_min(0), u_max(0), v_min(0), v_max(0), graphics(false),
105  thickness(1), maxDotSizePercentage(0.25), gray_level_out(0), mean_gray_level(0), gray_level_min(128),
106  gray_level_max(255), grayLevelPrecision(0.85), gamma(1.5), compute_moment(false), nbMaxPoint(0)
107 { }
108 
115  : m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), ip_connexities_list(),
116  ip_edges_list(), connexityType(CONNEXITY_4), cog(ip), u_min(0), u_max(0), v_min(0), v_max(0), graphics(false),
117  thickness(1), maxDotSizePercentage(0.25), gray_level_out(0), mean_gray_level(0), gray_level_min(128),
118  gray_level_max(255), grayLevelPrecision(0.85), gamma(1.5), compute_moment(false), nbMaxPoint(0)
119 { }
120 
125  : vpTracker(d), m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.),
126  ip_connexities_list(), ip_edges_list(), connexityType(CONNEXITY_4), cog(), u_min(0), u_max(0), v_min(0), v_max(0),
127  graphics(false), thickness(1), maxDotSizePercentage(0.25), gray_level_out(0), mean_gray_level(0),
128  gray_level_min(128), gray_level_max(255), grayLevelPrecision(0.85), gamma(1.5), compute_moment(false), nbMaxPoint(0)
129 {
130  *this = d;
131 }
132 
136 vpDot::~vpDot() { ip_connexities_list.clear(); }
137 
142 {
143  ip_edges_list = d.ip_edges_list;
144  ip_connexities_list = d.ip_connexities_list;
145  connexityType = d.connexityType;
146  cog = d.getCog();
147 
148  u_min = d.u_min;
149  v_min = d.v_min;
150  u_max = d.u_max;
151  v_max = d.v_max;
152 
153  graphics = d.graphics;
154  thickness = d.thickness;
155  maxDotSizePercentage = d.maxDotSizePercentage;
156  gray_level_out = d.gray_level_out;
157  mean_gray_level = d.mean_gray_level;
158  gray_level_min = d.gray_level_min;
159  gray_level_max = d.gray_level_max;
160  grayLevelPrecision = d.grayLevelPrecision;
161  gamma = d.gamma;
162  compute_moment = d.compute_moment;
163  nbMaxPoint = d.nbMaxPoint;
164 
165  m00 = d.m00;
166  m01 = d.m01;
167  m10 = d.m10;
168  m11 = d.m11;
169  m02 = d.m02;
170  m20 = d.m20;
171 
172  mu11 = d.mu11;
173  mu20 = d.mu20;
174  mu02 = d.mu02;
175 
176  return *this;
177 }
178 
179 bool vpDot::operator!=(const vpDot &d) const { return (cog != d.getCog()); }
180 
181 bool vpDot::operator==(const vpDot &d) const { return (cog == d.getCog()); }
182 
194 void vpDot::setGrayLevelOut()
195 {
196  if (gray_level_min == 0) {
197  if (gray_level_max == 255) {
198  // gray_level_min = 0 and gray_level_max = 255: this should not occur
199  // vpERROR_TRACE("Unable to choose a good \"out\" level") ;
200  throw(vpTrackingException(vpTrackingException::initializationError, "Unable to choose a good \"out\" level"));
201  }
202  gray_level_out = static_cast<unsigned char>(gray_level_max + 1u);
203  }
204 }
205 
223 bool vpDot::connexe(const vpImage<unsigned char> &I, unsigned int u, unsigned int v, double &mean_value, double &u_cog,
224  double &v_cog, double &n)
225 {
226  std::vector<bool> checkTab(I.getWidth() * I.getHeight(), false);
227  return connexe(I, u, v, mean_value, u_cog, v_cog, n, checkTab);
228 }
246 bool vpDot::connexe(const vpImage<unsigned char> &I, unsigned int u, unsigned int v, double &mean_value, double &u_cog,
247  double &v_cog, double &n, std::vector<bool> &checkTab)
248 {
249 
250  unsigned int width = I.getWidth();
251  unsigned int height = I.getHeight();
252 
253  // Test if we are in the image
254  if ((u >= width) || (v >= height)) {
255  return false;
256  }
257 
258  if (checkTab[u + (v * I.getWidth())]) {
259  return true;
260  }
261 
262  vpImagePoint ip;
263  ip.set_u(u);
264  ip.set_v(v);
265 
266  if ((I[v][u] >= gray_level_min) && (I[v][u] <= gray_level_max)) {
267  checkTab[(v * I.getWidth()) + u] = true;
268 
269  ip_connexities_list.push_back(ip);
270 
271  u_cog += u;
272  v_cog += v;
273  n += 1;
274 
275  if (n > nbMaxPoint) {
277  "Too many point %lf (%lf%% of image size). "
278  "This threshold can be modified using the setMaxDotSize() "
279  "method.",
280  n, n / (I.getWidth() * I.getHeight()), nbMaxPoint, maxDotSizePercentage));
281  }
282 
283  // Bounding box update
284  if (u < this->u_min) {
285  this->u_min = u;
286  }
287  if (u > this->u_max) {
288  this->u_max = u;
289  }
290  if (v < this->v_min) {
291  this->v_min = v;
292  }
293  if (v > this->v_max) {
294  this->v_max = v;
295  }
296 
297  // Mean value of the dot intensities
298  mean_value = ((mean_value * (n - 1)) + I[v][u]) / n;
299  if (compute_moment == true) {
300  ++m00;
301  m10 += u;
302  m01 += v;
303  m11 += (u * v);
304  m20 += u * u;
305  m02 += v * v;
306  }
307  }
308  else {
309  return false;
310  }
311 
312  bool edge = false;
313 
314  if (u >= 1) {
315  if (!checkTab[(u - 1) + (v * I.getWidth())]) {
316  if (!connexe(I, u - 1, v, mean_value, u_cog, v_cog, n, checkTab)) {
317  edge = true;
318  }
319  }
320  }
321 
322  if ((u + 1) < I.getWidth()) {
323  if (!checkTab[u + 1 + (v * I.getWidth())]) {
324  if (!connexe(I, u + 1, v, mean_value, u_cog, v_cog, n, checkTab)) {
325  edge = true;
326  }
327  }
328  }
329 
330  if (v >= 1) {
331  if (!checkTab[u + ((v - 1) * I.getWidth())]) {
332  if (!connexe(I, u, v - 1, mean_value, u_cog, v_cog, n, checkTab)) {
333  edge = true;
334  }
335  }
336  }
337 
338  if ((v + 1) < I.getHeight()) {
339  if (!checkTab[u + ((v + 1) * I.getWidth())]) {
340  if (!connexe(I, u, v + 1, mean_value, u_cog, v_cog, n, checkTab)) {
341  edge = true;
342  }
343  }
344  }
345 
346  if (connexityType == CONNEXITY_8) {
347  if ((v >= 1) && (u >= 1)) {
348  if (!checkTab[(u - 1) + ((v - 1) * I.getWidth())]) {
349  if (!connexe(I, u - 1, v - 1, mean_value, u_cog, v_cog, n, checkTab)) {
350  edge = true;
351  }
352  }
353  }
354 
355  if ((v >= 1) && ((u + 1) < I.getWidth())) {
356  if (!checkTab[u + 1 + ((v - 1) * I.getWidth())]) {
357  if (!connexe(I, u + 1, v - 1, mean_value, u_cog, v_cog, n, checkTab)) {
358  edge = true;
359  }
360  }
361  }
362 
363  if (((v + 1) < I.getHeight()) && (u >= 1)) {
364  if (!checkTab[(u - 1) + ((v + 1) * I.getWidth())]) {
365  if (!connexe(I, u - 1, v + 1, mean_value, u_cog, v_cog, n, checkTab)) {
366  edge = true;
367  }
368  }
369  }
370 
371  if (((v + 1) < I.getHeight()) && ((u + 1) < I.getWidth())) {
372  if (!checkTab[u + 1 + ((v + 1) * I.getWidth())]) {
373  if (!connexe(I, u + 1, v + 1, mean_value, u_cog, v_cog, n, checkTab)) {
374  edge = true;
375  }
376  }
377  }
378  }
379 
380  if (edge) {
381  ip_edges_list.push_back(ip);
382  if (graphics == true) {
383  vpImagePoint ip_(ip);
384  for (unsigned int t = 0; t < thickness; ++t) {
385  ip_.set_u(ip.get_u() + t);
387  }
388  // --comment: use vpDisplay to flush I
389  }
390  }
391 
392  return true;
393 }
394 
414 void vpDot::COG(const vpImage<unsigned char> &I, double &u, double &v)
415 {
416  // Set the maximal number of points considering the maximal dot size
417  // image percentage
418  nbMaxPoint = (I.getWidth() * I.getHeight()) * maxDotSizePercentage;
419 
420  // segmentation de l'image apres seuillage
421  // (etiquetage des composante connexe)
422  if (compute_moment) {
423  m00 = 0;
424  m11 = 0;
425  m02 = 0;
426  m20 = 0;
427  m10 = 0;
428  m01 = 0;
429  mu11 = 0;
430  mu20 = 0;
431  mu02 = 0;
432  }
433 
434  double u_cog = 0;
435  double v_cog = 0;
436  double npoint = 0;
437  this->mean_gray_level = 0;
438 
439  ip_connexities_list.clear();
440  ip_edges_list.clear();
441 
442  // Initialise the boundig box
443  this->u_min = I.getWidth();
444  this->u_max = 0;
445  this->v_min = I.getHeight();
446  this->v_max = 0;
447 
448 #if 0
449  // Original version
450  if (connexe(I, (unsigned int)u, (unsigned int)v,
451  gray_level_min, gray_level_max,
452  mean_gray_level, u_cog, v_cog, npoint) == vpDot::out) {
453  bool sol = false;
454  unsigned int pas;
455  for (pas = 2; pas <= 25; ++pas)if (sol==false) {
456  for (int k = -1; k <=1; ++k) if (sol==false)
457  for (int l = -1; l <=1; ++l) if (sol==false) {
458  u_cog = 0;
459  v_cog = 0;
460  ip_connexities_list.clear();
461 
462  this->mean_gray_level = 0;
463  if (connexe(I, (unsigned int)(u+k*pas), (unsigned int)(v+l*pas),
464  gray_level_min, gray_level_max,
465  mean_gray_level, u_cog, v_cog, npoint) != vpDot::out) {
466  sol = true; u += k*pas; v += l*pas;
467  }
468  }
469  }
470  if (sol == false) {
471  //vpERROR_TRACE("Dot has been lost") ;
473  "Dot has been lost"));
474  }
475  }
476 #else
477  // If the dot is not found, search around using a spiral
478  if (!connexe(I, static_cast<unsigned int>(u), static_cast<unsigned int>(v), mean_gray_level, u_cog, v_cog, npoint)) {
479  bool sol = false;
480 
481  unsigned int right = 1;
482  unsigned int botom = 1;
483  unsigned int left = 2;
484  unsigned int up = 2;
485  double u_ = u, v_ = v;
486  unsigned int k;
487 
488  // Spiral search from the center to find the nearest dot
489  while ((right < SPIRAL_SEARCH_SIZE) && (sol == false)) {
490  for (k = 1; k <= right; ++k) {
491  if (sol == false) {
492  u_cog = 0;
493  v_cog = 0;
494  ip_connexities_list.clear();
495  ip_edges_list.clear();
496 
497  this->mean_gray_level = 0;
498  if (connexe(I, static_cast<unsigned int>(u_) + k, static_cast<unsigned int>(v_), mean_gray_level, u_cog, v_cog, npoint)) {
499  sol = true;
500  u = u_ + k;
501  v = v_;
502  }
503  }
504  }
505  u_ += k;
506  right += 2;
507 
508  for (k = 1; k <= botom; ++k) {
509  if (sol == false) {
510  u_cog = 0;
511  v_cog = 0;
512  ip_connexities_list.clear();
513  ip_edges_list.clear();
514 
515  this->mean_gray_level = 0;
516 
517  if (connexe(I, static_cast<unsigned int>(u_), static_cast<unsigned int>(v_ + k), mean_gray_level, u_cog, v_cog, npoint)) {
518  sol = true;
519  u = u_;
520  v = v_ + k;
521  }
522  }
523  }
524  v_ += k;
525  botom += 2;
526 
527  for (k = 1; k <= left; ++k) {
528  if (sol == false) {
529  u_cog = 0;
530  v_cog = 0;
531  ip_connexities_list.clear();
532  ip_edges_list.clear();
533 
534  this->mean_gray_level = 0;
535 
536  if (connexe(I, static_cast<unsigned int>(u_ - k), static_cast<unsigned int>(v_), mean_gray_level, u_cog, v_cog, npoint)) {
537  sol = true;
538  u = u_ - k;
539  v = v_;
540  }
541  }
542  }
543  u_ -= k;
544  left += 2;
545 
546  for (k = 1; k <= up; ++k) {
547  if (sol == false) {
548  u_cog = 0;
549  v_cog = 0;
550  ip_connexities_list.clear();
551  ip_edges_list.clear();
552 
553  this->mean_gray_level = 0;
554 
555  if (connexe(I, static_cast<unsigned int>(u_), static_cast<unsigned int>(v_ - k), mean_gray_level, u_cog, v_cog, npoint)) {
556  sol = true;
557  u = u_;
558  v = v_ - k;
559  }
560  }
561  }
562  v_ -= k;
563  up += 2;
564  }
565 
566  if (sol == false) {
567  // vpERROR_TRACE("Dot has been lost") ;
568  throw(vpTrackingException(vpTrackingException::featureLostError, "Dot has been lost"));
569  }
570  }
571 
572 #endif
573  /*
574  vpImagePoint ip;
575  unsigned int i, j;
576  std::list<vpImagePoint>::iterator it;
577  for (it = ip_connexities_list.begin(); it != ip_connexities_list.end(); it
578  ++) { ip = *it; i = (unsigned int) ip.get_i(); j = (unsigned int)
579  ip.get_j(); I[i][j] = 255 ;
580  }*/
581 
582  u_cog = u_cog / npoint;
583  v_cog = v_cog / npoint;
584 
585  u = u_cog;
586  v = v_cog;
587 
588  // Initialize the threshold for the next call to track()
589  double Ip = pow((double)this->mean_gray_level / 255, 1 / gamma);
590 
591  if ((Ip - (1 - grayLevelPrecision)) < 0) {
592  gray_level_min = 0;
593  }
594  else {
595  gray_level_min = static_cast<unsigned int>(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
596  if (gray_level_min > 255) {
597  gray_level_min = 255;
598  }
599  }
600  gray_level_max = static_cast<unsigned int>(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
601  if (gray_level_max > 255) {
602  gray_level_max = 255;
603  }
604 
605  // --comment: trace the gray level
606 
607  if (npoint < 5) {
608  // --comment: trace the error using vpERROR_TRACE "Dot to small"
610  }
611 
612  if (npoint > nbMaxPoint) {
614  "Too many point %lf (%lf%%). Max allowed is "
615  "%lf (%lf%%). This threshold can be modified "
616  "using the setMaxDotSize() method.",
617  npoint, npoint / (I.getWidth() * I.getHeight()), nbMaxPoint, maxDotSizePercentage));
618  }
619 }
620 
633 void vpDot::setMaxDotSize(double percentage)
634 {
635  if ((percentage <= 0.0) || (percentage > 1.0)) {
636  // print a warning. We keep the default percentage
637  vpTRACE("Max dot size percentage is requested to be set to %lf.",
638  "Value should be in ]0:1]. Value will be set to %lf.", percentage, maxDotSizePercentage);
639  }
640  else {
641  maxDotSizePercentage = percentage;
642  }
643 }
644 
669 {
670  while (vpDisplay::getClick(I, cog) != true)
671  ;
672 
673  unsigned int i = static_cast<unsigned int>(cog.get_i());
674  unsigned int j = static_cast<unsigned int>(cog.get_j());
675 
676  double Ip = pow((double)I[i][j] / 255, 1 / gamma);
677 
678  if ((Ip - (1 - grayLevelPrecision)) < 0) {
679  gray_level_min = 0;
680  }
681  else {
682  gray_level_min = static_cast<unsigned int>(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
683  if (gray_level_min > 255) {
684  gray_level_min = 255;
685  }
686  }
687  gray_level_max = static_cast<unsigned int>(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
688  if (gray_level_max > 255) {
689  gray_level_max = 255;
690  }
691 
692  track(I);
693 }
694 
719 {
720 
721  cog = ip;
722 
723  unsigned int i = static_cast<unsigned int>(cog.get_i());
724  unsigned int j = static_cast<unsigned int>(cog.get_j());
725 
726  double Ip = pow((double)I[i][j] / 255, 1 / gamma);
727 
728  if ((Ip - (1 - grayLevelPrecision)) < 0) {
729  gray_level_min = 0;
730  }
731  else {
732  gray_level_min = static_cast<unsigned int>(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
733  if (gray_level_min > 255) {
734  gray_level_min = 255;
735  }
736  }
737  gray_level_max = static_cast<unsigned int>(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
738  if (gray_level_max > 255) {
739  gray_level_max = 255;
740  }
741 
742  track(I);
743 }
744 
772 void vpDot::initTracking(const vpImage<unsigned char> &I, const vpImagePoint &ip, unsigned int level_min,
773  unsigned int level_max)
774 {
775 
776  cog = ip;
777 
778  this->gray_level_min = level_min;
779  this->gray_level_max = level_max;
780 
781  track(I);
782 }
783 
799 {
800  setGrayLevelOut();
801  double u = this->cog.get_u();
802  double v = this->cog.get_v();
803 
804  COG(I, u, v);
805 
806  this->cog.set_u(u);
807  this->cog.set_v(v);
808 
809  if (compute_moment == true) {
810  mu11 = m11 - (u * m01);
811  mu02 = m02 - (v * m01);
812  mu20 = m20 - (u * m10);
813  }
814 
815  if (graphics) {
816  // display a red cross at the center of gravity's location in the image.
817  vpDisplay::displayCross(I, this->cog, (3 * thickness) + 8, vpColor::red, thickness);
818  }
819 }
820 
836 {
837  track(I);
838 
839  ip = this->cog;
840 }
841 
849 void vpDot::display(const vpImage<unsigned char> &I, vpColor color, unsigned int thick) const
850 {
851  vpDisplay::displayCross(I, cog, (3 * thickness) + 8, color, thick);
852  std::list<vpImagePoint>::const_iterator it;
853 
854  std::list<vpImagePoint>::const_iterator ip_edges_list_end = ip_edges_list.end();
855  for (it = ip_edges_list.begin(); it != ip_edges_list_end; ++it) {
856  vpDisplay::displayPoint(I, *it, color);
857  }
858 }
859 
878 void vpDot::setGrayLevelPrecision(const double &precision)
879 {
880  double epsilon = 0.05;
881  if (grayLevelPrecision < epsilon) {
882  this->grayLevelPrecision = epsilon;
883  }
884  else if (grayLevelPrecision > 1) {
885  this->grayLevelPrecision = 1.0;
886  }
887  else {
888  this->grayLevelPrecision = precision;
889  }
890 }
891 
906 void vpDot::display(const vpImage<unsigned char> &I, const vpImagePoint &cog, const std::list<vpImagePoint> &edges_list,
907  vpColor color, unsigned int thickness)
908 {
909  vpDisplay::displayCross(I, cog, (3 * thickness) + 8, color, thickness);
910  std::list<vpImagePoint>::const_iterator it;
911 
912  std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
913  for (it = edges_list.begin(); it != edges_list_end; ++it) {
914  vpDisplay::displayPoint(I, *it, color);
915  }
916 }
917 
932 void vpDot::display(const vpImage<vpRGBa> &I, const vpImagePoint &cog, const std::list<vpImagePoint> &edges_list,
933  vpColor color, unsigned int thickness)
934 {
935  vpDisplay::displayCross(I, cog, (3 * thickness) + 8, color, thickness);
936  std::list<vpImagePoint>::const_iterator it;
937 
938  std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
939  for (it = edges_list.begin(); it != edges_list_end; ++it) {
940  vpDisplay::displayPoint(I, *it, color);
941  }
942 }
943 
949 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:600
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:633
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:849
double m10
Definition: vpDot.h:146
bool operator!=(const vpDot &d) const
Definition: vpDot.cpp:179
void initTracking(const vpImage< unsigned char > &I)
Definition: vpDot.cpp:668
double mu11
Definition: vpDot.h:174
double m01
Definition: vpDot.h:139
vpDot()
Definition: vpDot.cpp:102
vpDot & operator=(const vpDot &d)
Copy operator.
Definition: vpDot.cpp:141
double mu20
Definition: vpDot.h:179
void setGrayLevelPrecision(const double &grayLevelPrecision)
Definition: vpDot.cpp:878
double m11
Definition: vpDot.h:153
virtual ~vpDot() vp_override
Destructor.
Definition: vpDot.cpp:136
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:181
void track(const vpImage< unsigned char > &I)
Definition: vpDot.cpp:798
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:330
void set_v(double v)
Definition: vpImagePoint.h:341
double get_i() const
Definition: vpImagePoint.h:114
double get_v() const
Definition: vpImagePoint.h:147
unsigned int getWidth() const
Definition: vpImage.h:245
unsigned int getHeight() const
Definition: vpImage.h:184
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:405