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) {
1340 double Sqrt = sqrt(tmp1 * tmp1 + 4 * tmp2 * tmp2);
1350 double innerCoef = ellipsoidShape_precision;
1352 double cog_u = this->cog.
get_u();
1353 double cog_v = this->cog.
get_v();
1357 for (
double theta = 0.; theta < 2 * M_PI; theta += step_angle) {
1358 u = (
unsigned int)(cog_u + innerCoef * (a1 * cos(alpha) * cos(theta) - a2 * sin(alpha) * sin(theta)));
1359 v = (
unsigned int)(cog_v + innerCoef * (a1 * sin(alpha) * cos(theta) + a2 * cos(alpha) * sin(theta)));
1360 if (!this->hasGoodLevel(I, u, v)) {
1364 printf(
"Inner circle pixel (%u, %u) has bad level for dot (%g, %g): " 1365 "%d not in [%u, %u]\n",
1366 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1372 for (
unsigned int t = 0; t < thickness; t++) {
1383 if (nb_bad_points > nb_max_bad_points) {
1385 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1394 double outCoef = 2 - ellipsoidShape_precision;
1396 for (
double theta = 0.; theta < 2 * M_PI; theta += step_angle) {
1397 u = (
unsigned int)(cog_u + outCoef * (a1 * cos(alpha) * cos(theta) - a2 * sin(alpha) * sin(theta)));
1398 v = (
unsigned int)(cog_v + outCoef * (a1 * sin(alpha) * cos(theta) + a2 * cos(alpha) * sin(theta)));
1409 if (!this->hasReverseLevel(I, u, v)) {
1413 printf(
"Outside circle pixel (%u, %u) has bad level for dot (%g, " 1414 "%g): %d not in [%u, %u]\n",
1415 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1421 for (
unsigned int t = 0; t < thickness; t++) {
1430 if (nb_bad_points > nb_max_bad_points) {
1432 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n", nb_bad_points, nb_max_bad_points);
1458 bool vpDot2::hasGoodLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const 1460 if (!isInArea(u, v))
1463 if (I[v][u] >= gray_level_min && I[v][u] <= gray_level_max) {
1482 bool vpDot2::hasReverseLevel(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v)
const 1485 if (!isInArea(u, v))
1488 if (I[v][u] < gray_level_min || I[v][u] > gray_level_max) {
1561 direction_list.clear();
1562 ip_edges_list.clear();
1569 if (std::fabs(est_u + 1.0) <=
vpMath::maximum(std::fabs(est_u), 1.) * std::numeric_limits<double>::epsilon()) {
1570 est_u = this->cog.
get_u();
1575 if (std::fabs(est_v + 1.0) <=
vpMath::maximum(std::fabs(est_v), 1.) * std::numeric_limits<double>::epsilon()) {
1576 est_v = this->cog.
get_v();
1581 if (!isInArea((
unsigned int)est_u, (
unsigned int)est_v)) {
1583 "Initial pixel coordinates (%d, %d) for dot tracking are " 1585 (
int)est_u, (
int)est_v);
1596 if (!hasGoodLevel(I, (
unsigned int)est_u, (
unsigned int)est_v)) {
1597 vpDEBUG_TRACE(3,
"Can't find a dot from pixel (%d, %d) coordinates", (
int)est_u, (
int)est_v);
1603 if (!findFirstBorder(I, (
unsigned int)est_u, (
unsigned int)est_v, this->firstBorder_u, this->firstBorder_v)) {
1605 vpDEBUG_TRACE(3,
"Can't find first border (%d, %d) coordinates", (
int)est_u, (
int)est_v);
1609 unsigned int dir = 6;
1612 computeFreemanChainElement(I, this->firstBorder_u, this->firstBorder_v, dir);
1613 unsigned int firstDir = dir;
1616 if (!isInArea(this->firstBorder_u, this->firstBorder_v)) {
1617 vpDEBUG_TRACE(3,
"Border pixel coordinates (%d, %d) of the dot are not in the area", this->firstBorder_u,
1618 this->firstBorder_v);
1623 direction_list.push_back(dir);
1625 ip.
set_u(this->firstBorder_u);
1626 ip.
set_v(this->firstBorder_v);
1628 ip_edges_list.push_back(ip);
1630 int border_u = (int)this->firstBorder_u;
1631 int border_v = (int)this->firstBorder_v;
1637 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1648 for (
int t = 0; t < (int)thickness; t++) {
1649 ip.
set_u(border_u + t);
1661 computeFreemanParameters(border_u, border_v, dir, du, dv,
1672 if (compute_moment) {
1678 if (!isInArea((
unsigned int)border_u, (
unsigned int)border_v)) {
1680 vpDEBUG_TRACE(3,
"Dot (%d, %d) is not in the area", border_u, border_v);
1687 direction_list.push_back(dir);
1691 ip_edges_list.push_back(ip);
1696 if (border_v < bbox_v_min)
1697 bbox_v_min = border_v;
1698 if (border_v > bbox_v_max)
1699 bbox_v_max = border_v;
1700 if (border_u < bbox_u_min)
1701 bbox_u_min = border_u;
1702 if (border_u > bbox_u_max)
1703 bbox_u_max = border_u;
1706 if (computeFreemanChainElement(I, (
unsigned int)border_u, (
unsigned int)border_v, dir) ==
false) {
1707 vpDEBUG_TRACE(3,
"Can't compute Freeman chain for dot (%d, %d)", border_u, border_v);
1714 }
while ((getFirstBorder_u() != (
unsigned int)border_u || getFirstBorder_v() != (
unsigned int)border_v ||
1716 isInArea((
unsigned int)border_u, (
unsigned int)border_v));
1719 #if VP_DEBUG_MODE == 3 1727 if (std::fabs(
m00) <= std::numeric_limits<double>::epsilon() ||
1728 std::fabs(
m00 - 1.) <=
vpMath::maximum(std::fabs(
m00), 1.) * std::numeric_limits<double>::epsilon()) {
1729 vpDEBUG_TRACE(3,
"The center of gravity of the dot wasn't properly detected");
1734 double tmpCenter_u =
m10 /
m00;
1735 double tmpCenter_v =
m01 /
m00;
1738 if (compute_moment) {
1752 cog.
set_u(tmpCenter_u);
1753 cog.
set_v(tmpCenter_v);
1756 width = bbox_u_max - bbox_u_min + 1;
1757 height = bbox_v_max - bbox_v_min + 1;
1760 computeMeanGrayLevel(I);
1779 bool vpDot2::findFirstBorder(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1780 unsigned int &border_u,
unsigned int &border_v)
1790 double epsilon = 0.001;
1793 std::cout <<
"gray level: " << gray_level_min <<
" " << gray_level_max << std::endl;
1795 while (hasGoodLevel(I, border_u + 1, border_v) && border_u < area.
getRight() ) {
1801 "The found dot (%d, %d, %d) has a greater width than the " 1834 bool vpDot2::computeFreemanChainElement(
const vpImage<unsigned char> &I,
const unsigned int &u,
const unsigned int &v,
1835 unsigned int &element)
1838 if (hasGoodLevel(I, u, v)) {
1839 unsigned int _u = u;
1840 unsigned int _v = v;
1842 updateFreemanPosition(_u, _v, (element + 2) % 8);
1843 if (hasGoodLevel(I, _u, _v)) {
1844 element = (element + 2) % 8;
1846 unsigned int _u1 = u;
1847 unsigned int _v1 = v;
1848 updateFreemanPosition(_u1, _v1, (element + 1) % 8);
1850 if (hasGoodLevel(I, _u1, _v1)) {
1851 element = (element + 1) % 8;
1853 unsigned int _u2 = u;
1854 unsigned int _v2 = v;
1855 updateFreemanPosition(_u2, _v2, element);
1857 if (hasGoodLevel(I, _u2, _v2)) {
1860 unsigned int _u3 = u;
1861 unsigned int _v3 = v;
1862 updateFreemanPosition(_u3, _v3, (element + 7) % 8);
1864 if (hasGoodLevel(I, _u3, _v3)) {
1865 element = (element + 7) % 8;
1867 unsigned int _u4 = u;
1868 unsigned int _v4 = v;
1869 updateFreemanPosition(_u4, _v4, (element + 6) % 8);
1871 if (hasGoodLevel(I, _u4, _v4)) {
1872 element = (element + 6) % 8;
1874 unsigned int _u5 = u;
1875 unsigned int _v5 = v;
1876 updateFreemanPosition(_u5, _v5, (element + 5) % 8);
1878 if (hasGoodLevel(I, _u5, _v5)) {
1879 element = (element + 5) % 8;
1881 unsigned int _u6 = u;
1882 unsigned int _v6 = v;
1883 updateFreemanPosition(_u6, _v6, (element + 4) % 8);
1885 if (hasGoodLevel(I, _u6, _v6)) {
1886 element = (element + 4) % 8;
1888 unsigned int _u7 = u;
1889 unsigned int _v7 = v;
1890 updateFreemanPosition(_u7, _v7, (element + 3) % 8);
1892 if (hasGoodLevel(I, _u7, _v7)) {
1893 element = (element + 3) % 8;
1946 void vpDot2::computeFreemanParameters(
const int &u_p,
const int &v_p,
unsigned int &element,
int &du,
int &dv,
1947 float &dS,
float &dMu,
float &dMv,
float &dMuv,
float &dMu2,
float &dMv2)
1969 dMv = (float)(0.5 * v_p * v_p);
1970 if (compute_moment) {
1971 dMuv = (float)(0.25 * v_p * v_p * (2 * u_p + 1));
1973 dMv2 = (float)(1.0 / 3. * v_p * v_p * v_p);
1980 dS = (float)(v_p + 0.5);
1981 dMu = -(float)(0.5 * u_p * (u_p + 1) + 1.0 / 6.0);
1982 dMv = (float)(0.5 * v_p * (v_p + 1) + 1.0 / 6.0);
1983 if (compute_moment) {
1984 float half_u_p = (float)(0.5 * u_p);
1985 dMuv = (float)(v_p * v_p * (0.25 + half_u_p) + v_p * (1. / 3. + half_u_p) + 1. / 6. * u_p + 0.125);
1986 dMu2 = (float)(-1. / 3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) - 1. / 12.0);
1987 dMv2 = (float)(1. / 3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) + 1. / 12.0);
1994 dMu = (float)(-0.5 * u_p * u_p);
1996 if (compute_moment) {
1998 dMu2 = (float)(-1.0 / 3. * u_p * u_p * u_p);
2006 dS = (float)(-v_p - 0.5);
2007 dMu = -(float)(0.5 * u_p * (u_p - 1) + 1.0 / 6.0);
2008 dMv = -(float)(0.5 * v_p * (v_p + 1) + 1.0 / 6.0);
2009 if (compute_moment) {
2010 float half_u_p = (float)(0.5 * u_p);
2011 dMuv = (float)(v_p * v_p * (0.25 - half_u_p) + v_p * (1. / 3. - half_u_p) - 1. / 6. * u_p + 0.125);
2012 dMu2 = (float)(-1. / 3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1. / 12.0);
2013 dMv2 = (float)(-1. / 3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) - 1. / 12.0);
2020 dMv = (float)(-0.5 * v_p * v_p);
2022 if (compute_moment) {
2023 dMuv = (float)(-0.25 * v_p * v_p * (2 * u_p - 1));
2025 dMv2 = (float)(-1.0 / 3. * v_p * v_p * v_p);
2032 dS = (float)(-v_p + 0.5);
2033 dMu = (float)(0.5 * u_p * (u_p - 1) + 1.0 / 6.0);
2034 dMv = (float)(-(0.5 * v_p * (v_p - 1) + 1.0 / 6.0));
2035 if (compute_moment) {
2036 float half_u_p = (float)(0.5 * u_p);
2037 dMuv = (float)(v_p * v_p * (0.25 - half_u_p) - v_p * (1. / 3. - half_u_p) - 1. / 6. * u_p + 0.125);
2038 dMu2 = (float)(1. / 3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1. / 12.0);
2039 dMv2 = (float)(-1. / 3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1. / 12.0);
2046 dMu = (float)(0.5 * u_p * u_p);
2048 if (compute_moment) {
2050 dMu2 = (float)(1.0 / 3. * u_p * u_p * u_p);
2058 dS = (float)(v_p - 0.5);
2059 dMu = (float)(0.5 * u_p * (u_p + 1) + 1.0 / 6.0);
2060 dMv = (float)(0.5 * v_p * (v_p - 1) + 1.0 / 6.0);
2061 if (compute_moment) {
2062 float half_u_p = (float)(0.5 * u_p);
2063 dMuv = (float)(v_p * v_p * (0.25 + half_u_p) - v_p * (1. / 3. + half_u_p) + 1. / 6. * u_p + 0.125);
2064 dMu2 = (float)(1. / 3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) + 1. / 12.0);
2065 dMv2 = (float)(1. / 3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1. / 12.0);
2084 void vpDot2::updateFreemanPosition(
unsigned int &u,
unsigned int &v,
const unsigned int &dir)
2146 double u = ip.
get_u();
2147 double v = ip.
get_v();
2149 if (u < 0 || u >= w)
2151 if (v < 0 || v >= h)
2167 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const 2169 unsigned int area_u_min = (
unsigned int)area.
getLeft();
2170 unsigned int area_u_max = (
unsigned int)area.
getRight();
2171 unsigned int area_v_min = (
unsigned int)area.
getTop();
2172 unsigned int area_v_max = (
unsigned int)area.
getBottom();
2174 if (u < area_u_min || u > area_u_max)
2176 if (v < area_v_min || v > area_v_max)
2192 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight)
2204 if (gridHeight == 0)
2222 int cog_u = (int)cog.
get_u();
2223 int cog_v = (int)cog.
get_v();
2225 unsigned int sum_value = 0;
2226 unsigned int nb_pixels = 0;
2228 for (
unsigned int i = (
unsigned int)this->bbox_u_min; i <= (
unsigned int)this->bbox_u_max; i++) {
2229 unsigned int pixel_gray = (
unsigned int)I[(
unsigned int)cog_v][i];
2231 sum_value += pixel_gray;
2235 for (
unsigned int i = (
unsigned int)this->bbox_v_min; i <= (
unsigned int)this->bbox_v_max; i++) {
2236 unsigned char pixel_gray = I[i][(
unsigned int)cog_u];
2238 sum_value += pixel_gray;
2242 if (nb_pixels < 10) {
2245 if ((cog_u - bbox_u_min) > (cog_v - bbox_v_min)) {
2246 imin = cog_v - bbox_v_min;
2248 imin = cog_u - bbox_u_min;
2250 if ((bbox_u_max - cog_u) > (bbox_v_max - cog_v)) {
2251 imax = bbox_v_max - cog_v;
2253 imax = bbox_u_max - cog_u;
2255 for (
int i = -imin; i <= imax; i++) {
2256 unsigned int pixel_gray = (
unsigned int)I[(
unsigned int)(cog_v + i)][(
unsigned int)(cog_u + i)];
2258 sum_value += pixel_gray;
2263 if ((cog_u - bbox_u_min) > (bbox_v_max - cog_v)) {
2264 imin = bbox_v_max - cog_v;
2266 imin = cog_u - bbox_u_min;
2268 if ((bbox_u_max - cog_u) > (cog_v - bbox_v_min)) {
2269 imax = cog_v - bbox_v_min;
2271 imax = bbox_u_max - cog_u;
2274 for (
int i = -imin; i <= imax; i++) {
2275 unsigned char pixel_gray = I[(
unsigned int)(cog_v - i)][(
unsigned int)(cog_u + i)];
2277 sum_value += pixel_gray;
2283 if (nb_pixels == 0) {
2287 mean_gray_level = sum_value / nb_pixels;
2318 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
2323 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
2330 for (i = 0; i < n; ++i) {
2331 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
2341 std::cout <<
"Cannot track dots from file" << std::endl;
2347 for (i = 0; i < n && fromFile; ++i) {
2349 for (
unsigned int j = 0; j < n && fromFile; ++j)
2353 std::cout <<
"Dots from file seem incoherent" << std::endl;
2362 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
2363 for (i = 0; i < n; i++) {
2372 Cogs[i][0] = cog.
get_u();
2373 Cogs[i][1] = cog.
get_v();
2379 if (!fromFile && (dotFile !=
"")) {
2381 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
2385 for (i = 0; i < n; ++i)
2408 std::vector<vpImagePoint> &cogs,
vpImagePoint *cogStar)
2412 for (i = 0; i < n; ++i) {
2414 cogs.push_back(dot[i].
getCog());
2417 for (i = n; i < cogs.size(); ++i)
2420 for (i = 0; i < n; ++i)
2423 if (cogStar != NULL)
2424 for (i = 0; i < n; ++i) {
2446 const std::list<vpImagePoint> &edges_list,
vpColor color,
unsigned int thickness)
2449 std::list<vpImagePoint>::const_iterator it;
2451 for (it = edges_list.begin(); it != edges_list.end(); ++it) {
2471 vpColor color,
unsigned int thickness)
2474 std::list<vpImagePoint>::const_iterator it;
2476 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 getClick(const vpImage< unsigned char > &I, bool blocking=true)
unsigned int getWidth() const
void setMaxSizeSearchDistancePrecision(const double &maxSizeSearchDistancePrecision)
void set_uv(double u, double v)
Class to define RGB colors available for display functionnalities.
void setEllipsoidBadPointsPercentage(const double &percentage=0.0)
void setGraphics(bool activate)
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 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)
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
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
unsigned int getGrayLevelMin() 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)
unsigned int getRows() const
void track(const vpImage< unsigned char > &I, bool canMakeTheWindowGrow=true)
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)
void setHeight(const double &height)
unsigned int getHeight() const
void setComputeMoments(bool activate)
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)
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