39 #include <visp3/blob/vpDot.h>
40 #include <visp3/core/vpColor.h>
41 #include <visp3/core/vpDisplay.h>
42 #include <visp3/core/vpTrackingException.h>
54 const unsigned int vpDot::SPIRAL_SEARCH_SIZE = 350;
63 const unsigned int val_max = 255;
64 const unsigned int val_median = 128;
68 m_compute_moment =
false;
71 m_maxDotSizePercentage = 0.25;
73 m_mean_gray_level = 0;
74 m_gray_level_min = val_median;
75 m_gray_level_max = val_max;
76 m_grayLevelPrecision = 0.85;
101 : m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), m_ip_connexities_list(),
102 m_ip_edges_list(), m_connexityType(CONNEXITY_4), m_cog(), m_u_min(0), m_u_max(0), m_v_min(0), m_v_max(0), m_graphics(false),
103 m_thickness(1), m_maxDotSizePercentage(0.25), m_gray_level_out(0), m_mean_gray_level(0),
104 m_grayLevelPrecision(0.85), m_gamma(1.5), m_compute_moment(false), m_nbMaxPoint(0)
106 const unsigned int val_min = 128;
107 const unsigned int val_max = 255;
108 m_gray_level_min = val_min;
109 m_gray_level_max = val_max;
118 : m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), m_ip_connexities_list(),
119 m_ip_edges_list(), m_connexityType(CONNEXITY_4), m_cog(cog), m_u_min(0), m_u_max(0), m_v_min(0), m_v_max(0), m_graphics(false),
120 m_thickness(1), m_maxDotSizePercentage(0.25), m_gray_level_out(0), m_mean_gray_level(0),
121 m_grayLevelPrecision(0.85), m_gamma(1.5), m_compute_moment(false), m_nbMaxPoint(0)
123 const unsigned int val_min = 128;
124 const unsigned int val_max = 255;
125 m_gray_level_min = val_min;
126 m_gray_level_max = val_max;
133 :
vpTracker(d), m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.),
134 m_ip_connexities_list(), m_ip_edges_list(), m_connexityType(CONNEXITY_4), m_cog(), m_u_min(0), m_u_max(0), m_v_min(0), m_v_max(0),
135 m_graphics(false), m_thickness(1), m_maxDotSizePercentage(0.25), m_gray_level_out(0), m_mean_gray_level(0),
136 m_grayLevelPrecision(0.85), m_gamma(1.5), m_compute_moment(false), m_nbMaxPoint(0)
152 m_ip_edges_list = d.m_ip_edges_list;
153 m_ip_connexities_list = d.m_ip_connexities_list;
154 m_connexityType = d.m_connexityType;
162 m_graphics = d.m_graphics;
163 m_thickness = d.m_thickness;
164 m_maxDotSizePercentage = d.m_maxDotSizePercentage;
165 m_gray_level_out = d.m_gray_level_out;
166 m_mean_gray_level = d.m_mean_gray_level;
167 m_gray_level_min = d.m_gray_level_min;
168 m_gray_level_max = d.m_gray_level_max;
169 m_grayLevelPrecision = d.m_grayLevelPrecision;
171 m_compute_moment = d.m_compute_moment;
172 m_nbMaxPoint = d.m_nbMaxPoint;
203 void vpDot::setGrayLevelOut()
205 if (m_gray_level_min == 0) {
206 const unsigned int val_max = 255;
207 if (m_gray_level_max == val_max) {
211 m_gray_level_out =
static_cast<unsigned char>(m_gray_level_max + 1u);
235 return connexe(I, u, v, mean_value, uv_cog, npoints, checkTab);
255 vpImagePoint &uv_cog,
unsigned int &npoints, std::vector<bool> &checkTab)
262 if ((u >= width) || (v >= height)) {
266 if (checkTab[u + (v * I.
getWidth())]) {
274 if ((I[v][u] >= m_gray_level_min) && (I[v][u] <= m_gray_level_max)) {
275 checkTab[(v * I.
getWidth()) + u] =
true;
277 m_ip_connexities_list.push_back(ip);
283 if (npoints > m_nbMaxPoint) {
285 "Too many point %u (%f%% of image size). "
286 "This threshold can be modified using the setMaxDotSize() "
288 npoints,
static_cast<float>(npoints) / (I.
getWidth() * I.
getHeight()), m_nbMaxPoint, m_maxDotSizePercentage));
306 mean_value = ((mean_value * (npoints - 1)) + I[v][u]) / npoints;
307 if (m_compute_moment ==
true) {
323 if (!checkTab[(u - 1) + (v * I.
getWidth())]) {
324 if (!connexe(I, u - 1, v, mean_value, uv_cog, npoints, checkTab)) {
331 if (!checkTab[u + 1 + (v * I.
getWidth())]) {
332 if (!connexe(I, u + 1, v, mean_value, uv_cog, npoints, checkTab)) {
339 if (!checkTab[u + ((v - 1) * I.
getWidth())]) {
340 if (!connexe(I, u, v - 1, mean_value, uv_cog, npoints, checkTab)) {
347 if (!checkTab[u + ((v + 1) * I.
getWidth())]) {
348 if (!connexe(I, u, v + 1, mean_value, uv_cog, npoints, checkTab)) {
355 if ((v >= 1) && (u >= 1)) {
356 if (!checkTab[(u - 1) + ((v - 1) * I.
getWidth())]) {
357 if (!connexe(I, u - 1, v - 1, mean_value, uv_cog, npoints, checkTab)) {
363 if ((v >= 1) && ((u + 1) < I.
getWidth())) {
364 if (!checkTab[u + 1 + ((v - 1) * I.
getWidth())]) {
365 if (!connexe(I, u + 1, v - 1, mean_value, uv_cog, npoints, checkTab)) {
371 if (((v + 1) < I.
getHeight()) && (u >= 1)) {
372 if (!checkTab[(u - 1) + ((v + 1) * I.
getWidth())]) {
373 if (!connexe(I, u - 1, v + 1, mean_value, uv_cog, npoints, checkTab)) {
380 if (!checkTab[u + 1 + ((v + 1) * I.
getWidth())]) {
381 if (!connexe(I, u + 1, v + 1, mean_value, uv_cog, npoints, checkTab)) {
389 m_ip_edges_list.push_back(ip);
390 if (m_graphics ==
true) {
392 for (
unsigned int t = 0; t < m_thickness; ++t) {
393 ip_.set_u(ip.
get_u() + t);
430 if (m_compute_moment) {
443 unsigned int npoints = 0;
444 m_mean_gray_level = 0;
446 m_ip_connexities_list.clear();
447 m_ip_edges_list.clear();
456 if (!connexe(I,
static_cast<unsigned int>(u),
static_cast<unsigned int>(v), m_mean_gray_level, uv_cog, npoints)) {
459 unsigned int right = 1;
460 unsigned int botom = 1;
461 unsigned int left = 2;
463 double u_ = u, v_ = v;
465 const unsigned int val_2 = 2;
467 while ((right < SPIRAL_SEARCH_SIZE) && (sol ==
false)) {
468 for (k = 1; k <= right; ++k) {
471 m_ip_connexities_list.clear();
472 m_ip_edges_list.clear();
474 m_mean_gray_level = 0;
475 if (connexe(I,
static_cast<unsigned int>(u_) + k,
static_cast<unsigned int>(v_), m_mean_gray_level, uv_cog, npoints)) {
485 for (k = 1; k <= botom; ++k) {
488 m_ip_connexities_list.clear();
489 m_ip_edges_list.clear();
491 m_mean_gray_level = 0;
493 if (connexe(I,
static_cast<unsigned int>(u_),
static_cast<unsigned int>(v_ + k), m_mean_gray_level, uv_cog, npoints)) {
503 for (k = 1; k <= left; ++k) {
506 m_ip_connexities_list.clear();
507 m_ip_edges_list.clear();
509 m_mean_gray_level = 0;
511 if (connexe(I,
static_cast<unsigned int>(u_ - k),
static_cast<unsigned int>(v_), m_mean_gray_level, uv_cog, npoints)) {
521 for (k = 1; k <= up; ++k) {
524 m_ip_connexities_list.clear();
525 m_ip_edges_list.clear();
527 m_mean_gray_level = 0;
529 if (connexe(I,
static_cast<unsigned int>(u_),
static_cast<unsigned int>(v_ - k), m_mean_gray_level, uv_cog, npoints)) {
551 const unsigned int val_max = 255;
553 double Ip = pow(
static_cast<double>(m_mean_gray_level) / val_max, 1 / m_gamma);
555 if ((Ip - (1 - m_grayLevelPrecision)) < 0) {
556 m_gray_level_min = 0;
559 m_gray_level_min =
static_cast<unsigned int>(val_max * pow(Ip - (1 - m_grayLevelPrecision), m_gamma));
560 if (m_gray_level_min > val_max) {
561 m_gray_level_min = val_max;
564 m_gray_level_max =
static_cast<unsigned int>(val_max * pow(Ip + (1 - m_grayLevelPrecision), m_gamma));
565 if (m_gray_level_max > val_max) {
566 m_gray_level_max = val_max;
569 const double nbMinPoint = 5;
570 if (npoints < nbMinPoint) {
574 if (npoints > m_nbMaxPoint) {
576 "Too many point %lf (%lf%%). Max allowed is "
577 "%u (%f%%). This threshold can be modified "
578 "using the setMaxDotSize() method.",
579 npoints,
static_cast<float>(npoints) / (I.
getWidth() * I.
getHeight()), m_nbMaxPoint, m_maxDotSizePercentage));
597 if ((percentage <= 0.0) || (percentage > 1.0)) {
599 std::cout <<
"Max dot size percentage is requested to be set to " << percentage <<
"." << std::endl;
600 std::cout <<
"Value should be in ]0:1]. Value will be set to " << m_maxDotSizePercentage <<
"." << std::endl;
603 m_maxDotSizePercentage = percentage;
636 unsigned int i =
static_cast<unsigned int>(m_cog.
get_i());
637 unsigned int j =
static_cast<unsigned int>(m_cog.
get_j());
638 const unsigned int val_max = 255;
640 double Ip = pow(
static_cast<double>(I[i][j]) / val_max, 1 / m_gamma);
642 if ((Ip - (1 - m_grayLevelPrecision)) < 0) {
643 m_gray_level_min = 0;
646 m_gray_level_min =
static_cast<unsigned int>(val_max * pow(Ip - (1 - m_grayLevelPrecision), m_gamma));
647 if (m_gray_level_min > val_max) {
648 m_gray_level_min = val_max;
651 m_gray_level_max =
static_cast<unsigned int>(val_max * pow(Ip + (1 - m_grayLevelPrecision), m_gamma));
652 if (m_gray_level_max > val_max) {
653 m_gray_level_max = val_max;
686 unsigned int i =
static_cast<unsigned int>(m_cog.
get_i());
687 unsigned int j =
static_cast<unsigned int>(m_cog.
get_j());
688 const unsigned int val_max = 255;
689 double Ip = pow(
static_cast<double>(I[i][j]) / val_max, 1 / m_gamma);
691 if ((Ip - (1 - m_grayLevelPrecision)) < 0) {
692 m_gray_level_min = 0;
695 m_gray_level_min =
static_cast<unsigned int>(val_max * pow(Ip - (1 - m_grayLevelPrecision), m_gamma));
696 if (m_gray_level_min > val_max) {
697 m_gray_level_min = val_max;
700 m_gray_level_max =
static_cast<unsigned int>(val_max * pow(Ip + (1 - m_grayLevelPrecision), m_gamma));
701 if (m_gray_level_max > val_max) {
702 m_gray_level_max = val_max;
736 unsigned int level_max)
740 m_gray_level_min = level_min;
741 m_gray_level_max = level_max;
763 double u = m_cog.
get_u();
764 double v = m_cog.
get_v();
771 if (m_compute_moment ==
true) {
772 mu11 = m11 - (u * m01);
773 mu02 = m02 - (v * m01);
774 mu20 = m20 - (u * m10);
778 const unsigned int val_3 = 3;
779 const unsigned int val_8 = 8;
815 const unsigned int val_3 = 3;
816 const unsigned int val_8 = 8;
818 std::list<vpImagePoint>::const_iterator it;
820 std::list<vpImagePoint>::const_iterator m_ip_edges_list_end = m_ip_edges_list.end();
821 for (it = m_ip_edges_list.begin(); it != m_ip_edges_list_end; ++it) {
846 double epsilon = 0.05;
847 if (m_grayLevelPrecision < epsilon) {
848 m_grayLevelPrecision = epsilon;
850 else if (m_grayLevelPrecision > 1) {
851 m_grayLevelPrecision = 1.0;
854 m_grayLevelPrecision = precision;
873 vpColor color,
unsigned int thickness)
875 const unsigned int val_3 = 3;
876 const unsigned int val_8 = 8;
878 std::list<vpImagePoint>::const_iterator it;
880 std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
881 for (it = edges_list.begin(); it != edges_list_end; ++it) {
901 vpColor color,
unsigned int thickness)
903 const unsigned int val_3 = 3;
904 const unsigned int val_8 = 8;
906 std::list<vpImagePoint>::const_iterator it;
908 std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
909 for (it = edges_list.begin(); it != edges_list_end; ++it) {
919 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.
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 ...
void set_uv(double u, double v)
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.