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) {
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;
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) {
Implementation of a matrix and operations on matrices.
void setGrayLevelMax(const unsigned int &max)
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 getFreemanChain(std::list< unsigned int > &freeman_chain) const
static bool loadMatrix(const std::string &filename, vpArray2D< double > &M, const bool binary=false, char *header=NULL)
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
unsigned int getWidth() const
void setMaxSizeSearchDistancePrecision(const double &maxSizeSearchDistancePrecision)
Class to define colors available for display functionnalities.
void setEllipsoidBadPointsPercentage(const double &percentage=0.0)
double getGrayLevelPrecision() const
vpDot2 & operator=(const vpDot2 &twinDot)
void setCog(const vpImagePoint &ip)
error that can be emited by ViSP classes.
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
double getEllipsoidShapePrecision() const
double getDistance(const vpDot2 &distantDot) const
static const vpColor green
This tracker is meant to track a blob (connex pixels with same gray level) on a vpImage.
void track(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
double getSizePrecision() const
Class that defines what is a feature generic tracker.
static Type maximum(const Type &a, const Type &b)
vpImagePoint getCog() const
friend VISP_EXPORT std::ostream & operator<<(std::ostream &os, vpDot2 &d)
void setGraphicsThickness(unsigned int t)
void setGrayLevelPrecision(const double &grayLevelPrecision)
Error that can be emited by the vpTracker class and its derivates.
double getMaxSizeSearchDistancePrecision() const
void set_u(const double u)
static double sqr(double x)
static void display(const vpImage< unsigned char > &I)
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1) const
void set_v(const double v)
unsigned int getGrayLevelMin() const
void setComputeMoments(const bool activate)
void setArea(const double &area)
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
unsigned int getRows() const
void setEllipsoidShapePrecision(const double &ellipsoidShapePrecision)
void setGrayLevelMin(const unsigned int &min)
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint ¢er, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
void setWidth(const double &width)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void trackAndDisplay(vpDot2 dot[], const unsigned int &n, vpImage< unsigned char > &I, std::vector< vpImagePoint > &cogs, vpImagePoint *cogStar=NULL)
void setSizePrecision(const double &sizePrecision)
void initTracking(const vpImage< unsigned char > &I, unsigned int size=0)
static bool saveMatrix(const std::string &filename, const vpArray2D< double > &M, const bool binary=false, const char *header="")
void setHeight(const double &height)
unsigned int getHeight() const
void set_uv(const double u, const double v)
Defines a rectangle in the plane.
double getMeanGrayLevel() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
unsigned int getGrayLevelMax() const
static const vpColor purple
void setRect(double l, double t, double w, double h)
static vpMatrix defineDots(vpDot2 dot[], const unsigned int &n, const std::string &dotFile, vpImage< unsigned char > &I, vpColor col=vpColor::blue, bool trackDot=true)
void setGraphics(const bool activate)
static void displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static const vpColor blue