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>
85 grayLevelPrecision = 0.80;
89 ellipsoidShapePrecision = 0.65;
90 maxSizeSearchDistancePrecision = 0.65;
95 bbox_u_min = bbox_u_max = bbox_v_min = bbox_v_max = 0;
100 compute_moment = false ;
109 : m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.),
110 mu11(0.), mu20(0.), mu02(0.), cog(), width(0), height(0), surface(0),
111 gray_level_min(128), gray_level_max(255), mean_gray_level(0), grayLevelPrecision(0.8), gamma(1.5),
112 sizePrecision(0.65), ellipsoidShapePrecision(0.65), maxSizeSearchDistancePrecision(0.65),
113 allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(), compute_moment(false),
114 graphics(false), thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0),
115 firstBorder_u(0), firstBorder_v()
128 : m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.),
129 mu11(0.), mu20(0.), mu02(0.), cog(), width(0), height(0), surface(0),
130 gray_level_min(128), gray_level_max(255), mean_gray_level(0), grayLevelPrecision(0.8), gamma(1.5),
131 sizePrecision(0.65), ellipsoidShapePrecision(0.65), maxSizeSearchDistancePrecision(0.65),
132 allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(), compute_moment(false),
133 graphics(false), thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0),
134 firstBorder_u(0), firstBorder_v()
144 m00(0.), m10(0.), m01(0.), m11(0.), m20(0.), m02(0.),
145 mu11(0.), mu20(0.), mu02(0.), cog(), width(0), height(0), surface(0),
146 gray_level_min(128), gray_level_max(255), mean_gray_level(0), grayLevelPrecision(0.8), gamma(1.5),
147 sizePrecision(0.65), ellipsoidShapePrecision(0.65), maxSizeSearchDistancePrecision(0.65),
148 allowedBadPointsPercentage_(0.), area(), direction_list(), ip_edges_list(), compute_moment(false),
149 graphics(false), thickness(1), bbox_u_min(0), bbox_u_max(0), bbox_v_min(0), bbox_v_max(0),
150 firstBorder_u(0), firstBorder_v()
162 width = twinDot.width;
163 height = twinDot.height;
164 surface = twinDot.surface;
165 gray_level_min = twinDot.gray_level_min;
166 gray_level_max = twinDot.gray_level_max;
167 mean_gray_level = twinDot.mean_gray_level;
168 grayLevelPrecision = twinDot.grayLevelPrecision;
169 gamma = twinDot.gamma; ;
170 sizePrecision = twinDot.sizePrecision;
171 ellipsoidShapePrecision = twinDot.ellipsoidShapePrecision ;
172 maxSizeSearchDistancePrecision = twinDot.maxSizeSearchDistancePrecision;
173 allowedBadPointsPercentage_ = twinDot.allowedBadPointsPercentage_;
176 direction_list = twinDot.direction_list;
177 ip_edges_list = twinDot.ip_edges_list;
179 compute_moment = twinDot.compute_moment;
180 graphics = twinDot.graphics;
181 thickness = twinDot.thickness;
183 bbox_u_min = twinDot.bbox_u_min;
184 bbox_u_max = twinDot.bbox_u_max;
185 bbox_v_min = twinDot.bbox_v_min;
186 bbox_v_max = twinDot.bbox_v_max;
188 firstBorder_u = twinDot.firstBorder_u;
189 firstBorder_v = twinDot.firstBorder_v;
226 std::list<vpImagePoint>::const_iterator it;
228 for (it = ip_edges_list.begin(); it != ip_edges_list.end(); ++it)
270 unsigned int i = (
unsigned int)cog.
get_i();
271 unsigned int j = (
unsigned int)cog.
get_j();
273 double Ip = pow((
double)I[i][j]/255,1/gamma);
275 if(Ip - (1 - grayLevelPrecision)<0){
279 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
280 if (gray_level_min > 255)
281 gray_level_min = 255;
283 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
284 if (gray_level_max > 255)
285 gray_level_max = 255;
332 unsigned int i = (
unsigned int)cog.
get_i();
333 unsigned int j = (
unsigned int)cog.
get_j();
335 double Ip = pow((
double)I[i][j]/255,1/gamma);
337 if(Ip - (1 - grayLevelPrecision)<0){
341 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
342 if (gray_level_min > 255)
343 gray_level_min = 255;
345 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
346 if (gray_level_max > 255)
347 gray_level_max = 255;
403 unsigned int gray_lvl_min,
404 unsigned int gray_lvl_max,
409 this->gray_level_min = gray_lvl_min;
410 this->gray_level_max = gray_lvl_max;
486 found = computeParameters(I, cog.
get_u(), cog.
get_v());
490 found = isValid( I, wantedDot);
509 double searchWindowWidth, searchWindowHeight;
511 if( std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon() || std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon() )
513 searchWindowWidth = 80.;
514 searchWindowHeight = 80.;
521 std::list<vpDot2> candidates;
523 (
int)(this->cog.
get_u()-searchWindowWidth /2.0),
524 (int)(this->cog.
get_v()-searchWindowHeight/2.0),
525 (
unsigned int)searchWindowWidth,
526 (
unsigned int)searchWindowHeight,
531 if( candidates.empty() )
535 "No dot was found")) ;
539 vpDot2 movingDot = candidates.front();
555 bbox_u_min = movingDot.bbox_u_min;
556 bbox_u_max = movingDot.bbox_u_max;
557 bbox_v_min = movingDot.bbox_v_min;
558 bbox_v_max = movingDot.bbox_v_max;
578 if( !isInImage( I ) )
580 vpERROR_TRACE(
"The center of gravity of the dot is not in the image") ;
582 "No dot was found")) ;
594 if(Ip - (1 - grayLevelPrecision)<0){
598 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
599 if (gray_level_min > 255)
600 gray_level_min = 255;
602 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
603 if (gray_level_max > 255)
604 gray_level_max = 255;
670 return fabs(surface);
680 return grayLevelPrecision;
690 return sizePrecision;
702 return ellipsoidShapePrecision;
711 return maxSizeSearchDistancePrecision;
720 double diff_u = this->cog.
get_u() - cogDistantDot.
get_u();
721 double diff_v = this->cog.
get_v() - cogDistantDot.
get_v();
722 return sqrt( diff_u*diff_u + diff_v*diff_v );
790 double epsilon = 0.05;
791 if( grayLevelPrecision<epsilon )
793 this->grayLevelPrecision = epsilon;
795 else if( grayLevelPrecision>1 )
797 this->grayLevelPrecision = 1.0;
801 this->grayLevelPrecision = precision;
820 if( sizePrecision<0 )
822 this->sizePrecision = 0;
824 else if( sizePrecision>1 )
826 this->sizePrecision = 1.0;
830 this->sizePrecision = precision;
865 if( ellipsoidShapePrecision<0 )
867 this->ellipsoidShapePrecision = 0;
869 else if( ellipsoidShapePrecision>1 )
871 this->ellipsoidShapePrecision = 1.0;
875 this->ellipsoidShapePrecision = precision;
894 double epsilon = 0.05;
895 if( maxSizeSearchDistancePrecision<epsilon )
897 this-> maxSizeSearchDistancePrecision = epsilon;
899 else if( maxSizeSearchDistancePrecision >1 )
901 this->maxSizeSearchDistancePrecision = 1.0;
905 this->maxSizeSearchDistancePrecision = precision;
938 unsigned int w,
unsigned int h)
940 unsigned int image_w = I.
getWidth();
945 else if (u >= (
int)image_w) u = (int)image_w - 1;
947 else if (v >= (
int)image_h) v = (
int)image_h - 1;
949 if (((
unsigned int)u + w) > image_w) w = image_w - (
unsigned int)u - 1;
950 if (((
unsigned int)v + h) > image_h) h = image_h - (
unsigned int)v - 1;
1048 unsigned int area_w,
1049 unsigned int area_h,
1050 std::list<vpDot2> &niceDots)
1058 setArea(I, area_u, area_v, area_w, area_h);
1061 unsigned int gridWidth;
1062 unsigned int gridHeight;
1063 getGridSize( gridWidth, gridHeight );
1078 std::list<vpDot2> badDotsVector;
1079 std::list<vpDot2>::iterator itnice;
1080 std::list<vpDot2>::iterator itbad;
1082 vpDot2* dotToTest = NULL;
1085 unsigned int area_u_min = (
unsigned int) area.
getLeft();
1086 unsigned int area_u_max = (
unsigned int) area.
getRight();
1087 unsigned int area_v_min = (
unsigned int) area.
getTop();
1088 unsigned int area_v_max = (
unsigned int) area.
getBottom();
1093 for( v=area_v_min ; v<area_v_max ; v=v+gridHeight )
1095 for( u=area_u_min ; u<area_u_max ; u=u+gridWidth )
1100 if( !hasGoodLevel(I, u, v) )
continue;
1104 bool good_germ =
true;
1106 itnice = niceDots.begin();
1107 while( itnice != niceDots.end() && good_germ ==
true) {
1110 cogTmpDot = tmpDot.
getCog();
1111 double u0 = cogTmpDot.
get_u();
1112 double v0 = cogTmpDot.
get_v();
1113 double half_w = tmpDot.
getWidth() / 2.;
1114 double half_h = tmpDot.
getHeight() / 2.;
1116 if ( u >= (u0-half_w) && u <= (u0+half_w) &&
1117 v >= (v0-half_h) && v <= (v0+half_h) ) {
1128 unsigned int border_u;
1129 unsigned int border_v;
1130 if(findFirstBorder(I, u, v, border_u, border_v) ==
false){
1138 itbad = badDotsVector.begin();
1139 #define vpBAD_DOT_VALUE (*itbad)
1142 while( itbad != badDotsVector.end() && good_germ ==
true) {
1143 if( (
double)u >= vpBAD_DOT_VALUE.bbox_u_min
1144 && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1145 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min
1146 && (double)v <= vpBAD_DOT_VALUE.bbox_v_max){
1147 std::list<vpImagePoint>::const_iterator it_edges = ip_edges_list.begin();
1148 while (it_edges != ip_edges_list.end() && good_germ ==
true){
1152 cogBadDot = *it_edges;
1154 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() )
1156 (std::fabs(v - cogBadDot.
get_v()) <=
vpMath::maximum(std::fabs((
double)v), std::fabs(cogBadDot.
get_v()))*std::numeric_limits<double>::epsilon() )) {
1164 #undef vpBAD_DOT_VALUE
1173 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1181 if( dotToTest != NULL )
delete dotToTest;
1182 dotToTest = getInstance();
1183 dotToTest->
setCog( germ );
1197 if( dotToTest->computeParameters( I ) == false ) {
1204 if( dotToTest->isValid( I, *
this ) )
1212 double area_center_u = area_u + area_w/2.0 - 0.5;
1213 double area_center_v = area_v + area_h/2.0 - 0.5;
1215 double thisDiff_u = cogDotToTest.
get_u() - area_center_u;
1216 double thisDiff_v = cogDotToTest.
get_v() - area_center_v;
1217 double thisDist = sqrt( thisDiff_u*thisDiff_u + thisDiff_v*thisDiff_v);
1219 bool stopLoop =
false;
1220 itnice = niceDots.begin();
1222 while( itnice != niceDots.end() && stopLoop == false )
1227 double epsilon = 3.0;
1230 cogTmpDot = tmpDot.
getCog();
1232 if( fabs( cogTmpDot.
get_u() - cogDotToTest.
get_u() ) < epsilon &&
1233 fabs( cogTmpDot.
get_v() - cogDotToTest.
get_v() ) < epsilon )
1242 double otherDiff_u = cogTmpDot.
get_u() - area_center_u;
1243 double otherDiff_v = cogTmpDot.
get_v() - area_center_v;
1244 double otherDist = sqrt( otherDiff_u*otherDiff_u +
1245 otherDiff_v*otherDiff_v );
1251 if( otherDist > thisDist )
1253 niceDots.insert(itnice, *dotToTest );
1263 vpTRACE(4,
"End while (%d, %d)", u, v);
1267 if( itnice == niceDots.end() && stopLoop == false )
1269 niceDots.push_back( *dotToTest );
1274 badDotsVector.push_front( *dotToTest );
1278 if( dotToTest != NULL )
delete dotToTest;
1305 double epsilon = 0.001;
1314 if ( (std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon())
1316 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon())
1318 (std::fabs(wantedDot.
getArea()) > std::numeric_limits<double>::epsilon()) )
1320 if (std::fabs(size_precision) > std::numeric_limits<double>::epsilon()){
1322 std::cout <<
"test size precision......................\n";
1323 std::cout <<
"wanted dot: " <<
"w=" << wantedDot.
getWidth()
1325 <<
" s=" << wantedDot.
getArea()
1326 <<
" precision=" << size_precision
1327 <<
" epsilon=" << epsilon << std::endl;
1328 std::cout <<
"dot found: " <<
"w=" <<
getWidth()
1330 <<
" s=" <<
getArea() << std::endl;
1332 if( ( wantedDot.
getWidth()*size_precision-epsilon <
getWidth() ) ==
false )
1337 printf(
"Bad width > for dot (%g, %g)\n", cog.
get_u(), cog.
get_v());
1342 if( (
getWidth() < wantedDot.
getWidth()/(size_precision+epsilon ) )== false )
1347 printf(
"Bad width %g > %g for dot (%g, %g)\n",
1359 printf(
"Bad height %g > %g for dot (%g, %g)\n",
1371 printf(
"Bad height %g > %g for dot (%g, %g)\n",
1378 if( ( wantedDot.
getArea()*(size_precision*size_precision)-epsilon <
getArea() ) ==
false )
1383 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1384 wantedDot.
getArea()*(size_precision*size_precision)-epsilon,
1391 if( (
getArea() < wantedDot.
getArea()/(size_precision*size_precision+epsilon )) == false )
1396 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
1397 getArea(), wantedDot.
getArea()/(size_precision*size_precision+epsilon),
1408 int nb_point_to_test = 20;
1409 int nb_bad_points = 0;
1410 int nb_max_bad_points = (int)(nb_point_to_test*allowedBadPointsPercentage_);
1411 double step_angle = 2*M_PI / nb_point_to_test;
1414 if (std::fabs(ellipsoidShape_precision) > std::numeric_limits<double>::epsilon() && compute_moment) {
1433 double Sqrt = sqrt(tmp1*tmp1 + 4*tmp2*tmp2);
1444 double innerCoef = ellipsoidShape_precision ;
1446 double cog_u = this->cog.
get_u();
1447 double cog_v = this->cog.
get_v();
1451 for(
double theta = 0. ; theta<2*M_PI ; theta+= step_angle ) {
1452 u = (
unsigned int) (cog_u + innerCoef*(a1*cos(alpha)*cos(theta)-a2*sin(alpha)*sin(theta)));
1453 v = (
unsigned int) (cog_v + innerCoef*(a1*sin(alpha)*cos(theta)+a2*cos(alpha)*sin(theta)));
1454 if( ! this->hasGoodLevel( I, u, v) ) {
1458 printf(
"Inner cercle pixel (%d, %d) has bad level for dot (%g, %g): %d not in [%d, %d]\n",
1459 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1465 for (
unsigned int t=0; t< thickness; t++) {
1476 if (nb_bad_points > nb_max_bad_points)
1479 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n",
1480 nb_bad_points, nb_max_bad_points);
1489 double outCoef = 2-ellipsoidShape_precision;
1491 for(
double theta=0. ; theta<2*M_PI ; theta+= step_angle ) {
1492 u = (
unsigned int) (cog_u + outCoef*(a1*cos(alpha)*cos(theta)-a2*sin(alpha)*sin(theta)));
1493 v = (
unsigned int) (cog_v + outCoef*(a1*sin(alpha)*cos(theta)+a2*cos(alpha)*sin(theta)));
1504 if( ! this->hasReverseLevel( I, u, v ) ) {
1508 printf(
"Outside cercle pixel (%d, %d) has bad level for dot (%g, %g): %d not in [%d, %d]\n",
1509 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1515 for(
unsigned int t=0; t<thickness; t++) {
1524 if (nb_bad_points > nb_max_bad_points)
1527 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n",
1528 nb_bad_points, nb_max_bad_points);
1556 const unsigned int &u,
1557 const unsigned int &v)
const
1559 if( !isInArea( u, v ) )
1562 if( I[v][u] >= gray_level_min && I[v][u] <= gray_level_max)
1586 const unsigned int &u,
1587 const unsigned int &v)
const
1590 if( !isInArea( u, v ) )
1593 if( I[v][u] < gray_level_min || I[v][u] > gray_level_max)
1612 vpDot2* vpDot2::getInstance()
1634 freeman_chain = direction_list;
1682 direction_list.clear();
1683 ip_edges_list.clear();
1690 if( std::fabs(est_u + 1.0) <=
vpMath::maximum(std::fabs(est_u),1.)*std::numeric_limits<double>::epsilon() )
1692 est_u = this->cog.
get_u();
1697 if( std::fabs(est_v + 1.0) <=
vpMath::maximum(std::fabs(est_v),1.)*std::numeric_limits<double>::epsilon() )
1699 est_v = this->cog.
get_v();
1704 if( !isInArea( (
unsigned int) est_u, (
unsigned int) est_v ) )
1706 vpDEBUG_TRACE(3,
"Initial pixel coordinates (%d, %d) for dot tracking are not in the area",
1707 (
int) est_u, (
int) est_v) ;
1718 if( !hasGoodLevel( I, (
unsigned int) est_u, (
unsigned int) est_v ) )
1720 vpDEBUG_TRACE(3,
"Can't find a dot from pixel (%d, %d) coordinates",
1721 (
int) est_u, (
int) est_v) ;
1727 if(!findFirstBorder(I, (
unsigned int) est_u, (
unsigned int) est_v,
1728 this->firstBorder_u, this->firstBorder_v)) {
1730 vpDEBUG_TRACE(3,
"Can't find first border (%d, %d) coordinates",
1731 (
int) est_u, (
int) est_v) ;
1735 unsigned int dir = 6;
1738 computeFreemanChainElement(I, this->firstBorder_u, this->firstBorder_v, dir);
1739 unsigned int firstDir = dir;
1742 if( !isInArea( this->firstBorder_u, this->firstBorder_v ) )
1744 vpDEBUG_TRACE(3,
"Border pixel coordinates (%d, %d) of the dot are not in the area",
1745 this->firstBorder_u, this->firstBorder_v);
1750 direction_list.push_back( dir );
1752 ip.
set_u( this->firstBorder_u );
1753 ip.
set_v( this->firstBorder_v );
1755 ip_edges_list.push_back( ip );
1757 int border_u = (int)this->firstBorder_u;
1758 int border_v = (int)this->firstBorder_v;
1764 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1775 for(
int t=0; t< (int)thickness; t++) {
1776 ip.
set_u ( border_u + t);
1777 ip.
set_v ( border_v );
1788 computeFreemanParameters(border_u, border_v, dir, du, dv,
1799 if (compute_moment) {
1805 if( !isInArea( (
unsigned int)border_u, (
unsigned int)border_v ) ) {
1807 vpDEBUG_TRACE(3,
"Dot (%d, %d) is not in the area", border_u, border_v);
1814 direction_list.push_back( dir );
1816 ip.
set_u( border_u );
1817 ip.
set_v( border_v );
1818 ip_edges_list.push_back( ip );
1823 if( border_v < bbox_v_min ) bbox_v_min = border_v;
1824 if( border_v > bbox_v_max ) bbox_v_max = border_v;
1825 if( border_u < bbox_u_min ) bbox_u_min = border_u;
1826 if( border_u > bbox_u_max ) bbox_u_max = border_u;
1829 if (computeFreemanChainElement(I, (
unsigned int)border_u, (
unsigned int)border_v, dir) ==
false) {
1830 vpDEBUG_TRACE(3,
"Can't compute Freeman chain for dot (%d, %d)",
1831 border_u, border_v);
1838 while( (getFirstBorder_u() != (
unsigned int)border_u
1839 || getFirstBorder_v() != (
unsigned int)border_v
1840 || firstDir != dir) &&
1841 isInArea( (
unsigned int)border_u, (
unsigned int)border_v ) );
1844 #if VP_DEBUG_MODE == 3
1852 if( std::fabs(
m00) <= std::numeric_limits<double>::epsilon()
1853 || std::fabs(
m00 - 1.) <=
vpMath::maximum(std::fabs(
m00), 1.)*std::numeric_limits<double>::epsilon() )
1855 vpDEBUG_TRACE(3,
"The center of gravity of the dot wasn't properly detected");
1861 double tmpCenter_u =
m10 /
m00;
1862 double tmpCenter_v = m01 /
m00;
1881 cog.
set_u( tmpCenter_u );
1882 cog.
set_v( tmpCenter_v );
1885 width = bbox_u_max - bbox_u_min + 1;
1886 height = bbox_v_max - bbox_v_min + 1;
1889 computeMeanGrayLevel(I);
1911 const unsigned int &u,
1912 const unsigned int &v,
1913 unsigned int &border_u,
1914 unsigned int &border_v)
1924 double epsilon =0.001;
1927 std::cout <<
"gray level: " << gray_level_min <<
" " << gray_level_max << std::endl;
1929 while( hasGoodLevel( I, border_u+1, border_v ) &&
1935 vpDEBUG_TRACE(3,
"The found dot (%d, %d, %d) has a greater width than the required one", u, v, border_u);
1969 const unsigned int &u,
1970 const unsigned int &v,
1971 unsigned int &element)
1974 if (hasGoodLevel( I, u, v )) {
1975 unsigned int _u = u;
1976 unsigned int _v = v;
1978 updateFreemanPosition( _u, _v, (element + 2) %8 );
1979 if (hasGoodLevel( I, _u, _v )) {
1980 element = (element + 2) % 8;
1983 unsigned int _u1 = u;
1984 unsigned int _v1 = v;
1985 updateFreemanPosition( _u1, _v1, (element + 1) %8 );
1987 if ( hasGoodLevel( I, _u1, _v1 )) {
1988 element = (element + 1) % 8;
1991 unsigned int _u2 = u;
1992 unsigned int _v2 = v;
1993 updateFreemanPosition( _u2, _v2, element );
1995 if ( hasGoodLevel( I, _u2, _v2 )) {
1999 unsigned int _u3 = u;
2000 unsigned int _v3 = v;
2001 updateFreemanPosition( _u3, _v3, (element + 7) %8 );
2003 if ( hasGoodLevel( I, _u3, _v3 )) {
2004 element = (element + 7) %8;
2007 unsigned int _u4 = u;
2008 unsigned int _v4 = v;
2009 updateFreemanPosition( _u4, _v4, (element + 6) %8 );
2011 if ( hasGoodLevel( I, _u4, _v4 )) {
2012 element = (element + 6) %8 ;
2015 unsigned int _u5 = u;
2016 unsigned int _v5 = v;
2017 updateFreemanPosition( _u5, _v5, (element + 5) %8 );
2019 if ( hasGoodLevel( I, _u5, _v5 )) {
2020 element = (element + 5) %8 ;
2023 unsigned int _u6 = u;
2024 unsigned int _v6 = v;
2025 updateFreemanPosition( _u6, _v6, (element + 4) %8 );
2027 if ( hasGoodLevel( I, _u6, _v6 )) {
2028 element = (element + 4) %8 ;
2031 unsigned int _u7 = u;
2032 unsigned int _v7 = v;
2033 updateFreemanPosition( _u7, _v7, (element + 3) %8 );
2035 if ( hasGoodLevel( I, _u7, _v7 )) {
2036 element = (element + 3) %8 ;
2092 vpDot2::computeFreemanParameters(
const int &u_p,
2094 unsigned int &element,
2097 float &dMu,
float &dMv,
2099 float &dMu2,
float &dMv2)
2121 dMv = (float)(0.5 * v_p * v_p);
2122 if (compute_moment) {
2123 dMuv = (float)(0.25 * v_p * v_p * (2 * u_p + 1));
2125 dMv2 = (float)(1.0/ 3. * v_p * v_p * v_p);
2132 dS = (float)(v_p + 0.5);
2133 dMu = - (float)(0.5 * u_p * ( u_p + 1 ) + 1.0 / 6.0);
2134 dMv = (float)(0.5 * v_p * ( v_p + 1 ) + 1.0 / 6.0);
2135 if (compute_moment) {
2136 float half_u_p = (float)(0.5*u_p);
2137 dMuv = (float)(v_p*v_p*(0.25+half_u_p) + v_p*(1./3.+half_u_p) + 1./6.*u_p +0.125);
2138 dMu2 = (float)(-1./3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) - 1./12.0);
2139 dMv2 = (float)( 1./3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) + 1./12.0);
2146 dMu = (float)(- 0.5 * u_p * u_p);
2148 if (compute_moment) {
2150 dMu2 = (float)(-1.0/ 3. * u_p * u_p * u_p);
2158 dS = (float)(- v_p - 0.5);
2159 dMu = - (float)(0.5 * u_p * ( u_p - 1 ) + 1.0 / 6.0);
2160 dMv = - (float)(0.5 * v_p * ( v_p + 1 ) + 1.0 / 6.0);
2161 if (compute_moment) {
2162 float half_u_p = (float)(0.5*u_p);
2163 dMuv = (float)(v_p*v_p*(0.25-half_u_p) + v_p*(1./3.-half_u_p) - 1./6.*u_p +0.125);
2164 dMu2 = (float)(-1./3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1./12.0);
2165 dMv2 = (float)(-1./3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) - 1./12.0);
2171 dS = (float)(- v_p);
2172 dMv = (float)(- 0.5 * v_p * v_p);
2174 if (compute_moment) {
2175 dMuv = (float)(-0.25 * v_p * v_p * (2 * u_p - 1));
2177 dMv2 = (float)(-1.0/ 3. * v_p * v_p * v_p);
2184 dS = (float)(- v_p + 0.5);
2185 dMu = (float)( 0.5 * u_p * ( u_p - 1 ) + 1.0 / 6.0);
2186 dMv = (float)(- (0.5 * v_p * ( v_p - 1 ) + 1.0 / 6.0));
2187 if (compute_moment) {
2188 float half_u_p = (float)(0.5*u_p);
2189 dMuv = (float)(v_p*v_p*(0.25-half_u_p) - v_p*(1./3.-half_u_p) - 1./6.*u_p +0.125);
2190 dMu2 = (float)( 1./3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1./12.0);
2191 dMv2 = (float)(-1./3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1./12.0);
2198 dMu = (float)(0.5 * u_p * u_p);
2200 if (compute_moment) {
2202 dMu2 = (float)(1.0/ 3. * u_p * u_p * u_p);
2210 dS = (float)(v_p - 0.5);
2211 dMu = (float)(0.5 * u_p * ( u_p + 1 ) + 1.0 / 6.0);
2212 dMv = (float)(0.5 * v_p * ( v_p - 1 ) + 1.0 / 6.0);
2213 if (compute_moment) {
2214 float half_u_p = (float)(0.5*u_p);
2215 dMuv = (float)(v_p*v_p*(0.25+half_u_p) - v_p*(1./3.+half_u_p) + 1./6.*u_p +0.125);
2216 dMu2 = (float)(1./3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) + 1./12.0);
2217 dMv2 = (float)(1./3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1./12.0);
2237 void vpDot2::updateFreemanPosition(
unsigned int& u,
unsigned int& v,
2238 const unsigned int &dir )
2241 case 0: u += 1;
break;
2242 case 1: u += 1; v += 1;
break;
2243 case 2: v += 1;
break;
2244 case 3: u -= 1; v += 1;
break;
2245 case 4: u -= 1;
break;
2246 case 5: u -= 1; v -= 1;
break;
2247 case 6: v -= 1;
break;
2248 case 7: u += 1; v -= 1;
break;
2265 return isInImage( I, cog);
2283 double u = ip.
get_u();
2284 double v = ip.
get_v();
2286 if( u < 0 || u >= w )
return false;
2287 if( v < 0 || v >= h )
return false;
2302 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const
2304 unsigned int area_u_min = (
unsigned int) area.
getLeft();
2305 unsigned int area_u_max = (
unsigned int) area.
getRight();
2306 unsigned int area_v_min = (
unsigned int) area.
getTop();
2307 unsigned int area_v_max = (
unsigned int) area.
getBottom();
2309 if( u < area_u_min || u > area_u_max )
return false;
2310 if( v < area_v_min || v > area_v_max )
return false;
2326 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight )
2336 if( gridWidth == 0 ) gridWidth = 1;
2337 if( gridHeight == 0 ) gridHeight = 1;
2356 int cog_u = (int)cog.
get_u();
2357 int cog_v = (int)cog.
get_v();
2359 unsigned int sum_value =0;
2360 unsigned int nb_pixels =0;
2362 for(
unsigned int i=(
unsigned int)this->bbox_u_min; i <=(
unsigned int)this->bbox_u_max ; i++){
2363 unsigned int pixel_gray =(
unsigned int) I[(
unsigned int)cog_v][i];
2365 sum_value += pixel_gray;
2369 for(
unsigned int i=(
unsigned int)this->bbox_v_min; i <=(
unsigned int)this->bbox_v_max ; i++){
2370 unsigned char pixel_gray =I[i][(
unsigned int)cog_u];
2372 sum_value += pixel_gray;
2379 if( (cog_u - bbox_u_min) > (cog_v - bbox_v_min)){
2380 imin=cog_v - bbox_v_min;
2382 else{ imin = cog_u - bbox_u_min;}
2383 if( (bbox_u_max - cog_u) > (bbox_v_max - cog_v)){
2384 imax=bbox_v_max - cog_v;
2386 else{ imax = bbox_u_max - cog_u;}
2387 for(
int i=-imin; i <=imax ; i++){
2388 unsigned int pixel_gray =(
unsigned int) I[(
unsigned int)(cog_v + i)][(
unsigned int)(cog_u + i)];
2390 sum_value += pixel_gray;
2395 if( (cog_u - bbox_u_min) > (bbox_v_max - cog_v)){
2396 imin = bbox_v_max - cog_v;
2398 else{ imin = cog_u - bbox_u_min;}
2399 if( (bbox_u_max - cog_u) > (cog_v - bbox_v_min)){
2400 imax = cog_v - bbox_v_min;
2402 else{ imax = bbox_u_max - cog_u;}
2404 for(
int i=-imin; i <=imax ; i++){
2405 unsigned char pixel_gray =I[(
unsigned int)(cog_v - i)][(
unsigned int)(cog_u + i)];
2407 sum_value += pixel_gray;
2418 mean_gray_level = sum_value/nb_pixels;
2447 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
2453 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
2464 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
2477 std::cout <<
"Cannot track dots from file" << std::endl;
2484 for(i=0;i<n && fromFile;++i)
2487 for(
unsigned int j=0;j<n && fromFile;++j)
2492 std::cout <<
"Dots from file seem incoherent" << std::endl;
2502 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
2503 for (i = 0; i < n; i++)
2516 Cogs[i][0] = cog.
get_u();
2517 Cogs[i][1] = cog.
get_v();
2523 if (!fromFile & (dotFile !=
""))
2526 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
2552 cogs.push_back(dot[i].
getCog());
2555 for(i=n;i<cogs.size();++i)
2585 const std::list<vpImagePoint> &edges_list,
vpColor color,
2586 unsigned int thickness)
2589 std::list<vpImagePoint>::const_iterator it;
2591 for (it = edges_list.begin(); it != edges_list.end(); ++it)
2612 const std::list<vpImagePoint> &edges_list,
vpColor color,
2613 unsigned int thickness)
2616 std::list<vpImagePoint>::const_iterator it;
2618 for (it = edges_list.begin(); it != edges_list.end(); ++it)
2629 VISP_EXPORT std::ostream& operator<< (std::ostream& os,
vpDot2& d) {
2630 return (os <<
"(" << d.
getCog() <<
")" ) ;
2633 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
2646 return fabs(surface);
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)
static bool loadMatrix(std::string filename, vpMatrix &M, const bool binary=false, char *Header=NULL)
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
unsigned int getWidth() const
void setMaxSizeSearchDistancePrecision(const double &maxSizeSearchDistancePrecision)
vp_deprecated double getSurface() const
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)
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
vp_deprecated void setSurface(const double &surface)
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)
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 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)
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 getRows() const
Return the number of rows of the matrix.
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
static bool saveMatrix(std::string filename, const vpMatrix &M, const bool binary=false, const char *Header="")