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) {
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 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
void set_uv(double u, double v)
Class to define colors available for display functionnalities.
void setEllipsoidBadPointsPercentage(const double &percentage=0.0)
void setGraphics(bool activate)
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 bool saveMatrix(const std::string &filename, const vpArray2D< double > &M, bool binary=false, const char *header="")
static const vpColor green
This tracker is meant to track a blob (connex pixels with same gray level) on a vpImage.
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.
static double sqr(double x)
static void display(const vpImage< unsigned char > &I)
unsigned int getGrayLevelMin() const
double getDistance(const vpDot2 &distantDot) const
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 track(const vpImage< unsigned char > &I, bool canMakeTheWindowGrow=true)
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)
double getEllipsoidShapePrecision() const
void setHeight(const double &height)
vpImagePoint getCog() const
void setComputeMoments(bool activate)
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)
static bool loadMatrix(const std::string &filename, vpArray2D< double > &M, bool binary=false, char *header=NULL)
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