39#include <visp3/core/vpDisplay.h>
42#include <visp3/core/vpIoTools.h>
43#include <visp3/core/vpMath.h>
44#include <visp3/core/vpTrackingException.h>
50#include <visp3/blob/vpDot2.h>
65 const unsigned int val_max = 255;
66 const unsigned int val_median = 128;
73 m_mean_gray_level = 0;
74 m_gray_level_min = val_median;
75 m_gray_level_max = val_max;
76 m_grayLevelPrecision = 0.80;
79 m_sizePrecision = 0.65;
80 m_ellipsoidShapePrecision = 0.65;
81 m_maxSizeSearchDistPrecision = 0.65;
101 m_compute_moment =
false;
110 :
m00(0.),
m10(0.),
m01(0.),
m11(0.),
m20(0.),
m02(0.),
mu11(0.),
mu20(0.),
mu02(0.), m_cog(), m_width(0), m_height(0),
111 m_surface(0), m_mean_gray_level(0), m_grayLevelPrecision(0.8), m_gamma(1.5),
112 m_sizePrecision(0.65), m_ellipsoidShapePrecision(0.65), m_maxSizeSearchDistPrecision(0.65),
113 m_allowedBadPointsPercentage(0.), m_area(), m_direction_list(), m_ip_edges_list(), m_compute_moment(false), m_graphics(false),
114 m_thickness(1), m_bbox_u_min(0), m_bbox_u_max(0), m_bbox_v_min(0), m_bbox_v_max(0), m_firstBorder_u(0), m_firstBorder_v()
116 const unsigned int val_max = 255;
117 const unsigned int val_median = 128;
118 m_gray_level_min = val_median;
119 m_gray_level_max = val_max;
131 :
m00(0.),
m10(0.),
m01(0.),
m11(0.),
m20(0.),
m02(0.),
mu11(0.),
mu20(0.),
mu02(0.), m_cog(ip), m_width(0), m_height(0),
132 m_surface(0), m_mean_gray_level(0), m_grayLevelPrecision(0.8), m_gamma(1.5),
133 m_sizePrecision(0.65), m_ellipsoidShapePrecision(0.65), m_maxSizeSearchDistPrecision(0.65),
134 m_allowedBadPointsPercentage(0.), m_area(), m_direction_list(), m_ip_edges_list(), m_compute_moment(false), m_graphics(false),
135 m_thickness(1), m_bbox_u_min(0), m_bbox_u_max(0), m_bbox_v_min(0), m_bbox_v_max(0), m_firstBorder_u(0), m_firstBorder_v()
137 const unsigned int val_max = 255;
138 const unsigned int val_median = 128;
139 m_gray_level_min = val_median;
140 m_gray_level_max = val_max;
147 :
vpTracker(twinDot),
m00(0.),
m10(0.),
m01(0.),
m11(0.),
m20(0.),
m02(0.),
mu11(0.),
mu20(0.),
mu02(0.), m_cog(),
148 m_width(0), m_height(0), m_surface(0), m_mean_gray_level(0),
149 m_grayLevelPrecision(0.8), m_gamma(1.5), m_sizePrecision(0.65), m_ellipsoidShapePrecision(0.65),
150 m_maxSizeSearchDistPrecision(0.65), m_allowedBadPointsPercentage(0.), m_area(), m_direction_list(), m_ip_edges_list(),
151 m_compute_moment(false), m_graphics(false), m_thickness(1), m_bbox_u_min(0), m_bbox_u_max(0), m_bbox_v_min(0), m_bbox_v_max(0),
152 m_firstBorder_u(0), m_firstBorder_v()
154 const unsigned int val_max = 255;
155 const unsigned int val_median = 128;
156 m_gray_level_min = val_median;
157 m_gray_level_max = val_max;
166 m_cog = twinDot.m_cog;
168 m_width = twinDot.m_width;
169 m_height = twinDot.m_height;
170 m_surface = twinDot.m_surface;
171 m_gray_level_min = twinDot.m_gray_level_min;
172 m_gray_level_max = twinDot.m_gray_level_max;
173 m_mean_gray_level = twinDot.m_mean_gray_level;
174 m_grayLevelPrecision = twinDot.m_grayLevelPrecision;
175 m_gamma = twinDot.m_gamma;
177 m_sizePrecision = twinDot.m_sizePrecision;
178 m_ellipsoidShapePrecision = twinDot.m_ellipsoidShapePrecision;
179 m_maxSizeSearchDistPrecision = twinDot.m_maxSizeSearchDistPrecision;
180 m_allowedBadPointsPercentage = twinDot.m_allowedBadPointsPercentage;
181 m_area = twinDot.m_area;
183 m_direction_list = twinDot.m_direction_list;
184 m_ip_edges_list = twinDot.m_ip_edges_list;
186 m_compute_moment = twinDot.m_compute_moment;
187 m_graphics = twinDot.m_graphics;
188 m_thickness = twinDot.m_thickness;
190 m_bbox_u_min = twinDot.m_bbox_u_min;
191 m_bbox_u_max = twinDot.m_bbox_u_max;
192 m_bbox_v_min = twinDot.m_bbox_v_min;
193 m_bbox_v_max = twinDot.m_bbox_v_max;
195 m_firstBorder_u = twinDot.m_firstBorder_u;
196 m_firstBorder_v = twinDot.m_firstBorder_v;
221 const unsigned int val_3 = 3;
222 const unsigned int val_8 = 8;
224 std::list<vpImagePoint>::const_iterator it;
226 std::list<vpImagePoint>::const_iterator ip_edges_list_end = m_ip_edges_list.end();
227 for (it = m_ip_edges_list.begin(); it != ip_edges_list_end; ++it) {
269 unsigned int i =
static_cast<unsigned int>(m_cog.get_i());
270 unsigned int j =
static_cast<unsigned int>(m_cog.get_j());
271 const unsigned int val_max = 255;
273 double Ip = pow(
static_cast<double>(I[i][j]) / val_max, 1 / m_gamma);
275 if ((Ip - (1 - m_grayLevelPrecision)) < 0) {
276 m_gray_level_min = 0;
279 m_gray_level_min =
static_cast<unsigned int>(val_max * pow(Ip - (1 - m_grayLevelPrecision), m_gamma));
280 if (m_gray_level_min > val_max) {
281 m_gray_level_min = val_max;
284 m_gray_level_max =
static_cast<unsigned int>(val_max * pow(Ip + (1 - m_grayLevelPrecision), m_gamma));
285 if (m_gray_level_max > val_max) {
286 m_gray_level_max = val_max;
326 unsigned int i =
static_cast<unsigned int>(m_cog.get_i());
327 unsigned int j =
static_cast<unsigned int>(m_cog.get_j());
328 const unsigned int val_max = 255;
330 double Ip = pow(
static_cast<double>(I[i][j]) / val_max, 1 / m_gamma);
332 if ((Ip - (1 - m_grayLevelPrecision)) < 0) {
333 m_gray_level_min = 0;
336 m_gray_level_min =
static_cast<unsigned int>(val_max * pow(Ip - (1 - m_grayLevelPrecision), m_gamma));
337 if (m_gray_level_min > val_max) {
338 m_gray_level_min = val_max;
341 m_gray_level_max =
static_cast<unsigned int>(val_max * pow(Ip + (1 - m_grayLevelPrecision), m_gamma));
342 if (m_gray_level_max > val_max) {
343 m_gray_level_max = val_max;
392 unsigned int gray_lvl_max,
unsigned int size)
396 m_gray_level_min = gray_lvl_min;
397 m_gray_level_max = gray_lvl_max;
462 bool found = computeParameters(I, m_cog.get_u(), m_cog.get_v());
466 found = isValid(I, wantedDot);
480 double searchWindowWidth = 0.0;
481 double searchWindowHeight = 0.0;
483 if ((std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon()) ||
484 (std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon())) {
485 searchWindowWidth = 80.;
486 searchWindowHeight = 80.;
488 else if (canMakeTheWindowGrow) {
489 const unsigned int val_5 = 5;
490 searchWindowWidth =
getWidth() * val_5;
491 searchWindowHeight =
getHeight() * val_5;
498 std::list<vpDot2> candidates;
499 searchDotsInArea(I,
static_cast<int>(m_cog.get_u() - (searchWindowWidth / 2.0)),
500 static_cast<int>(m_cog.get_v() - (searchWindowHeight / 2.0)),
501 static_cast<unsigned int>(searchWindowWidth),
502 static_cast<unsigned int>(searchWindowHeight), candidates);
506 if (candidates.empty()) {
511 vpDot2 movingDot = candidates.front();
527 m_bbox_u_min = movingDot.m_bbox_u_min;
528 m_bbox_u_max = movingDot.m_bbox_u_max;
529 m_bbox_v_min = movingDot.m_bbox_v_min;
530 m_bbox_v_max = movingDot.m_bbox_v_max;
536 "The center of gravity of the dot is not in the image"));
539 const unsigned int val_max = 255;
544 if ((Ip - (1 - m_grayLevelPrecision)) < 0) {
545 m_gray_level_min = 0;
548 m_gray_level_min =
static_cast<unsigned int>(val_max * pow(Ip - (1 - m_grayLevelPrecision), m_gamma));
549 if (m_gray_level_min > val_max) {
550 m_gray_level_min = val_max;
553 m_gray_level_max =
static_cast<unsigned int>(val_max * pow(Ip + (1 - m_grayLevelPrecision), m_gamma));
554 if (m_gray_level_max > val_max) {
555 m_gray_level_max = val_max;
560 const unsigned int val_3 = 3;
561 const unsigned int val_8 = 8;
590 track(I, canMakeTheWindowGrow);
656 double diff_u = m_cog.
get_u() - cogDistantDot.
get_u();
657 double diff_v = m_cog.get_v() - cogDistantDot.
get_v();
658 return sqrt((diff_u * diff_u) + (diff_v * diff_v));
717 double epsilon = 0.05;
718 if (m_grayLevelPrecision < epsilon) {
719 m_grayLevelPrecision = epsilon;
721 else if (m_grayLevelPrecision > 1) {
722 m_grayLevelPrecision = 1.0;
725 m_grayLevelPrecision = precision;
747 if (m_sizePrecision < 0) {
750 else if (m_sizePrecision > 1) {
751 m_sizePrecision = 1.0;
754 m_sizePrecision = precision;
793 if (m_ellipsoidShapePrecision < 0) {
794 m_ellipsoidShapePrecision = 0;
796 else if (m_ellipsoidShapePrecision > 1) {
797 m_ellipsoidShapePrecision = 1.0;
800 m_ellipsoidShapePrecision = precision;
821 double epsilon = 0.05;
822 if (m_maxSizeSearchDistPrecision < epsilon) {
823 m_maxSizeSearchDistPrecision = epsilon;
825 else if (m_maxSizeSearchDistPrecision > 1) {
826 m_maxSizeSearchDistPrecision = 1.0;
829 m_maxSizeSearchDistPrecision = precision;
857 unsigned int image_w = I.
getWidth();
864 else if (u >=
static_cast<int>(image_w)) {
865 u =
static_cast<int>(image_w) - 1;
870 else if (v >=
static_cast<int>(image_h)) {
871 v =
static_cast<int>(image_h) - 1;
874 if ((
static_cast<unsigned int>(u) + w) > image_w) {
875 w = image_w -
static_cast<unsigned int>(
u) - 1;
877 if ((
static_cast<unsigned int>(v) + h) > image_h) {
878 h = image_h -
static_cast<unsigned int>(
v) - 1;
881 m_area.setRect(u, v, w, h);
979 if ((std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon()) &&
980 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon()) &&
981 (std::fabs(wantedDot.
getArea()) > std::numeric_limits<double>::epsilon())) {
982 if (std::fabs(size_precision) > std::numeric_limits<double>::epsilon()) {
983 double epsilon = 0.001;
985 std::cout <<
"test size precision......................\n";
986 std::cout <<
"wanted dot: "
988 <<
" precision=" << size_precision <<
" epsilon=" << epsilon << std::endl;
989 std::cout <<
"dot found: "
993 if ((((wantedDot.
getWidth() * size_precision) - epsilon) <
getWidth()) ==
false) {
995 printf(
"Bad width > for dot (%g, %g)\n", m_cog.
get_u(), m_cog.
get_v());
1000 if ((
getWidth() < (wantedDot.
getWidth() / (size_precision + epsilon))) ==
false) {
1002 printf(
"Bad width %g > %g for dot (%g, %g)\n",
getWidth(), wantedDot.
getWidth() / (size_precision + epsilon),
1003 m_cog.get_u(), m_cog.get_v());
1010 printf(
"Bad height %g > %g for dot (%g, %g)\n", wantedDot.
getHeight() * size_precision - epsilon,
getHeight(),
1011 m_cog.get_u(), m_cog.get_v());
1018 printf(
"Bad height %g > %g for dot (%g, %g)\n",
getHeight(), wantedDot.
getHeight() / (size_precision + epsilon),
1019 m_cog.get_u(), m_cog.get_v());
1024 if ((((wantedDot.
getArea() * (size_precision * size_precision)) - epsilon) <
getArea()) ==
false) {
1026 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1027 wantedDot.
getArea() * (size_precision * size_precision) - epsilon,
getArea(), m_cog.get_u(), m_cog.get_v());
1032 if ((
getArea() < (wantedDot.
getArea() / ((size_precision * size_precision) + epsilon))) ==
false) {
1034 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
getArea(),
1035 wantedDot.
getArea() / (size_precision * size_precision + epsilon), m_cog.get_u(), m_cog.get_v());
1046 int nb_point_to_test = 20;
1047 int nb_bad_points = 0;
1048 int nb_max_bad_points =
static_cast<int>(nb_point_to_test * m_allowedBadPointsPercentage);
1049 double step_angle = (2 * M_PI) / nb_point_to_test;
1052 if ((std::fabs(ellipsoidShape_precision) > std::numeric_limits<double>::epsilon()) && m_compute_moment) {
1070 double Sqrt = sqrt((tmp1 * tmp1) + (4 * tmp2 * tmp2));
1080 double innerCoef = ellipsoidShape_precision;
1082 double cog_u = m_cog.get_u();
1083 double cog_v = m_cog.get_v();
1088 for (
double theta = 0.; theta < (val_2 * M_PI); theta += step_angle) {
1089 u =
static_cast<unsigned int>(cog_u + (innerCoef * ((a1 * cos(alpha) * cos(theta)) - (a2 * sin(alpha) * sin(theta)))));
1090 v =
static_cast<unsigned int>(cog_v + (innerCoef * ((a1 * sin(alpha) * cos(theta)) + (a2 * cos(alpha) * sin(theta)))));
1091 if (!this->hasGoodLevel(I, u, v)) {
1093 printf(
"Inner circle pixel (%u, %u) has bad level for dot (%g, %g): "
1094 "%d not in [%u, %u]\n",
1095 u, v, cog_u, cog_v, I[v][u], m_gray_level_min, m_gray_level_max);
1100 for (
unsigned int t = 0;
t < m_thickness; ++
t) {
1111 if (nb_bad_points > nb_max_bad_points) {
1113 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1122 double outCoef = 2 - ellipsoidShape_precision;
1124 for (
double theta = 0.; theta < (val_2 * M_PI); theta += step_angle) {
1125 u =
static_cast<unsigned int>(cog_u + (outCoef * ((a1 * cos(alpha) * cos(theta)) - (a2 * sin(alpha) * sin(theta)))));
1126 v =
static_cast<unsigned int>(cog_v + (outCoef * ((a1 * sin(alpha) * cos(theta)) + (a2 * cos(alpha) * sin(theta)))));
1133 if ((
static_cast<double>(u) < m_area.getLeft()) ||
1134 (
static_cast<double>(u) > m_area.getRight()) ||
1135 (
static_cast<double>(v) < m_area.getTop()) ||
1136 (
static_cast<double>(v) > m_area.getBottom())) {
1140 if (!this->hasReverseLevel(I, u, v)) {
1142 printf(
"Outside circle pixel (%u, %u) has bad level for dot (%g, "
1143 "%g): %d not in [%u, %u]\n",
1144 u, v, cog_u, cog_v, I[v][u], m_gray_level_min, m_gray_level_max);
1149 for (
unsigned int t = 0;
t < m_thickness; ++
t) {
1159 if (nb_bad_points > nb_max_bad_points) {
1161 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1187bool vpDot2::hasGoodLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const
1189 if (!isInArea(u, v)) {
1193 if ((I[v][u] >= m_gray_level_min) && (I[v][u] <= m_gray_level_max)) {
1213bool vpDot2::hasReverseLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const
1216 if (!isInArea(u, v)) {
1220 if ((I[v][u] < m_gray_level_min) || (I[v][u] > m_gray_level_max)) {
1269 m_direction_list.clear();
1270 m_ip_edges_list.clear();
1277 if (std::fabs(est_u + 1.0) <= (
vpMath::maximum(std::fabs(est_u), 1.) * std::numeric_limits<double>::epsilon())) {
1278 est_u = m_cog.get_u();
1283 if (std::fabs(est_v + 1.0) <= (
vpMath::maximum(std::fabs(est_v), 1.) * std::numeric_limits<double>::epsilon())) {
1284 est_v = m_cog.get_v();
1289 if (!isInArea(
static_cast<unsigned int>(est_u),
static_cast<unsigned int>(est_v))) {
1293 m_bbox_u_min =
static_cast<int>(I.
getWidth());
1295 m_bbox_v_min =
static_cast<int>(I.
getHeight());
1300 if (!hasGoodLevel(I,
static_cast<unsigned int>(est_u),
static_cast<unsigned int>(est_v))) {
1306 if (!findFirstBorder(I,
static_cast<unsigned int>(est_u),
static_cast<unsigned int>(est_v), m_firstBorder_u, m_firstBorder_v)) {
1310 unsigned int dir = 6;
1313 computeFreemanChainElement(I, m_firstBorder_u, m_firstBorder_v, dir);
1314 unsigned int firstDir = dir;
1317 if (!isInArea(m_firstBorder_u, m_firstBorder_v)) {
1322 m_direction_list.push_back(dir);
1324 ip.
set_u(m_firstBorder_u);
1325 ip.
set_v(m_firstBorder_v);
1327 m_ip_edges_list.push_back(ip);
1329 int border_u =
static_cast<int>(m_firstBorder_u);
1330 int border_v =
static_cast<int>(m_firstBorder_v);
1332 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1343 for (
int t = 0; t < static_cast<int>(m_thickness); ++
t) {
1344 ip.
set_u(border_u + t);
1355 computeFreemanParameters(border_u, border_v, dir, du, dv,
1366 if (m_compute_moment) {
1372 if (!isInArea(
static_cast<unsigned int>(border_u),
static_cast<unsigned int>(border_v))) {
1379 m_direction_list.push_back(dir);
1383 m_ip_edges_list.push_back(ip);
1386 if (border_v < m_bbox_v_min) {
1387 m_bbox_v_min = border_v;
1389 if (border_v > m_bbox_v_max) {
1390 m_bbox_v_max = border_v;
1392 if (border_u < m_bbox_u_min) {
1393 m_bbox_u_min = border_u;
1395 if (border_u > m_bbox_u_max) {
1396 m_bbox_u_max = border_u;
1400 if (computeFreemanChainElement(I,
static_cast<unsigned int>(border_u),
static_cast<unsigned int>(border_v), dir) ==
false) {
1403 }
while (((getFirstBorder_u() !=
static_cast<unsigned int>(border_u)) || (getFirstBorder_v() !=
static_cast<unsigned int>(border_v)) ||
1404 (firstDir != dir)) &&
1405 isInArea(
static_cast<unsigned int>(border_u),
static_cast<unsigned int>(border_v)));
1408#if VP_DEBUG_MODE == 3
1416 if ((std::fabs(
m00) <= std::numeric_limits<double>::epsilon()) ||
1417 (std::fabs(
m00 - 1.) <= (
vpMath::maximum(std::fabs(
m00), 1.) * std::numeric_limits<double>::epsilon()))) {
1423 double tmpCenter_u =
m10 /
m00;
1424 double tmpCenter_v =
m01 /
m00;
1427 if (m_compute_moment) {
1433 m_cog.set_u(tmpCenter_u);
1434 m_cog.set_v(tmpCenter_v);
1437 m_width = (m_bbox_u_max - m_bbox_u_min) + 1;
1438 m_height = (m_bbox_v_max - m_bbox_v_min) + 1;
1441 computeMeanGrayLevel(I);
1460bool vpDot2::findFirstBorder(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1461 unsigned int &border_u,
unsigned int &border_v)
1471 double epsilon = 0.001;
1474 std::cout <<
"gray level: " << m_gray_level_min <<
" " << m_gray_level_max << std::endl;
1476 while (hasGoodLevel(I, border_u + 1, border_v) && (border_u < m_area.getRight()) ) {
1524 if ((u < 0) || (u >= w)) {
1527 if ((v < 0) || (v >= h)) {
1544bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const
1546 unsigned int area_u_min =
static_cast<unsigned int>(m_area.getLeft());
1547 unsigned int area_u_max =
static_cast<unsigned int>(m_area.getRight());
1548 unsigned int area_v_min =
static_cast<unsigned int>(m_area.getTop());
1549 unsigned int area_v_max =
static_cast<unsigned int>(m_area.getBottom());
1551 if ((u < area_u_min) || (u > area_u_max)) {
1554 if ((v < area_v_min) || (v > area_v_max)) {
1568void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight)
1578 if (gridWidth == 0) {
1581 if (gridHeight == 0) {
1597 int cog_u =
static_cast<int>(m_cog.get_u());
1598 int cog_v =
static_cast<int>(m_cog.get_v());
1600 unsigned int sum_value = 0;
1601 unsigned int nb_pixels = 0;
1603 for (
unsigned int i =
static_cast<unsigned int>(m_bbox_u_min); i <= static_cast<unsigned int>(m_bbox_u_max); ++
i) {
1604 unsigned int pixel_gray =
static_cast<unsigned int>(I[
static_cast<unsigned int>(cog_v)][
i]);
1606 sum_value += pixel_gray;
1610 for (
unsigned int i =
static_cast<unsigned int>(m_bbox_v_min); i <= static_cast<unsigned int>(m_bbox_v_max); ++
i) {
1611 unsigned char pixel_gray = I[
i][
static_cast<unsigned int>(cog_u)];
1613 sum_value += pixel_gray;
1617 const unsigned int nb_min_pixels = 10;
1618 if (nb_pixels < nb_min_pixels) {
1621 if ((cog_u - m_bbox_u_min) >(cog_v - m_bbox_v_min)) {
1622 imin = cog_v - m_bbox_v_min;
1625 imin = cog_u - m_bbox_u_min;
1627 if ((m_bbox_u_max - cog_u) > (m_bbox_v_max - cog_v)) {
1628 imax = m_bbox_v_max - cog_v;
1631 imax = m_bbox_u_max - cog_u;
1633 for (
int i = -imin;
i <= imax; ++
i) {
1634 unsigned int pixel_gray =
static_cast<unsigned int>(I[
static_cast<unsigned int>(cog_v +
i)][
static_cast<unsigned int>(cog_u +
i)]);
1636 sum_value += pixel_gray;
1641 if ((cog_u - m_bbox_u_min) > (m_bbox_v_max - cog_v)) {
1642 imin = m_bbox_v_max - cog_v;
1645 imin = cog_u - m_bbox_u_min;
1647 if ((m_bbox_u_max - cog_u) > (cog_v - m_bbox_v_min)) {
1648 imax = cog_v - m_bbox_v_min;
1651 imax = m_bbox_u_max - cog_u;
1654 for (
int i = -imin;
i <= imax; ++
i) {
1655 unsigned char pixel_gray = I[
static_cast<unsigned int>(cog_v -
i)][
static_cast<unsigned int>(cog_u + i)];
1657 sum_value += pixel_gray;
1663 if (nb_pixels == 0) {
1668 m_mean_gray_level = sum_value / nb_pixels;
1699 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
1704 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
1711 const unsigned int cross_size = 10;
1712 for (i = 0; i < n; ++i) {
1713 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
1724 std::cout <<
"Cannot track dots from file" << std::endl;
1731 while ((i < n) && fromFile) {
1734 while ((j < n) && fromFile) {
1738 std::cout <<
"Dots from file seem incoherent" << std::endl;
1751 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
1752 const unsigned int cross_size = 10;
1753 for (i = 0; i < n; ++i) {
1763 Cogs[i][0] = cog.
get_u();
1764 Cogs[i][1] = cog.
get_v();
1770 if ((!fromFile) && (dotFile !=
"")) {
1772 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
1776 for (i = 0; i < n; ++i) {
1800 std::vector<vpImagePoint> &cogs,
vpImagePoint *cogStar)
1803 for (
unsigned int i = 0; i < n; ++i) {
1805 cogs.push_back(dot[i].
getCog());
1808 unsigned int cogs_size =
static_cast<unsigned int>(cogs.size());
1809 for (
unsigned int i = n; i < cogs_size; ++i) {
1810 const unsigned int circle_size = 4;
1814 for (
unsigned int i = 0; i < n; ++i) {
1815 const unsigned int circle_size = 4;
1819 if (cogStar !=
nullptr) {
1820 const unsigned int circle_size = 10;
1821 for (
unsigned int i = 0; i < n; ++i) {
1844 const std::list<vpImagePoint> &edges_list,
vpColor color,
unsigned int thickness)
1846 const unsigned int val_3 = 3;
1847 const unsigned int val_8 = 8;
1850 std::list<vpImagePoint>::const_iterator it;
1852 std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
1853 for (it = edges_list.begin(); it != edges_list_end; ++it) {
1873 vpColor color,
unsigned int thickness)
1875 const unsigned int val_3 = 3;
1876 const unsigned int val_8 = 8;
1878 std::list<vpImagePoint>::const_iterator it;
1879 std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
1880 for (it = edges_list.begin(); it != edges_list_end; ++it) {
1890VISP_EXPORT std::ostream &
operator<<(std::ostream &os,
vpDot2 &d) {
return (os <<
"(" << d.getCog() <<
")"); }
unsigned int getRows() const
Class to define RGB colors available for display functionalities.
static const vpColor blue
static const vpColor purple
static const vpColor green
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void displayCircle(const vpImage< unsigned char > &I, const vpImageCircle &circle, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void display(const vpImage< unsigned char > &I)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
static void displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
This tracker is meant to track a blob (connex pixels with same gray level) on a vpImage.
unsigned int getGrayLevelMin() const
friend VISP_EXPORT std::ostream & operator<<(std::ostream &os, vpDot2 &d)
unsigned int getGrayLevelMax() const
void track(const vpImage< unsigned char > &I, bool canMakeTheWindowGrow=true)
void setGraphics(bool activate)
vpDot2 & operator=(const vpDot2 &twinDot)
static void trackAndDisplay(vpDot2 dot[], const unsigned int &n, vpImage< unsigned char > &I, std::vector< vpImagePoint > &cogs, vpImagePoint *cogStar=nullptr)
double getEllipsoidShapePrecision() const
void searchDotsInArea(const vpImage< unsigned char > &I, int area_u, int area_v, unsigned int area_w, unsigned int area_h, std::list< vpDot2 > &niceDots)
void setMaxSizeSearchDistPrecision(const double &maxSizeSearchDistancePrecision)
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1) const
void setSizePrecision(const double &sizePrecision)
void setGrayLevelPrecision(const double &grayLevelPrecision)
void setHeight(const double &height)
double getMaxSizeSearchDistPrecision() const
void setCog(const vpImagePoint &ip)
vpImagePoint getCog() const
double getSizePrecision() const
double getGrayLevelPrecision() const
void setEllipsoidBadPointsPercentage(const double &percentage=0.0)
double getDistance(const vpDot2 &distantDot) const
void setWidth(const double &width)
void setEllipsoidShapePrecision(const double &ellipsoidShapePrecision)
double getMeanGrayLevel() const
void setArea(const double &area)
void initTracking(const vpImage< unsigned char > &I, unsigned int size=0)
static vpMatrix defineDots(vpDot2 dot[], const unsigned int &n, const std::string &dotFile, vpImage< unsigned char > &I, vpColor col=vpColor::blue, bool trackDot=true)
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)
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getHeight() const
static Type maximum(const Type &a, const Type &b)
static double sqr(double x)
Implementation of a matrix and operations on matrices.
static bool loadMatrix(const std::string &filename, vpArray2D< double > &M, bool binary=false, char *header=nullptr)
static bool saveMatrix(const std::string &filename, const vpArray2D< double > &M, bool binary=false, const char *header="")
Defines a rectangle in the plane.
void init()
Default initialization.
vpTracker()
Default constructor.
Error that can be emitted by the vpTracker class and its derivatives.
@ featureLostError
Tracker lost feature.
@ notEnoughPointError
Not enough point to track.