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>
66 const unsigned int val_max = 255;
67 const unsigned int val_median = 128;
74 m_mean_gray_level = 0;
75 m_gray_level_min = val_median;
76 m_gray_level_max = val_max;
77 m_grayLevelPrecision = 0.80;
80 m_sizePrecision = 0.65;
81 m_ellipsoidShapePrecision = 0.65;
82 m_maxSizeSearchDistPrecision = 0.65;
102 m_compute_moment =
false;
111 : 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),
112 m_surface(0), m_mean_gray_level(0), m_grayLevelPrecision(0.8), m_gamma(1.5),
113 m_sizePrecision(0.65), m_ellipsoidShapePrecision(0.65), m_maxSizeSearchDistPrecision(0.65),
114 m_allowedBadPointsPercentage(0.), m_area(), m_direction_list(), m_ip_edges_list(), m_compute_moment(false), m_graphics(false),
115 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()
117 const unsigned int val_max = 255;
118 const unsigned int val_median = 128;
119 m_gray_level_min = val_median;
120 m_gray_level_max = val_max;
132 : 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),
133 m_surface(0), m_mean_gray_level(0), m_grayLevelPrecision(0.8), m_gamma(1.5),
134 m_sizePrecision(0.65), m_ellipsoidShapePrecision(0.65), m_maxSizeSearchDistPrecision(0.65),
135 m_allowedBadPointsPercentage(0.), m_area(), m_direction_list(), m_ip_edges_list(), m_compute_moment(false), m_graphics(false),
136 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()
138 const unsigned int val_max = 255;
139 const unsigned int val_median = 128;
140 m_gray_level_min = val_median;
141 m_gray_level_max = val_max;
148 :
vpTracker(twinDot), m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), m_cog(),
149 m_width(0), m_height(0), m_surface(0), m_mean_gray_level(0),
150 m_grayLevelPrecision(0.8), m_gamma(1.5), m_sizePrecision(0.65), m_ellipsoidShapePrecision(0.65),
151 m_maxSizeSearchDistPrecision(0.65), m_allowedBadPointsPercentage(0.), m_area(), m_direction_list(), m_ip_edges_list(),
152 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),
153 m_firstBorder_u(0), m_firstBorder_v()
155 const unsigned int val_max = 255;
156 const unsigned int val_median = 128;
157 m_gray_level_min = val_median;
158 m_gray_level_max = val_max;
167 m_cog = twinDot.m_cog;
169 m_width = twinDot.m_width;
170 m_height = twinDot.m_height;
171 m_surface = twinDot.m_surface;
172 m_gray_level_min = twinDot.m_gray_level_min;
173 m_gray_level_max = twinDot.m_gray_level_max;
174 m_mean_gray_level = twinDot.m_mean_gray_level;
175 m_grayLevelPrecision = twinDot.m_grayLevelPrecision;
176 m_gamma = twinDot.m_gamma;
178 m_sizePrecision = twinDot.m_sizePrecision;
179 m_ellipsoidShapePrecision = twinDot.m_ellipsoidShapePrecision;
180 m_maxSizeSearchDistPrecision = twinDot.m_maxSizeSearchDistPrecision;
181 m_allowedBadPointsPercentage = twinDot.m_allowedBadPointsPercentage;
182 m_area = twinDot.m_area;
184 m_direction_list = twinDot.m_direction_list;
185 m_ip_edges_list = twinDot.m_ip_edges_list;
187 m_compute_moment = twinDot.m_compute_moment;
188 m_graphics = twinDot.m_graphics;
189 m_thickness = twinDot.m_thickness;
191 m_bbox_u_min = twinDot.m_bbox_u_min;
192 m_bbox_u_max = twinDot.m_bbox_u_max;
193 m_bbox_v_min = twinDot.m_bbox_v_min;
194 m_bbox_v_max = twinDot.m_bbox_v_max;
196 m_firstBorder_u = twinDot.m_firstBorder_u;
197 m_firstBorder_v = twinDot.m_firstBorder_v;
227 const unsigned int val_3 = 3;
228 const unsigned int val_8 = 8;
230 std::list<vpImagePoint>::const_iterator it;
232 std::list<vpImagePoint>::const_iterator ip_edges_list_end = m_ip_edges_list.end();
233 for (it = m_ip_edges_list.begin(); it != ip_edges_list_end; ++it) {
275 unsigned int i =
static_cast<unsigned int>(m_cog.
get_i());
276 unsigned int j =
static_cast<unsigned int>(m_cog.
get_j());
277 const unsigned int val_max = 255;
279 double Ip = pow(
static_cast<double>(I[i][j]) / val_max, 1 / m_gamma);
281 if ((Ip - (1 - m_grayLevelPrecision)) < 0) {
282 m_gray_level_min = 0;
285 m_gray_level_min =
static_cast<unsigned int>(val_max * pow(Ip - (1 - m_grayLevelPrecision), m_gamma));
286 if (m_gray_level_min > val_max) {
287 m_gray_level_min = val_max;
290 m_gray_level_max =
static_cast<unsigned int>(val_max * pow(Ip + (1 - m_grayLevelPrecision), m_gamma));
291 if (m_gray_level_max > val_max) {
292 m_gray_level_max = val_max;
332 unsigned int i =
static_cast<unsigned int>(m_cog.
get_i());
333 unsigned int j =
static_cast<unsigned int>(m_cog.
get_j());
334 const unsigned int val_max = 255;
336 double Ip = pow(
static_cast<double>(I[i][j]) / val_max, 1 / m_gamma);
338 if ((Ip - (1 - m_grayLevelPrecision)) < 0) {
339 m_gray_level_min = 0;
342 m_gray_level_min =
static_cast<unsigned int>(val_max * pow(Ip - (1 - m_grayLevelPrecision), m_gamma));
343 if (m_gray_level_min > val_max) {
344 m_gray_level_min = val_max;
347 m_gray_level_max =
static_cast<unsigned int>(val_max * pow(Ip + (1 - m_grayLevelPrecision), m_gamma));
348 if (m_gray_level_max > val_max) {
349 m_gray_level_max = val_max;
398 unsigned int gray_lvl_max,
unsigned int size)
402 m_gray_level_min = gray_lvl_min;
403 m_gray_level_max = gray_lvl_max;
473 bool found = computeParameters(I, m_cog.
get_u(), m_cog.
get_v());
477 found = isValid(I, wantedDot);
491 double searchWindowWidth = 0.0;
492 double searchWindowHeight = 0.0;
494 if ((std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon()) ||
495 (std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon())) {
496 searchWindowWidth = 80.;
497 searchWindowHeight = 80.;
499 else if (canMakeTheWindowGrow) {
500 const unsigned int val_5 = 5;
501 searchWindowWidth =
getWidth() * val_5;
502 searchWindowHeight =
getHeight() * val_5;
509 std::list<vpDot2> candidates;
511 static_cast<int>(m_cog.
get_v() - (searchWindowHeight / 2.0)),
512 static_cast<unsigned int>(searchWindowWidth),
513 static_cast<unsigned int>(searchWindowHeight), candidates);
517 if (candidates.empty()) {
522 vpDot2 movingDot = candidates.front();
538 m_bbox_u_min = movingDot.m_bbox_u_min;
539 m_bbox_u_max = movingDot.m_bbox_u_max;
540 m_bbox_v_min = movingDot.m_bbox_v_min;
541 m_bbox_v_max = movingDot.m_bbox_v_max;
547 "The center of gravity of the dot is not in the image"));
550 const unsigned int val_max = 255;
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;
571 const unsigned int val_3 = 3;
572 const unsigned int val_8 = 8;
601 track(I, canMakeTheWindowGrow);
667 double diff_u = m_cog.
get_u() - cogDistantDot.
get_u();
668 double diff_v = m_cog.
get_v() - cogDistantDot.
get_v();
669 return sqrt((diff_u * diff_u) + (diff_v * diff_v));
728 double epsilon = 0.05;
729 if (m_grayLevelPrecision < epsilon) {
730 m_grayLevelPrecision = epsilon;
732 else if (m_grayLevelPrecision > 1) {
733 m_grayLevelPrecision = 1.0;
736 m_grayLevelPrecision = precision;
758 if (m_sizePrecision < 0) {
761 else if (m_sizePrecision > 1) {
762 m_sizePrecision = 1.0;
765 m_sizePrecision = precision;
804 if (m_ellipsoidShapePrecision < 0) {
805 m_ellipsoidShapePrecision = 0;
807 else if (m_ellipsoidShapePrecision > 1) {
808 m_ellipsoidShapePrecision = 1.0;
811 m_ellipsoidShapePrecision = precision;
832 double epsilon = 0.05;
833 if (m_maxSizeSearchDistPrecision < epsilon) {
834 m_maxSizeSearchDistPrecision = epsilon;
836 else if (m_maxSizeSearchDistPrecision > 1) {
837 m_maxSizeSearchDistPrecision = 1.0;
840 m_maxSizeSearchDistPrecision = precision;
868 unsigned int image_w = I.
getWidth();
875 else if (u >=
static_cast<int>(image_w)) {
876 u =
static_cast<int>(image_w) - 1;
881 else if (v >=
static_cast<int>(image_h)) {
882 v =
static_cast<int>(image_h) - 1;
885 if ((
static_cast<unsigned int>(u) + w) > image_w) {
886 w = image_w -
static_cast<unsigned int>(u) - 1;
888 if ((
static_cast<unsigned int>(v) + h) > image_h) {
889 h = image_h -
static_cast<unsigned int>(v) - 1;
994 if ((std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon()) &&
995 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon()) &&
996 (std::fabs(wantedDot.
getArea()) > std::numeric_limits<double>::epsilon())) {
997 if (std::fabs(size_precision) > std::numeric_limits<double>::epsilon()) {
998 double epsilon = 0.001;
1000 std::cout <<
"test size precision......................\n";
1001 std::cout <<
"wanted dot: "
1003 <<
" precision=" << size_precision <<
" epsilon=" << epsilon << std::endl;
1004 std::cout <<
"dot found: "
1008 if ((((wantedDot.
getWidth() * size_precision) - epsilon) <
getWidth()) ==
false) {
1010 printf(
"Bad width > for dot (%g, %g)\n", m_cog.
get_u(), m_cog.
get_v());
1015 if ((
getWidth() < (wantedDot.
getWidth() / (size_precision + epsilon))) ==
false) {
1017 printf(
"Bad width %g > %g for dot (%g, %g)\n",
getWidth(), wantedDot.
getWidth() / (size_precision + epsilon),
1025 printf(
"Bad height %g > %g for dot (%g, %g)\n", wantedDot.
getHeight() * size_precision - epsilon,
getHeight(),
1033 printf(
"Bad height %g > %g for dot (%g, %g)\n",
getHeight(), wantedDot.
getHeight() / (size_precision + epsilon),
1039 if ((((wantedDot.
getArea() * (size_precision * size_precision)) - epsilon) <
getArea()) ==
false) {
1041 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1047 if ((
getArea() < (wantedDot.
getArea() / ((size_precision * size_precision) + epsilon))) ==
false) {
1049 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
getArea(),
1050 wantedDot.
getArea() / (size_precision * size_precision + epsilon), m_cog.
get_u(), m_cog.
get_v());
1061 int nb_point_to_test = 20;
1062 int nb_bad_points = 0;
1063 int nb_max_bad_points =
static_cast<int>(nb_point_to_test * m_allowedBadPointsPercentage);
1064 double step_angle = (2 * M_PI) / nb_point_to_test;
1067 if ((std::fabs(ellipsoidShape_precision) > std::numeric_limits<double>::epsilon()) && m_compute_moment) {
1083 double tmp1 = (((m01 * m01) - (m10 * m10)) / m00) + (m20 - m02);
1084 double tmp2 = m11 - ((m10 * m01) / m00);
1085 double Sqrt = sqrt((tmp1 * tmp1) + (4 * tmp2 * tmp2));
1086 double a1 = sqrt((2 / m00) * (((m20 + m02) - (((m10 * m10) + (m01 * m01)) / m00)) + Sqrt));
1087 double a2 = sqrt((2 / m00) * (((m20 + m02) - (((m10 * m10) + (m01 * m01)) / m00)) - Sqrt));
1088 double alpha = 0.5 * atan2(2 * ((m11 * m00) - (m10 * m01)), ((((m20 - m02) * m00) - (m10 * m10)) + (m01 * m01)));
1095 double innerCoef = ellipsoidShape_precision;
1097 double cog_u = m_cog.
get_u();
1098 double cog_v = m_cog.
get_v();
1103 for (
double theta = 0.; theta < (val_2 * M_PI); theta += step_angle) {
1104 u =
static_cast<unsigned int>(cog_u + (innerCoef * ((a1 * cos(alpha) * cos(theta)) - (a2 * sin(alpha) * sin(theta)))));
1105 v =
static_cast<unsigned int>(cog_v + (innerCoef * ((a1 * sin(alpha) * cos(theta)) + (a2 * cos(alpha) * sin(theta)))));
1106 if (!this->hasGoodLevel(I, u, v)) {
1108 printf(
"Inner circle pixel (%u, %u) has bad level for dot (%g, %g): "
1109 "%d not in [%u, %u]\n",
1110 u, v, cog_u, cog_v, I[v][u], m_gray_level_min, m_gray_level_max);
1115 for (
unsigned int t = 0; t < m_thickness; ++t) {
1126 if (nb_bad_points > nb_max_bad_points) {
1128 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1137 double outCoef = 2 - ellipsoidShape_precision;
1139 for (
double theta = 0.; theta < (val_2 * M_PI); theta += step_angle) {
1140 u =
static_cast<unsigned int>(cog_u + (outCoef * ((a1 * cos(alpha) * cos(theta)) - (a2 * sin(alpha) * sin(theta)))));
1141 v =
static_cast<unsigned int>(cog_v + (outCoef * ((a1 * sin(alpha) * cos(theta)) + (a2 * cos(alpha) * sin(theta)))));
1148 if ((
static_cast<double>(u) < m_area.
getLeft()) ||
1149 (
static_cast<double>(u) > m_area.
getRight()) ||
1150 (
static_cast<double>(v) < m_area.
getTop()) ||
1151 (
static_cast<double>(v) > m_area.
getBottom())) {
1155 if (!this->hasReverseLevel(I, u, v)) {
1157 printf(
"Outside circle pixel (%u, %u) has bad level for dot (%g, "
1158 "%g): %d not in [%u, %u]\n",
1159 u, v, cog_u, cog_v, I[v][u], m_gray_level_min, m_gray_level_max);
1164 for (
unsigned int t = 0; t < m_thickness; ++t) {
1174 if (nb_bad_points > nb_max_bad_points) {
1176 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1202 bool vpDot2::hasGoodLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const
1204 if (!isInArea(u, v)) {
1208 if ((I[v][u] >= m_gray_level_min) && (I[v][u] <= m_gray_level_max)) {
1228 bool vpDot2::hasReverseLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const
1231 if (!isInArea(u, v)) {
1235 if ((I[v][u] < m_gray_level_min) || (I[v][u] > m_gray_level_max)) {
1293 m_direction_list.clear();
1294 m_ip_edges_list.clear();
1301 if (std::fabs(est_u + 1.0) <= (
vpMath::maximum(std::fabs(est_u), 1.) * std::numeric_limits<double>::epsilon())) {
1302 est_u = m_cog.
get_u();
1307 if (std::fabs(est_v + 1.0) <= (
vpMath::maximum(std::fabs(est_v), 1.) * std::numeric_limits<double>::epsilon())) {
1308 est_v = m_cog.
get_v();
1313 if (!isInArea(
static_cast<unsigned int>(est_u),
static_cast<unsigned int>(est_v))) {
1317 m_bbox_u_min =
static_cast<int>(I.
getWidth());
1319 m_bbox_v_min =
static_cast<int>(I.
getHeight());
1324 if (!hasGoodLevel(I,
static_cast<unsigned int>(est_u),
static_cast<unsigned int>(est_v))) {
1330 if (!findFirstBorder(I,
static_cast<unsigned int>(est_u),
static_cast<unsigned int>(est_v), m_firstBorder_u, m_firstBorder_v)) {
1334 unsigned int dir = 6;
1337 computeFreemanChainElement(I, m_firstBorder_u, m_firstBorder_v, dir);
1338 unsigned int firstDir = dir;
1341 if (!isInArea(m_firstBorder_u, m_firstBorder_v)) {
1346 m_direction_list.push_back(dir);
1348 ip.
set_u(m_firstBorder_u);
1349 ip.
set_v(m_firstBorder_v);
1351 m_ip_edges_list.push_back(ip);
1353 int border_u =
static_cast<int>(m_firstBorder_u);
1354 int border_v =
static_cast<int>(m_firstBorder_v);
1356 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1367 for (
int t = 0; t < static_cast<int>(m_thickness); ++t) {
1368 ip.
set_u(border_u + t);
1379 computeFreemanParameters(border_u, border_v, dir, du, dv,
1390 if (m_compute_moment) {
1396 if (!isInArea(
static_cast<unsigned int>(border_u),
static_cast<unsigned int>(border_v))) {
1403 m_direction_list.push_back(dir);
1407 m_ip_edges_list.push_back(ip);
1410 if (border_v < m_bbox_v_min) {
1411 m_bbox_v_min = border_v;
1413 if (border_v > m_bbox_v_max) {
1414 m_bbox_v_max = border_v;
1416 if (border_u < m_bbox_u_min) {
1417 m_bbox_u_min = border_u;
1419 if (border_u > m_bbox_u_max) {
1420 m_bbox_u_max = border_u;
1424 if (computeFreemanChainElement(I,
static_cast<unsigned int>(border_u),
static_cast<unsigned int>(border_v), dir) ==
false) {
1427 }
while (((getFirstBorder_u() !=
static_cast<unsigned int>(border_u)) || (getFirstBorder_v() !=
static_cast<unsigned int>(border_v)) ||
1428 (firstDir != dir)) &&
1429 isInArea(
static_cast<unsigned int>(border_u),
static_cast<unsigned int>(border_v)));
1432 #if VP_DEBUG_MODE == 3
1440 if ((std::fabs(m00) <= std::numeric_limits<double>::epsilon()) ||
1441 (std::fabs(m00 - 1.) <= (
vpMath::maximum(std::fabs(m00), 1.) * std::numeric_limits<double>::epsilon()))) {
1447 double tmpCenter_u = m10 / m00;
1448 double tmpCenter_v = m01 / m00;
1451 if (m_compute_moment) {
1452 mu11 = m11 - (tmpCenter_u * m01);
1453 mu02 = m02 - (tmpCenter_v * m01);
1454 mu20 = m20 - (tmpCenter_u * m10);
1457 m_cog.
set_u(tmpCenter_u);
1458 m_cog.
set_v(tmpCenter_v);
1461 m_width = (m_bbox_u_max - m_bbox_u_min) + 1;
1462 m_height = (m_bbox_v_max - m_bbox_v_min) + 1;
1465 computeMeanGrayLevel(I);
1484 bool vpDot2::findFirstBorder(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1485 unsigned int &border_u,
unsigned int &border_v)
1495 double epsilon = 0.001;
1498 std::cout <<
"gray level: " << m_gray_level_min <<
" " << m_gray_level_max << std::endl;
1500 while (hasGoodLevel(I, border_u + 1, border_v) && (border_u < m_area.
getRight()) ) {
1545 double u = ip.
get_u();
1546 double v = ip.
get_v();
1548 if ((u < 0) || (u >= w)) {
1551 if ((v < 0) || (v >= h)) {
1568 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const
1570 unsigned int area_u_min =
static_cast<unsigned int>(m_area.
getLeft());
1571 unsigned int area_u_max =
static_cast<unsigned int>(m_area.
getRight());
1572 unsigned int area_v_min =
static_cast<unsigned int>(m_area.
getTop());
1573 unsigned int area_v_max =
static_cast<unsigned int>(m_area.
getBottom());
1575 if ((u < area_u_min) || (u > area_u_max)) {
1578 if ((v < area_v_min) || (v > area_v_max)) {
1592 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight)
1602 if (gridWidth == 0) {
1605 if (gridHeight == 0) {
1621 int cog_u =
static_cast<int>(m_cog.
get_u());
1622 int cog_v =
static_cast<int>(m_cog.
get_v());
1624 unsigned int sum_value = 0;
1625 unsigned int nb_pixels = 0;
1627 for (
unsigned int i =
static_cast<unsigned int>(m_bbox_u_min); i <= static_cast<unsigned int>(m_bbox_u_max); ++i) {
1628 unsigned int pixel_gray =
static_cast<unsigned int>(I[
static_cast<unsigned int>(cog_v)][i]);
1630 sum_value += pixel_gray;
1634 for (
unsigned int i =
static_cast<unsigned int>(m_bbox_v_min); i <= static_cast<unsigned int>(m_bbox_v_max); ++i) {
1635 unsigned char pixel_gray = I[i][
static_cast<unsigned int>(cog_u)];
1637 sum_value += pixel_gray;
1641 const unsigned int nb_min_pixels = 10;
1642 if (nb_pixels < nb_min_pixels) {
1645 if ((cog_u - m_bbox_u_min) >(cog_v - m_bbox_v_min)) {
1646 imin = cog_v - m_bbox_v_min;
1649 imin = cog_u - m_bbox_u_min;
1651 if ((m_bbox_u_max - cog_u) > (m_bbox_v_max - cog_v)) {
1652 imax = m_bbox_v_max - cog_v;
1655 imax = m_bbox_u_max - cog_u;
1657 for (
int i = -imin; i <= imax; ++i) {
1658 unsigned int pixel_gray =
static_cast<unsigned int>(I[
static_cast<unsigned int>(cog_v + i)][
static_cast<unsigned int>(cog_u + i)]);
1660 sum_value += pixel_gray;
1665 if ((cog_u - m_bbox_u_min) > (m_bbox_v_max - cog_v)) {
1666 imin = m_bbox_v_max - cog_v;
1669 imin = cog_u - m_bbox_u_min;
1671 if ((m_bbox_u_max - cog_u) > (cog_v - m_bbox_v_min)) {
1672 imax = cog_v - m_bbox_v_min;
1675 imax = m_bbox_u_max - cog_u;
1678 for (
int i = -imin; i <= imax; ++i) {
1679 unsigned char pixel_gray = I[
static_cast<unsigned int>(cog_v - i)][
static_cast<unsigned int>(cog_u + i)];
1681 sum_value += pixel_gray;
1687 if (nb_pixels == 0) {
1692 m_mean_gray_level = sum_value / nb_pixels;
1723 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
1728 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
1735 const unsigned int cross_size = 10;
1736 for (i = 0; i < n; ++i) {
1737 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
1748 std::cout <<
"Cannot track dots from file" << std::endl;
1755 while ((i < n) && fromFile) {
1758 while ((j < n) && fromFile) {
1762 std::cout <<
"Dots from file seem incoherent" << std::endl;
1775 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
1776 const unsigned int cross_size = 10;
1777 for (i = 0; i < n; ++i) {
1787 Cogs[i][0] = cog.
get_u();
1788 Cogs[i][1] = cog.
get_v();
1794 if ((!fromFile) && (dotFile !=
"")) {
1796 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
1800 for (i = 0; i < n; ++i) {
1824 std::vector<vpImagePoint> &cogs,
vpImagePoint *cogStar)
1827 for (
unsigned int i = 0; i < n; ++i) {
1829 cogs.push_back(dot[i].
getCog());
1832 unsigned int cogs_size =
static_cast<unsigned int>(cogs.size());
1833 for (
unsigned int i = n; i < cogs_size; ++i) {
1834 const unsigned int circle_size = 4;
1838 for (
unsigned int i = 0; i < n; ++i) {
1839 const unsigned int circle_size = 4;
1843 if (cogStar !=
nullptr) {
1844 const unsigned int circle_size = 10;
1845 for (
unsigned int i = 0; i < n; ++i) {
1868 const std::list<vpImagePoint> &edges_list,
vpColor color,
unsigned int thickness)
1870 const unsigned int val_3 = 3;
1871 const unsigned int val_8 = 8;
1874 std::list<vpImagePoint>::const_iterator it;
1876 std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
1877 for (it = edges_list.begin(); it != edges_list_end; ++it) {
1897 vpColor color,
unsigned int thickness)
1899 const unsigned int val_3 = 3;
1900 const unsigned int val_8 = 8;
1902 std::list<vpImagePoint>::const_iterator it;
1903 std::list<vpImagePoint>::const_iterator edges_list_end = edges_list.end();
1904 for (it = edges_list.begin(); it != edges_list_end; ++it) {
1914 VISP_EXPORT std::ostream &
operator<<(std::ostream &os,
vpDot2 &d) {
return (os <<
"(" << d.getCog() <<
")"); }
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
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
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)
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 setRect(double l, double t, double w, double h)
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.
@ notEnoughPointError
Not enough point to track.