Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
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 */
57const unsigned int vpDot::SPIRAL_SEARCH_SIZE = 350;
58
65void 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
125vpDot::~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
168bool vpDot::operator!=(const vpDot &d) const { return (cog != d.getCog()); }
169
170bool vpDot::operator==(const vpDot &d) const { return (cog == d.getCog()); }
171
183void 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
212bool 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}
235bool 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
377void 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") ;
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
582void 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
726void 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
814void 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
842void 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
870void 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
895void 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
911VISP_EXPORT std::ostream &operator<<(std::ostream &os, vpDot &d) { return (os << "(" << d.getCog() << ")"); };
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:183
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:145
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:173
double m01
Definition vpDot.h:138
vpDot()
Definition vpDot.cpp:91
vpDot & operator=(const vpDot &d)
Copy operator.
Definition vpDot.cpp:130
double mu20
Definition vpDot.h:178
void setGrayLevelPrecision(const double &grayLevelPrecision)
Definition vpDot.cpp:842
double m11
Definition vpDot.h:152
virtual ~vpDot()
Destructor.
Definition vpDot.cpp:125
double m02
Definition vpDot.h:166
static const unsigned int SPIRAL_SEARCH_SIZE
Definition vpDot.h:129
double m00
Definition vpDot.h:131
double m20
Definition vpDot.h:159
@ CONNEXITY_8
Definition vpDot.h:120
@ CONNEXITY_4
Definition vpDot.h:118
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 ...
double get_j() const
double get_u() const
void set_u(double u)
void set_v(double v)
double get_i() const
double get_v() const
Definition of the vpImage class member functions.
Definition vpImage.h:135
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:184
Class that defines what is a feature generic tracker.
Definition vpTracker.h:60
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