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;
481 bool found = computeParameters(I, cog.
get_u(), cog.
get_v());
485 found = isValid( I, wantedDot);
504 double searchWindowWidth, searchWindowHeight;
506 if( std::fabs(
getWidth()) <= std::numeric_limits<double>::epsilon() || std::fabs(
getHeight()) <= std::numeric_limits<double>::epsilon() )
508 searchWindowWidth = 80.;
509 searchWindowHeight = 80.;
516 std::list<vpDot2> candidates;
518 (
int)(this->cog.
get_u()-searchWindowWidth /2.0),
519 (int)(this->cog.
get_v()-searchWindowHeight/2.0),
520 (
unsigned int)searchWindowWidth,
521 (
unsigned int)searchWindowHeight,
526 if( candidates.empty() )
530 "No dot was found")) ;
534 vpDot2 movingDot = candidates.front();
550 bbox_u_min = movingDot.bbox_u_min;
551 bbox_u_max = movingDot.bbox_u_max;
552 bbox_v_min = movingDot.bbox_v_min;
553 bbox_v_max = movingDot.bbox_v_max;
573 if( !isInImage( I ) )
577 "The center of gravity of the dot is not in the image")) ;
589 if(Ip - (1 - grayLevelPrecision)<0){
593 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
594 if (gray_level_min > 255)
595 gray_level_min = 255;
597 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
598 if (gray_level_max > 255)
599 gray_level_max = 255;
665 return fabs(surface);
675 return grayLevelPrecision;
685 return sizePrecision;
697 return ellipsoidShapePrecision;
706 return maxSizeSearchDistancePrecision;
715 double diff_u = this->cog.
get_u() - cogDistantDot.
get_u();
716 double diff_v = this->cog.
get_v() - cogDistantDot.
get_v();
717 return sqrt( diff_u*diff_u + diff_v*diff_v );
785 double epsilon = 0.05;
786 if( grayLevelPrecision<epsilon )
788 this->grayLevelPrecision = epsilon;
790 else if( grayLevelPrecision>1 )
792 this->grayLevelPrecision = 1.0;
796 this->grayLevelPrecision = precision;
815 if( sizePrecision<0 )
817 this->sizePrecision = 0;
819 else if( sizePrecision>1 )
821 this->sizePrecision = 1.0;
825 this->sizePrecision = precision;
860 if( ellipsoidShapePrecision<0 )
862 this->ellipsoidShapePrecision = 0;
864 else if( ellipsoidShapePrecision>1 )
866 this->ellipsoidShapePrecision = 1.0;
870 this->ellipsoidShapePrecision = precision;
889 double epsilon = 0.05;
890 if( maxSizeSearchDistancePrecision<epsilon )
892 this-> maxSizeSearchDistancePrecision = epsilon;
894 else if( maxSizeSearchDistancePrecision >1 )
896 this->maxSizeSearchDistancePrecision = 1.0;
900 this->maxSizeSearchDistancePrecision = precision;
933 unsigned int w,
unsigned int h)
935 unsigned int image_w = I.
getWidth();
940 else if (u >= (
int)image_w) u = (int)image_w - 1;
942 else if (v >= (
int)image_h) v = (
int)image_h - 1;
944 if (((
unsigned int)u + w) > image_w) w = image_w - (
unsigned int)u - 1;
945 if (((
unsigned int)v + h) > image_h) h = image_h - (
unsigned int)v - 1;
1043 unsigned int area_w,
1044 unsigned int area_h,
1045 std::list<vpDot2> &niceDots)
1053 setArea(I, area_u, area_v, area_w, area_h);
1056 unsigned int gridWidth;
1057 unsigned int gridHeight;
1058 getGridSize( gridWidth, gridHeight );
1073 std::list<vpDot2> badDotsVector;
1074 std::list<vpDot2>::iterator itnice;
1075 std::list<vpDot2>::iterator itbad;
1077 vpDot2* dotToTest = NULL;
1080 unsigned int area_u_min = (
unsigned int) area.
getLeft();
1081 unsigned int area_u_max = (
unsigned int) area.
getRight();
1082 unsigned int area_v_min = (
unsigned int) area.
getTop();
1083 unsigned int area_v_max = (
unsigned int) area.
getBottom();
1088 for( v=area_v_min ; v<area_v_max ; v=v+gridHeight )
1090 for( u=area_u_min ; u<area_u_max ; u=u+gridWidth )
1095 if( !hasGoodLevel(I, u, v) )
continue;
1099 bool good_germ =
true;
1101 itnice = niceDots.begin();
1102 while( itnice != niceDots.end() && good_germ ==
true) {
1105 cogTmpDot = tmpDot.
getCog();
1106 double u0 = cogTmpDot.
get_u();
1107 double v0 = cogTmpDot.
get_v();
1108 double half_w = tmpDot.
getWidth() / 2.;
1109 double half_h = tmpDot.
getHeight() / 2.;
1111 if ( u >= (u0-half_w) && u <= (u0+half_w) &&
1112 v >= (v0-half_h) && v <= (v0+half_h) ) {
1123 unsigned int border_u;
1124 unsigned int border_v;
1125 if(findFirstBorder(I, u, v, border_u, border_v) ==
false){
1133 itbad = badDotsVector.begin();
1134 #define vpBAD_DOT_VALUE (*itbad)
1137 while( itbad != badDotsVector.end() && good_germ ==
true) {
1138 if( (
double)u >= vpBAD_DOT_VALUE.bbox_u_min
1139 && (double)u <= vpBAD_DOT_VALUE.bbox_u_max &&
1140 (
double)v >= vpBAD_DOT_VALUE.bbox_v_min
1141 && (double)v <= vpBAD_DOT_VALUE.bbox_v_max){
1142 std::list<vpImagePoint>::const_iterator it_edges = ip_edges_list.begin();
1143 while (it_edges != ip_edges_list.end() && good_germ ==
true){
1147 cogBadDot = *it_edges;
1149 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() )
1151 (std::fabs(v - cogBadDot.
get_v()) <=
vpMath::maximum(std::fabs((
double)v), std::fabs(cogBadDot.
get_v()))*std::numeric_limits<double>::epsilon() )) {
1159 #undef vpBAD_DOT_VALUE
1168 vpTRACE(4,
"Try germ (%d, %d)", u, v);
1176 if( dotToTest != NULL )
delete dotToTest;
1177 dotToTest = getInstance();
1178 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;
1309 if ( (std::fabs(wantedDot.
getWidth()) > std::numeric_limits<double>::epsilon())
1311 (std::fabs(wantedDot.
getHeight()) > std::numeric_limits<double>::epsilon())
1313 (std::fabs(wantedDot.
getArea()) > std::numeric_limits<double>::epsilon()) )
1316 if (std::fabs(size_precision) > std::numeric_limits<double>::epsilon()){
1317 double epsilon = 0.001;
1319 std::cout <<
"test size precision......................\n";
1320 std::cout <<
"wanted dot: " <<
"w=" << wantedDot.
getWidth()
1322 <<
" s=" << wantedDot.
getArea()
1323 <<
" precision=" << size_precision
1324 <<
" epsilon=" << epsilon << std::endl;
1325 std::cout <<
"dot found: " <<
"w=" <<
getWidth()
1327 <<
" s=" <<
getArea() << std::endl;
1330 if( ( wantedDot.
getWidth()*size_precision-epsilon <
getWidth() ) ==
false )
1335 printf(
"Bad width > for dot (%g, %g)\n", cog.
get_u(), cog.
get_v());
1340 if( (
getWidth() < wantedDot.
getWidth()/(size_precision+epsilon ) )== false )
1345 printf(
"Bad width %g > %g for dot (%g, %g)\n",
1357 printf(
"Bad height %g > %g for dot (%g, %g)\n",
1369 printf(
"Bad height %g > %g for dot (%g, %g)\n",
1376 if( ( wantedDot.
getArea()*(size_precision*size_precision)-epsilon <
getArea() ) ==
false )
1381 printf(
"Bad surface %g > %g for dot (%g, %g)\n",
1382 wantedDot.
getArea()*(size_precision*size_precision)-epsilon,
1389 if( (
getArea() < wantedDot.
getArea()/(size_precision*size_precision+epsilon )) == false )
1394 printf(
"Bad surface %g < %g for dot (%g, %g)\n",
1395 getArea(), wantedDot.
getArea()/(size_precision*size_precision+epsilon),
1407 int nb_point_to_test = 20;
1408 int nb_bad_points = 0;
1409 int nb_max_bad_points = (int)(nb_point_to_test*allowedBadPointsPercentage_);
1410 double step_angle = 2*M_PI / nb_point_to_test;
1413 if (std::fabs(ellipsoidShape_precision) > std::numeric_limits<double>::epsilon() && compute_moment) {
1432 double Sqrt = sqrt(tmp1*tmp1 + 4*tmp2*tmp2);
1443 double innerCoef = ellipsoidShape_precision ;
1445 double cog_u = this->cog.
get_u();
1446 double cog_v = this->cog.
get_v();
1450 for(
double theta = 0. ; theta<2*M_PI ; theta+= step_angle ) {
1451 u = (
unsigned int) (cog_u + innerCoef*(a1*cos(alpha)*cos(theta)-a2*sin(alpha)*sin(theta)));
1452 v = (
unsigned int) (cog_v + innerCoef*(a1*sin(alpha)*cos(theta)+a2*cos(alpha)*sin(theta)));
1453 if( ! this->hasGoodLevel( I, u, v) ) {
1457 printf(
"Inner cercle pixel (%u, %u) has bad level for dot (%g, %g): %d not in [%d, %d]\n",
1458 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1464 for (
unsigned int t=0; t< thickness; t++) {
1475 if (nb_bad_points > nb_max_bad_points)
1478 printf(
"Inner ellipse has %d bad points. Max allowed is %d\n",
1479 nb_bad_points, nb_max_bad_points);
1488 double outCoef = 2-ellipsoidShape_precision;
1490 for(
double theta=0. ; theta<2*M_PI ; theta+= step_angle ) {
1491 u = (
unsigned int) (cog_u + outCoef*(a1*cos(alpha)*cos(theta)-a2*sin(alpha)*sin(theta)));
1492 v = (
unsigned int) (cog_v + outCoef*(a1*sin(alpha)*cos(theta)+a2*cos(alpha)*sin(theta)));
1503 if( ! this->hasReverseLevel( I, u, v ) ) {
1507 printf(
"Outside cercle pixel (%u, %u) has bad level for dot (%g, %g): %d not in [%d, %d]\n",
1508 u, v, cog_u, cog_v, I[v][u], gray_level_min, gray_level_max);
1514 for(
unsigned int t=0; t<thickness; t++) {
1523 if (nb_bad_points > nb_max_bad_points)
1526 printf(
"Outside ellipse has %d bad points. Max allowed is %d\n",
1527 nb_bad_points, nb_max_bad_points);
1555 const unsigned int &u,
1556 const unsigned int &v)
const
1558 if( !isInArea( u, v ) )
1561 if( I[v][u] >= gray_level_min && I[v][u] <= gray_level_max)
1585 const unsigned int &u,
1586 const unsigned int &v)
const
1589 if( !isInArea( u, v ) )
1592 if( I[v][u] < gray_level_min || I[v][u] > gray_level_max)
1611 vpDot2* vpDot2::getInstance()
1633 freeman_chain = direction_list;
1681 direction_list.clear();
1682 ip_edges_list.clear();
1689 if( std::fabs(est_u + 1.0) <=
vpMath::maximum(std::fabs(est_u),1.)*std::numeric_limits<double>::epsilon() )
1691 est_u = this->cog.
get_u();
1696 if( std::fabs(est_v + 1.0) <=
vpMath::maximum(std::fabs(est_v),1.)*std::numeric_limits<double>::epsilon() )
1698 est_v = this->cog.
get_v();
1703 if( !isInArea( (
unsigned int) est_u, (
unsigned int) est_v ) )
1705 vpDEBUG_TRACE(3,
"Initial pixel coordinates (%d, %d) for dot tracking are not in the area",
1706 (
int) est_u, (
int) est_v) ;
1717 if( !hasGoodLevel( I, (
unsigned int) est_u, (
unsigned int) est_v ) )
1719 vpDEBUG_TRACE(3,
"Can't find a dot from pixel (%d, %d) coordinates",
1720 (
int) est_u, (
int) est_v) ;
1726 if(!findFirstBorder(I, (
unsigned int) est_u, (
unsigned int) est_v,
1727 this->firstBorder_u, this->firstBorder_v)) {
1729 vpDEBUG_TRACE(3,
"Can't find first border (%d, %d) coordinates",
1730 (
int) est_u, (
int) est_v) ;
1734 unsigned int dir = 6;
1737 computeFreemanChainElement(I, this->firstBorder_u, this->firstBorder_v, dir);
1738 unsigned int firstDir = dir;
1741 if( !isInArea( this->firstBorder_u, this->firstBorder_v ) )
1743 vpDEBUG_TRACE(3,
"Border pixel coordinates (%d, %d) of the dot are not in the area",
1744 this->firstBorder_u, this->firstBorder_v);
1749 direction_list.push_back( dir );
1751 ip.
set_u( this->firstBorder_u );
1752 ip.
set_v( this->firstBorder_v );
1754 ip_edges_list.push_back( ip );
1756 int border_u = (int)this->firstBorder_u;
1757 int border_v = (int)this->firstBorder_v;
1763 float dS, dMu, dMv, dMuv, dMu2, dMv2;
1774 for(
int t=0; t< (int)thickness; t++) {
1775 ip.
set_u ( border_u + t);
1776 ip.
set_v ( border_v );
1787 computeFreemanParameters(border_u, border_v, dir, du, dv,
1798 if (compute_moment) {
1804 if( !isInArea( (
unsigned int)border_u, (
unsigned int)border_v ) ) {
1806 vpDEBUG_TRACE(3,
"Dot (%d, %d) is not in the area", border_u, border_v);
1813 direction_list.push_back( dir );
1815 ip.
set_u( border_u );
1816 ip.
set_v( border_v );
1817 ip_edges_list.push_back( ip );
1822 if( border_v < bbox_v_min ) bbox_v_min = border_v;
1823 if( border_v > bbox_v_max ) bbox_v_max = border_v;
1824 if( border_u < bbox_u_min ) bbox_u_min = border_u;
1825 if( border_u > bbox_u_max ) bbox_u_max = border_u;
1828 if (computeFreemanChainElement(I, (
unsigned int)border_u, (
unsigned int)border_v, dir) ==
false) {
1829 vpDEBUG_TRACE(3,
"Can't compute Freeman chain for dot (%d, %d)",
1830 border_u, border_v);
1837 while( (getFirstBorder_u() != (
unsigned int)border_u
1838 || getFirstBorder_v() != (
unsigned int)border_v
1839 || firstDir != dir) &&
1840 isInArea( (
unsigned int)border_u, (
unsigned int)border_v ) );
1843 #if VP_DEBUG_MODE == 3
1851 if( std::fabs(
m00) <= std::numeric_limits<double>::epsilon()
1852 || std::fabs(
m00 - 1.) <=
vpMath::maximum(std::fabs(
m00), 1.)*std::numeric_limits<double>::epsilon() )
1854 vpDEBUG_TRACE(3,
"The center of gravity of the dot wasn't properly detected");
1860 double tmpCenter_u =
m10 /
m00;
1861 double tmpCenter_v = m01 /
m00;
1880 cog.
set_u( tmpCenter_u );
1881 cog.
set_v( tmpCenter_v );
1884 width = bbox_u_max - bbox_u_min + 1;
1885 height = bbox_v_max - bbox_v_min + 1;
1888 computeMeanGrayLevel(I);
1910 const unsigned int &u,
1911 const unsigned int &v,
1912 unsigned int &border_u,
1913 unsigned int &border_v)
1923 double epsilon =0.001;
1926 std::cout <<
"gray level: " << gray_level_min <<
" " << gray_level_max << std::endl;
1928 while( hasGoodLevel( I, border_u+1, border_v ) &&
1934 vpDEBUG_TRACE(3,
"The found dot (%d, %d, %d) has a greater width than the required one", u, v, border_u);
1968 const unsigned int &u,
1969 const unsigned int &v,
1970 unsigned int &element)
1973 if (hasGoodLevel( I, u, v )) {
1974 unsigned int _u = u;
1975 unsigned int _v = v;
1977 updateFreemanPosition( _u, _v, (element + 2) %8 );
1978 if (hasGoodLevel( I, _u, _v )) {
1979 element = (element + 2) % 8;
1982 unsigned int _u1 = u;
1983 unsigned int _v1 = v;
1984 updateFreemanPosition( _u1, _v1, (element + 1) %8 );
1986 if ( hasGoodLevel( I, _u1, _v1 )) {
1987 element = (element + 1) % 8;
1990 unsigned int _u2 = u;
1991 unsigned int _v2 = v;
1992 updateFreemanPosition( _u2, _v2, element );
1994 if ( hasGoodLevel( I, _u2, _v2 )) {
1998 unsigned int _u3 = u;
1999 unsigned int _v3 = v;
2000 updateFreemanPosition( _u3, _v3, (element + 7) %8 );
2002 if ( hasGoodLevel( I, _u3, _v3 )) {
2003 element = (element + 7) %8;
2006 unsigned int _u4 = u;
2007 unsigned int _v4 = v;
2008 updateFreemanPosition( _u4, _v4, (element + 6) %8 );
2010 if ( hasGoodLevel( I, _u4, _v4 )) {
2011 element = (element + 6) %8 ;
2014 unsigned int _u5 = u;
2015 unsigned int _v5 = v;
2016 updateFreemanPosition( _u5, _v5, (element + 5) %8 );
2018 if ( hasGoodLevel( I, _u5, _v5 )) {
2019 element = (element + 5) %8 ;
2022 unsigned int _u6 = u;
2023 unsigned int _v6 = v;
2024 updateFreemanPosition( _u6, _v6, (element + 4) %8 );
2026 if ( hasGoodLevel( I, _u6, _v6 )) {
2027 element = (element + 4) %8 ;
2030 unsigned int _u7 = u;
2031 unsigned int _v7 = v;
2032 updateFreemanPosition( _u7, _v7, (element + 3) %8 );
2034 if ( hasGoodLevel( I, _u7, _v7 )) {
2035 element = (element + 3) %8 ;
2091 vpDot2::computeFreemanParameters(
const int &u_p,
2093 unsigned int &element,
2096 float &dMu,
float &dMv,
2098 float &dMu2,
float &dMv2)
2120 dMv = (float)(0.5 * v_p * v_p);
2121 if (compute_moment) {
2122 dMuv = (float)(0.25 * v_p * v_p * (2 * u_p + 1));
2124 dMv2 = (float)(1.0/ 3. * v_p * v_p * v_p);
2131 dS = (float)(v_p + 0.5);
2132 dMu = - (float)(0.5 * u_p * ( u_p + 1 ) + 1.0 / 6.0);
2133 dMv = (float)(0.5 * v_p * ( v_p + 1 ) + 1.0 / 6.0);
2134 if (compute_moment) {
2135 float half_u_p = (float)(0.5*u_p);
2136 dMuv = (float)(v_p*v_p*(0.25+half_u_p) + v_p*(1./3.+half_u_p) + 1./6.*u_p +0.125);
2137 dMu2 = (float)(-1./3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) - 1./12.0);
2138 dMv2 = (float)( 1./3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) + 1./12.0);
2145 dMu = (float)(- 0.5 * u_p * u_p);
2147 if (compute_moment) {
2149 dMu2 = (float)(-1.0/ 3. * u_p * u_p * u_p);
2157 dS = (float)(- v_p - 0.5);
2158 dMu = - (float)(0.5 * u_p * ( u_p - 1 ) + 1.0 / 6.0);
2159 dMv = - (float)(0.5 * v_p * ( v_p + 1 ) + 1.0 / 6.0);
2160 if (compute_moment) {
2161 float half_u_p = (float)(0.5*u_p);
2162 dMuv = (float)(v_p*v_p*(0.25-half_u_p) + v_p*(1./3.-half_u_p) - 1./6.*u_p +0.125);
2163 dMu2 = (float)(-1./3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1./12.0);
2164 dMv2 = (float)(-1./3. * v_p * (v_p * v_p + 1.5 * v_p + 1.) - 1./12.0);
2170 dS = (float)(- v_p);
2171 dMv = (float)(- 0.5 * v_p * v_p);
2173 if (compute_moment) {
2174 dMuv = (float)(-0.25 * v_p * v_p * (2 * u_p - 1));
2176 dMv2 = (float)(-1.0/ 3. * v_p * v_p * v_p);
2183 dS = (float)(- v_p + 0.5);
2184 dMu = (float)( 0.5 * u_p * ( u_p - 1 ) + 1.0 / 6.0);
2185 dMv = (float)(- (0.5 * v_p * ( v_p - 1 ) + 1.0 / 6.0));
2186 if (compute_moment) {
2187 float half_u_p = (float)(0.5*u_p);
2188 dMuv = (float)(v_p*v_p*(0.25-half_u_p) - v_p*(1./3.-half_u_p) - 1./6.*u_p +0.125);
2189 dMu2 = (float)( 1./3. * u_p * (u_p * u_p - 1.5 * u_p + 1.) - 1./12.0);
2190 dMv2 = (float)(-1./3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1./12.0);
2197 dMu = (float)(0.5 * u_p * u_p);
2199 if (compute_moment) {
2201 dMu2 = (float)(1.0/ 3. * u_p * u_p * u_p);
2209 dS = (float)(v_p - 0.5);
2210 dMu = (float)(0.5 * u_p * ( u_p + 1 ) + 1.0 / 6.0);
2211 dMv = (float)(0.5 * v_p * ( v_p - 1 ) + 1.0 / 6.0);
2212 if (compute_moment) {
2213 float half_u_p = (float)(0.5*u_p);
2214 dMuv = (float)(v_p*v_p*(0.25+half_u_p) - v_p*(1./3.+half_u_p) + 1./6.*u_p +0.125);
2215 dMu2 = (float)(1./3. * u_p * (u_p * u_p + 1.5 * u_p + 1.) + 1./12.0);
2216 dMv2 = (float)(1./3. * v_p * (v_p * v_p - 1.5 * v_p + 1.) - 1./12.0);
2236 void vpDot2::updateFreemanPosition(
unsigned int& u,
unsigned int& v,
2237 const unsigned int &dir )
2240 case 0: u += 1;
break;
2241 case 1: u += 1; v += 1;
break;
2242 case 2: v += 1;
break;
2243 case 3: u -= 1; v += 1;
break;
2244 case 4: u -= 1;
break;
2245 case 5: u -= 1; v -= 1;
break;
2246 case 6: v -= 1;
break;
2247 case 7: u += 1; v -= 1;
break;
2264 return isInImage( I, cog);
2282 double u = ip.
get_u();
2283 double v = ip.
get_v();
2285 if( u < 0 || u >= w )
return false;
2286 if( v < 0 || v >= h )
return false;
2301 bool vpDot2::isInArea(
const unsigned int &u,
const unsigned int &v)
const
2303 unsigned int area_u_min = (
unsigned int) area.
getLeft();
2304 unsigned int area_u_max = (
unsigned int) area.
getRight();
2305 unsigned int area_v_min = (
unsigned int) area.
getTop();
2306 unsigned int area_v_max = (
unsigned int) area.
getBottom();
2308 if( u < area_u_min || u > area_u_max )
return false;
2309 if( v < area_v_min || v > area_v_max )
return false;
2325 void vpDot2::getGridSize(
unsigned int &gridWidth,
unsigned int &gridHeight )
2335 if( gridWidth == 0 ) gridWidth = 1;
2336 if( gridHeight == 0 ) gridHeight = 1;
2355 int cog_u = (int)cog.
get_u();
2356 int cog_v = (int)cog.
get_v();
2358 unsigned int sum_value =0;
2359 unsigned int nb_pixels =0;
2361 for(
unsigned int i=(
unsigned int)this->bbox_u_min; i <=(
unsigned int)this->bbox_u_max ; i++){
2362 unsigned int pixel_gray =(
unsigned int) I[(
unsigned int)cog_v][i];
2364 sum_value += pixel_gray;
2368 for(
unsigned int i=(
unsigned int)this->bbox_v_min; i <=(
unsigned int)this->bbox_v_max ; i++){
2369 unsigned char pixel_gray =I[i][(
unsigned int)cog_u];
2371 sum_value += pixel_gray;
2378 if( (cog_u - bbox_u_min) > (cog_v - bbox_v_min)){
2379 imin=cog_v - bbox_v_min;
2381 else{ imin = cog_u - bbox_u_min;}
2382 if( (bbox_u_max - cog_u) > (bbox_v_max - cog_v)){
2383 imax=bbox_v_max - cog_v;
2385 else{ imax = bbox_u_max - cog_u;}
2386 for(
int i=-imin; i <=imax ; i++){
2387 unsigned int pixel_gray =(
unsigned int) I[(
unsigned int)(cog_v + i)][(
unsigned int)(cog_u + i)];
2389 sum_value += pixel_gray;
2394 if( (cog_u - bbox_u_min) > (bbox_v_max - cog_v)){
2395 imin = bbox_v_max - cog_v;
2397 else{ imin = cog_u - bbox_u_min;}
2398 if( (bbox_u_max - cog_u) > (cog_v - bbox_v_min)){
2399 imax = cog_v - bbox_v_min;
2401 else{ imax = bbox_u_max - cog_u;}
2403 for(
int i=-imin; i <=imax ; i++){
2404 unsigned char pixel_gray =I[(
unsigned int)(cog_v - i)][(
unsigned int)(cog_u + i)];
2406 sum_value += pixel_gray;
2417 mean_gray_level = sum_value/nb_pixels;
2445 std::cout << Cogs.
getRows() <<
" dots loaded from file " << dotFile << std::endl;
2451 std::cout <<
"Dot file has a wrong number of dots : redefining them" << std::endl;
2462 cog.
set_uv(Cogs[i][0], Cogs[i][1]);
2475 std::cout <<
"Cannot track dots from file" << std::endl;
2481 for(i=0;i<n && fromFile;++i)
2484 for(
unsigned int j=0;j<n && fromFile;++j)
2489 std::cout <<
"Dots from file seem incoherent" << std::endl;
2499 std::cout <<
"Click on the " << n <<
" dots clockwise starting from upper/left dot..." << std::endl;
2500 for (i = 0; i < n; i++)
2513 Cogs[i][0] = cog.
get_u();
2514 Cogs[i][1] = cog.
get_v();
2520 if (!fromFile && (dotFile !=
""))
2523 std::cout << Cogs.
getRows() <<
" dots written to file " << dotFile << std::endl;
2549 cogs.push_back(dot[i].
getCog());
2552 for(i=n;i<cogs.size();++i)
2582 const std::list<vpImagePoint> &edges_list,
vpColor color,
2583 unsigned int thickness)
2586 std::list<vpImagePoint>::const_iterator it;
2588 for (it = edges_list.begin(); it != edges_list.end(); ++it)
2609 const std::list<vpImagePoint> &edges_list,
vpColor color,
2610 unsigned int thickness)
2613 std::list<vpImagePoint>::const_iterator it;
2615 for (it = edges_list.begin(); it != edges_list.end(); ++it)
2627 return (os <<
"(" << d.
getCog() <<
")" ) ;
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)
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
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.
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
double getEllipsoidShapePrecision() const
double getDistance(const vpDot2 &distantDot) const
static 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)
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)
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
unsigned int getRows() const
Return the number of rows of the 2D array.
void setEllipsoidShapePrecision(const double &ellipsoidShapePrecision)
void setGrayLevelMin(const unsigned int &min)
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint ¢er, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
void setWidth(const double &width)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void trackAndDisplay(vpDot2 dot[], const unsigned int &n, vpImage< unsigned char > &I, std::vector< vpImagePoint > &cogs, vpImagePoint *cogStar=NULL)
void setSizePrecision(const double &sizePrecision)
void initTracking(const vpImage< unsigned char > &I, unsigned int size=0)
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
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)
static void displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static const vpColor blue