47 #include <visp3/core/vpDisplay.h>
50 #include <visp3/core/vpTrackingException.h>
51 #include <visp3/core/vpMath.h>
52 #include <visp3/core/vpIoTools.h>
54 #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.),
106 mu11(0.), mu20(0.), mu02(0.), cog(), width(0), height(0), surface(0),
107 gray_level_min(128), gray_level_max(255), mean_gray_level(0), grayLevelPrecision(0.8), gamma(1.5),
108 sizePrecision(0.65), ellipsoidShapePrecision(0.65), maxSizeSearchDistancePrecision(0.65),
109 allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(), compute_moment(false),
110 graphics(false), thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0),
111 firstBorder_u(0), firstBorder_v()
124 : m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.),
125 mu11(0.), mu20(0.), mu02(0.), cog(), width(0), height(0), surface(0),
126 gray_level_min(128), gray_level_max(255), mean_gray_level(0), grayLevelPrecision(0.8), gamma(1.5),
127 sizePrecision(0.65), ellipsoidShapePrecision(0.65), maxSizeSearchDistancePrecision(0.65),
128 allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(), compute_moment(false),
129 graphics(false), thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0),
130 firstBorder_u(0), firstBorder_v()
140 m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.),
141 mu11(0.), mu20(0.), mu02(0.), cog(), width(0), height(0), surface(0),
142 gray_level_min(128), gray_level_max(255), mean_gray_level(0), grayLevelPrecision(0.8), gamma(1.5),
143 sizePrecision(0.65), ellipsoidShapePrecision(0.65), maxSizeSearchDistancePrecision(0.65),
144 allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(), compute_moment(false),
145 graphics(false), thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0),
146 firstBorder_u(0), firstBorder_v()
158 width = twinDot.width;
159 height = twinDot.height;
160 surface = twinDot.surface;
161 gray_level_min = twinDot.gray_level_min;
162 gray_level_max = twinDot.gray_level_max;
163 mean_gray_level = twinDot.mean_gray_level;
164 grayLevelPrecision = twinDot.grayLevelPrecision;
165 gamma = twinDot.gamma; ;
166 sizePrecision = twinDot.sizePrecision;
167 ellipsoidShapePrecision = twinDot.ellipsoidShapePrecision ;
168 maxSizeSearchDistancePrecision = twinDot.maxSizeSearchDistancePrecision;
169 allowedBadPointsPercentage_ = twinDot.allowedBadPointsPercentage_;
172 direction_list = twinDot.direction_list;
173 ip_edges_list = twinDot.ip_edges_list;
175 compute_moment = twinDot.compute_moment;
176 graphics = twinDot.graphics;
177 thickness = twinDot.thickness;
179 bbox_u_min = twinDot.bbox_u_min;
180 bbox_u_max = twinDot.bbox_u_max;
181 bbox_v_min = twinDot.bbox_v_min;
182 bbox_v_max = twinDot.bbox_v_max;
184 firstBorder_u = twinDot.firstBorder_u;
185 firstBorder_v = twinDot.firstBorder_v;
222 std::list<vpImagePoint>::const_iterator it;
224 for (it = ip_edges_list.begin(); it != ip_edges_list.end(); ++it)
266 unsigned int i = (
unsigned int)cog.
get_i();
267 unsigned int j = (
unsigned int)cog.
get_j();
269 double Ip = pow((
double)I[i][j]/255,1/gamma);
271 if(Ip - (1 - grayLevelPrecision)<0){
275 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
276 if (gray_level_min > 255)
277 gray_level_min = 255;
279 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
280 if (gray_level_max > 255)
281 gray_level_max = 255;
328 unsigned int i = (
unsigned int)cog.
get_i();
329 unsigned int j = (
unsigned int)cog.
get_j();
331 double Ip = pow((
double)I[i][j]/255,1/gamma);
333 if(Ip - (1 - grayLevelPrecision)<0){
337 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
338 if (gray_level_min > 255)
339 gray_level_min = 255;
341 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
342 if (gray_level_max > 255)
343 gray_level_max = 255;
399 unsigned int gray_lvl_min,
400 unsigned int gray_lvl_max,
405 this->gray_level_min = gray_lvl_min;
406 this->gray_level_max = gray_lvl_max;
482 found = computeParameters(I, cog.
get_u(), cog.
get_v());
486 found = isValid( I, wantedDot);
505 double searchWindowWidth, searchWindowHeight;
507 if( std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon() || std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon() )
509 searchWindowWidth = 80.;
510 searchWindowHeight = 80.;
517 std::list<vpDot2> candidates;
519 (
int)(this->cog.
get_u()-searchWindowWidth /2.0),
520 (int)(this->cog.
get_v()-searchWindowHeight/2.0),
521 (
unsigned int)searchWindowWidth,
522 (
unsigned int)searchWindowHeight,
527 if( candidates.empty() )
531 "No dot was found")) ;
535 vpDot2 movingDot = candidates.front();
551 bbox_u_min = movingDot.bbox_u_min;
552 bbox_u_max = movingDot.bbox_u_max;
553 bbox_v_min = movingDot.bbox_v_min;
554 bbox_v_max = movingDot.bbox_v_max;
574 if( !isInImage( I ) )
578 "The center of gravity of the dot is not in the image")) ;
590 if(Ip - (1 - grayLevelPrecision)<0){
594 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
595 if (gray_level_min > 255)
596 gray_level_min = 255;
598 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
599 if (gray_level_max > 255)
600 gray_level_max = 255;
666 return fabs(surface);
676 return grayLevelPrecision;
686 return sizePrecision;
698 return ellipsoidShapePrecision;
707 return maxSizeSearchDistancePrecision;
716 double diff_u = this->cog.
get_u() - cogDistantDot.
get_u();
717 double diff_v = this->cog.
get_v() - cogDistantDot.
get_v();
718 return sqrt( diff_u*diff_u + diff_v*diff_v );
786 double epsilon = 0.05;
787 if( grayLevelPrecision<epsilon )
789 this->grayLevelPrecision = epsilon;
791 else if( grayLevelPrecision>1 )
793 this->grayLevelPrecision = 1.0;
797 this->grayLevelPrecision = precision;
816 if( sizePrecision<0 )
818 this->sizePrecision = 0;
820 else if( sizePrecision>1 )
822 this->sizePrecision = 1.0;
826 this->sizePrecision = precision;
861 if( ellipsoidShapePrecision<0 )
863 this->ellipsoidShapePrecision = 0;
865 else if( ellipsoidShapePrecision>1 )
867 this->ellipsoidShapePrecision = 1.0;
871 this->ellipsoidShapePrecision = precision;
890 double epsilon = 0.05;
891 if( maxSizeSearchDistancePrecision<epsilon )
893 this-> maxSizeSearchDistancePrecision = epsilon;
895 else if( maxSizeSearchDistancePrecision >1 )
897 this->maxSizeSearchDistancePrecision = 1.0;
901 this->maxSizeSearchDistancePrecision = precision;
934 unsigned int w,
unsigned int h)
936 unsigned int image_w = I.
getWidth();
941 else if (u >= (
int)image_w) u = (int)image_w - 1;
943 else if (v >= (
int)image_h) v = (
int)image_h - 1;
945 if (((
unsigned int)u + w) > image_w) w = image_w - (
unsigned int)u - 1;
946 if (((
unsigned int)v + h) > image_h) h = image_h - (
unsigned int)v - 1;
1044 unsigned int area_w,
1045 unsigned int area_h,
1046 std::list<vpDot2> &niceDots)
1054 setArea(I, area_u, area_v, area_w, area_h);
1057 unsigned int gridWidth;
1058 unsigned int gridHeight;
1059 getGridSize( gridWidth, gridHeight );
1074 std::list<vpDot2> badDotsVector;
1075 std::list<vpDot2>::iterator itnice;
1076 std::list<vpDot2>::iterator itbad;
1078 vpDot2* dotToTest = NULL;
1081 unsigned int area_u_min = (
unsigned int) area.
getLeft();
1082 unsigned int area_u_max = (
unsigned int) area.
getRight();
1083 unsigned int area_v_min = (
unsigned int) area.
getTop();
1084 unsigned int area_v_max = (
unsigned int) area.
getBottom();
1089 for( v=area_v_min ; v<area_v_max ; v=v+gridHeight )
1091 for( u=area_u_min ; u<area_u_max ; u=u+gridWidth )
1096 if( !hasGoodLevel(I, u, v) )
continue;
1100 bool good_germ =
true;
1102 itnice = niceDots.begin();
1103 while( itnice != niceDots.end() && good_germ ==
true) {
1106 cogTmpDot = tmpDot.
getCog();
1107 double u0 = cogTmpDot.
get_u();
1108 double v0 = cogTmpDot.
get_v();
1109 double half_w = tmpDot.
getWidth() / 2.;
1110 double half_h = tmpDot.
getHeight() / 2.;
1112 if ( u >= (u0-half_w) && u <= (u0+half_w) &&
1113 v >= (v0-half_h) && v <= (v0+half_h) ) {
1124 unsigned int border_u;
1125 unsigned int border_v;
1126 if(findFirstBorder(I, u, v, border_u, border_v) ==
false){
1134 itbad = badDotsVector.begin();
1135 #define vpBAD_DOT_VALUE (*itbad)
1138 while( itbad != badDotsVector.end() && good_germ ==
true) {
1139 if( (
double)u >= vpBAD_DOT_VALUE.bbox_u_min
1140 && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1141 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min
1142 && (double)v <= vpBAD_DOT_VALUE.bbox_v_max){
1143 std::list<vpImagePoint>::const_iterator it_edges = ip_edges_list.begin();
1144 while (it_edges != ip_edges_list.end() && good_germ ==
true){
1148 cogBadDot = *it_edges;
1150 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() )
1152 (std::fabs(v - cogBadDot.
get_v()) <=
vpMath::maximum(std::fabs((
double)v), std::fabs(cogBadDot.
get_v()))*std::numeric_limits<double>::epsilon() )) {
1160 #undef vpBAD_DOT_VALUE
1169 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1177 if( dotToTest != NULL )
delete dotToTest;
1178 dotToTest = getInstance();
1179 dotToTest->
setCog( germ );
1193 if( dotToTest->computeParameters( I ) == false ) {
1200 if( dotToTest->isValid( I, *
this ) )
1208 double area_center_u = area_u + area_w/2.0 - 0.5;
1209 double area_center_v = area_v + area_h/2.0 - 0.5;
1211 double thisDiff_u = cogDotToTest.
get_u() - area_center_u;
1212 double thisDiff_v = cogDotToTest.
get_v() - area_center_v;
1213 double thisDist = sqrt( thisDiff_u*thisDiff_u + thisDiff_v*thisDiff_v);
1215 bool stopLoop =
false;
1216 itnice = niceDots.begin();
1218 while( itnice != niceDots.end() && stopLoop == false )
1223 double epsilon = 3.0;
1226 cogTmpDot = tmpDot.
getCog();
1228 if( fabs( cogTmpDot.
get_u() - cogDotToTest.
get_u() ) < epsilon &&
1229 fabs( cogTmpDot.
get_v() - cogDotToTest.
get_v() ) < epsilon )
1238 double otherDiff_u = cogTmpDot.
get_u() - area_center_u;
1239 double otherDiff_v = cogTmpDot.
get_v() - area_center_v;
1240 double otherDist = sqrt( otherDiff_u*otherDiff_u +
1241 otherDiff_v*otherDiff_v );
1247 if( otherDist > thisDist )
1249 niceDots.insert(itnice, *dotToTest );
1259 vpTRACE(4,
"End while (%d, %d)", u, v);
1263 if( itnice == niceDots.end() && stopLoop == false )
1265 niceDots.push_back( *dotToTest );
1270 badDotsVector.push_front( *dotToTest );
1274 if( dotToTest != NULL )
delete dotToTest;
1301 double epsilon = 0.001;
1310 if ( (std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon())
1312 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon())
1314 (std::fabs(wantedDot.
getArea()) > std::numeric_limits<double>::epsilon()) )
1316 if (std::fabs(size_precision) > std::numeric_limits<double>::epsilon()){
1318 std::cout <<
"test size precision......................\n";
1319 std::cout <<
"wanted dot: " <<
"w=" << wantedDot.
getWidth()
1321 <<
" s=" << wantedDot.
getArea()
1322 <<
" precision=" << size_precision
1323 <<
" epsilon=" << epsilon << std::endl;
1324 std::cout <<
"dot found: " <<
"w=" <<
getWidth()
1326 <<
" s=" <<
getArea() << std::endl;
1328 if( ( wantedDot.
getWidth()*size_precision-epsilon <
getWidth() ) ==
false )
1333 printf(
"Bad width > for dot (%g, %g)\n", cog.
get_u(), cog.
get_v());
1338 if( (
getWidth() < wantedDot.
getWidth()/(size_precision+epsilon ) )== false )
1343 printf(
"Bad width %g > %g for dot (%g, %g)\n",
1355 printf(
"Bad height %g > %g for dot (%g, %g)\n",
1367 printf(
"Bad height %g > %g for dot (%g, %g)\n",
1374 if( ( wantedDot.
getArea()*(size_precision*size_precision)-epsilon <
getArea() ) ==
false )
1379 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1380 wantedDot.
getArea()*(size_precision*size_precision)-epsilon,
1387 if( (
getArea() < wantedDot.
getArea()/(size_precision*size_precision+epsilon )) == false )
1392 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
1393 getArea(), wantedDot.
getArea()/(size_precision*size_precision+epsilon),
1404 int nb_point_to_test = 20;
1405 int nb_bad_points = 0;
1406 int nb_max_bad_points = (int)(nb_point_to_test*allowedBadPointsPercentage_);
1407 double step_angle = 2*M_PI / nb_point_to_test;
1410 if (std::fabs(ellipsoidShape_precision) > std::numeric_limits<double>::epsilon() && compute_moment) {
1429 double Sqrt = sqrt(tmp1*tmp1 + 4*tmp2*tmp2);
1440 double innerCoef = ellipsoidShape_precision ;
1442 double cog_u = this->cog.
get_u();
1443 double cog_v = this->cog.
get_v();
1447 for(
double theta = 0. ; theta<2*M_PI ; theta+= step_angle ) {
1448 u = (
unsigned int) (cog_u + innerCoef*(a1*cos(alpha)*cos(theta)-a2*sin(alpha)*sin(theta)));
1449 v = (
unsigned int) (cog_v + innerCoef*(a1*sin(alpha)*cos(theta)+a2*cos(alpha)*sin(theta)));
1450 if( ! this->hasGoodLevel( I, u, v) ) {
1454 printf(
"Inner cercle pixel (%d, %d) has bad level for dot (%g, %g): %d not in [%d, %d]\n",
1455 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1461 for (
unsigned int t=0; t< thickness; t++) {
1472 if (nb_bad_points > nb_max_bad_points)
1475 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n",
1476 nb_bad_points, nb_max_bad_points);
1485 double outCoef = 2-ellipsoidShape_precision;
1487 for(
double theta=0. ; theta<2*M_PI ; theta+= step_angle ) {
1488 u = (
unsigned int) (cog_u + outCoef*(a1*cos(alpha)*cos(theta)-a2*sin(alpha)*sin(theta)));
1489 v = (
unsigned int) (cog_v + outCoef*(a1*sin(alpha)*cos(theta)+a2*cos(alpha)*sin(theta)));
1500 if( ! this->hasReverseLevel( I, u, v ) ) {
1504 printf(
"Outside cercle pixel (%d, %d) has bad level for dot (%g, %g): %d not in [%d, %d]\n",
1505 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1511 for(
unsigned int t=0; t<thickness; t++) {
1520 if (nb_bad_points > nb_max_bad_points)
1523 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n",
1524 nb_bad_points, nb_max_bad_points);
1552 const unsigned int &u,
1553 const unsigned int &v)
const
1555 if( !isInArea( u, v ) )
1558 if( I[v][u] >= gray_level_min && I[v][u] <= gray_level_max)
1582 const unsigned int &u,
1583 const unsigned int &v)
const
1586 if( !isInArea( u, v ) )
1589 if( I[v][u] < gray_level_min || I[v][u] > gray_level_max)
1608 vpDot2* vpDot2::getInstance()
1630 freeman_chain = direction_list;
1678 direction_list.clear();
1679 ip_edges_list.clear();
1686 if( std::fabs(est_u + 1.0) <=
vpMath::maximum(std::fabs(est_u),1.)*std::numeric_limits<double>::epsilon() )
1688 est_u = this->cog.
get_u();
1693 if( std::fabs(est_v + 1.0) <=
vpMath::maximum(std::fabs(est_v),1.)*std::numeric_limits<double>::epsilon() )
1695 est_v = this->cog.
get_v();
1700 if( !isInArea( (
unsigned int) est_u, (
unsigned int) est_v ) )
1702 vpDEBUG_TRACE(3,
"Initial pixel coordinates (%d, %d) for dot tracking are not in the area",
1703 (
int) est_u, (
int) est_v) ;
1714 if( !hasGoodLevel( I, (
unsigned int) est_u, (
unsigned int) est_v ) )
1716 vpDEBUG_TRACE(3,
"Can't find a dot from pixel (%d, %d) coordinates",
1717 (
int) est_u, (
int) est_v) ;
1723 if(!findFirstBorder(I, (
unsigned int) est_u, (
unsigned int) est_v,
1724 this->firstBorder_u, this->firstBorder_v)) {
1726 vpDEBUG_TRACE(3,
"Can't find first border (%d, %d) coordinates",
1727 (
int) est_u, (
int) est_v) ;
1731 unsigned int dir = 6;
1734 computeFreemanChainElement(I, this->firstBorder_u, this->firstBorder_v, dir);
1735 unsigned int firstDir = dir;
1738 if( !isInArea( this->firstBorder_u, this->firstBorder_v ) )
1740 vpDEBUG_TRACE(3,
"Border pixel coordinates (%d, %d) of the dot are not in the area",
1741 this->firstBorder_u, this->firstBorder_v);
1746 direction_list.push_back( dir );
1748 ip.
set_u( this->firstBorder_u );
1749 ip.
set_v( this->firstBorder_v );
1751 ip_edges_list.push_back( ip );
1753 int border_u = (int)this->firstBorder_u;
1754 int border_v = (int)this->firstBorder_v;
1760 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1771 for(
int t=0; t< (int)thickness; t++) {
1772 ip.
set_u ( border_u + t);
1773 ip.
set_v ( border_v );
1784 computeFreemanParameters(border_u, border_v, dir, du, dv,
1795 if (compute_moment) {
1801 if( !isInArea( (
unsigned int)border_u, (
unsigned int)border_v ) ) {
1803 vpDEBUG_TRACE(3,
"Dot (%d, %d) is not in the area", border_u, border_v);
1810 direction_list.push_back( dir );
1812 ip.
set_u( border_u );
1813 ip.
set_v( border_v );
1814 ip_edges_list.push_back( ip );
1819 if( border_v < bbox_v_min ) bbox_v_min = border_v;
1820 if( border_v > bbox_v_max ) bbox_v_max = border_v;
1821 if( border_u < bbox_u_min ) bbox_u_min = border_u;
1822 if( border_u > bbox_u_max ) bbox_u_max = border_u;
1825 if (computeFreemanChainElement(I, (
unsigned int)border_u, (
unsigned int)border_v, dir) ==
false) {
1826 vpDEBUG_TRACE(3,
"Can't compute Freeman chain for dot (%d, %d)",
1827 border_u, border_v);
1834 while( (getFirstBorder_u() != (
unsigned int)border_u
1835 || getFirstBorder_v() != (
unsigned int)border_v
1836 || firstDir != dir) &&
1837 isInArea( (
unsigned int)border_u, (
unsigned int)border_v ) );
1840 #if VP_DEBUG_MODE == 3
1848 if( std::fabs(
m00) <= std::numeric_limits<double>::epsilon()
1849 || std::fabs(
m00 - 1.) <=
vpMath::maximum(std::fabs(
m00), 1.)*std::numeric_limits<double>::epsilon() )
1851 vpDEBUG_TRACE(3,
"The center of gravity of the dot wasn't properly detected");
1857 double tmpCenter_u =
m10 /
m00;
1858 double tmpCenter_v = m01 /
m00;
1877 cog.
set_u( tmpCenter_u );
1878 cog.
set_v( tmpCenter_v );
1881 width = bbox_u_max - bbox_u_min + 1;
1882 height = bbox_v_max - bbox_v_min + 1;
1885 computeMeanGrayLevel(I);
1907 const unsigned int &u,
1908 const unsigned int &v,
1909 unsigned int &border_u,
1910 unsigned int &border_v)
1920 double epsilon =0.001;
1923 std::cout <<
"gray level: " << gray_level_min <<
" " << gray_level_max << std::endl;
1925 while( hasGoodLevel( I, border_u+1, border_v ) &&
1931 vpDEBUG_TRACE(3,
"The found dot (%d, %d, %d) has a greater width than the required one", u, v, border_u);
1965 const unsigned int &u,
1966 const unsigned int &v,
1967 unsigned int &element)
1970 if (hasGoodLevel( I, u, v )) {
1971 unsigned int _u = u;
1972 unsigned int _v = v;
1974 updateFreemanPosition( _u, _v, (element + 2) %8 );
1975 if (hasGoodLevel( I, _u, _v )) {
1976 element = (element + 2) % 8;
1979 unsigned int _u1 = u;
1980 unsigned int _v1 = v;
1981 updateFreemanPosition( _u1, _v1, (element + 1) %8 );
1983 if ( hasGoodLevel( I, _u1, _v1 )) {
1984 element = (element + 1) % 8;
1987 unsigned int _u2 = u;
1988 unsigned int _v2 = v;
1989 updateFreemanPosition( _u2, _v2, element );
1991 if ( hasGoodLevel( I, _u2, _v2 )) {
1995 unsigned int _u3 = u;
1996 unsigned int _v3 = v;
1997 updateFreemanPosition( _u3, _v3, (element + 7) %8 );
1999 if ( hasGoodLevel( I, _u3, _v3 )) {
2000 element = (element + 7) %8;
2003 unsigned int _u4 = u;
2004 unsigned int _v4 = v;
2005 updateFreemanPosition( _u4, _v4, (element + 6) %8 );
2007 if ( hasGoodLevel( I, _u4, _v4 )) {
2008 element = (element + 6) %8 ;
2011 unsigned int _u5 = u;
2012 unsigned int _v5 = v;
2013 updateFreemanPosition( _u5, _v5, (element + 5) %8 );
2015 if ( hasGoodLevel( I, _u5, _v5 )) {
2016 element = (element + 5) %8 ;
2019 unsigned int _u6 = u;
2020 unsigned int _v6 = v;
2021 updateFreemanPosition( _u6, _v6, (element + 4) %8 );
2023 if ( hasGoodLevel( I, _u6, _v6 )) {
2024 element = (element + 4) %8 ;
2027 unsigned int _u7 = u;
2028 unsigned int _v7 = v;
2029 updateFreemanPosition( _u7, _v7, (element + 3) %8 );
2031 if ( hasGoodLevel( I, _u7, _v7 )) {
2032 element = (element + 3) %8 ;
2088 vpDot2::computeFreemanParameters(
const int &u_p,
2090 unsigned int &element,
2093 float &dMu,
float &dMv,
2095 float &dMu2,
float &dMv2)
2117 dMv = (float)(0.5 * v_p * v_p);
2118 if (compute_moment) {
2119 dMuv = (float)(0.25 * v_p * v_p * (2 * u_p + 1));
2121 dMv2 = (float)(1.0/ 3. * v_p * v_p * v_p);
2128 dS = (float)(v_p + 0.5);
2129 dMu = - (float)(0.5 * u_p * ( u_p + 1 ) + 1.0 / 6.0);
2130 dMv = (float)(0.5 * v_p * ( v_p + 1 ) + 1.0 / 6.0);
2131 if (compute_moment) {
2132 float half_u_p = (float)(0.5*u_p);
2133 dMuv = (float)(v_p*v_p*(0.25+half_u_p) + v_p*(1./3.+half_u_p) + 1./6.*u_p +0.125);
2134 dMu2 = (float)(-1./3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) - 1./12.0);
2135 dMv2 = (float)( 1./3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) + 1./12.0);
2142 dMu = (float)(- 0.5 * u_p * u_p);
2144 if (compute_moment) {
2146 dMu2 = (float)(-1.0/ 3. * u_p * u_p * u_p);
2154 dS = (float)(- v_p - 0.5);
2155 dMu = - (float)(0.5 * u_p * ( u_p - 1 ) + 1.0 / 6.0);
2156 dMv = - (float)(0.5 * v_p * ( v_p + 1 ) + 1.0 / 6.0);
2157 if (compute_moment) {
2158 float half_u_p = (float)(0.5*u_p);
2159 dMuv = (float)(v_p*v_p*(0.25-half_u_p) + v_p*(1./3.-half_u_p) - 1./6.*u_p +0.125);
2160 dMu2 = (float)(-1./3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1./12.0);
2161 dMv2 = (float)(-1./3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) - 1./12.0);
2167 dS = (float)(- v_p);
2168 dMv = (float)(- 0.5 * v_p * v_p);
2170 if (compute_moment) {
2171 dMuv = (float)(-0.25 * v_p * v_p * (2 * u_p - 1));
2173 dMv2 = (float)(-1.0/ 3. * v_p * v_p * v_p);
2180 dS = (float)(- v_p + 0.5);
2181 dMu = (float)( 0.5 * u_p * ( u_p - 1 ) + 1.0 / 6.0);
2182 dMv = (float)(- (0.5 * v_p * ( v_p - 1 ) + 1.0 / 6.0));
2183 if (compute_moment) {
2184 float half_u_p = (float)(0.5*u_p);
2185 dMuv = (float)(v_p*v_p*(0.25-half_u_p) - v_p*(1./3.-half_u_p) - 1./6.*u_p +0.125);
2186 dMu2 = (float)( 1./3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1./12.0);
2187 dMv2 = (float)(-1./3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1./12.0);
2194 dMu = (float)(0.5 * u_p * u_p);
2196 if (compute_moment) {
2198 dMu2 = (float)(1.0/ 3. * u_p * u_p * u_p);
2206 dS = (float)(v_p - 0.5);
2207 dMu = (float)(0.5 * u_p * ( u_p + 1 ) + 1.0 / 6.0);
2208 dMv = (float)(0.5 * v_p * ( v_p - 1 ) + 1.0 / 6.0);
2209 if (compute_moment) {
2210 float half_u_p = (float)(0.5*u_p);
2211 dMuv = (float)(v_p*v_p*(0.25+half_u_p) - v_p*(1./3.+half_u_p) + 1./6.*u_p +0.125);
2212 dMu2 = (float)(1./3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) + 1./12.0);
2213 dMv2 = (float)(1./3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1./12.0);
2233 void vpDot2::updateFreemanPosition(
unsigned int& u,
unsigned int& v,
2234 const unsigned int &dir )
2237 case 0: u += 1;
break;
2238 case 1: u += 1; v += 1;
break;
2239 case 2: v += 1;
break;
2240 case 3: u -= 1; v += 1;
break;
2241 case 4: u -= 1;
break;
2242 case 5: u -= 1; v -= 1;
break;
2243 case 6: v -= 1;
break;
2244 case 7: u += 1; v -= 1;
break;
2261 return isInImage( I, cog);
2279 double u = ip.
get_u();
2280 double v = ip.
get_v();
2282 if( u < 0 || u >= w )
return false;
2283 if( v < 0 || v >= h )
return false;
2298 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const
2300 unsigned int area_u_min = (
unsigned int) area.
getLeft();
2301 unsigned int area_u_max = (
unsigned int) area.
getRight();
2302 unsigned int area_v_min = (
unsigned int) area.
getTop();
2303 unsigned int area_v_max = (
unsigned int) area.
getBottom();
2305 if( u < area_u_min || u > area_u_max )
return false;
2306 if( v < area_v_min || v > area_v_max )
return false;
2322 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight )
2332 if( gridWidth == 0 ) gridWidth = 1;
2333 if( gridHeight == 0 ) gridHeight = 1;
2352 int cog_u = (int)cog.
get_u();
2353 int cog_v = (int)cog.
get_v();
2355 unsigned int sum_value =0;
2356 unsigned int nb_pixels =0;
2358 for(
unsigned int i=(
unsigned int)this->bbox_u_min; i <=(
unsigned int)this->bbox_u_max ; i++){
2359 unsigned int pixel_gray =(
unsigned int) I[(
unsigned int)cog_v][i];
2361 sum_value += pixel_gray;
2365 for(
unsigned int i=(
unsigned int)this->bbox_v_min; i <=(
unsigned int)this->bbox_v_max ; i++){
2366 unsigned char pixel_gray =I[i][(
unsigned int)cog_u];
2368 sum_value += pixel_gray;
2375 if( (cog_u - bbox_u_min) > (cog_v - bbox_v_min)){
2376 imin=cog_v - bbox_v_min;
2378 else{ imin = cog_u - bbox_u_min;}
2379 if( (bbox_u_max - cog_u) > (bbox_v_max - cog_v)){
2380 imax=bbox_v_max - cog_v;
2382 else{ imax = bbox_u_max - cog_u;}
2383 for(
int i=-imin; i <=imax ; i++){
2384 unsigned int pixel_gray =(
unsigned int) I[(
unsigned int)(cog_v + i)][(
unsigned int)(cog_u + i)];
2386 sum_value += pixel_gray;
2391 if( (cog_u - bbox_u_min) > (bbox_v_max - cog_v)){
2392 imin = bbox_v_max - cog_v;
2394 else{ imin = cog_u - bbox_u_min;}
2395 if( (bbox_u_max - cog_u) > (cog_v - bbox_v_min)){
2396 imax = cog_v - bbox_v_min;
2398 else{ imax = bbox_u_max - cog_u;}
2400 for(
int i=-imin; i <=imax ; i++){
2401 unsigned char pixel_gray =I[(
unsigned int)(cog_v - i)][(
unsigned int)(cog_u + i)];
2403 sum_value += pixel_gray;
2414 mean_gray_level = sum_value/nb_pixels;
2442 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
2448 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
2459 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
2472 std::cout <<
"Cannot track dots from file" << std::endl;
2479 for(i=0;i<n && fromFile;++i)
2482 for(
unsigned int j=0;j<n && fromFile;++j)
2487 std::cout <<
"Dots from file seem incoherent" << std::endl;
2497 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
2498 for (i = 0; i < n; i++)
2511 Cogs[i][0] = cog.
get_u();
2512 Cogs[i][1] = cog.
get_v();
2518 if (!fromFile & (dotFile !=
""))
2521 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
2547 cogs.push_back(dot[i].
getCog());
2550 for(i=n;i<cogs.size();++i)
2580 const std::list<vpImagePoint> &edges_list,
vpColor color,
2581 unsigned int thickness)
2584 std::list<vpImagePoint>::const_iterator it;
2586 for (it = edges_list.begin(); it != edges_list.end(); ++it)
2607 const std::list<vpImagePoint> &edges_list,
vpColor color,
2608 unsigned int thickness)
2611 std::list<vpImagePoint>::const_iterator it;
2613 for (it = edges_list.begin(); it != edges_list.end(); ++it)
2625 return (os <<
"(" << d.
getCog() <<
")" ) ;
virtual void displayCircle(const vpImagePoint ¢er, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)=0
Implementation of a matrix and operations on matrices.
void setGrayLevelMax(const unsigned int &max)
void searchDotsInArea(const vpImage< unsigned char > &I, int area_u, int area_v, unsigned int area_w, unsigned int area_h, std::list< vpDot2 > &niceDots)
void getFreemanChain(std::list< unsigned int > &freeman_chain) const
static bool loadMatrix(const std::string &filename, vpArray2D< double > &M, const bool binary=false, char *header=NULL)
unsigned int getWidth() const
void setMaxSizeSearchDistancePrecision(const double &maxSizeSearchDistancePrecision)
Class to define colors available for display functionnalities.
void setEllipsoidBadPointsPercentage(const double &percentage=0.0)
double getGrayLevelPrecision() const
vpDot2 & operator=(const vpDot2 &twinDot)
void setCog(const vpImagePoint &ip)
error that can be emited by ViSP classes.
double getEllipsoidShapePrecision() const
double getDistance(const vpDot2 &distantDot) const
static const vpColor green
This tracker is meant to track a blob (connex pixels with same gray level) on a vpImage.
void track(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
double getSizePrecision() const
Class that defines what is a feature generic tracker.
static Type maximum(const Type &a, const Type &b)
vpImagePoint getCog() const
void setGraphicsThickness(unsigned int t)
void setGrayLevelPrecision(const double &grayLevelPrecision)
Error that can be emited by the vpTracker class and its derivates.
double getMaxSizeSearchDistancePrecision() const
void set_u(const double u)
static double sqr(double x)
static void display(const vpImage< unsigned char > &I)
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1) const
void set_v(const double v)
unsigned int getGrayLevelMin() const
void setComputeMoments(const bool activate)
void setArea(const double &area)
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
virtual void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)=0
unsigned int getRows() const
Return the number of rows of the 2D array.
void setEllipsoidShapePrecision(const double &ellipsoidShapePrecision)
virtual void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
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)
void initTracking(const vpImage< unsigned char > &I, unsigned int size=0)
static bool saveMatrix(const std::string &filename, const vpArray2D< double > &M, const bool binary=false, const char *header="")
void setHeight(const double &height)
unsigned int getHeight() const
void set_uv(const double u, const double v)
Defines a rectangle in the plane.
double getMeanGrayLevel() const
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 getGrayLevelMax() const
static const vpColor purple
void setRect(double l, double t, double w, double h)
static vpMatrix defineDots(vpDot2 dot[], const unsigned int &n, const std::string &dotFile, vpImage< unsigned char > &I, vpColor col=vpColor::blue, bool trackDot=true)
void setGraphics(const bool activate)
virtual void displayPoint(const vpImagePoint &ip, const vpColor &color)=0
static const vpColor blue