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) {
258 unsigned int i = (
unsigned int)cog.
get_i();
259 unsigned int j = (
unsigned int)cog.
get_j();
261 double Ip = pow((
double)I[i][j] / 255, 1 / gamma);
263 if (Ip - (1 - grayLevelPrecision) < 0) {
266 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
267 if (gray_level_min > 255)
268 gray_level_min = 255;
270 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
271 if (gray_level_max > 255)
272 gray_level_max = 255;
316 unsigned int i = (
unsigned int)cog.
get_i();
317 unsigned int j = (
unsigned int)cog.
get_j();
319 double Ip = pow((
double)I[i][j] / 255, 1 / gamma);
321 if (Ip - (1 - grayLevelPrecision) < 0) {
324 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
325 if (gray_level_min > 255)
326 gray_level_min = 255;
328 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
329 if (gray_level_max > 255)
330 gray_level_max = 255;
383 unsigned int gray_lvl_max,
unsigned int size)
387 this->gray_level_min = gray_lvl_min;
388 this->gray_level_max = gray_lvl_max;
458 bool found = computeParameters(I, cog.
get_u(), cog.
get_v());
462 found = isValid(I, wantedDot);
481 double searchWindowWidth, searchWindowHeight;
483 if (std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon() ||
484 std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon()) {
485 searchWindowWidth = 80.;
486 searchWindowHeight = 80.;
491 std::list<vpDot2> candidates;
493 (int)(this->cog.
get_v() - searchWindowHeight / 2.0), (
unsigned int)searchWindowWidth,
494 (
unsigned int)searchWindowHeight, candidates);
498 if (candidates.empty()) {
504 vpDot2 movingDot = candidates.front();
520 bbox_u_min = movingDot.bbox_u_min;
521 bbox_u_max = movingDot.bbox_u_max;
522 bbox_v_min = movingDot.bbox_v_min;
523 bbox_v_max = movingDot.bbox_v_max;
548 "The center of gravity of the dot is not in the image"));
560 if (Ip - (1 - grayLevelPrecision) < 0) {
563 gray_level_min = (
unsigned int)(255 * pow(Ip - (1 - grayLevelPrecision), gamma));
564 if (gray_level_min > 255)
565 gray_level_min = 255;
567 gray_level_max = (
unsigned int)(255 * pow(Ip + (1 - grayLevelPrecision), gamma));
568 if (gray_level_max > 255)
569 gray_level_max = 255;
666 double diff_u = this->cog.
get_u() - cogDistantDot.
get_u();
667 double diff_v = this->cog.
get_v() - cogDistantDot.
get_v();
668 return sqrt(diff_u * diff_u + diff_v * diff_v);
727 double epsilon = 0.05;
728 if (grayLevelPrecision < epsilon) {
729 this->grayLevelPrecision = epsilon;
730 }
else if (grayLevelPrecision > 1) {
731 this->grayLevelPrecision = 1.0;
733 this->grayLevelPrecision = precision;
755 if (sizePrecision < 0) {
756 this->sizePrecision = 0;
757 }
else if (sizePrecision > 1) {
758 this->sizePrecision = 1.0;
760 this->sizePrecision = precision;
799 if (ellipsoidShapePrecision < 0) {
800 this->ellipsoidShapePrecision = 0;
801 }
else if (ellipsoidShapePrecision > 1) {
802 this->ellipsoidShapePrecision = 1.0;
804 this->ellipsoidShapePrecision = precision;
825 double epsilon = 0.05;
826 if (maxSizeSearchDistancePrecision < epsilon) {
827 this->maxSizeSearchDistancePrecision = epsilon;
828 }
else if (maxSizeSearchDistancePrecision > 1) {
829 this->maxSizeSearchDistancePrecision = 1.0;
831 this->maxSizeSearchDistancePrecision = precision;
859 unsigned int image_w = I.
getWidth();
865 else if (u >= (
int)image_w)
866 u = (int)image_w - 1;
869 else if (v >= (
int)image_h)
870 v = (
int)image_h - 1;
872 if (((
unsigned int)u + w) > image_w)
873 w = image_w - (
unsigned int)u - 1;
874 if (((
unsigned int)v + h) > image_h)
875 h = image_h - (
unsigned int)v - 1;
970 unsigned int area_h, std::list<vpDot2> &niceDots)
978 setArea(I, area_u, area_v, area_w, area_h);
981 unsigned int gridWidth;
982 unsigned int gridHeight;
983 getGridSize(gridWidth, gridHeight);
998 std::list<vpDot2> badDotsVector;
999 std::list<vpDot2>::iterator itnice;
1000 std::list<vpDot2>::iterator itbad;
1002 vpDot2 *dotToTest = NULL;
1005 unsigned int area_u_min = (
unsigned int)area.
getLeft();
1006 unsigned int area_u_max = (
unsigned int)area.
getRight();
1007 unsigned int area_v_min = (
unsigned int)area.
getTop();
1008 unsigned int area_v_max = (
unsigned int)area.
getBottom();
1013 for (v = area_v_min; v < area_v_max; v = v + gridHeight) {
1014 for (u = area_u_min; u < area_u_max; u = u + gridWidth) {
1018 if (!hasGoodLevel(I, u, v))
1023 bool good_germ =
true;
1025 itnice = niceDots.begin();
1026 while (itnice != niceDots.end() && good_germ ==
true) {
1029 cogTmpDot = tmpDot.
getCog();
1030 double u0 = cogTmpDot.
get_u();
1031 double v0 = cogTmpDot.
get_v();
1032 double half_w = tmpDot.
getWidth() / 2.;
1033 double half_h = tmpDot.
getHeight() / 2.;
1035 if (u >= (u0 - half_w) && u <= (u0 + half_w) && v >= (v0 - half_h) && v <= (v0 + half_h)) {
1046 unsigned int border_u;
1047 unsigned int border_v;
1048 if (findFirstBorder(I, u, v, border_u, border_v) ==
false) {
1057 itbad = badDotsVector.begin();
1058 #define vpBAD_DOT_VALUE (*itbad) 1061 while (itbad != badDotsVector.end() && good_germ ==
true) {
1062 if ((
double)u >= vpBAD_DOT_VALUE.bbox_u_min && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1063 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min && (double)v <= vpBAD_DOT_VALUE.bbox_v_max) {
1064 std::list<vpImagePoint>::const_iterator it_edges = ip_edges_list.begin();
1065 while (it_edges != ip_edges_list.end() && good_germ ==
true) {
1069 cogBadDot = *it_edges;
1071 if ((std::fabs(border_u - cogBadDot.
get_u()) <=
1073 std::numeric_limits<double>::epsilon()) &&
1074 (std::fabs(v - cogBadDot.
get_v()) <=
1076 std::numeric_limits<double>::epsilon())) {
1084 #undef vpBAD_DOT_VALUE 1094 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1102 if (dotToTest != NULL)
1104 dotToTest = getInstance();
1120 if (dotToTest->computeParameters(I) ==
false) {
1128 if (dotToTest->isValid(I, *
this)) {
1135 double area_center_u = area_u + area_w / 2.0 - 0.5;
1136 double area_center_v = area_v + area_h / 2.0 - 0.5;
1138 double thisDiff_u = cogDotToTest.
get_u() - area_center_u;
1139 double thisDiff_v = cogDotToTest.
get_v() - area_center_v;
1140 double thisDist = sqrt(thisDiff_u * thisDiff_u + thisDiff_v * thisDiff_v);
1142 bool stopLoop =
false;
1143 itnice = niceDots.begin();
1145 while (itnice != niceDots.end() && stopLoop ==
false) {
1149 double epsilon = 3.0;
1152 cogTmpDot = tmpDot.
getCog();
1154 if (fabs(cogTmpDot.
get_u() - cogDotToTest.
get_u()) < epsilon &&
1155 fabs(cogTmpDot.
get_v() - cogDotToTest.
get_v()) < epsilon) {
1164 double otherDiff_u = cogTmpDot.
get_u() - area_center_u;
1165 double otherDiff_v = cogTmpDot.
get_v() - area_center_v;
1166 double otherDist = sqrt(otherDiff_u * otherDiff_u + otherDiff_v * otherDiff_v);
1171 if (otherDist > thisDist) {
1172 niceDots.insert(itnice, *dotToTest);
1183 vpTRACE(4,
"End while (%d, %d)", u, v);
1187 if (itnice == niceDots.end() && stopLoop ==
false) {
1188 niceDots.push_back(*dotToTest);
1192 badDotsVector.push_front(*dotToTest);
1196 if (dotToTest != NULL)
1232 if ((std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon()) &&
1233 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon()) &&
1234 (std::fabs(wantedDot.
getArea()) > std::numeric_limits<double>::epsilon()))
1237 if (std::fabs(size_precision) > std::numeric_limits<double>::epsilon()) {
1238 double epsilon = 0.001;
1240 std::cout <<
"test size precision......................\n";
1241 std::cout <<
"wanted dot: " 1243 <<
" precision=" << size_precision <<
" epsilon=" << epsilon << std::endl;
1244 std::cout <<
"dot found: " 1248 if ((wantedDot.
getWidth() * size_precision - epsilon <
getWidth()) ==
false) {
1251 printf(
"Bad width > for dot (%g, %g)\n", cog.
get_u(), cog.
get_v());
1256 if ((
getWidth() < wantedDot.
getWidth() / (size_precision + epsilon)) ==
false) {
1259 printf(
"Bad width %g > %g for dot (%g, %g)\n",
getWidth(), wantedDot.
getWidth() / (size_precision + epsilon),
1268 printf(
"Bad height %g > %g for dot (%g, %g)\n", wantedDot.
getHeight() * size_precision - epsilon,
getHeight(),
1277 printf(
"Bad height %g > %g for dot (%g, %g)\n",
getHeight(), wantedDot.
getHeight() / (size_precision + epsilon),
1283 if ((wantedDot.
getArea() * (size_precision * size_precision) - epsilon <
getArea()) ==
false) {
1286 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1292 if ((
getArea() < wantedDot.
getArea() / (size_precision * size_precision + epsilon)) ==
false) {
1295 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
getArea(),
1296 wantedDot.
getArea() / (size_precision * size_precision + epsilon), cog.
get_u(), cog.
get_v());
1307 int nb_point_to_test = 20;
1308 int nb_bad_points = 0;
1309 int nb_max_bad_points = (int)(nb_point_to_test * allowedBadPointsPercentage_);
1310 double step_angle = 2 * M_PI / nb_point_to_test;
1313 if (std::fabs(ellipsoidShape_precision) > std::numeric_limits<double>::epsilon() && compute_moment) {
1333 double Sqrt = sqrt(tmp1 * tmp1 + 4 * tmp2 * tmp2);
1343 double innerCoef = ellipsoidShape_precision;
1345 double cog_u = this->cog.
get_u();
1346 double cog_v = this->cog.
get_v();
1350 for (
double theta = 0.; theta < 2 * M_PI; theta += step_angle) {
1351 u = (
unsigned int)(cog_u + innerCoef * (a1 * cos(alpha) * cos(theta) - a2 * sin(alpha) * sin(theta)));
1352 v = (
unsigned int)(cog_v + innerCoef * (a1 * sin(alpha) * cos(theta) + a2 * cos(alpha) * sin(theta)));
1353 if (!this->hasGoodLevel(I, u, v)) {
1357 printf(
"Inner cercle pixel (%u, %u) has bad level for dot (%g, %g): " 1358 "%d not in [%u, %u]\n",
1359 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1365 for (
unsigned int t = 0; t < thickness; t++) {
1376 if (nb_bad_points > nb_max_bad_points) {
1378 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1387 double outCoef = 2 - ellipsoidShape_precision;
1389 for (
double theta = 0.; theta < 2 * M_PI; theta += step_angle) {
1390 u = (
unsigned int)(cog_u + outCoef * (a1 * cos(alpha) * cos(theta) - a2 * sin(alpha) * sin(theta)));
1391 v = (
unsigned int)(cog_v + outCoef * (a1 * sin(alpha) * cos(theta) + a2 * cos(alpha) * sin(theta)));
1402 if (!this->hasReverseLevel(I, u, v)) {
1406 printf(
"Outside cercle pixel (%u, %u) has bad level for dot (%g, " 1407 "%g): %d not in [%u, %u]\n",
1408 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1414 for (
unsigned int t = 0; t < thickness; t++) {
1423 if (nb_bad_points > nb_max_bad_points) {
1425 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1451 bool vpDot2::hasGoodLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const 1453 if (!isInArea(u, v))
1456 if (I[v][u] >= gray_level_min && I[v][u] <= gray_level_max) {
1475 bool vpDot2::hasReverseLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const 1478 if (!isInArea(u, v))
1481 if (I[v][u] < gray_level_min || I[v][u] > gray_level_max) {
1554 direction_list.clear();
1555 ip_edges_list.clear();
1562 if (std::fabs(est_u + 1.0) <=
vpMath::maximum(std::fabs(est_u), 1.) * std::numeric_limits<double>::epsilon()) {
1563 est_u = this->cog.
get_u();
1568 if (std::fabs(est_v + 1.0) <=
vpMath::maximum(std::fabs(est_v), 1.) * std::numeric_limits<double>::epsilon()) {
1569 est_v = this->cog.
get_v();
1574 if (!isInArea((
unsigned int)est_u, (
unsigned int)est_v)) {
1576 "Initial pixel coordinates (%d, %d) for dot tracking are " 1578 (
int)est_u, (
int)est_v);
1589 if (!hasGoodLevel(I, (
unsigned int)est_u, (
unsigned int)est_v)) {
1590 vpDEBUG_TRACE(3,
"Can't find a dot from pixel (%d, %d) coordinates", (
int)est_u, (
int)est_v);
1596 if (!findFirstBorder(I, (
unsigned int)est_u, (
unsigned int)est_v, this->firstBorder_u, this->firstBorder_v)) {
1598 vpDEBUG_TRACE(3,
"Can't find first border (%d, %d) coordinates", (
int)est_u, (
int)est_v);
1602 unsigned int dir = 6;
1605 computeFreemanChainElement(I, this->firstBorder_u, this->firstBorder_v, dir);
1606 unsigned int firstDir = dir;
1609 if (!isInArea(this->firstBorder_u, this->firstBorder_v)) {
1610 vpDEBUG_TRACE(3,
"Border pixel coordinates (%d, %d) of the dot are not in the area", this->firstBorder_u,
1611 this->firstBorder_v);
1616 direction_list.push_back(dir);
1618 ip.
set_u(this->firstBorder_u);
1619 ip.
set_v(this->firstBorder_v);
1621 ip_edges_list.push_back(ip);
1623 int border_u = (int)this->firstBorder_u;
1624 int border_v = (int)this->firstBorder_v;
1630 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1641 for (
int t = 0; t < (int)thickness; t++) {
1642 ip.
set_u(border_u + t);
1654 computeFreemanParameters(border_u, border_v, dir, du, dv,
1665 if (compute_moment) {
1671 if (!isInArea((
unsigned int)border_u, (
unsigned int)border_v)) {
1673 vpDEBUG_TRACE(3,
"Dot (%d, %d) is not in the area", border_u, border_v);
1680 direction_list.push_back(dir);
1684 ip_edges_list.push_back(ip);
1689 if (border_v < bbox_v_min)
1690 bbox_v_min = border_v;
1691 if (border_v > bbox_v_max)
1692 bbox_v_max = border_v;
1693 if (border_u < bbox_u_min)
1694 bbox_u_min = border_u;
1695 if (border_u > bbox_u_max)
1696 bbox_u_max = border_u;
1699 if (computeFreemanChainElement(I, (
unsigned int)border_u, (
unsigned int)border_v, dir) ==
false) {
1700 vpDEBUG_TRACE(3,
"Can't compute Freeman chain for dot (%d, %d)", border_u, border_v);
1707 }
while ((getFirstBorder_u() != (
unsigned int)border_u || getFirstBorder_v() != (
unsigned int)border_v ||
1709 isInArea((
unsigned int)border_u, (
unsigned int)border_v));
1712 #if VP_DEBUG_MODE == 3 1720 if (std::fabs(
m00) <= std::numeric_limits<double>::epsilon() ||
1721 std::fabs(
m00 - 1.) <=
vpMath::maximum(std::fabs(
m00), 1.) * std::numeric_limits<double>::epsilon()) {
1722 vpDEBUG_TRACE(3,
"The center of gravity of the dot wasn't properly detected");
1727 double tmpCenter_u =
m10 /
m00;
1728 double tmpCenter_v =
m01 /
m00;
1731 if (compute_moment) {
1745 cog.
set_u(tmpCenter_u);
1746 cog.
set_v(tmpCenter_v);
1749 width = bbox_u_max - bbox_u_min + 1;
1750 height = bbox_v_max - bbox_v_min + 1;
1753 computeMeanGrayLevel(I);
1772 bool vpDot2::findFirstBorder(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1773 unsigned int &border_u,
unsigned int &border_v)
1783 double epsilon = 0.001;
1786 std::cout <<
"gray level: " << gray_level_min <<
" " << gray_level_max << std::endl;
1788 while (hasGoodLevel(I, border_u + 1, border_v) && border_u < area.
getRight() ) {
1794 "The found dot (%d, %d, %d) has a greater width than the " 1827 bool vpDot2::computeFreemanChainElement(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1828 unsigned int &element)
1831 if (hasGoodLevel(I, u, v)) {
1832 unsigned int _u = u;
1833 unsigned int _v = v;
1835 updateFreemanPosition(_u, _v, (element + 2) % 8);
1836 if (hasGoodLevel(I, _u, _v)) {
1837 element = (element + 2) % 8;
1839 unsigned int _u1 = u;
1840 unsigned int _v1 = v;
1841 updateFreemanPosition(_u1, _v1, (element + 1) % 8);
1843 if (hasGoodLevel(I, _u1, _v1)) {
1844 element = (element + 1) % 8;
1846 unsigned int _u2 = u;
1847 unsigned int _v2 = v;
1848 updateFreemanPosition(_u2, _v2, element);
1850 if (hasGoodLevel(I, _u2, _v2)) {
1853 unsigned int _u3 = u;
1854 unsigned int _v3 = v;
1855 updateFreemanPosition(_u3, _v3, (element + 7) % 8);
1857 if (hasGoodLevel(I, _u3, _v3)) {
1858 element = (element + 7) % 8;
1860 unsigned int _u4 = u;
1861 unsigned int _v4 = v;
1862 updateFreemanPosition(_u4, _v4, (element + 6) % 8);
1864 if (hasGoodLevel(I, _u4, _v4)) {
1865 element = (element + 6) % 8;
1867 unsigned int _u5 = u;
1868 unsigned int _v5 = v;
1869 updateFreemanPosition(_u5, _v5, (element + 5) % 8);
1871 if (hasGoodLevel(I, _u5, _v5)) {
1872 element = (element + 5) % 8;
1874 unsigned int _u6 = u;
1875 unsigned int _v6 = v;
1876 updateFreemanPosition(_u6, _v6, (element + 4) % 8);
1878 if (hasGoodLevel(I, _u6, _v6)) {
1879 element = (element + 4) % 8;
1881 unsigned int _u7 = u;
1882 unsigned int _v7 = v;
1883 updateFreemanPosition(_u7, _v7, (element + 3) % 8);
1885 if (hasGoodLevel(I, _u7, _v7)) {
1886 element = (element + 3) % 8;
1939 void vpDot2::computeFreemanParameters(
const int &u_p,
const int &v_p,
unsigned int &element,
int &du,
int &dv,
1940 float &dS,
float &dMu,
float &dMv,
float &dMuv,
float &dMu2,
float &dMv2)
1962 dMv = (float)(0.5 * v_p * v_p);
1963 if (compute_moment) {
1964 dMuv = (float)(0.25 * v_p * v_p * (2 * u_p + 1));
1966 dMv2 = (float)(1.0 / 3. * v_p * v_p * v_p);
1973 dS = (float)(v_p + 0.5);
1974 dMu = -(float)(0.5 * u_p * (u_p + 1) + 1.0 / 6.0);
1975 dMv = (float)(0.5 * v_p * (v_p + 1) + 1.0 / 6.0);
1976 if (compute_moment) {
1977 float half_u_p = (float)(0.5 * u_p);
1978 dMuv = (float)(v_p * v_p * (0.25 + half_u_p) + v_p * (1. / 3. + half_u_p) + 1. / 6. * u_p + 0.125);
1979 dMu2 = (float)(-1. / 3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) - 1. / 12.0);
1980 dMv2 = (float)(1. / 3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) + 1. / 12.0);
1987 dMu = (float)(-0.5 * u_p * u_p);
1989 if (compute_moment) {
1991 dMu2 = (float)(-1.0 / 3. * u_p * u_p * u_p);
1999 dS = (float)(-v_p - 0.5);
2000 dMu = -(float)(0.5 * u_p * (u_p - 1) + 1.0 / 6.0);
2001 dMv = -(float)(0.5 * v_p * (v_p + 1) + 1.0 / 6.0);
2002 if (compute_moment) {
2003 float half_u_p = (float)(0.5 * u_p);
2004 dMuv = (float)(v_p * v_p * (0.25 - half_u_p) + v_p * (1. / 3. - half_u_p) - 1. / 6. * u_p + 0.125);
2005 dMu2 = (float)(-1. / 3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1. / 12.0);
2006 dMv2 = (float)(-1. / 3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) - 1. / 12.0);
2013 dMv = (float)(-0.5 * v_p * v_p);
2015 if (compute_moment) {
2016 dMuv = (float)(-0.25 * v_p * v_p * (2 * u_p - 1));
2018 dMv2 = (float)(-1.0 / 3. * v_p * v_p * v_p);
2025 dS = (float)(-v_p + 0.5);
2026 dMu = (float)(0.5 * u_p * (u_p - 1) + 1.0 / 6.0);
2027 dMv = (float)(-(0.5 * v_p * (v_p - 1) + 1.0 / 6.0));
2028 if (compute_moment) {
2029 float half_u_p = (float)(0.5 * u_p);
2030 dMuv = (float)(v_p * v_p * (0.25 - half_u_p) - v_p * (1. / 3. - half_u_p) - 1. / 6. * u_p + 0.125);
2031 dMu2 = (float)(1. / 3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1. / 12.0);
2032 dMv2 = (float)(-1. / 3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1. / 12.0);
2039 dMu = (float)(0.5 * u_p * u_p);
2041 if (compute_moment) {
2043 dMu2 = (float)(1.0 / 3. * u_p * u_p * u_p);
2051 dS = (float)(v_p - 0.5);
2052 dMu = (float)(0.5 * u_p * (u_p + 1) + 1.0 / 6.0);
2053 dMv = (float)(0.5 * v_p * (v_p - 1) + 1.0 / 6.0);
2054 if (compute_moment) {
2055 float half_u_p = (float)(0.5 * u_p);
2056 dMuv = (float)(v_p * v_p * (0.25 + half_u_p) - v_p * (1. / 3. + half_u_p) + 1. / 6. * u_p + 0.125);
2057 dMu2 = (float)(1. / 3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) + 1. / 12.0);
2058 dMv2 = (float)(1. / 3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1. / 12.0);
2077 void vpDot2::updateFreemanPosition(
unsigned int &u,
unsigned int &v,
const unsigned int &dir)
2139 double u = ip.
get_u();
2140 double v = ip.
get_v();
2142 if (u < 0 || u >= w)
2144 if (v < 0 || v >= h)
2160 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const 2162 unsigned int area_u_min = (
unsigned int)area.
getLeft();
2163 unsigned int area_u_max = (
unsigned int)area.
getRight();
2164 unsigned int area_v_min = (
unsigned int)area.
getTop();
2165 unsigned int area_v_max = (
unsigned int)area.
getBottom();
2167 if (u < area_u_min || u > area_u_max)
2169 if (v < area_v_min || v > area_v_max)
2185 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight)
2197 if (gridHeight == 0)
2215 int cog_u = (int)cog.
get_u();
2216 int cog_v = (int)cog.
get_v();
2218 unsigned int sum_value = 0;
2219 unsigned int nb_pixels = 0;
2221 for (
unsigned int i = (
unsigned int)this->bbox_u_min; i <= (
unsigned int)this->bbox_u_max; i++) {
2222 unsigned int pixel_gray = (
unsigned int)I[(
unsigned int)cog_v][i];
2224 sum_value += pixel_gray;
2228 for (
unsigned int i = (
unsigned int)this->bbox_v_min; i <= (
unsigned int)this->bbox_v_max; i++) {
2229 unsigned char pixel_gray = I[i][(
unsigned int)cog_u];
2231 sum_value += pixel_gray;
2235 if (nb_pixels < 10) {
2238 if ((cog_u - bbox_u_min) > (cog_v - bbox_v_min)) {
2239 imin = cog_v - bbox_v_min;
2241 imin = cog_u - bbox_u_min;
2243 if ((bbox_u_max - cog_u) > (bbox_v_max - cog_v)) {
2244 imax = bbox_v_max - cog_v;
2246 imax = bbox_u_max - cog_u;
2248 for (
int i = -imin; i <= imax; i++) {
2249 unsigned int pixel_gray = (
unsigned int)I[(
unsigned int)(cog_v + i)][(
unsigned int)(cog_u + i)];
2251 sum_value += pixel_gray;
2256 if ((cog_u - bbox_u_min) > (bbox_v_max - cog_v)) {
2257 imin = bbox_v_max - cog_v;
2259 imin = cog_u - bbox_u_min;
2261 if ((bbox_u_max - cog_u) > (cog_v - bbox_v_min)) {
2262 imax = cog_v - bbox_v_min;
2264 imax = bbox_u_max - cog_u;
2267 for (
int i = -imin; i <= imax; i++) {
2268 unsigned char pixel_gray = I[(
unsigned int)(cog_v - i)][(
unsigned int)(cog_u + i)];
2270 sum_value += pixel_gray;
2276 if (nb_pixels == 0) {
2280 mean_gray_level = sum_value / nb_pixels;
2311 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
2316 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
2323 for (i = 0; i < n; ++i) {
2324 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
2334 std::cout <<
"Cannot track dots from file" << std::endl;
2340 for (i = 0; i < n && fromFile; ++i) {
2342 for (
unsigned int j = 0; j < n && fromFile; ++j)
2346 std::cout <<
"Dots from file seem incoherent" << std::endl;
2355 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
2356 for (i = 0; i < n; i++) {
2365 Cogs[i][0] = cog.
get_u();
2366 Cogs[i][1] = cog.
get_v();
2372 if (!fromFile && (dotFile !=
"")) {
2374 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
2378 for (i = 0; i < n; ++i)
2401 std::vector<vpImagePoint> &cogs,
vpImagePoint *cogStar)
2405 for (i = 0; i < n; ++i) {
2407 cogs.push_back(dot[i].
getCog());
2410 for (i = n; i < cogs.size(); ++i)
2413 for (i = 0; i < n; ++i)
2416 if (cogStar != NULL)
2417 for (i = 0; i < n; ++i) {
2439 const std::list<vpImagePoint> &edges_list,
vpColor color,
unsigned int thickness)
2442 std::list<vpImagePoint>::const_iterator it;
2444 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
2464 vpColor color,
unsigned int thickness)
2467 std::list<vpImagePoint>::const_iterator it;
2469 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
Implementation of a matrix and operations on matrices.
double getMeanGrayLevel() const
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)
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)
void setMaxSizeSearchDistancePrecision(const double &maxSizeSearchDistancePrecision)
double getSizePrecision() const
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1) const
Class to define colors available for display functionnalities.
void setEllipsoidBadPointsPercentage(const double &percentage=0.0)
vpDot2 & operator=(const vpDot2 &twinDot)
void setCog(const vpImagePoint &ip)
error that can be emited by ViSP classes.
unsigned int getRows() const
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
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)
Class that defines what is a feature generic tracker.
static Type maximum(const Type &a, const Type &b)
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.
void set_u(const double u)
static double sqr(double x)
static void display(const vpImage< unsigned char > &I)
void set_v(const double v)
unsigned int getGrayLevelMin() const
double getDistance(const vpDot2 &distantDot) 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)
void setEllipsoidShapePrecision(const double &ellipsoidShapePrecision)
double getGrayLevelPrecision() const
void setGrayLevelMin(const unsigned int &min)
unsigned int getGrayLevelMax() const
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)
unsigned int getHeight() const
void getFreemanChain(std::list< unsigned int > &freeman_chain) const
double getMaxSizeSearchDistancePrecision() const
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="")
double getEllipsoidShapePrecision() const
void setHeight(const double &height)
vpImagePoint getCog() const
void set_uv(const double u, const double v)
Defines a rectangle in the plane.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static const vpColor purple
void setRect(double l, double t, double w, double h)
unsigned int getWidth() const
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