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;
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)
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)
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)
143 ip_edges_list = d.ip_edges_list;
144 ip_connexities_list = d.ip_connexities_list;
145 connexityType = d.connexityType;
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;
162 compute_moment = d.compute_moment;
163 nbMaxPoint = d.nbMaxPoint;
194 void vpDot::setGrayLevelOut()
196 if (gray_level_min == 0) {
197 if (gray_level_max == 255) {
202 gray_level_out =
static_cast<unsigned char>(gray_level_max + 1u);
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)
227 return connexe(I, u, v, mean_value, u_cog, v_cog, n, checkTab);
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)
254 if ((u >= width) || (v >= height)) {
258 if (checkTab[u + (v * I.
getWidth())]) {
266 if ((I[v][u] >= gray_level_min) && (I[v][u] <= gray_level_max)) {
267 checkTab[(v * I.
getWidth()) + u] =
true;
269 ip_connexities_list.push_back(ip);
275 if (n > nbMaxPoint) {
277 "Too many point %lf (%lf%% of image size). "
278 "This threshold can be modified using the setMaxDotSize() "
284 if (u < this->u_min) {
287 if (u > this->u_max) {
290 if (v < this->v_min) {
293 if (v > this->v_max) {
298 mean_value = ((mean_value * (n - 1)) + I[v][u]) / n;
299 if (compute_moment ==
true) {
315 if (!checkTab[(u - 1) + (v * I.
getWidth())]) {
316 if (!connexe(I, u - 1, v, mean_value, u_cog, v_cog, n, checkTab)) {
323 if (!checkTab[u + 1 + (v * I.
getWidth())]) {
324 if (!connexe(I, u + 1, v, mean_value, u_cog, v_cog, n, checkTab)) {
331 if (!checkTab[u + ((v - 1) * I.
getWidth())]) {
332 if (!connexe(I, u, v - 1, mean_value, u_cog, v_cog, n, checkTab)) {
339 if (!checkTab[u + ((v + 1) * I.
getWidth())]) {
340 if (!connexe(I, u, v + 1, mean_value, u_cog, v_cog, n, checkTab)) {
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)) {
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)) {
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)) {
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)) {
381 ip_edges_list.push_back(ip);
382 if (graphics ==
true) {
384 for (
unsigned int t = 0; t < thickness; ++t) {
385 ip_.set_u(ip.
get_u() + t);
422 if (compute_moment) {
437 this->mean_gray_level = 0;
439 ip_connexities_list.clear();
440 ip_edges_list.clear();
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) {
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) {
460 ip_connexities_list.clear();
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;
473 "Dot has been lost"));
478 if (!connexe(I,
static_cast<unsigned int>(u),
static_cast<unsigned int>(v), mean_gray_level, u_cog, v_cog, npoint)) {
481 unsigned int right = 1;
482 unsigned int botom = 1;
483 unsigned int left = 2;
485 double u_ = u, v_ = v;
490 for (k = 1; k <= right; ++k) {
494 ip_connexities_list.clear();
495 ip_edges_list.clear();
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)) {
508 for (k = 1; k <= botom; ++k) {
512 ip_connexities_list.clear();
513 ip_edges_list.clear();
515 this->mean_gray_level = 0;
517 if (connexe(I,
static_cast<unsigned int>(u_),
static_cast<unsigned int>(v_ + k), mean_gray_level, u_cog, v_cog, npoint)) {
527 for (k = 1; k <= left; ++k) {
531 ip_connexities_list.clear();
532 ip_edges_list.clear();
534 this->mean_gray_level = 0;
536 if (connexe(I,
static_cast<unsigned int>(u_ - k),
static_cast<unsigned int>(v_), mean_gray_level, u_cog, v_cog, npoint)) {
546 for (k = 1; k <= up; ++k) {
550 ip_connexities_list.clear();
551 ip_edges_list.clear();
553 this->mean_gray_level = 0;
555 if (connexe(I,
static_cast<unsigned int>(u_),
static_cast<unsigned int>(v_ - k), mean_gray_level, u_cog, v_cog, npoint)) {
582 u_cog = u_cog / npoint;
583 v_cog = v_cog / npoint;
589 double Ip = pow((
double)this->mean_gray_level / 255, 1 / gamma);
591 if ((Ip - (1 - grayLevelPrecision)) < 0) {
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;
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;
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));
635 if ((percentage <= 0.0) || (percentage > 1.0)) {
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);
641 maxDotSizePercentage = percentage;
673 unsigned int i =
static_cast<unsigned int>(cog.
get_i());
674 unsigned int j =
static_cast<unsigned int>(cog.
get_j());
676 double Ip = pow((
double)I[i][j] / 255, 1 / gamma);
678 if ((Ip - (1 - grayLevelPrecision)) < 0) {
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;
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;
723 unsigned int i =
static_cast<unsigned int>(cog.
get_i());
724 unsigned int j =
static_cast<unsigned int>(cog.
get_j());
726 double Ip = pow((
double)I[i][j] / 255, 1 / gamma);
728 if ((Ip - (1 - grayLevelPrecision)) < 0) {
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;
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;
773 unsigned int level_max)
778 this->gray_level_min = level_min;
779 this->gray_level_max = level_max;
801 double u = this->cog.
get_u();
802 double v = this->cog.
get_v();
809 if (compute_moment ==
true) {
852 std::list<vpImagePoint>::const_iterator it;
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) {
880 double epsilon = 0.05;
881 if (grayLevelPrecision < epsilon) {
882 this->grayLevelPrecision = epsilon;
884 else if (grayLevelPrecision > 1) {
885 this->grayLevelPrecision = 1.0;
888 this->grayLevelPrecision = precision;
907 vpColor color,
unsigned int thickness)
910 std::list<vpImagePoint>::const_iterator it;
912 std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
913 for (it = edges_list.begin(); it != edges_list_end; ++it) {
933 vpColor color,
unsigned int thickness)
936 std::list<vpImagePoint>::const_iterator it;
938 std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
939 for (it = edges_list.begin(); it != edges_list_end; ++it) {
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)
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() vp_override
Destructor.
static const unsigned int SPIRAL_SEARCH_SIZE
bool operator==(const vpDot &d) const
void track(const vpImage< unsigned char > &I)
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.