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;
183 void 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);
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)
216 return connexe(I, u, v, mean_value, u_cog, v_cog, n, checkTab);
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)
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) {
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)
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() override
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 ...
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.