51 #include <visp/vpDisplay.h>
54 #include <visp/vpTrackingException.h>
55 #include <visp/vpMath.h>
56 #include <visp/vpIoTools.h>
58 #include <visp/vpDot2.h>
86 grayLevelPrecision = 0.80;
90 ellipsoidShapePrecision = 0.65;
91 maxSizeSearchDistancePrecision = 0.65;
95 bbox_u_min = bbox_u_max = bbox_v_min = bbox_v_max = 0;
100 compute_moment = false ;
142 width = twinDot.width;
143 height = twinDot.height;
144 surface = twinDot.surface;
145 mean_gray_level = twinDot.mean_gray_level;
146 gray_level_min = twinDot.gray_level_min;
147 gray_level_max = twinDot.gray_level_max;
148 grayLevelPrecision = twinDot.grayLevelPrecision;
149 gamma = twinDot.gamma; ;
150 sizePrecision = twinDot.sizePrecision;
151 ellipsoidShapePrecision = twinDot.ellipsoidShapePrecision ;
152 maxSizeSearchDistancePrecision = twinDot.maxSizeSearchDistancePrecision;
153 allowedBadPointsPercentage_ = twinDot.allowedBadPointsPercentage_;
163 bbox_u_min = twinDot.bbox_u_min;
164 bbox_u_max = twinDot.bbox_u_max;
165 bbox_v_min = twinDot.bbox_v_min;
166 bbox_v_max = twinDot.bbox_v_max;
168 firstBorder_u = twinDot.firstBorder_u;
169 firstBorder_v = twinDot.firstBorder_v;
171 compute_moment = twinDot.compute_moment;
172 graphics = twinDot.graphics;
174 direction_list = twinDot.direction_list;
175 ip_edges_list = twinDot.ip_edges_list;
197 unsigned int thickness)
200 std::list<vpImagePoint>::const_iterator it;
202 for (it = ip_edges_list.begin(); it != ip_edges_list.end(); ++it)
244 unsigned int i = (
unsigned int)cog.
get_i();
245 unsigned int j = (
unsigned int)cog.
get_j();
247 double Ip = pow((
double)I[i][j]/255,1/gamma);
249 if(Ip - (1 - grayLevelPrecision)<0){
253 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
254 if (gray_level_min > 255)
255 gray_level_min = 255;
257 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
258 if (gray_level_max > 255)
259 gray_level_max = 255;
306 unsigned int i = (
unsigned int)cog.
get_i();
307 unsigned int j = (
unsigned int)cog.
get_j();
309 double Ip = pow((
double)I[i][j]/255,1/gamma);
311 if(Ip - (1 - grayLevelPrecision)<0){
315 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
316 if (gray_level_min > 255)
317 gray_level_min = 255;
319 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
320 if (gray_level_max > 255)
321 gray_level_max = 255;
377 unsigned int gray_level_min,
378 unsigned int gray_level_max,
383 this->gray_level_min = gray_level_min;
384 this->gray_level_max = gray_level_max;
460 found = computeParameters(I, cog.
get_u(), cog.
get_v());
464 found = isValid( I, wantedDot);
483 double searchWindowWidth, searchWindowHeight;
485 if( std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon() || std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon() )
487 searchWindowWidth = 80.;
488 searchWindowHeight = 80.;
495 std::list<vpDot2> candidates;
497 (
int)(this->cog.
get_u()-searchWindowWidth /2.0),
498 (int)(this->cog.
get_v()-searchWindowHeight/2.0),
499 (
unsigned int)searchWindowWidth,
500 (
unsigned int)searchWindowHeight,
505 if( candidates.empty() )
509 "No dot was found")) ;
513 vpDot2 movingDot = candidates.front();
529 bbox_u_min = movingDot.bbox_u_min;
530 bbox_u_max = movingDot.bbox_u_max;
531 bbox_v_min = movingDot.bbox_v_min;
532 bbox_v_max = movingDot.bbox_v_max;
552 if( !isInImage( I ) )
554 vpERROR_TRACE(
"The center of gravity of the dot is not in the image") ;
556 "No dot was found")) ;
568 if(Ip - (1 - grayLevelPrecision)<0){
572 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
573 if (gray_level_min > 255)
574 gray_level_min = 255;
576 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
577 if (gray_level_max > 255)
578 gray_level_max = 255;
644 return fabs(surface);
654 return grayLevelPrecision;
664 return sizePrecision;
676 return ellipsoidShapePrecision;
685 return maxSizeSearchDistancePrecision;
694 double diff_u = this->cog.
get_u() - cogDistantDot.
get_u();
695 double diff_v = this->cog.
get_v() - cogDistantDot.
get_v();
696 return sqrt( diff_u*diff_u + diff_v*diff_v );
729 this->height = height;
744 this->surface = surface;
765 double epsilon = 0.05;
766 if( grayLevelPrecision<epsilon )
768 this->grayLevelPrecision = epsilon;
770 else if( grayLevelPrecision>1 )
772 this->grayLevelPrecision = 1.0;
776 this->grayLevelPrecision = grayLevelPrecision;
795 if( sizePrecision<0 )
797 this->sizePrecision = 0;
799 else if( sizePrecision>1 )
801 this->sizePrecision = 1.0;
805 this->sizePrecision = sizePrecision;
840 if( ellipsoidShapePrecision<0 )
842 this->ellipsoidShapePrecision = 0;
844 else if( ellipsoidShapePrecision>1 )
846 this->ellipsoidShapePrecision = 1.0;
850 this->ellipsoidShapePrecision = ellipsoidShapePrecision;
869 double epsilon = 0.05;
870 if( maxSizeSearchDistancePrecision<epsilon )
872 this-> maxSizeSearchDistancePrecision = epsilon;
874 else if( maxSizeSearchDistancePrecision >1 )
876 this->maxSizeSearchDistancePrecision = 1.0;
880 this->maxSizeSearchDistancePrecision = maxSizeSearchDistancePrecision;
913 unsigned int w,
unsigned int h)
915 unsigned int image_w = I.
getWidth();
920 else if (u >= (
int)image_w) u = (int)image_w - 1;
922 else if (v >= (
int)image_h) v = (
int)image_h - 1;
924 if (((
unsigned int)u + w) > image_w) w = image_w - (
unsigned int)u - 1;
925 if (((
unsigned int)v + h) > image_h) h = image_h - (
unsigned int)v - 1;
938 vpDot2::setArea(
const vpRect & a)
945 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
1015 unsigned int area_w = I.
getWidth();
1017 setArea(I, area_u, area_v, area_w, area_h);
1020 unsigned int gridWidth;
1021 unsigned int gridHeight;
1022 getGridSize( gridWidth, gridHeight );
1036 vpDot2* dotToTest = NULL;
1039 unsigned int area_u_min = (
unsigned int) area.
getLeft();
1040 unsigned int area_u_max = (
unsigned int) area.
getRight();
1041 unsigned int area_v_min = (
unsigned int) area.
getTop();
1042 unsigned int area_v_max = (
unsigned int) area.
getBottom();
1047 for( v=area_v_min ; v<area_v_max ; v=v+gridHeight )
1049 for( u=area_u_min ; u<area_u_max ; u=u+gridWidth )
1054 if( !hasGoodLevel(I, u, v) )
continue;
1058 bool good_germ =
true;
1059 niceDotsVector->
front();
1060 while( !niceDotsVector->
outside() && good_germ ==
true) {
1061 tmpDot = niceDotsVector->
value();
1063 cogTmpDot = tmpDot.
getCog();
1064 double u0 = cogTmpDot.
get_u();
1065 double v0 = cogTmpDot.
get_v();
1066 double half_w = tmpDot.
getWidth() / 2.;
1067 double half_h = tmpDot.
getHeight() / 2.;
1069 if ( u >= (u0-half_w) && u <= (u0+half_w) &&
1070 v >= (v0-half_h) && v <= (v0+half_h) ) {
1074 niceDotsVector->
next();
1081 unsigned int border_u;
1082 unsigned int border_v;
1083 if(findFirstBorder(I, u, v, border_u, border_v) ==
false){
1091 badDotsVector->
front();
1092 #define vpBAD_DOT_VALUE (badDotsVector->value())
1095 std::list<vpImagePoint>::const_iterator it_edges;
1096 while( !badDotsVector->
outside() && good_germ ==
true)
1098 if( (
double)u >= vpBAD_DOT_VALUE.bbox_u_min
1099 && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1100 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min
1101 && (double)v <= vpBAD_DOT_VALUE.bbox_v_max)
1104 it_edges = ip_edges_list.begin();
1105 while (it_edges != ip_edges_list.end() && good_germ ==
true)
1110 cogBadDot = *it_edges;
1112 if( (std::fabs(border_u - cogBadDot.
get_u()) <=
vpMath::maximum(std::fabs((
double)border_u), std::fabs(cogBadDot.
get_u()))*std::numeric_limits<double>::epsilon() )
1114 (std::fabs(v - cogBadDot.
get_v()) <=
vpMath::maximum(std::fabs((
double)v), std::fabs(cogBadDot.
get_v()))*std::numeric_limits<double>::epsilon() ))
1121 badDotsVector->
next();
1123 #undef vpBAD_DOT_VALUE
1132 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1140 if( dotToTest != NULL )
delete dotToTest;
1141 dotToTest = getInstance();
1142 dotToTest->setCog( germ );
1147 dotToTest->setGraphics( graphics );
1148 dotToTest->setComputeMoments(
true );
1149 dotToTest->setArea( area );
1150 dotToTest->setEllipsoidShapePrecision( ellipsoidShapePrecision );
1155 if( dotToTest->computeParameters( I ) == false ) {
1162 if( dotToTest->isValid( I, *
this ) )
1170 double area_center_u = area_u + area_w/2.0 - 0.5;
1171 double area_center_v = area_v + area_h/2.0 - 0.5;
1173 double thisDiff_u = cogDotToTest.
get_u() - area_center_u;
1174 double thisDiff_v = cogDotToTest.
get_v() - area_center_v;
1175 double thisDist = sqrt( thisDiff_u*thisDiff_u + thisDiff_v*thisDiff_v);
1177 bool stopLoop =
false;
1178 niceDotsVector->
front();
1180 while( !niceDotsVector->
outside() && stopLoop == false )
1185 double epsilon = 3.0;
1188 cogTmpDot = tmpDot.
getCog();
1190 if( fabs( cogTmpDot.
get_u() - cogDotToTest.
get_u() ) < epsilon &&
1191 fabs( cogTmpDot.
get_v() - cogDotToTest.
get_v() ) < epsilon )
1200 double otherDiff_u = cogTmpDot.
get_u() - area_center_u;
1201 double otherDiff_v = cogTmpDot.
get_v() - area_center_v;
1202 double otherDist = sqrt( otherDiff_u*otherDiff_u +
1203 otherDiff_v*otherDiff_v );
1209 if( otherDist > thisDist )
1211 niceDotsVector->
addLeft( *dotToTest );
1212 niceDotsVector->
next();
1219 niceDotsVector->
next();
1221 vpTRACE(4,
"End while (%d, %d)", u, v);
1225 if( niceDotsVector->
outside() && stopLoop == false )
1227 niceDotsVector->
end();
1228 niceDotsVector->
addRight( *dotToTest );
1233 badDotsVector->
front();
1234 badDotsVector->
addRight( *dotToTest );
1238 if( dotToTest != NULL )
delete dotToTest;
1240 delete badDotsVector;
1246 return niceDotsVector;
1276 unsigned int area_w,
1277 unsigned int area_h)
1282 setArea(I, area_u, area_v, area_w, area_h);
1285 unsigned int gridWidth;
1286 unsigned int gridHeight;
1287 getGridSize( gridWidth, gridHeight );
1301 vpDot2* dotToTest = NULL;
1304 unsigned int area_u_min = (
unsigned int) area.
getLeft();
1305 unsigned int area_u_max = (
unsigned int) area.
getRight();
1306 unsigned int area_v_min = (
unsigned int) area.
getTop();
1307 unsigned int area_v_max = (
unsigned int) area.
getBottom();
1312 for( v=area_v_min ; v<area_v_max ; v=v+gridHeight )
1314 for( u=area_u_min ; u<area_u_max ; u=u+gridWidth )
1319 if( !hasGoodLevel(I, u, v) )
continue;
1323 bool good_germ =
true;
1324 niceDotsVector->
front();
1325 while( !niceDotsVector->
outside() && good_germ ==
true) {
1326 tmpDot = niceDotsVector->
value();
1328 cogTmpDot = tmpDot.
getCog();
1329 double u0 = cogTmpDot.
get_u();
1330 double v0 = cogTmpDot.
get_v();
1331 double half_w = tmpDot.
getWidth() / 2.;
1332 double half_h = tmpDot.
getHeight() / 2.;
1334 if ( u >= (u0-half_w) && u <= (u0+half_w) &&
1335 v >= (v0-half_h) && v <= (v0+half_h) ) {
1339 niceDotsVector->
next();
1346 unsigned int border_u;
1347 unsigned int border_v;
1348 if(findFirstBorder(I, u, v, border_u, border_v) ==
false){
1356 badDotsVector->
front();
1357 #define vpBAD_DOT_VALUE (badDotsVector->value())
1360 std::list<vpImagePoint>::const_iterator it_edges;
1361 while( !badDotsVector->
outside() && good_germ ==
true)
1363 if( (
double)u >= vpBAD_DOT_VALUE.bbox_u_min
1364 && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1365 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min
1366 && (double)v <= vpBAD_DOT_VALUE.bbox_v_max)
1369 it_edges = ip_edges_list.begin();
1370 while (it_edges != ip_edges_list.end() && good_germ ==
true)
1375 cogBadDot = *it_edges;
1377 if( (std::fabs(border_u - cogBadDot.
get_u()) <=
vpMath::maximum(std::fabs((
double)border_u), std::fabs(cogBadDot.
get_u()))*std::numeric_limits<double>::epsilon() )
1379 (std::fabs(v - cogBadDot.
get_v()) <=
vpMath::maximum(std::fabs((
double)v), std::fabs(cogBadDot.
get_v()))*std::numeric_limits<double>::epsilon() ))
1386 badDotsVector->
next();
1388 #undef vpBAD_DOT_VALUE
1397 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1405 if( dotToTest != NULL )
delete dotToTest;
1406 dotToTest = getInstance();
1407 dotToTest->setCog( germ );
1412 dotToTest->setGraphics( graphics );
1413 dotToTest->setComputeMoments(
true );
1414 dotToTest->setArea( area );
1415 dotToTest->setEllipsoidShapePrecision( ellipsoidShapePrecision );
1420 if( dotToTest->computeParameters( I ) == false ) {
1427 if( dotToTest->isValid( I, *
this ) )
1435 double area_center_u = area_u + area_w/2.0 - 0.5;
1436 double area_center_v = area_v + area_h/2.0 - 0.5;
1438 double thisDiff_u = cogDotToTest.
get_u() - area_center_u;
1439 double thisDiff_v = cogDotToTest.
get_v() - area_center_v;
1440 double thisDist = sqrt( thisDiff_u*thisDiff_u + thisDiff_v*thisDiff_v);
1442 bool stopLoop =
false;
1443 niceDotsVector->
front();
1445 while( !niceDotsVector->
outside() && stopLoop == false )
1450 double epsilon = 3.0;
1453 cogTmpDot = tmpDot.
getCog();
1455 if( fabs( cogTmpDot.
get_u() - cogDotToTest.
get_u() ) < epsilon &&
1456 fabs( cogTmpDot.
get_v() - cogDotToTest.
get_v() ) < epsilon )
1465 double otherDiff_u = cogTmpDot.
get_u() - area_center_u;
1466 double otherDiff_v = cogTmpDot.
get_v() - area_center_v;
1467 double otherDist = sqrt( otherDiff_u*otherDiff_u +
1468 otherDiff_v*otherDiff_v );
1474 if( otherDist > thisDist )
1476 niceDotsVector->
addLeft( *dotToTest );
1477 niceDotsVector->
next();
1484 niceDotsVector->
next();
1486 vpTRACE(4,
"End while (%d, %d)", u, v);
1490 if( niceDotsVector->
outside() && stopLoop == false )
1492 niceDotsVector->
end();
1493 niceDotsVector->
addRight( *dotToTest );
1498 badDotsVector->
front();
1499 badDotsVector->
addRight( *dotToTest );
1503 if( dotToTest != NULL )
delete dotToTest;
1505 delete badDotsVector;
1507 return niceDotsVector;
1509 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
1587 unsigned int area_w,
1588 unsigned int area_h,
1589 std::list<vpDot2> &niceDots)
1597 setArea(I, area_u, area_v, area_w, area_h);
1600 unsigned int gridWidth;
1601 unsigned int gridHeight;
1602 getGridSize( gridWidth, gridHeight );
1617 std::list<vpDot2> badDotsVector;
1618 std::list<vpDot2>::iterator itnice;
1619 std::list<vpDot2>::iterator itbad;
1621 vpDot2* dotToTest = NULL;
1624 unsigned int area_u_min = (
unsigned int) area.
getLeft();
1625 unsigned int area_u_max = (
unsigned int) area.
getRight();
1626 unsigned int area_v_min = (
unsigned int) area.
getTop();
1627 unsigned int area_v_max = (
unsigned int) area.
getBottom();
1632 for( v=area_v_min ; v<area_v_max ; v=v+gridHeight )
1634 for( u=area_u_min ; u<area_u_max ; u=u+gridWidth )
1639 if( !hasGoodLevel(I, u, v) )
continue;
1643 bool good_germ =
true;
1645 itnice = niceDots.begin();
1646 while( itnice != niceDots.end() && good_germ ==
true) {
1649 cogTmpDot = tmpDot.
getCog();
1650 double u0 = cogTmpDot.
get_u();
1651 double v0 = cogTmpDot.
get_v();
1652 double half_w = tmpDot.
getWidth() / 2.;
1653 double half_h = tmpDot.
getHeight() / 2.;
1655 if ( u >= (u0-half_w) && u <= (u0+half_w) &&
1656 v >= (v0-half_h) && v <= (v0+half_h) ) {
1667 unsigned int border_u;
1668 unsigned int border_v;
1669 if(findFirstBorder(I, u, v, border_u, border_v) ==
false){
1677 itbad = badDotsVector.begin();
1678 #define vpBAD_DOT_VALUE (*itbad)
1681 while( itbad != badDotsVector.end() && good_germ ==
true) {
1682 if( (
double)u >= vpBAD_DOT_VALUE.bbox_u_min
1683 && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1684 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min
1685 && (double)v <= vpBAD_DOT_VALUE.bbox_v_max){
1686 std::list<vpImagePoint>::const_iterator it_edges = ip_edges_list.begin();
1687 while (it_edges != ip_edges_list.end() && good_germ ==
true){
1691 cogBadDot = *it_edges;
1693 if( (std::fabs(border_u - cogBadDot.
get_u()) <=
vpMath::maximum(std::fabs((
double)border_u), std::fabs(cogBadDot.
get_u()))*std::numeric_limits<double>::epsilon() )
1695 (std::fabs(v - cogBadDot.
get_v()) <=
vpMath::maximum(std::fabs((
double)v), std::fabs(cogBadDot.
get_v()))*std::numeric_limits<double>::epsilon() )) {
1703 #undef vpBAD_DOT_VALUE
1712 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1720 if( dotToTest != NULL )
delete dotToTest;
1721 dotToTest = getInstance();
1722 dotToTest->
setCog( germ );
1729 dotToTest->setArea( area );
1735 if( dotToTest->computeParameters( I ) == false ) {
1742 if( dotToTest->isValid( I, *
this ) )
1750 double area_center_u = area_u + area_w/2.0 - 0.5;
1751 double area_center_v = area_v + area_h/2.0 - 0.5;
1753 double thisDiff_u = cogDotToTest.
get_u() - area_center_u;
1754 double thisDiff_v = cogDotToTest.
get_v() - area_center_v;
1755 double thisDist = sqrt( thisDiff_u*thisDiff_u + thisDiff_v*thisDiff_v);
1757 bool stopLoop =
false;
1758 itnice = niceDots.begin();
1760 while( itnice != niceDots.end() && stopLoop == false )
1765 double epsilon = 3.0;
1768 cogTmpDot = tmpDot.
getCog();
1770 if( fabs( cogTmpDot.
get_u() - cogDotToTest.
get_u() ) < epsilon &&
1771 fabs( cogTmpDot.
get_v() - cogDotToTest.
get_v() ) < epsilon )
1780 double otherDiff_u = cogTmpDot.
get_u() - area_center_u;
1781 double otherDiff_v = cogTmpDot.
get_v() - area_center_v;
1782 double otherDist = sqrt( otherDiff_u*otherDiff_u +
1783 otherDiff_v*otherDiff_v );
1789 if( otherDist > thisDist )
1791 niceDots.insert(itnice, *dotToTest );
1801 vpTRACE(4,
"End while (%d, %d)", u, v);
1805 if( itnice == niceDots.end() && stopLoop == false )
1807 niceDots.push_back( *dotToTest );
1812 badDotsVector.push_front( *dotToTest );
1816 if( dotToTest != NULL )
delete dotToTest;
1843 double epsilon = 0.001;
1852 if ( (std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon())
1854 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon())
1856 (std::fabs(wantedDot.
getSurface()) > std::numeric_limits<double>::epsilon()) )
1858 if (std::fabs(sizePrecision) > std::numeric_limits<double>::epsilon()){
1860 std::cout <<
"test size precision......................\n";
1861 std::cout <<
"wanted dot: " <<
"w=" << wantedDot.
getWidth()
1864 <<
" precision=" << sizePrecision
1865 <<
" epsilon=" << epsilon << std::endl;
1866 std::cout <<
"dot found: " <<
"w=" <<
getWidth()
1875 printf(
"Bad width > for dot (%g, %g)\n", cog.
get_u(), cog.
get_v());
1880 if( (
getWidth() < wantedDot.
getWidth()/(sizePrecision+epsilon ) )== false )
1885 printf(
"Bad width %g > %g for dot (%g, %g)\n",
1897 printf(
"Bad height %g > %g for dot (%g, %g)\n",
1909 printf(
"Bad height %g > %g for dot (%g, %g)\n",
1921 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1922 wantedDot.
getSurface()*(sizePrecision*sizePrecision)-epsilon,
1934 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
1946 int nb_point_to_test = 20;
1947 int nb_bad_points = 0;
1948 int nb_max_bad_points = (int)(nb_point_to_test*allowedBadPointsPercentage_);
1949 double step_angle = 2*M_PI / nb_point_to_test;
1952 if (std::fabs(ellipsoidShapePrecision) > std::numeric_limits<double>::epsilon() && compute_moment) {
1971 double Sqrt = sqrt(tmp1*tmp1 + 4*tmp2*tmp2);
1982 double innerCoef = ellipsoidShapePrecision ;
1984 double cog_u = this->cog.
get_u();
1985 double cog_v = this->cog.
get_v();
1989 for(
double theta = 0. ; theta<2*M_PI ; theta+= step_angle ) {
1990 u = (
unsigned int) (cog_u + innerCoef*(a1*cos(alpha)*cos(theta)-a2*sin(alpha)*sin(theta)));
1991 v = (
unsigned int) (cog_v + innerCoef*(a1*sin(alpha)*cos(theta)+a2*cos(alpha)*sin(theta)));
1992 if( ! this->hasGoodLevel( I, u, v) ) {
1996 printf(
"Inner cercle pixel (%d, %d) has bad level for dot (%g, %g): %d not in [%d, %d]\n",
1997 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
2013 if (nb_bad_points > nb_max_bad_points)
2016 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n",
2017 nb_bad_points, nb_max_bad_points);
2026 double outCoef = 2-ellipsoidShapePrecision;
2028 for(
double theta=0. ; theta<2*M_PI ; theta+= step_angle ) {
2029 u = (
unsigned int) (cog_u + outCoef*(a1*cos(alpha)*cos(theta)-a2*sin(alpha)*sin(theta)));
2030 v = (
unsigned int) (cog_v + outCoef*(a1*sin(alpha)*cos(theta)+a2*cos(alpha)*sin(theta)));
2041 if( ! this->hasReverseLevel( I, u, v ) ) {
2045 printf(
"Outside cercle pixel (%d, %d) has bad level for dot (%g, %g): %d not in [%d, %d]\n",
2046 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
2059 if (nb_bad_points > nb_max_bad_points)
2062 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n",
2063 nb_bad_points, nb_max_bad_points);
2091 const unsigned int &u,
2092 const unsigned int &v)
const
2094 if( !isInArea( u, v ) )
2097 if( I[v][u] >= gray_level_min && I[v][u] <= gray_level_max)
2121 const unsigned int &u,
2122 const unsigned int &v)
const
2125 if( !isInArea( u, v ) )
2128 if( I[v][u] < gray_level_min || I[v][u] > gray_level_max)
2147 vpDot2* vpDot2::getInstance()
2153 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
2174 std::list<unsigned int>::const_iterator it;
2175 freeman_chain.
kill();
2176 for (it = direction_list.begin(); it != direction_list.end(); ++it) {
2177 freeman_chain += *it;
2199 freeman_chain = direction_list;
2247 direction_list.clear();
2248 ip_edges_list.clear();
2255 if( std::fabs(est_u + 1.0) <=
vpMath::maximum(std::fabs(est_u),1.)*std::numeric_limits<double>::epsilon() )
2257 est_u = this->cog.
get_u();
2262 if( std::fabs(est_v + 1.0) <=
vpMath::maximum(std::fabs(est_v),1.)*std::numeric_limits<double>::epsilon() )
2264 est_v = this->cog.
get_v();
2269 if( !isInArea( (
unsigned int) est_u, (
unsigned int) est_v ) )
2271 vpDEBUG_TRACE(3,
"Initial pixel coordinates (%d, %d) for dot tracking are not in the area",
2272 (
int) est_u, (
int) est_v) ;
2283 if( !hasGoodLevel( I, (
unsigned int) est_u, (
unsigned int) est_v ) )
2285 vpDEBUG_TRACE(3,
"Can't find a dot from pixel (%d, %d) coordinates",
2286 (
int) est_u, (
int) est_v) ;
2292 if(!findFirstBorder(I, (
unsigned int) est_u, (
unsigned int) est_v,
2293 this->firstBorder_u, this->firstBorder_v)) {
2295 vpDEBUG_TRACE(3,
"Can't find first border (%d, %d) coordinates",
2296 (
int) est_u, (
int) est_v) ;
2300 unsigned int dir = 6;
2303 computeFreemanChainElement(I, this->firstBorder_u, this->firstBorder_v, dir);
2304 unsigned int firstDir = dir;
2307 if( !isInArea( this->firstBorder_u, this->firstBorder_v ) )
2309 vpDEBUG_TRACE(3,
"Border pixel coordinates (%d, %d) of the dot are not in the area",
2310 this->firstBorder_u, this->firstBorder_v);
2315 direction_list.push_back( dir );
2317 ip.
set_u( this->firstBorder_u );
2318 ip.
set_v( this->firstBorder_v );
2320 ip_edges_list.push_back( ip );
2322 int border_u = (int)this->firstBorder_u;
2323 int border_v = (int)this->firstBorder_v;
2329 float dS, dMu, dMv, dMuv, dMu2, dMv2;
2340 ip.
set_u ( border_u );
2341 ip.
set_v ( border_v );
2351 computeFreemanParameters(border_u, border_v, dir, du, dv,
2362 if (compute_moment) {
2368 if( !isInArea( (
unsigned int)border_u, (
unsigned int)border_v ) ) {
2370 vpDEBUG_TRACE(3,
"Dot (%d, %d) is not in the area", border_u, border_v);
2377 direction_list.push_back( dir );
2379 ip.
set_u( border_u );
2380 ip.
set_v( border_v );
2381 ip_edges_list.push_back( ip );
2386 if( border_v < bbox_v_min ) bbox_v_min = border_v;
2387 if( border_v > bbox_v_max ) bbox_v_max = border_v;
2388 if( border_u < bbox_u_min ) bbox_u_min = border_u;
2389 if( border_u > bbox_u_max ) bbox_u_max = border_u;
2392 if (computeFreemanChainElement(I, (
unsigned int)border_u, (
unsigned int)border_v, dir) ==
false) {
2393 vpDEBUG_TRACE(3,
"Can't compute Freeman chain for dot (%d, %d)",
2394 border_u, border_v);
2401 while( (getFirstBorder_u() != (
unsigned int)border_u
2402 || getFirstBorder_v() != (
unsigned int)border_v
2403 || firstDir != dir) &&
2404 isInArea( (
unsigned int)border_u, (
unsigned int)border_v ) );
2407 #if VP_DEBUG_MODE == 3
2415 if( std::fabs(
m00) <= std::numeric_limits<double>::epsilon()
2416 || std::fabs(
m00 - 1.) <=
vpMath::maximum(std::fabs(
m00), 1.)*std::numeric_limits<double>::epsilon() )
2418 vpDEBUG_TRACE(3,
"The center of gravity of the dot wasn't properly detected");
2424 double tmpCenter_u =
m10 /
m00;
2425 double tmpCenter_v = m01 /
m00;
2444 cog.
set_u( tmpCenter_u );
2445 cog.
set_v( tmpCenter_v );
2448 width = bbox_u_max - bbox_u_min + 1;
2449 height = bbox_v_max - bbox_v_min + 1;
2452 computeMeanGrayLevel(I);
2474 const unsigned int &u,
2475 const unsigned int &v,
2476 unsigned int &border_u,
2477 unsigned int &border_v)
2487 double epsilon =0.001;
2490 std::cout <<
"gray level: " << gray_level_min <<
" " << gray_level_max << std::endl;
2492 while( hasGoodLevel( I, border_u+1, border_v ) &&
2498 vpDEBUG_TRACE(3,
"The found dot (%d, %d, %d) has a greater width than the required one", u, v, border_u);
2532 const unsigned int &u,
2533 const unsigned int &v,
2534 unsigned int &element)
2537 if (hasGoodLevel( I, u, v )) {
2538 unsigned int _u = u;
2539 unsigned int _v = v;
2541 updateFreemanPosition( _u, _v, (element + 2) %8 );
2542 if (hasGoodLevel( I, _u, _v )) {
2543 element = (element + 2) % 8;
2546 unsigned int _u = u;
2547 unsigned int _v = v;
2548 updateFreemanPosition( _u, _v, (element + 1) %8 );
2550 if ( hasGoodLevel( I, _u, _v )) {
2551 element = (element + 1) % 8;
2554 unsigned int _u = u;
2555 unsigned int _v = v;
2556 updateFreemanPosition( _u, _v, element );
2558 if ( hasGoodLevel( I, _u, _v )) {
2562 unsigned int _u = u;
2563 unsigned int _v = v;
2564 updateFreemanPosition( _u, _v, (element + 7) %8 );
2566 if ( hasGoodLevel( I, _u, _v )) {
2567 element = (element + 7) %8;
2570 unsigned int _u = u;
2571 unsigned int _v = v;
2572 updateFreemanPosition( _u, _v, (element + 6) %8 );
2574 if ( hasGoodLevel( I, _u, _v )) {
2575 element = (element + 6) %8 ;
2578 unsigned int _u = u;
2579 unsigned int _v = v;
2580 updateFreemanPosition( _u, _v, (element + 5) %8 );
2582 if ( hasGoodLevel( I, _u, _v )) {
2583 element = (element + 5) %8 ;
2586 unsigned int _u = u;
2587 unsigned int _v = v;
2588 updateFreemanPosition( _u, _v, (element + 4) %8 );
2590 if ( hasGoodLevel( I, _u, _v )) {
2591 element = (element + 4) %8 ;
2594 unsigned int _u = u;
2595 unsigned int _v = v;
2596 updateFreemanPosition( _u, _v, (element + 3) %8 );
2598 if ( hasGoodLevel( I, _u, _v )) {
2599 element = (element + 3) %8 ;
2655 vpDot2::computeFreemanParameters(
const int &u_p,
2657 unsigned int &element,
2660 float &dMu,
float &dMv,
2662 float &dMu2,
float &dMv2)
2684 dMv = (float)(0.5 * v_p * v_p);
2685 if (compute_moment) {
2686 dMuv = (float)(0.25 * v_p * v_p * (2 * u_p + 1));
2688 dMv2 = (float)(1.0/ 3. * v_p * v_p * v_p);
2695 dS = (float)(v_p + 0.5);
2696 dMu = - (float)(0.5 * u_p * ( u_p + 1 ) + 1.0 / 6.0);
2697 dMv = (float)(0.5 * v_p * ( v_p + 1 ) + 1.0 / 6.0);
2698 if (compute_moment) {
2699 float half_u_p = (float)(0.5*u_p);
2700 dMuv = (float)(v_p*v_p*(0.25+half_u_p) + v_p*(1./3.+half_u_p) + 1./6.*u_p +0.125);
2701 dMu2 = (float)(-1./3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) - 1./12.0);
2702 dMv2 = (float)( 1./3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) + 1./12.0);
2709 dMu = (float)(- 0.5 * u_p * u_p);
2711 if (compute_moment) {
2713 dMu2 = (float)(-1.0/ 3. * u_p * u_p * u_p);
2721 dS = (float)(- v_p - 0.5);
2722 dMu = - (float)(0.5 * u_p * ( u_p - 1 ) + 1.0 / 6.0);
2723 dMv = - (float)(0.5 * v_p * ( v_p + 1 ) + 1.0 / 6.0);
2724 if (compute_moment) {
2725 float half_u_p = (float)(0.5*u_p);
2726 dMuv = (float)(v_p*v_p*(0.25-half_u_p) + v_p*(1./3.-half_u_p) - 1./6.*u_p +0.125);
2727 dMu2 = (float)(-1./3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1./12.0);
2728 dMv2 = (float)(-1./3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) - 1./12.0);
2734 dS = (float)(- v_p);
2735 dMv = (float)(- 0.5 * v_p * v_p);
2737 if (compute_moment) {
2738 dMuv = (float)(-0.25 * v_p * v_p * (2 * u_p - 1));
2740 dMv2 = (float)(-1.0/ 3. * v_p * v_p * v_p);
2747 dS = (float)(- v_p + 0.5);
2748 dMu = (float)( 0.5 * u_p * ( u_p - 1 ) + 1.0 / 6.0);
2749 dMv = (float)(- (0.5 * v_p * ( v_p - 1 ) + 1.0 / 6.0));
2750 if (compute_moment) {
2751 float half_u_p = (float)(0.5*u_p);
2752 dMuv = (float)(v_p*v_p*(0.25-half_u_p) - v_p*(1./3.-half_u_p) - 1./6.*u_p +0.125);
2753 dMu2 = (float)( 1./3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1./12.0);
2754 dMv2 = (float)(-1./3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1./12.0);
2761 dMu = (float)(0.5 * u_p * u_p);
2763 if (compute_moment) {
2765 dMu2 = (float)(1.0/ 3. * u_p * u_p * u_p);
2773 dS = (float)(v_p - 0.5);
2774 dMu = (float)(0.5 * u_p * ( u_p + 1 ) + 1.0 / 6.0);
2775 dMv = (float)(0.5 * v_p * ( v_p - 1 ) + 1.0 / 6.0);
2776 if (compute_moment) {
2777 float half_u_p = (float)(0.5*u_p);
2778 dMuv = (float)(v_p*v_p*(0.25+half_u_p) - v_p*(1./3.+half_u_p) + 1./6.*u_p +0.125);
2779 dMu2 = (float)(1./3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) + 1./12.0);
2780 dMv2 = (float)(1./3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1./12.0);
2800 void vpDot2::updateFreemanPosition(
unsigned int& u,
unsigned int& v,
2801 const unsigned int &dir )
2804 case 0: u += 1;
break;
2805 case 1: u += 1; v += 1;
break;
2806 case 2: v += 1;
break;
2807 case 3: u -= 1; v += 1;
break;
2808 case 4: u -= 1;
break;
2809 case 5: u -= 1; v -= 1;
break;
2810 case 6: v -= 1;
break;
2811 case 7: u += 1; v -= 1;
break;
2828 return isInImage( I, cog);
2847 double u = ip.
get_u();
2848 double v = ip.
get_v();
2850 if( u < 0 || u >= width )
return false;
2851 if( v < 0 || v >= height )
return false;
2866 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const
2868 unsigned int area_u_min = (
unsigned int) area.
getLeft();
2869 unsigned int area_u_max = (
unsigned int) area.
getRight();
2870 unsigned int area_v_min = (
unsigned int) area.
getTop();
2871 unsigned int area_v_max = (
unsigned int) area.
getBottom();
2873 if( u < area_u_min || u > area_u_max )
return false;
2874 if( v < area_v_min || v > area_v_max )
return false;
2890 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight )
2900 if( gridWidth == 0 ) gridWidth = 1;
2901 if( gridHeight == 0 ) gridHeight = 1;
2920 int cog_u = (int)cog.
get_u();
2921 int cog_v = (int)cog.
get_v();
2923 unsigned int sum_value =0;
2924 unsigned int nb_pixels =0;
2926 for(
unsigned int i=(
unsigned int)this->bbox_u_min; i <=(
unsigned int)this->bbox_u_max ; i++){
2927 unsigned int pixel_gray =(
unsigned int) I[(
unsigned int)cog_v][i];
2929 sum_value += pixel_gray;
2933 for(
unsigned int i=(
unsigned int)this->bbox_v_min; i <=(
unsigned int)this->bbox_v_max ; i++){
2934 unsigned char pixel_gray =I[i][(
unsigned int)cog_u];
2936 sum_value += pixel_gray;
2943 if( (cog_u - bbox_u_min) > (cog_v - bbox_v_min)){
2944 imin=cog_v - bbox_v_min;
2946 else{ imin = cog_u - bbox_u_min;}
2947 if( (bbox_u_max - cog_u) > (bbox_v_max - cog_v)){
2948 imax=bbox_v_max - cog_v;
2950 else{ imax = bbox_u_max - cog_u;}
2951 for(
int i=-imin; i <=imax ; i++){
2952 unsigned int pixel_gray =(
unsigned int) I[(
unsigned int)(cog_v + i)][(
unsigned int)(cog_u + i)];
2954 sum_value += pixel_gray;
2959 if( (cog_u - bbox_u_min) > (bbox_v_max - cog_v)){
2960 imin = bbox_v_max - cog_v;
2962 else{ imin = cog_u - bbox_u_min;}
2963 if( (bbox_u_max - cog_u) > (cog_v - bbox_v_min)){
2964 imax = cog_v - bbox_v_min;
2966 else{ imax = bbox_u_max - cog_u;}
2968 for(
int i=-imin; i <=imax ; i++){
2969 unsigned char pixel_gray =I[(
unsigned int)(cog_v - i)][(
unsigned int)(cog_u + i)];
2971 sum_value += pixel_gray;
2982 mean_gray_level = sum_value/nb_pixels;
3011 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
3017 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
3028 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
3041 std::cout <<
"Cannot track dots from file" << std::endl;
3048 for(i=0;i<n && fromFile;++i)
3051 for(
unsigned int j=0;j<n && fromFile;++j)
3056 std::cout <<
"Dots from file seem incoherent" << std::endl;
3066 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
3067 for (i = 0; i < n; i++)
3080 Cogs[i][0] = cog.
get_u();
3081 Cogs[i][1] = cog.
get_v();
3087 if (!fromFile & (dotFile !=
""))
3090 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
3116 cogs.push_back(dot[i].
getCog());
3119 for(i=n;i<cogs.size();++i)
3149 const std::list<vpImagePoint> &edges_list,
vpColor color,
3150 unsigned int thickness)
3153 std::list<vpImagePoint>::const_iterator it;
3155 for (it = edges_list.begin(); it != edges_list.end(); ++it)
virtual void displayCircle(const vpImagePoint ¢er, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)=0
Definition of the vpMatrix class.
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 end(void)
Position the current element on the last element of the list.
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
unsigned int getWidth() const
void setMaxSizeSearchDistancePrecision(const double &maxSizeSearchDistancePrecision)
void setCog(const vpImagePoint &cog)
Provide simple list management.
static bool saveMatrix(const char *filename, const vpMatrix &M, const bool binary=false, const char *Header="")
double getSurface() const
Class to define colors available for display functionnalities.
void setEllipsoidBadPointsPercentage(const double &percentage=0.0)
double getGrayLevelPrecision() const
void kill()
Destroy the list.
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
void setSurface(const double &surface)
void next(void)
position the current element on the next one
Class that defines what is a feature generic tracker.
static Type maximum(const Type &a, const Type &b)
vpImagePoint getCog() const
void setGrayLevelPrecision(const double &grayLevelPrecision)
void setRect(double left, double top, double width, double height)
Error that can be emited by the vpTracker class and its derivates.
void addLeft(const type &el)
add a new element in the list, at the left of the current one
double getMaxSizeSearchDistancePrecision() const
void set_u(const double u)
static double sqr(double x)
static bool loadMatrix(const char *filename, vpMatrix &M, const bool binary=false, char *Header=NULL)
void front(void)
Position the current element on the first element of the list.
void getFreemanChain(std::list< unsigned int > &freeman_chain)
void operator=(const vpDot2 &twinDot)
static void display(const vpImage< unsigned char > &I)
type & value(void)
return the value of the current element
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
void set_v(const double v)
void addRight(const type &el)
add a new element in the list, at the right of the current one
unsigned int getGrayLevelMin() const
void setComputeMoments(const bool activate)
virtual void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)=0
void setEllipsoidShapePrecision(const double &ellipsoidShapePrecision)
virtual void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1)
void setGrayLevelMin(const unsigned int &min)
void setWidth(const double &width)
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)
double getMeanGrayLevel()
void initTracking(const vpImage< unsigned char > &I, unsigned int size=0)
void setHeight(const double &height)
unsigned int getHeight() const
void set_uv(const double u, const double v)
Defines a rectangle in the plane.
virtual bool getClick(bool blocking=true)=0
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
unsigned int getRows() const
Return the number of rows of the matrix.
unsigned int getGrayLevelMax() const
static const vpColor purple
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)
virtual void displayPoint(const vpImagePoint &ip, const vpColor &color)=0
static const vpColor blue