44#include <visp3/blob/vpDot.h>
45#include <visp3/core/vpColor.h>
46#include <visp3/core/vpDisplay.h>
47#include <visp3/core/vpTrackingException.h>
70 compute_moment =
false;
73 maxDotSizePercentage = 0.25;
78 grayLevelPrecision = 0.85;
85 u_min = u_max = v_min = v_max = 0;
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)
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)
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)
132 ip_edges_list = d.ip_edges_list;
133 ip_connexities_list = d.ip_connexities_list;
134 connexityType = d.connexityType;
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;
151 compute_moment = d.compute_moment;
152 nbMaxPoint = d.nbMaxPoint;
183void vpDot::setGrayLevelOut()
185 if (gray_level_min == 0) {
186 if (gray_level_max == 255) {
191 gray_level_out =
static_cast<unsigned char>(gray_level_max + 1u);
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)
216 return connexe(I, u, v, mean_value, u_cog, v_cog, n, checkTab);
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)
243 if ((u >= width) || (v >= height)) {
255 if (I[v][u] >= gray_level_min && I[v][u] <= gray_level_max) {
256 checkTab[v * I.
getWidth() + u] =
true;
258 ip_connexities_list.push_back(ip);
264 if (n > nbMaxPoint) {
266 "Too many point %lf (%lf%% of image size). "
267 "This threshold can be modified using the setMaxDotSize() "
283 mean_value = (mean_value * (n - 1) + I[v][u]) / n;
284 if (compute_moment ==
true) {
302 if (!checkTab[u - 1 + v * I.
getWidth()])
303 if (!connexe(I, u - 1, v, mean_value, u_cog, v_cog, n, checkTab))
307 if (!checkTab[u + 1 + v * I.
getWidth()])
308 if (!connexe(I, u + 1, v, mean_value, u_cog, v_cog, n, checkTab))
312 if (!checkTab[u + (v - 1) * I.
getWidth()])
313 if (!connexe(I, u, v - 1, mean_value, u_cog, v_cog, n, checkTab))
317 if (!checkTab[u + (v + 1) * I.
getWidth()])
318 if (!connexe(I, u, v + 1, mean_value, u_cog, v_cog, n, checkTab))
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))
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))
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))
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))
344 ip_edges_list.push_back(ip);
345 if (graphics ==
true) {
347 for (
unsigned int t = 0; t < thickness; t++) {
348 ip_.set_u(ip.
get_u() + t);
391 this->mean_gray_level = 0;
393 ip_connexities_list.clear();
394 ip_edges_list.clear();
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) {
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) {
414 ip_connexities_list.clear();
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;
427 "Dot has been lost"));
432 if (!connexe(I, (
unsigned int)u, (
unsigned int)v, mean_gray_level, u_cog, v_cog, npoint)) {
435 unsigned int right = 1;
436 unsigned int botom = 1;
437 unsigned int left = 2;
439 double u_ = u, v_ = v;
444 for (k = 1; k <= right; k++)
448 ip_connexities_list.clear();
449 ip_edges_list.clear();
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)) {
461 for (k = 1; k <= botom; k++)
465 ip_connexities_list.clear();
466 ip_edges_list.clear();
468 this->mean_gray_level = 0;
470 if (connexe(I, (
unsigned int)(u_), (
unsigned int)(v_ + k), mean_gray_level, u_cog, v_cog, npoint)) {
479 for (k = 1; k <= left; k++)
483 ip_connexities_list.clear();
484 ip_edges_list.clear();
486 this->mean_gray_level = 0;
488 if (connexe(I, (
unsigned int)(u_ - k), (
unsigned int)(v_), mean_gray_level, u_cog, v_cog, npoint)) {
497 for (k = 1; k <= up; k++)
501 ip_connexities_list.clear();
502 ip_edges_list.clear();
504 this->mean_gray_level = 0;
506 if (connexe(I, (
unsigned int)(u_), (
unsigned int)(v_ - k), mean_gray_level, u_cog, v_cog, npoint)) {
532 u_cog = u_cog / npoint;
533 v_cog = v_cog / npoint;
539 double Ip = pow((
double)this->mean_gray_level / 255, 1 / gamma);
541 if (Ip - (1 - grayLevelPrecision) < 0) {
545 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
546 if (gray_level_min > 255)
547 gray_level_min = 255;
549 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
550 if (gray_level_max > 255)
551 gray_level_max = 255;
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));
584 if (percentage <= 0.0 || percentage > 1.0) {
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);
590 maxDotSizePercentage = percentage;
622 unsigned int i = (
unsigned int)cog.
get_i();
623 unsigned int j = (
unsigned int)cog.
get_j();
625 double Ip = pow((
double)I[i][j] / 255, 1 / gamma);
627 if (Ip - (1 - grayLevelPrecision) < 0) {
631 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
632 if (gray_level_min > 255)
633 gray_level_min = 255;
635 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
636 if (gray_level_max > 255)
637 gray_level_max = 255;
675 unsigned int i = (
unsigned int)cog.
get_i();
676 unsigned int j = (
unsigned int)cog.
get_j();
678 double Ip = pow((
double)I[i][j] / 255, 1 / gamma);
680 if (Ip - (1 - grayLevelPrecision) < 0) {
684 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
685 if (gray_level_min > 255)
686 gray_level_min = 255;
688 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
689 if (gray_level_max > 255)
690 gray_level_max = 255;
727 unsigned int level_max)
732 this->gray_level_min = level_min;
733 this->gray_level_max = level_max;
761 double u = this->cog.
get_u();
762 double v = this->cog.
get_v();
769 if (compute_moment ==
true) {
817 std::list<vpImagePoint>::const_iterator it;
819 for (it = ip_edges_list.begin(); it != ip_edges_list.end(); ++it) {
844 double epsilon = 0.05;
845 if (grayLevelPrecision < epsilon) {
846 this->grayLevelPrecision = epsilon;
848 else if (grayLevelPrecision > 1) {
849 this->grayLevelPrecision = 1.0;
852 this->grayLevelPrecision = precision;
871 vpColor color,
unsigned int thickness)
874 std::list<vpImagePoint>::const_iterator it;
876 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
896 vpColor color,
unsigned int thickness)
899 std::list<vpImagePoint>::const_iterator it;
901 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
911VISP_EXPORT std::ostream &operator<<(std::ostream &os,
vpDot &d) {
return (os <<
"(" << d.getCog() <<
")"); };
Class to define RGB colors available for display functionalities.
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.
void setMaxDotSize(double percentage)
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1) const
bool operator!=(const vpDot &d) const
void initTracking(const vpImage< unsigned char > &I)
vpDot & operator=(const vpDot &d)
Copy operator.
void setGrayLevelPrecision(const double &grayLevelPrecision)
virtual ~vpDot()
Destructor.
static const unsigned int SPIRAL_SEARCH_SIZE
bool operator==(const vpDot &d) const
void track(const vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getHeight() const
Class that defines what is a feature generic tracker.
Error that can be emitted by the vpTracker class and its derivatives.
@ featureLostError
Tracker lost feature.
@ initializationError
Tracker initialization error.