47 #include <visp3/core/vpDisplay.h>
50 #include <visp3/core/vpIoTools.h>
51 #include <visp3/core/vpMath.h>
52 #include <visp3/core/vpTrackingException.h>
58 #include <visp3/blob/vpDot2.h>
81 grayLevelPrecision = 0.80;
85 ellipsoidShapePrecision = 0.65;
86 maxSizeSearchDistancePrecision = 0.65;
91 bbox_u_min = bbox_u_max = bbox_v_min = bbox_v_max = 0;
96 compute_moment =
false;
105 : m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), cog(), width(0), height(0),
106 surface(0), gray_level_min(128), gray_level_max(255), mean_gray_level(0), grayLevelPrecision(0.8), gamma(1.5),
107 sizePrecision(0.65), ellipsoidShapePrecision(0.65), maxSizeSearchDistancePrecision(0.65),
108 allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(), compute_moment(false), graphics(false),
109 thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0), firstBorder_u(0), firstBorder_v()
122 : m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), cog(ip), width(0), height(0),
123 surface(0), gray_level_min(128), gray_level_max(255), mean_gray_level(0), grayLevelPrecision(0.8), gamma(1.5),
124 sizePrecision(0.65), ellipsoidShapePrecision(0.65), maxSizeSearchDistancePrecision(0.65),
125 allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(), compute_moment(false), graphics(false),
126 thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0), firstBorder_u(0), firstBorder_v()
134 :
vpTracker(twinDot), m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.), mu11(0.), mu20(0.), mu02(0.), cog(),
135 width(0), height(0), surface(0), gray_level_min(128), gray_level_max(255), mean_gray_level(0),
136 grayLevelPrecision(0.8), gamma(1.5), sizePrecision(0.65), ellipsoidShapePrecision(0.65),
137 maxSizeSearchDistancePrecision(0.65), allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(),
138 compute_moment(false), graphics(false), thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0),
139 firstBorder_u(0), firstBorder_v()
151 width = twinDot.width;
152 height = twinDot.height;
153 surface = twinDot.surface;
154 gray_level_min = twinDot.gray_level_min;
155 gray_level_max = twinDot.gray_level_max;
156 mean_gray_level = twinDot.mean_gray_level;
157 grayLevelPrecision = twinDot.grayLevelPrecision;
158 gamma = twinDot.gamma;
160 sizePrecision = twinDot.sizePrecision;
161 ellipsoidShapePrecision = twinDot.ellipsoidShapePrecision;
162 maxSizeSearchDistancePrecision = twinDot.maxSizeSearchDistancePrecision;
163 allowedBadPointsPercentage_ = twinDot.allowedBadPointsPercentage_;
166 direction_list = twinDot.direction_list;
167 ip_edges_list = twinDot.ip_edges_list;
169 compute_moment = twinDot.compute_moment;
170 graphics = twinDot.graphics;
171 thickness = twinDot.thickness;
173 bbox_u_min = twinDot.bbox_u_min;
174 bbox_u_max = twinDot.bbox_u_max;
175 bbox_v_min = twinDot.bbox_v_min;
176 bbox_v_max = twinDot.bbox_v_max;
178 firstBorder_u = twinDot.firstBorder_u;
179 firstBorder_v = twinDot.firstBorder_v;
215 std::list<vpImagePoint>::const_iterator it;
217 for (it = ip_edges_list.begin(); it != ip_edges_list.end(); ++it) {
257 unsigned int i = (
unsigned int)cog.
get_i();
258 unsigned int j = (
unsigned int)cog.
get_j();
260 double Ip = pow((
double)I[i][j] / 255, 1 / gamma);
262 if (Ip - (1 - grayLevelPrecision) < 0) {
265 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
266 if (gray_level_min > 255)
267 gray_level_min = 255;
269 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
270 if (gray_level_max > 255)
271 gray_level_max = 255;
315 unsigned int i = (
unsigned int)cog.
get_i();
316 unsigned int j = (
unsigned int)cog.
get_j();
318 double Ip = pow((
double)I[i][j] / 255, 1 / gamma);
320 if (Ip - (1 - grayLevelPrecision) < 0) {
323 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
324 if (gray_level_min > 255)
325 gray_level_min = 255;
327 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
328 if (gray_level_max > 255)
329 gray_level_max = 255;
382 unsigned int gray_lvl_max,
unsigned int size)
386 this->gray_level_min = gray_lvl_min;
387 this->gray_level_max = gray_lvl_max;
460 bool found = computeParameters(I, cog.
get_u(), cog.
get_v());
464 found = isValid(I, wantedDot);
483 double searchWindowWidth = 0.0, searchWindowHeight = 0.0;
485 if (std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon() ||
486 std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon()) {
487 searchWindowWidth = 80.;
488 searchWindowHeight = 80.;
489 }
else if (canMakeTheWindowGrow) {
497 std::list<vpDot2> candidates;
499 (
int)(this->cog.get_v() - searchWindowHeight / 2.0), (
unsigned int)searchWindowWidth,
500 (
unsigned int)searchWindowHeight, candidates);
504 if (candidates.empty()) {
510 vpDot2 movingDot = candidates.front();
526 bbox_u_min = movingDot.bbox_u_min;
527 bbox_u_max = movingDot.bbox_u_max;
528 bbox_v_min = movingDot.bbox_v_min;
529 bbox_v_max = movingDot.bbox_v_max;
554 "The center of gravity of the dot is not in the image"));
566 if (Ip - (1 - grayLevelPrecision) < 0) {
569 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
570 if (gray_level_min > 255)
571 gray_level_min = 255;
573 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
574 if (gray_level_max > 255)
575 gray_level_max = 255;
610 track(I, canMakeTheWindowGrow);
676 double diff_u = this->cog.
get_u() - cogDistantDot.
get_u();
677 double diff_v = this->cog.
get_v() - cogDistantDot.
get_v();
678 return sqrt(diff_u * diff_u + diff_v * diff_v);
737 double epsilon = 0.05;
738 if (grayLevelPrecision < epsilon) {
739 this->grayLevelPrecision = epsilon;
740 }
else if (grayLevelPrecision > 1) {
741 this->grayLevelPrecision = 1.0;
743 this->grayLevelPrecision = precision;
765 if (sizePrecision < 0) {
766 this->sizePrecision = 0;
767 }
else if (sizePrecision > 1) {
768 this->sizePrecision = 1.0;
770 this->sizePrecision = precision;
809 if (ellipsoidShapePrecision < 0) {
810 this->ellipsoidShapePrecision = 0;
811 }
else if (ellipsoidShapePrecision > 1) {
812 this->ellipsoidShapePrecision = 1.0;
814 this->ellipsoidShapePrecision = precision;
835 double epsilon = 0.05;
836 if (maxSizeSearchDistancePrecision < epsilon) {
837 this->maxSizeSearchDistancePrecision = epsilon;
838 }
else if (maxSizeSearchDistancePrecision > 1) {
839 this->maxSizeSearchDistancePrecision = 1.0;
841 this->maxSizeSearchDistancePrecision = precision;
869 unsigned int image_w = I.
getWidth();
875 else if (u >= (
int)image_w)
876 u = (int)image_w - 1;
879 else if (v >= (
int)image_h)
880 v = (
int)image_h - 1;
882 if (((
unsigned int)u + w) > image_w)
883 w = image_w - (
unsigned int)u - 1;
884 if (((
unsigned int)v + h) > image_h)
885 h = image_h - (
unsigned int)v - 1;
980 unsigned int area_h, std::list<vpDot2> &niceDots)
988 setArea(I, area_u, area_v, area_w, area_h);
991 unsigned int gridWidth;
992 unsigned int gridHeight;
993 getGridSize(gridWidth, gridHeight);
1008 std::list<vpDot2> badDotsVector;
1009 std::list<vpDot2>::iterator itnice;
1010 std::list<vpDot2>::iterator itbad;
1012 vpDot2 *dotToTest = NULL;
1015 unsigned int area_u_min = (
unsigned int)area.
getLeft();
1016 unsigned int area_u_max = (
unsigned int)area.
getRight();
1017 unsigned int area_v_min = (
unsigned int)area.
getTop();
1018 unsigned int area_v_max = (
unsigned int)area.
getBottom();
1023 for (v = area_v_min; v < area_v_max; v = v + gridHeight) {
1024 for (u = area_u_min; u < area_u_max; u = u + gridWidth) {
1028 if (!hasGoodLevel(I, u, v))
1033 bool good_germ =
true;
1035 itnice = niceDots.begin();
1036 while (itnice != niceDots.end() && good_germ ==
true) {
1039 cogTmpDot = tmpDot.
getCog();
1040 double u0 = cogTmpDot.
get_u();
1041 double v0 = cogTmpDot.
get_v();
1042 double half_w = tmpDot.
getWidth() / 2.;
1043 double half_h = tmpDot.
getHeight() / 2.;
1045 if (u >= (u0 - half_w) && u <= (u0 + half_w) && v >= (v0 - half_h) && v <= (v0 + half_h)) {
1056 unsigned int border_u;
1057 unsigned int border_v;
1058 if (findFirstBorder(I, u, v, border_u, border_v) ==
false) {
1067 itbad = badDotsVector.begin();
1068 #define vpBAD_DOT_VALUE (*itbad)
1071 while (itbad != badDotsVector.end() && good_germ ==
true) {
1072 if ((
double)u >= vpBAD_DOT_VALUE.bbox_u_min && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1073 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min && (double)v <= vpBAD_DOT_VALUE.bbox_v_max) {
1074 std::list<vpImagePoint>::const_iterator it_edges = ip_edges_list.begin();
1075 while (it_edges != ip_edges_list.end() && good_germ ==
true) {
1079 cogBadDot = *it_edges;
1081 if ((std::fabs(border_u - cogBadDot.
get_u()) <=
1083 std::numeric_limits<double>::epsilon()) &&
1084 (std::fabs(v - cogBadDot.
get_v()) <=
1086 std::numeric_limits<double>::epsilon())) {
1094 #undef vpBAD_DOT_VALUE
1104 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1112 if (dotToTest != NULL)
1114 dotToTest = getInstance();
1130 if (dotToTest->computeParameters(I) ==
false) {
1138 if (dotToTest->isValid(I, *
this)) {
1145 double area_center_u = area_u + area_w / 2.0 - 0.5;
1146 double area_center_v = area_v + area_h / 2.0 - 0.5;
1148 double thisDiff_u = cogDotToTest.
get_u() - area_center_u;
1149 double thisDiff_v = cogDotToTest.
get_v() - area_center_v;
1150 double thisDist = sqrt(thisDiff_u * thisDiff_u + thisDiff_v * thisDiff_v);
1152 bool stopLoop =
false;
1153 itnice = niceDots.begin();
1155 while (itnice != niceDots.end() && stopLoop ==
false) {
1159 double epsilon = 3.0;
1162 cogTmpDot = tmpDot.
getCog();
1164 if (fabs(cogTmpDot.
get_u() - cogDotToTest.
get_u()) < epsilon &&
1165 fabs(cogTmpDot.
get_v() - cogDotToTest.
get_v()) < epsilon) {
1174 double otherDiff_u = cogTmpDot.
get_u() - area_center_u;
1175 double otherDiff_v = cogTmpDot.
get_v() - area_center_v;
1176 double otherDist = sqrt(otherDiff_u * otherDiff_u + otherDiff_v * otherDiff_v);
1181 if (otherDist > thisDist) {
1182 niceDots.insert(itnice, *dotToTest);
1193 vpTRACE(4,
"End while (%d, %d)", u, v);
1197 if (itnice == niceDots.end() && stopLoop ==
false) {
1198 niceDots.push_back(*dotToTest);
1202 badDotsVector.push_front(*dotToTest);
1206 if (dotToTest != NULL)
1242 if ((std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon()) &&
1243 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon()) &&
1244 (std::fabs(wantedDot.
getArea()) > std::numeric_limits<double>::epsilon()))
1247 if (std::fabs(size_precision) > std::numeric_limits<double>::epsilon()) {
1248 double epsilon = 0.001;
1250 std::cout <<
"test size precision......................\n";
1251 std::cout <<
"wanted dot: "
1253 <<
" precision=" << size_precision <<
" epsilon=" << epsilon << std::endl;
1254 std::cout <<
"dot found: "
1258 if ((wantedDot.
getWidth() * size_precision - epsilon <
getWidth()) ==
false) {
1261 printf(
"Bad width > for dot (%g, %g)\n", cog.
get_u(), cog.
get_v());
1266 if ((
getWidth() < wantedDot.
getWidth() / (size_precision + epsilon)) ==
false) {
1269 printf(
"Bad width %g > %g for dot (%g, %g)\n",
getWidth(), wantedDot.
getWidth() / (size_precision + epsilon),
1278 printf(
"Bad height %g > %g for dot (%g, %g)\n", wantedDot.
getHeight() * size_precision - epsilon,
getHeight(),
1287 printf(
"Bad height %g > %g for dot (%g, %g)\n",
getHeight(), wantedDot.
getHeight() / (size_precision + epsilon),
1293 if ((wantedDot.
getArea() * (size_precision * size_precision) - epsilon <
getArea()) ==
false) {
1296 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1302 if ((
getArea() < wantedDot.
getArea() / (size_precision * size_precision + epsilon)) ==
false) {
1305 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
getArea(),
1306 wantedDot.
getArea() / (size_precision * size_precision + epsilon), cog.
get_u(), cog.
get_v());
1317 int nb_point_to_test = 20;
1318 int nb_bad_points = 0;
1319 int nb_max_bad_points = (int)(nb_point_to_test * allowedBadPointsPercentage_);
1320 double step_angle = 2 * M_PI / nb_point_to_test;
1323 if (std::fabs(ellipsoidShape_precision) > std::numeric_limits<double>::epsilon() && compute_moment) {
1343 double Sqrt = sqrt(tmp1 * tmp1 + 4 * tmp2 * tmp2);
1353 double innerCoef = ellipsoidShape_precision;
1355 double cog_u = this->cog.
get_u();
1356 double cog_v = this->cog.
get_v();
1360 for (
double theta = 0.; theta < 2 * M_PI; theta += step_angle) {
1361 u = (
unsigned int)(cog_u + innerCoef * (a1 * cos(alpha) * cos(theta) - a2 * sin(alpha) * sin(theta)));
1362 v = (
unsigned int)(cog_v + innerCoef * (a1 * sin(alpha) * cos(theta) + a2 * cos(alpha) * sin(theta)));
1363 if (!this->hasGoodLevel(I, u, v)) {
1367 printf(
"Inner circle pixel (%u, %u) has bad level for dot (%g, %g): "
1368 "%d not in [%u, %u]\n",
1369 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1375 for (
unsigned int t = 0; t < thickness; t++) {
1386 if (nb_bad_points > nb_max_bad_points) {
1388 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1397 double outCoef = 2 - ellipsoidShape_precision;
1399 for (
double theta = 0.; theta < 2 * M_PI; theta += step_angle) {
1400 u = (
unsigned int)(cog_u + outCoef * (a1 * cos(alpha) * cos(theta) - a2 * sin(alpha) * sin(theta)));
1401 v = (
unsigned int)(cog_v + outCoef * (a1 * sin(alpha) * cos(theta) + a2 * cos(alpha) * sin(theta)));
1412 if (!this->hasReverseLevel(I, u, v)) {
1416 printf(
"Outside circle pixel (%u, %u) has bad level for dot (%g, "
1417 "%g): %d not in [%u, %u]\n",
1418 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1424 for (
unsigned int t = 0; t < thickness; t++) {
1433 if (nb_bad_points > nb_max_bad_points) {
1435 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1461 bool vpDot2::hasGoodLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const
1463 if (!isInArea(u, v))
1466 if (I[v][u] >= gray_level_min && I[v][u] <= gray_level_max) {
1485 bool vpDot2::hasReverseLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const
1488 if (!isInArea(u, v))
1491 if (I[v][u] < gray_level_min || I[v][u] > gray_level_max) {
1564 direction_list.clear();
1565 ip_edges_list.clear();
1572 if (std::fabs(est_u + 1.0) <=
vpMath::maximum(std::fabs(est_u), 1.) * std::numeric_limits<double>::epsilon()) {
1573 est_u = this->cog.
get_u();
1578 if (std::fabs(est_v + 1.0) <=
vpMath::maximum(std::fabs(est_v), 1.) * std::numeric_limits<double>::epsilon()) {
1579 est_v = this->cog.
get_v();
1584 if (!isInArea((
unsigned int)est_u, (
unsigned int)est_v)) {
1586 "Initial pixel coordinates (%d, %d) for dot tracking are "
1588 (
int)est_u, (
int)est_v);
1599 if (!hasGoodLevel(I, (
unsigned int)est_u, (
unsigned int)est_v)) {
1600 vpDEBUG_TRACE(3,
"Can't find a dot from pixel (%d, %d) coordinates", (
int)est_u, (
int)est_v);
1606 if (!findFirstBorder(I, (
unsigned int)est_u, (
unsigned int)est_v, this->firstBorder_u, this->firstBorder_v)) {
1608 vpDEBUG_TRACE(3,
"Can't find first border (%d, %d) coordinates", (
int)est_u, (
int)est_v);
1612 unsigned int dir = 6;
1615 computeFreemanChainElement(I, this->firstBorder_u, this->firstBorder_v, dir);
1616 unsigned int firstDir = dir;
1619 if (!isInArea(this->firstBorder_u, this->firstBorder_v)) {
1620 vpDEBUG_TRACE(3,
"Border pixel coordinates (%d, %d) of the dot are not in the area", this->firstBorder_u,
1621 this->firstBorder_v);
1626 direction_list.push_back(dir);
1628 ip.
set_u(this->firstBorder_u);
1629 ip.
set_v(this->firstBorder_v);
1631 ip_edges_list.push_back(ip);
1633 int border_u = (int)this->firstBorder_u;
1634 int border_v = (int)this->firstBorder_v;
1640 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1651 for (
int t = 0; t < (int)thickness; t++) {
1652 ip.
set_u(border_u + t);
1664 computeFreemanParameters(border_u, border_v, dir, du, dv,
1675 if (compute_moment) {
1681 if (!isInArea((
unsigned int)border_u, (
unsigned int)border_v)) {
1683 vpDEBUG_TRACE(3,
"Dot (%d, %d) is not in the area", border_u, border_v);
1690 direction_list.push_back(dir);
1694 ip_edges_list.push_back(ip);
1699 if (border_v < bbox_v_min)
1700 bbox_v_min = border_v;
1701 if (border_v > bbox_v_max)
1702 bbox_v_max = border_v;
1703 if (border_u < bbox_u_min)
1704 bbox_u_min = border_u;
1705 if (border_u > bbox_u_max)
1706 bbox_u_max = border_u;
1709 if (computeFreemanChainElement(I, (
unsigned int)border_u, (
unsigned int)border_v, dir) ==
false) {
1710 vpDEBUG_TRACE(3,
"Can't compute Freeman chain for dot (%d, %d)", border_u, border_v);
1717 }
while ((getFirstBorder_u() != (
unsigned int)border_u || getFirstBorder_v() != (
unsigned int)border_v ||
1719 isInArea((
unsigned int)border_u, (
unsigned int)border_v));
1722 #if VP_DEBUG_MODE == 3
1730 if (std::fabs(
m00) <= std::numeric_limits<double>::epsilon() ||
1731 std::fabs(
m00 - 1.) <=
vpMath::maximum(std::fabs(
m00), 1.) * std::numeric_limits<double>::epsilon()) {
1732 vpDEBUG_TRACE(3,
"The center of gravity of the dot wasn't properly detected");
1737 double tmpCenter_u =
m10 /
m00;
1738 double tmpCenter_v =
m01 /
m00;
1741 if (compute_moment) {
1755 cog.
set_u(tmpCenter_u);
1756 cog.
set_v(tmpCenter_v);
1759 width = bbox_u_max - bbox_u_min + 1;
1760 height = bbox_v_max - bbox_v_min + 1;
1763 computeMeanGrayLevel(I);
1782 bool vpDot2::findFirstBorder(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1783 unsigned int &border_u,
unsigned int &border_v)
1793 double epsilon = 0.001;
1796 std::cout <<
"gray level: " << gray_level_min <<
" " << gray_level_max << std::endl;
1798 while (hasGoodLevel(I, border_u + 1, border_v) && border_u < area.
getRight() ) {
1804 "The found dot (%d, %d, %d) has a greater width than the "
1837 bool vpDot2::computeFreemanChainElement(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1838 unsigned int &element)
1841 if (hasGoodLevel(I, u, v)) {
1842 unsigned int _u = u;
1843 unsigned int _v = v;
1845 updateFreemanPosition(_u, _v, (element + 2) % 8);
1846 if (hasGoodLevel(I, _u, _v)) {
1847 element = (element + 2) % 8;
1849 unsigned int _u1 = u;
1850 unsigned int _v1 = v;
1851 updateFreemanPosition(_u1, _v1, (element + 1) % 8);
1853 if (hasGoodLevel(I, _u1, _v1)) {
1854 element = (element + 1) % 8;
1856 unsigned int _u2 = u;
1857 unsigned int _v2 = v;
1858 updateFreemanPosition(_u2, _v2, element);
1860 if (hasGoodLevel(I, _u2, _v2)) {
1863 unsigned int _u3 = u;
1864 unsigned int _v3 = v;
1865 updateFreemanPosition(_u3, _v3, (element + 7) % 8);
1867 if (hasGoodLevel(I, _u3, _v3)) {
1868 element = (element + 7) % 8;
1870 unsigned int _u4 = u;
1871 unsigned int _v4 = v;
1872 updateFreemanPosition(_u4, _v4, (element + 6) % 8);
1874 if (hasGoodLevel(I, _u4, _v4)) {
1875 element = (element + 6) % 8;
1877 unsigned int _u5 = u;
1878 unsigned int _v5 = v;
1879 updateFreemanPosition(_u5, _v5, (element + 5) % 8);
1881 if (hasGoodLevel(I, _u5, _v5)) {
1882 element = (element + 5) % 8;
1884 unsigned int _u6 = u;
1885 unsigned int _v6 = v;
1886 updateFreemanPosition(_u6, _v6, (element + 4) % 8);
1888 if (hasGoodLevel(I, _u6, _v6)) {
1889 element = (element + 4) % 8;
1891 unsigned int _u7 = u;
1892 unsigned int _v7 = v;
1893 updateFreemanPosition(_u7, _v7, (element + 3) % 8);
1895 if (hasGoodLevel(I, _u7, _v7)) {
1896 element = (element + 3) % 8;
1949 void vpDot2::computeFreemanParameters(
const int &u_p,
const int &v_p,
unsigned int &element,
int &du,
int &dv,
1950 float &dS,
float &dMu,
float &dMv,
float &dMuv,
float &dMu2,
float &dMv2)
1972 dMv = (float)(0.5 * v_p * v_p);
1973 if (compute_moment) {
1974 dMuv = (float)(0.25 * v_p * v_p * (2 * u_p + 1));
1976 dMv2 = (float)(1.0 / 3. * v_p * v_p * v_p);
1983 dS = (float)(v_p + 0.5);
1984 dMu = -(float)(0.5 * u_p * (u_p + 1) + 1.0 / 6.0);
1985 dMv = (float)(0.5 * v_p * (v_p + 1) + 1.0 / 6.0);
1986 if (compute_moment) {
1987 float half_u_p = (float)(0.5 * u_p);
1988 dMuv = (float)(v_p * v_p * (0.25 + half_u_p) + v_p * (1. / 3. + half_u_p) + 1. / 6. * u_p + 0.125);
1989 dMu2 = (float)(-1. / 3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) - 1. / 12.0);
1990 dMv2 = (float)(1. / 3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) + 1. / 12.0);
1997 dMu = (float)(-0.5 * u_p * u_p);
1999 if (compute_moment) {
2001 dMu2 = (float)(-1.0 / 3. * u_p * u_p * u_p);
2009 dS = (float)(-v_p - 0.5);
2010 dMu = -(float)(0.5 * u_p * (u_p - 1) + 1.0 / 6.0);
2011 dMv = -(float)(0.5 * v_p * (v_p + 1) + 1.0 / 6.0);
2012 if (compute_moment) {
2013 float half_u_p = (float)(0.5 * u_p);
2014 dMuv = (float)(v_p * v_p * (0.25 - half_u_p) + v_p * (1. / 3. - half_u_p) - 1. / 6. * u_p + 0.125);
2015 dMu2 = (float)(-1. / 3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1. / 12.0);
2016 dMv2 = (float)(-1. / 3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) - 1. / 12.0);
2023 dMv = (float)(-0.5 * v_p * v_p);
2025 if (compute_moment) {
2026 dMuv = (float)(-0.25 * v_p * v_p * (2 * u_p - 1));
2028 dMv2 = (float)(-1.0 / 3. * v_p * v_p * v_p);
2035 dS = (float)(-v_p + 0.5);
2036 dMu = (float)(0.5 * u_p * (u_p - 1) + 1.0 / 6.0);
2037 dMv = (float)(-(0.5 * v_p * (v_p - 1) + 1.0 / 6.0));
2038 if (compute_moment) {
2039 float half_u_p = (float)(0.5 * u_p);
2040 dMuv = (float)(v_p * v_p * (0.25 - half_u_p) - v_p * (1. / 3. - half_u_p) - 1. / 6. * u_p + 0.125);
2041 dMu2 = (float)(1. / 3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1. / 12.0);
2042 dMv2 = (float)(-1. / 3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1. / 12.0);
2049 dMu = (float)(0.5 * u_p * u_p);
2051 if (compute_moment) {
2053 dMu2 = (float)(1.0 / 3. * u_p * u_p * u_p);
2061 dS = (float)(v_p - 0.5);
2062 dMu = (float)(0.5 * u_p * (u_p + 1) + 1.0 / 6.0);
2063 dMv = (float)(0.5 * v_p * (v_p - 1) + 1.0 / 6.0);
2064 if (compute_moment) {
2065 float half_u_p = (float)(0.5 * u_p);
2066 dMuv = (float)(v_p * v_p * (0.25 + half_u_p) - v_p * (1. / 3. + half_u_p) + 1. / 6. * u_p + 0.125);
2067 dMu2 = (float)(1. / 3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) + 1. / 12.0);
2068 dMv2 = (float)(1. / 3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1. / 12.0);
2087 void vpDot2::updateFreemanPosition(
unsigned int &u,
unsigned int &v,
const unsigned int &dir)
2149 double u = ip.
get_u();
2150 double v = ip.
get_v();
2152 if (u < 0 || u >= w)
2154 if (v < 0 || v >= h)
2170 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const
2172 unsigned int area_u_min = (
unsigned int)area.
getLeft();
2173 unsigned int area_u_max = (
unsigned int)area.
getRight();
2174 unsigned int area_v_min = (
unsigned int)area.
getTop();
2175 unsigned int area_v_max = (
unsigned int)area.
getBottom();
2177 if (u < area_u_min || u > area_u_max)
2179 if (v < area_v_min || v > area_v_max)
2195 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight)
2207 if (gridHeight == 0)
2225 int cog_u = (int)cog.
get_u();
2226 int cog_v = (int)cog.
get_v();
2228 unsigned int sum_value = 0;
2229 unsigned int nb_pixels = 0;
2231 for (
unsigned int i = (
unsigned int)this->bbox_u_min; i <= (
unsigned int)this->bbox_u_max; i++) {
2232 unsigned int pixel_gray = (
unsigned int)I[(
unsigned int)cog_v][i];
2234 sum_value += pixel_gray;
2238 for (
unsigned int i = (
unsigned int)this->bbox_v_min; i <= (
unsigned int)this->bbox_v_max; i++) {
2239 unsigned char pixel_gray = I[i][(
unsigned int)cog_u];
2241 sum_value += pixel_gray;
2245 if (nb_pixels < 10) {
2248 if ((cog_u - bbox_u_min) > (cog_v - bbox_v_min)) {
2249 imin = cog_v - bbox_v_min;
2251 imin = cog_u - bbox_u_min;
2253 if ((bbox_u_max - cog_u) > (bbox_v_max - cog_v)) {
2254 imax = bbox_v_max - cog_v;
2256 imax = bbox_u_max - cog_u;
2258 for (
int i = -imin; i <= imax; i++) {
2259 unsigned int pixel_gray = (
unsigned int)I[(
unsigned int)(cog_v + i)][(
unsigned int)(cog_u + i)];
2261 sum_value += pixel_gray;
2266 if ((cog_u - bbox_u_min) > (bbox_v_max - cog_v)) {
2267 imin = bbox_v_max - cog_v;
2269 imin = cog_u - bbox_u_min;
2271 if ((bbox_u_max - cog_u) > (cog_v - bbox_v_min)) {
2272 imax = cog_v - bbox_v_min;
2274 imax = bbox_u_max - cog_u;
2277 for (
int i = -imin; i <= imax; i++) {
2278 unsigned char pixel_gray = I[(
unsigned int)(cog_v - i)][(
unsigned int)(cog_u + i)];
2280 sum_value += pixel_gray;
2286 if (nb_pixels == 0) {
2290 mean_gray_level = sum_value / nb_pixels;
2321 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
2326 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
2333 for (i = 0; i < n; ++i) {
2334 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
2344 std::cout <<
"Cannot track dots from file" << std::endl;
2350 for (i = 0; i < n && fromFile; ++i) {
2352 for (
unsigned int j = 0; j < n && fromFile; ++j)
2356 std::cout <<
"Dots from file seem incoherent" << std::endl;
2365 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
2366 for (i = 0; i < n; i++) {
2375 Cogs[i][0] = cog.
get_u();
2376 Cogs[i][1] = cog.
get_v();
2382 if (!fromFile && (dotFile !=
"")) {
2384 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
2388 for (i = 0; i < n; ++i)
2411 std::vector<vpImagePoint> &cogs,
vpImagePoint *cogStar)
2415 for (i = 0; i < n; ++i) {
2417 cogs.push_back(dot[i].
getCog());
2420 for (i = n; i < cogs.size(); ++i)
2423 for (i = 0; i < n; ++i)
2426 if (cogStar != NULL)
2427 for (i = 0; i < n; ++i) {
2449 const std::list<vpImagePoint> &edges_list,
vpColor color,
unsigned int thickness)
2452 std::list<vpImagePoint>::const_iterator it;
2454 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
2474 vpColor color,
unsigned int thickness)
2477 std::list<vpImagePoint>::const_iterator it;
2479 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
2489 VISP_EXPORT std::ostream &
operator<<(std::ostream &os,
vpDot2 &d) {
return (os <<
"(" << d.getCog() <<
")"); }