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;
457 bool found = computeParameters(I, cog.
get_u(), cog.
get_v());
461 found = isValid(I, wantedDot);
480 double searchWindowWidth, searchWindowHeight;
482 if (std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon() ||
483 std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon()) {
484 searchWindowWidth = 80.;
485 searchWindowHeight = 80.;
490 std::list<vpDot2> candidates;
492 (int)(this->cog.
get_v() - searchWindowHeight / 2.0), (
unsigned int)searchWindowWidth,
493 (
unsigned int)searchWindowHeight, candidates);
497 if (candidates.empty()) {
503 vpDot2 movingDot = candidates.front();
519 bbox_u_min = movingDot.bbox_u_min;
520 bbox_u_max = movingDot.bbox_u_max;
521 bbox_v_min = movingDot.bbox_v_min;
522 bbox_v_max = movingDot.bbox_v_max;
547 "The center of gravity of the dot is not in the image"));
559 if (Ip - (1 - grayLevelPrecision) < 0) {
562 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
563 if (gray_level_min > 255)
564 gray_level_min = 255;
566 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
567 if (gray_level_max > 255)
568 gray_level_max = 255;
665 double diff_u = this->cog.
get_u() - cogDistantDot.
get_u();
666 double diff_v = this->cog.
get_v() - cogDistantDot.
get_v();
667 return sqrt(diff_u * diff_u + diff_v * diff_v);
726 double epsilon = 0.05;
727 if (grayLevelPrecision < epsilon) {
728 this->grayLevelPrecision = epsilon;
729 }
else if (grayLevelPrecision > 1) {
730 this->grayLevelPrecision = 1.0;
732 this->grayLevelPrecision = precision;
754 if (sizePrecision < 0) {
755 this->sizePrecision = 0;
756 }
else if (sizePrecision > 1) {
757 this->sizePrecision = 1.0;
759 this->sizePrecision = precision;
798 if (ellipsoidShapePrecision < 0) {
799 this->ellipsoidShapePrecision = 0;
800 }
else if (ellipsoidShapePrecision > 1) {
801 this->ellipsoidShapePrecision = 1.0;
803 this->ellipsoidShapePrecision = precision;
824 double epsilon = 0.05;
825 if (maxSizeSearchDistancePrecision < epsilon) {
826 this->maxSizeSearchDistancePrecision = epsilon;
827 }
else if (maxSizeSearchDistancePrecision > 1) {
828 this->maxSizeSearchDistancePrecision = 1.0;
830 this->maxSizeSearchDistancePrecision = precision;
858 unsigned int image_w = I.
getWidth();
864 else if (u >= (
int)image_w)
865 u = (int)image_w - 1;
868 else if (v >= (
int)image_h)
869 v = (
int)image_h - 1;
871 if (((
unsigned int)u + w) > image_w)
872 w = image_w - (
unsigned int)u - 1;
873 if (((
unsigned int)v + h) > image_h)
874 h = image_h - (
unsigned int)v - 1;
969 unsigned int area_h, std::list<vpDot2> &niceDots)
977 setArea(I, area_u, area_v, area_w, area_h);
980 unsigned int gridWidth;
981 unsigned int gridHeight;
982 getGridSize(gridWidth, gridHeight);
997 std::list<vpDot2> badDotsVector;
998 std::list<vpDot2>::iterator itnice;
999 std::list<vpDot2>::iterator itbad;
1001 vpDot2 *dotToTest = NULL;
1004 unsigned int area_u_min = (
unsigned int)area.
getLeft();
1005 unsigned int area_u_max = (
unsigned int)area.
getRight();
1006 unsigned int area_v_min = (
unsigned int)area.
getTop();
1007 unsigned int area_v_max = (
unsigned int)area.
getBottom();
1012 for (v = area_v_min; v < area_v_max; v = v + gridHeight) {
1013 for (u = area_u_min; u < area_u_max; u = u + gridWidth) {
1017 if (!hasGoodLevel(I, u, v))
1022 bool good_germ =
true;
1024 itnice = niceDots.begin();
1025 while (itnice != niceDots.end() && good_germ ==
true) {
1028 cogTmpDot = tmpDot.
getCog();
1029 double u0 = cogTmpDot.
get_u();
1030 double v0 = cogTmpDot.
get_v();
1031 double half_w = tmpDot.
getWidth() / 2.;
1032 double half_h = tmpDot.
getHeight() / 2.;
1034 if (u >= (u0 - half_w) && u <= (u0 + half_w) && v >= (v0 - half_h) && v <= (v0 + half_h)) {
1045 unsigned int border_u;
1046 unsigned int border_v;
1047 if (findFirstBorder(I, u, v, border_u, border_v) ==
false) {
1056 itbad = badDotsVector.begin();
1057 #define vpBAD_DOT_VALUE (*itbad)
1060 while (itbad != badDotsVector.end() && good_germ ==
true) {
1061 if ((
double)u >= vpBAD_DOT_VALUE.bbox_u_min && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1062 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min && (double)v <= vpBAD_DOT_VALUE.bbox_v_max) {
1063 std::list<vpImagePoint>::const_iterator it_edges = ip_edges_list.begin();
1064 while (it_edges != ip_edges_list.end() && good_germ ==
true) {
1068 cogBadDot = *it_edges;
1070 if ((std::fabs(border_u - cogBadDot.
get_u()) <=
1072 std::numeric_limits<double>::epsilon()) &&
1073 (std::fabs(v - cogBadDot.
get_v()) <=
1075 std::numeric_limits<double>::epsilon())) {
1083 #undef vpBAD_DOT_VALUE
1093 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1101 if (dotToTest != NULL)
1103 dotToTest = getInstance();
1119 if (dotToTest->computeParameters(I) ==
false) {
1127 if (dotToTest->isValid(I, *
this)) {
1134 double area_center_u = area_u + area_w / 2.0 - 0.5;
1135 double area_center_v = area_v + area_h / 2.0 - 0.5;
1137 double thisDiff_u = cogDotToTest.
get_u() - area_center_u;
1138 double thisDiff_v = cogDotToTest.
get_v() - area_center_v;
1139 double thisDist = sqrt(thisDiff_u * thisDiff_u + thisDiff_v * thisDiff_v);
1141 bool stopLoop =
false;
1142 itnice = niceDots.begin();
1144 while (itnice != niceDots.end() && stopLoop ==
false) {
1148 double epsilon = 3.0;
1151 cogTmpDot = tmpDot.
getCog();
1153 if (fabs(cogTmpDot.
get_u() - cogDotToTest.
get_u()) < epsilon &&
1154 fabs(cogTmpDot.
get_v() - cogDotToTest.
get_v()) < epsilon) {
1163 double otherDiff_u = cogTmpDot.
get_u() - area_center_u;
1164 double otherDiff_v = cogTmpDot.
get_v() - area_center_v;
1165 double otherDist = sqrt(otherDiff_u * otherDiff_u + otherDiff_v * otherDiff_v);
1170 if (otherDist > thisDist) {
1171 niceDots.insert(itnice, *dotToTest);
1182 vpTRACE(4,
"End while (%d, %d)", u, v);
1186 if (itnice == niceDots.end() && stopLoop ==
false) {
1187 niceDots.push_back(*dotToTest);
1191 badDotsVector.push_front(*dotToTest);
1195 if (dotToTest != NULL)
1231 if ((std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon()) &&
1232 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon()) &&
1233 (std::fabs(wantedDot.
getArea()) > std::numeric_limits<double>::epsilon()))
1236 if (std::fabs(size_precision) > std::numeric_limits<double>::epsilon()) {
1237 double epsilon = 0.001;
1239 std::cout <<
"test size precision......................\n";
1240 std::cout <<
"wanted dot: "
1242 <<
" precision=" << size_precision <<
" epsilon=" << epsilon << std::endl;
1243 std::cout <<
"dot found: "
1247 if ((wantedDot.
getWidth() * size_precision - epsilon <
getWidth()) ==
false) {
1250 printf(
"Bad width > for dot (%g, %g)\n", cog.
get_u(), cog.
get_v());
1255 if ((
getWidth() < wantedDot.
getWidth() / (size_precision + epsilon)) ==
false) {
1258 printf(
"Bad width %g > %g for dot (%g, %g)\n",
getWidth(), wantedDot.
getWidth() / (size_precision + epsilon),
1267 printf(
"Bad height %g > %g for dot (%g, %g)\n", wantedDot.
getHeight() * size_precision - epsilon,
getHeight(),
1276 printf(
"Bad height %g > %g for dot (%g, %g)\n",
getHeight(), wantedDot.
getHeight() / (size_precision + epsilon),
1282 if ((wantedDot.
getArea() * (size_precision * size_precision) - epsilon <
getArea()) ==
false) {
1285 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1291 if ((
getArea() < wantedDot.
getArea() / (size_precision * size_precision + epsilon)) ==
false) {
1294 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
getArea(),
1295 wantedDot.
getArea() / (size_precision * size_precision + epsilon), cog.
get_u(), cog.
get_v());
1306 int nb_point_to_test = 20;
1307 int nb_bad_points = 0;
1308 int nb_max_bad_points = (int)(nb_point_to_test * allowedBadPointsPercentage_);
1309 double step_angle = 2 * M_PI / nb_point_to_test;
1312 if (std::fabs(ellipsoidShape_precision) > std::numeric_limits<double>::epsilon() && compute_moment) {
1332 double Sqrt = sqrt(tmp1 * tmp1 + 4 * tmp2 * tmp2);
1342 double innerCoef = ellipsoidShape_precision;
1344 double cog_u = this->cog.
get_u();
1345 double cog_v = this->cog.
get_v();
1349 for (
double theta = 0.; theta < 2 * M_PI; theta += step_angle) {
1350 u = (
unsigned int)(cog_u + innerCoef * (a1 * cos(alpha) * cos(theta) - a2 * sin(alpha) * sin(theta)));
1351 v = (
unsigned int)(cog_v + innerCoef * (a1 * sin(alpha) * cos(theta) + a2 * cos(alpha) * sin(theta)));
1352 if (!this->hasGoodLevel(I, u, v)) {
1356 printf(
"Inner circle pixel (%u, %u) has bad level for dot (%g, %g): "
1357 "%d not in [%u, %u]\n",
1358 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1364 for (
unsigned int t = 0; t < thickness; t++) {
1375 if (nb_bad_points > nb_max_bad_points) {
1377 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1386 double outCoef = 2 - ellipsoidShape_precision;
1388 for (
double theta = 0.; theta < 2 * M_PI; theta += step_angle) {
1389 u = (
unsigned int)(cog_u + outCoef * (a1 * cos(alpha) * cos(theta) - a2 * sin(alpha) * sin(theta)));
1390 v = (
unsigned int)(cog_v + outCoef * (a1 * sin(alpha) * cos(theta) + a2 * cos(alpha) * sin(theta)));
1401 if (!this->hasReverseLevel(I, u, v)) {
1405 printf(
"Outside circle pixel (%u, %u) has bad level for dot (%g, "
1406 "%g): %d not in [%u, %u]\n",
1407 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1413 for (
unsigned int t = 0; t < thickness; t++) {
1422 if (nb_bad_points > nb_max_bad_points) {
1424 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1450 bool vpDot2::hasGoodLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const
1452 if (!isInArea(u, v))
1455 if (I[v][u] >= gray_level_min && I[v][u] <= gray_level_max) {
1474 bool vpDot2::hasReverseLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const
1477 if (!isInArea(u, v))
1480 if (I[v][u] < gray_level_min || I[v][u] > gray_level_max) {
1512 void vpDot2::getFreemanChain(std::list<unsigned int> &freeman_chain)
const { freeman_chain = direction_list; }
1553 direction_list.clear();
1554 ip_edges_list.clear();
1561 if (std::fabs(est_u + 1.0) <=
vpMath::maximum(std::fabs(est_u), 1.) * std::numeric_limits<double>::epsilon()) {
1562 est_u = this->cog.
get_u();
1567 if (std::fabs(est_v + 1.0) <=
vpMath::maximum(std::fabs(est_v), 1.) * std::numeric_limits<double>::epsilon()) {
1568 est_v = this->cog.
get_v();
1573 if (!isInArea((
unsigned int)est_u, (
unsigned int)est_v)) {
1575 "Initial pixel coordinates (%d, %d) for dot tracking are "
1577 (
int)est_u, (
int)est_v);
1588 if (!hasGoodLevel(I, (
unsigned int)est_u, (
unsigned int)est_v)) {
1589 vpDEBUG_TRACE(3,
"Can't find a dot from pixel (%d, %d) coordinates", (
int)est_u, (
int)est_v);
1595 if (!findFirstBorder(I, (
unsigned int)est_u, (
unsigned int)est_v, this->firstBorder_u, this->firstBorder_v)) {
1597 vpDEBUG_TRACE(3,
"Can't find first border (%d, %d) coordinates", (
int)est_u, (
int)est_v);
1601 unsigned int dir = 6;
1604 computeFreemanChainElement(I, this->firstBorder_u, this->firstBorder_v, dir);
1605 unsigned int firstDir = dir;
1608 if (!isInArea(this->firstBorder_u, this->firstBorder_v)) {
1609 vpDEBUG_TRACE(3,
"Border pixel coordinates (%d, %d) of the dot are not in the area", this->firstBorder_u,
1610 this->firstBorder_v);
1615 direction_list.push_back(dir);
1617 ip.
set_u(this->firstBorder_u);
1618 ip.
set_v(this->firstBorder_v);
1620 ip_edges_list.push_back(ip);
1622 int border_u = (int)this->firstBorder_u;
1623 int border_v = (int)this->firstBorder_v;
1629 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1640 for (
int t = 0; t < (int)thickness; t++) {
1641 ip.
set_u(border_u + t);
1653 computeFreemanParameters(border_u, border_v, dir, du, dv,
1664 if (compute_moment) {
1670 if (!isInArea((
unsigned int)border_u, (
unsigned int)border_v)) {
1672 vpDEBUG_TRACE(3,
"Dot (%d, %d) is not in the area", border_u, border_v);
1679 direction_list.push_back(dir);
1683 ip_edges_list.push_back(ip);
1688 if (border_v < bbox_v_min)
1689 bbox_v_min = border_v;
1690 if (border_v > bbox_v_max)
1691 bbox_v_max = border_v;
1692 if (border_u < bbox_u_min)
1693 bbox_u_min = border_u;
1694 if (border_u > bbox_u_max)
1695 bbox_u_max = border_u;
1698 if (computeFreemanChainElement(I, (
unsigned int)border_u, (
unsigned int)border_v, dir) ==
false) {
1699 vpDEBUG_TRACE(3,
"Can't compute Freeman chain for dot (%d, %d)", border_u, border_v);
1706 }
while ((getFirstBorder_u() != (
unsigned int)border_u || getFirstBorder_v() != (
unsigned int)border_v ||
1708 isInArea((
unsigned int)border_u, (
unsigned int)border_v));
1711 #if VP_DEBUG_MODE == 3
1719 if (std::fabs(
m00) <= std::numeric_limits<double>::epsilon() ||
1720 std::fabs(
m00 - 1.) <=
vpMath::maximum(std::fabs(
m00), 1.) * std::numeric_limits<double>::epsilon()) {
1721 vpDEBUG_TRACE(3,
"The center of gravity of the dot wasn't properly detected");
1726 double tmpCenter_u =
m10 /
m00;
1727 double tmpCenter_v =
m01 /
m00;
1730 if (compute_moment) {
1744 cog.
set_u(tmpCenter_u);
1745 cog.
set_v(tmpCenter_v);
1748 width = bbox_u_max - bbox_u_min + 1;
1749 height = bbox_v_max - bbox_v_min + 1;
1752 computeMeanGrayLevel(I);
1771 bool vpDot2::findFirstBorder(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1772 unsigned int &border_u,
unsigned int &border_v)
1782 double epsilon = 0.001;
1785 std::cout <<
"gray level: " << gray_level_min <<
" " << gray_level_max << std::endl;
1787 while (hasGoodLevel(I, border_u + 1, border_v) && border_u < area.
getRight() ) {
1793 "The found dot (%d, %d, %d) has a greater width than the "
1826 bool vpDot2::computeFreemanChainElement(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1827 unsigned int &element)
1830 if (hasGoodLevel(I, u, v)) {
1831 unsigned int _u = u;
1832 unsigned int _v = v;
1834 updateFreemanPosition(_u, _v, (element + 2) % 8);
1835 if (hasGoodLevel(I, _u, _v)) {
1836 element = (element + 2) % 8;
1838 unsigned int _u1 = u;
1839 unsigned int _v1 = v;
1840 updateFreemanPosition(_u1, _v1, (element + 1) % 8);
1842 if (hasGoodLevel(I, _u1, _v1)) {
1843 element = (element + 1) % 8;
1845 unsigned int _u2 = u;
1846 unsigned int _v2 = v;
1847 updateFreemanPosition(_u2, _v2, element);
1849 if (hasGoodLevel(I, _u2, _v2)) {
1852 unsigned int _u3 = u;
1853 unsigned int _v3 = v;
1854 updateFreemanPosition(_u3, _v3, (element + 7) % 8);
1856 if (hasGoodLevel(I, _u3, _v3)) {
1857 element = (element + 7) % 8;
1859 unsigned int _u4 = u;
1860 unsigned int _v4 = v;
1861 updateFreemanPosition(_u4, _v4, (element + 6) % 8);
1863 if (hasGoodLevel(I, _u4, _v4)) {
1864 element = (element + 6) % 8;
1866 unsigned int _u5 = u;
1867 unsigned int _v5 = v;
1868 updateFreemanPosition(_u5, _v5, (element + 5) % 8);
1870 if (hasGoodLevel(I, _u5, _v5)) {
1871 element = (element + 5) % 8;
1873 unsigned int _u6 = u;
1874 unsigned int _v6 = v;
1875 updateFreemanPosition(_u6, _v6, (element + 4) % 8);
1877 if (hasGoodLevel(I, _u6, _v6)) {
1878 element = (element + 4) % 8;
1880 unsigned int _u7 = u;
1881 unsigned int _v7 = v;
1882 updateFreemanPosition(_u7, _v7, (element + 3) % 8);
1884 if (hasGoodLevel(I, _u7, _v7)) {
1885 element = (element + 3) % 8;
1938 void vpDot2::computeFreemanParameters(
const int &u_p,
const int &v_p,
unsigned int &element,
int &du,
int &dv,
1939 float &dS,
float &dMu,
float &dMv,
float &dMuv,
float &dMu2,
float &dMv2)
1961 dMv = (float)(0.5 * v_p * v_p);
1962 if (compute_moment) {
1963 dMuv = (float)(0.25 * v_p * v_p * (2 * u_p + 1));
1965 dMv2 = (float)(1.0 / 3. * v_p * v_p * v_p);
1972 dS = (float)(v_p + 0.5);
1973 dMu = -(float)(0.5 * u_p * (u_p + 1) + 1.0 / 6.0);
1974 dMv = (float)(0.5 * v_p * (v_p + 1) + 1.0 / 6.0);
1975 if (compute_moment) {
1976 float half_u_p = (float)(0.5 * u_p);
1977 dMuv = (float)(v_p * v_p * (0.25 + half_u_p) + v_p * (1. / 3. + half_u_p) + 1. / 6. * u_p + 0.125);
1978 dMu2 = (float)(-1. / 3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) - 1. / 12.0);
1979 dMv2 = (float)(1. / 3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) + 1. / 12.0);
1986 dMu = (float)(-0.5 * u_p * u_p);
1988 if (compute_moment) {
1990 dMu2 = (float)(-1.0 / 3. * u_p * u_p * u_p);
1998 dS = (float)(-v_p - 0.5);
1999 dMu = -(float)(0.5 * u_p * (u_p - 1) + 1.0 / 6.0);
2000 dMv = -(float)(0.5 * v_p * (v_p + 1) + 1.0 / 6.0);
2001 if (compute_moment) {
2002 float half_u_p = (float)(0.5 * u_p);
2003 dMuv = (float)(v_p * v_p * (0.25 - half_u_p) + v_p * (1. / 3. - half_u_p) - 1. / 6. * u_p + 0.125);
2004 dMu2 = (float)(-1. / 3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1. / 12.0);
2005 dMv2 = (float)(-1. / 3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) - 1. / 12.0);
2012 dMv = (float)(-0.5 * v_p * v_p);
2014 if (compute_moment) {
2015 dMuv = (float)(-0.25 * v_p * v_p * (2 * u_p - 1));
2017 dMv2 = (float)(-1.0 / 3. * v_p * v_p * v_p);
2024 dS = (float)(-v_p + 0.5);
2025 dMu = (float)(0.5 * u_p * (u_p - 1) + 1.0 / 6.0);
2026 dMv = (float)(-(0.5 * v_p * (v_p - 1) + 1.0 / 6.0));
2027 if (compute_moment) {
2028 float half_u_p = (float)(0.5 * u_p);
2029 dMuv = (float)(v_p * v_p * (0.25 - half_u_p) - v_p * (1. / 3. - half_u_p) - 1. / 6. * u_p + 0.125);
2030 dMu2 = (float)(1. / 3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1. / 12.0);
2031 dMv2 = (float)(-1. / 3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1. / 12.0);
2038 dMu = (float)(0.5 * u_p * u_p);
2040 if (compute_moment) {
2042 dMu2 = (float)(1.0 / 3. * u_p * u_p * u_p);
2050 dS = (float)(v_p - 0.5);
2051 dMu = (float)(0.5 * u_p * (u_p + 1) + 1.0 / 6.0);
2052 dMv = (float)(0.5 * v_p * (v_p - 1) + 1.0 / 6.0);
2053 if (compute_moment) {
2054 float half_u_p = (float)(0.5 * u_p);
2055 dMuv = (float)(v_p * v_p * (0.25 + half_u_p) - v_p * (1. / 3. + half_u_p) + 1. / 6. * u_p + 0.125);
2056 dMu2 = (float)(1. / 3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) + 1. / 12.0);
2057 dMv2 = (float)(1. / 3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1. / 12.0);
2076 void vpDot2::updateFreemanPosition(
unsigned int &u,
unsigned int &v,
const unsigned int &dir)
2138 double u = ip.
get_u();
2139 double v = ip.
get_v();
2141 if (u < 0 || u >= w)
2143 if (v < 0 || v >= h)
2159 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const
2161 unsigned int area_u_min = (
unsigned int)area.
getLeft();
2162 unsigned int area_u_max = (
unsigned int)area.
getRight();
2163 unsigned int area_v_min = (
unsigned int)area.
getTop();
2164 unsigned int area_v_max = (
unsigned int)area.
getBottom();
2166 if (u < area_u_min || u > area_u_max)
2168 if (v < area_v_min || v > area_v_max)
2184 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight)
2196 if (gridHeight == 0)
2214 int cog_u = (int)cog.
get_u();
2215 int cog_v = (int)cog.
get_v();
2217 unsigned int sum_value = 0;
2218 unsigned int nb_pixels = 0;
2220 for (
unsigned int i = (
unsigned int)this->bbox_u_min; i <= (
unsigned int)this->bbox_u_max; i++) {
2221 unsigned int pixel_gray = (
unsigned int)I[(
unsigned int)cog_v][i];
2223 sum_value += pixel_gray;
2227 for (
unsigned int i = (
unsigned int)this->bbox_v_min; i <= (
unsigned int)this->bbox_v_max; i++) {
2228 unsigned char pixel_gray = I[i][(
unsigned int)cog_u];
2230 sum_value += pixel_gray;
2234 if (nb_pixels < 10) {
2237 if ((cog_u - bbox_u_min) > (cog_v - bbox_v_min)) {
2238 imin = cog_v - bbox_v_min;
2240 imin = cog_u - bbox_u_min;
2242 if ((bbox_u_max - cog_u) > (bbox_v_max - cog_v)) {
2243 imax = bbox_v_max - cog_v;
2245 imax = bbox_u_max - cog_u;
2247 for (
int i = -imin; i <= imax; i++) {
2248 unsigned int pixel_gray = (
unsigned int)I[(
unsigned int)(cog_v + i)][(
unsigned int)(cog_u + i)];
2250 sum_value += pixel_gray;
2255 if ((cog_u - bbox_u_min) > (bbox_v_max - cog_v)) {
2256 imin = bbox_v_max - cog_v;
2258 imin = cog_u - bbox_u_min;
2260 if ((bbox_u_max - cog_u) > (cog_v - bbox_v_min)) {
2261 imax = cog_v - bbox_v_min;
2263 imax = bbox_u_max - cog_u;
2266 for (
int i = -imin; i <= imax; i++) {
2267 unsigned char pixel_gray = I[(
unsigned int)(cog_v - i)][(
unsigned int)(cog_u + i)];
2269 sum_value += pixel_gray;
2275 if (nb_pixels == 0) {
2279 mean_gray_level = sum_value / nb_pixels;
2310 std::cout << Cogs.getRows() <<
" dots loaded from file " << dotFile << std::endl;
2314 if (Cogs.getRows() < n) {
2315 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
2322 for (i = 0; i < n; ++i) {
2323 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
2333 std::cout <<
"Cannot track dots from file" << std::endl;
2339 for (i = 0; i < n && fromFile; ++i) {
2341 for (
unsigned int j = 0; j < n && fromFile; ++j)
2345 std::cout <<
"Dots from file seem incoherent" << std::endl;
2354 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
2355 for (i = 0; i < n; i++) {
2364 Cogs[i][0] = cog.
get_u();
2365 Cogs[i][1] = cog.
get_v();
2371 if (!fromFile && (dotFile !=
"")) {
2373 std::cout << Cogs.getRows() <<
" dots written to file " << dotFile << std::endl;
2377 for (i = 0; i < n; ++i)
2400 std::vector<vpImagePoint> &cogs,
vpImagePoint *cogStar)
2404 for (i = 0; i < n; ++i) {
2406 cogs.push_back(dot[i].
getCog());
2409 for (i = n; i < cogs.size(); ++i)
2412 for (i = 0; i < n; ++i)
2415 if (cogStar != NULL)
2416 for (i = 0; i < n; ++i) {
2438 const std::list<vpImagePoint> &edges_list,
vpColor color,
unsigned int thickness)
2441 std::list<vpImagePoint>::const_iterator it;
2443 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
2463 vpColor color,
unsigned int thickness)
2466 std::list<vpImagePoint>::const_iterator it;
2468 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
2478 VISP_EXPORT std::ostream &
operator<<(std::ostream &os,
vpDot2 &d) {
return (os <<
"(" << d.getCog() <<
")"); }