49 #include <visp/vpDot.h>
51 #include <visp/vpDisplay.h>
52 #include <visp/vpColor.h>
55 #include <visp/vpTrackingException.h>
59 # pragma comment(linker, "/STACK:256000000") // Increase max recursion depth
81 compute_moment = false ;
84 maxDotSizePercentage = 0.25 ;
89 grayLevelPrecision = 0.85;
96 u_min = u_max = v_min = v_max = 0;
103 : m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.),
104 mu11(0.), mu20(0.), mu02(0.), ip_connexities_list(), ip_edges_list(), connexityType(CONNEXITY_4),
105 cog(), u_min(0), u_max(0), v_min(0), v_max(0), graphics(false), thickness(1), maxDotSizePercentage(0.25),
106 gray_level_out(0), mean_gray_level(0), gray_level_min(128), gray_level_max(255), grayLevelPrecision(0.85),
107 gamma(1.5), compute_moment(false), nbMaxPoint(0)
117 : m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.),
118 mu11(0.), mu20(0.), mu02(0.), ip_connexities_list(), ip_edges_list(), connexityType(CONNEXITY_4),
119 cog(), u_min(0), u_max(0), v_min(0), v_max(0), graphics(false), thickness(1), maxDotSizePercentage(0.25),
120 gray_level_out(0), mean_gray_level(0), gray_level_min(128), gray_level_max(255), grayLevelPrecision(0.85),
121 gamma(1.5), compute_moment(false), nbMaxPoint(0)
131 m00(0.), m01(0.), m10(0.), m11(0.), m20(0.), m02(0.),
132 mu11(0.), mu20(0.), mu02(0.), ip_connexities_list(), ip_edges_list(), connexityType(CONNEXITY_4),
133 cog(), u_min(0), u_max(0), v_min(0), v_max(0), graphics(false), thickness(1), maxDotSizePercentage(0.25),
134 gray_level_out(0), mean_gray_level(0), gray_level_min(128), gray_level_max(255), grayLevelPrecision(0.85),
135 gamma(1.5), compute_moment(false), nbMaxPoint(0)
145 ip_connexities_list.clear() ;
154 ip_edges_list = d.ip_edges_list;
155 ip_connexities_list = d.ip_connexities_list;
156 connexityType = d.connexityType;
164 graphics = d.graphics ;
165 thickness = d.thickness;
166 maxDotSizePercentage = d.maxDotSizePercentage;
167 gray_level_out = d.gray_level_out;
168 mean_gray_level = d.mean_gray_level ;
169 gray_level_min = d.gray_level_min ;
170 gray_level_max = d.gray_level_max ;
171 grayLevelPrecision = d.grayLevelPrecision;
173 compute_moment = d.compute_moment ;
174 nbMaxPoint = d.nbMaxPoint;
193 return ( cog != d.
getCog() );
199 return ( cog == d.
getCog() );
214 vpDot::setGrayLevelOut()
216 if (gray_level_min == 0) {
217 if (gray_level_max == 255) {
221 "Unable to choose a good \"out\" level")) ;
223 gray_level_out =
static_cast<unsigned char>(gray_level_max + 1u);
245 double &mean_value,
double &u_cog,
double &v_cog,
double &n)
248 return connexe(I,u,v,mean_value,u_cog,v_cog,n,checkTab);
268 double &mean_value,
double &u_cog,
double &v_cog,
double &n,std::vector<bool> &checkTab)
275 if ( (u >= width) || (v >= height) )
288 if (I[v][u] >= gray_level_min && I[v][u] <= gray_level_max)
290 checkTab[v*I.
getWidth() + u] =
true;
292 ip_connexities_list.push_back(ip);
298 if (n > nbMaxPoint) {
300 "This threshold can be modified using the setMaxDotSize() "
303 nbMaxPoint, maxDotSizePercentage) ;
310 if (u < this->u_min) this->u_min = u;
311 if (u > this->u_max) this->u_max = u;
312 if (v < this->v_min) this->v_min = v;
313 if (v > this->v_max) this->v_max = v;
316 mean_value = (mean_value *(n-1) + I[v][u]) / n;
317 if (compute_moment==
true)
338 if(!connexe(I,u-1,v, mean_value,u_cog,v_cog, n, checkTab))
343 if(!connexe(I,u+1,v,mean_value,u_cog, v_cog, n, checkTab))
348 if(!connexe(I,u, v-1,mean_value,u_cog, v_cog, n, checkTab))
353 if(!connexe(I,u,v+1,mean_value,u_cog, v_cog, n, checkTab))
358 if(!checkTab[u-1+(v-1)*I.
getWidth()])
359 if(!connexe(I,u-1,v-1,mean_value,u_cog, v_cog, n, checkTab))
363 if(!checkTab[u+1+(v-1)*I.
getWidth()])
364 if(!connexe(I,u+1,v-1,mean_value,u_cog, v_cog, n, checkTab))
368 if(!checkTab[u-1+(v+1)*I.
getWidth()])
369 if(!connexe(I,u-1,v+1,mean_value, u_cog, v_cog, n, checkTab))
373 if(!checkTab[u+1+(v+1)*I.
getWidth()])
374 if(!connexe(I,u+1,v+1,mean_value,u_cog, v_cog, n, checkTab))
379 ip_edges_list.push_back(ip);
383 for(
unsigned int t=0; t<thickness; t++) {
384 ip_.set_u(ip.
get_u() + t);
428 this->mean_gray_level = 0 ;
430 ip_connexities_list.clear() ;
431 ip_edges_list.clear();
441 if ( connexe(I, (
unsigned int)u, (
unsigned int)v,
442 gray_level_min, gray_level_max,
443 mean_gray_level, u_cog, v_cog, npoint) == vpDot::out)
447 for (pas = 2 ; pas <= 25 ; pas ++ )
if (sol==
false)
449 for (
int k=-1 ; k <=1 ; k++)
if (sol==
false)
450 for (
int l=-1 ; l <=1 ; l++)
if (sol==
false)
454 ip_connexities_list.clear() ;
456 this->mean_gray_level = 0 ;
457 if (connexe(I, (
unsigned int)(u+k*pas),(
unsigned int)(v+l*pas),
458 gray_level_min, gray_level_max,
459 mean_gray_level, u_cog, v_cog, npoint) != vpDot::out)
461 sol = true ; u += k*pas ; v += l*pas ;
469 "Dot has been lost")) ;
474 if ( !connexe(I,(
unsigned int)u,(
unsigned int)v, mean_gray_level, u_cog, v_cog, npoint) )
478 unsigned int right = 1;
479 unsigned int botom = 1;
480 unsigned int left = 2;
482 double u_ = u, v_ = v;
487 for (k=1; k <= right; k++)
if(sol==
false) {
490 ip_connexities_list.clear() ;
491 ip_edges_list.clear();
493 this->mean_gray_level = 0 ;
494 if ( connexe(I, (
unsigned int)u_+k, (
unsigned int)(v_),mean_gray_level, u_cog, v_cog, npoint) ) {
495 sol =
true; u = u_+k; v = v_;
501 for (k=1; k <= botom; k++)
if (sol==
false) {
504 ip_connexities_list.clear() ;
505 ip_edges_list.clear();
507 this->mean_gray_level = 0 ;
509 if ( connexe(I, (
unsigned int)(u_), (
unsigned int)(v_+k),mean_gray_level, u_cog, v_cog, npoint) ) {
510 sol =
true; u = u_; v = v_+k;
516 for (k=1; k <= left; k++)
if (sol==
false) {
519 ip_connexities_list.clear() ;
520 ip_edges_list.clear();
522 this->mean_gray_level = 0 ;
524 if ( connexe(I, (
unsigned int)(u_-k), (
unsigned int)(v_),mean_gray_level,u_cog, v_cog, npoint) ) {
525 sol = true ; u = u_-k; v = v_;
531 for (k=1; k <= up; k++)
if(sol==
false) {
534 ip_connexities_list.clear() ;
535 ip_edges_list.clear();
537 this->mean_gray_level = 0 ;
539 if ( connexe(I, (
unsigned int)(u_), (
unsigned int)(v_-k),mean_gray_level,u_cog, v_cog, npoint) ) {
540 sol = true ; u = u_; v = v_-k;
550 "Dot has been lost")) ;
566 u_cog = u_cog/npoint ;
567 v_cog = v_cog/npoint ;
573 double Ip = pow((
double)this->mean_gray_level/255,1/gamma);
575 if(Ip - (1 - grayLevelPrecision)<0){
579 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
580 if (gray_level_min > 255)
581 gray_level_min = 255;
583 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
584 if (gray_level_max > 255)
585 gray_level_max = 255;
597 if (npoint > nbMaxPoint)
599 vpERROR_TRACE(
"Too many point %lf (%lf%%). Max allowed is %lf (%lf%%). This threshold can be modified using the setMaxDotSize() method.",
601 nbMaxPoint, maxDotSizePercentage) ;
623 if (percentage <= 0.0 || percentage > 1.0) {
625 vpTRACE(
"Max dot size percentage is requested to be set to %lf.",
626 "Value should be in ]0:1]. Value will be set to %lf.",
627 percentage, maxDotSizePercentage);
630 maxDotSizePercentage = percentage;
662 unsigned int i = (
unsigned int)cog.
get_i();
663 unsigned int j = (
unsigned int)cog.
get_j();
665 double Ip = pow((
double)I[i][j]/255, 1/gamma);
667 if(Ip - (1 - grayLevelPrecision)<0){
671 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
672 if (gray_level_min > 255)
673 gray_level_min = 255;
675 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
676 if (gray_level_max > 255)
677 gray_level_max = 255;
718 unsigned int i = (
unsigned int)cog.
get_i();
719 unsigned int j = (
unsigned int)cog.
get_j();
721 double Ip = pow((
double)I[i][j]/255, 1/gamma);
723 if(Ip - (1 - grayLevelPrecision)<0){
727 gray_level_min = (
unsigned int) (255*pow(Ip - (1 - grayLevelPrecision),gamma));
728 if (gray_level_min > 255)
729 gray_level_min = 255;
731 gray_level_max = (
unsigned int) (255*pow(Ip + (1 - grayLevelPrecision),gamma));
732 if (gray_level_max > 255)
733 gray_level_max = 255;
773 unsigned int level_min,
unsigned int level_max)
778 this->gray_level_min = level_min;
779 this->gray_level_max = level_max;
811 double u = this->cog.
get_u();
812 double v = this->cog.
get_v();
816 this->cog.
set_u( u );
817 this->cog.
set_v( v );
819 if (compute_moment==
true)
871 std::list<vpImagePoint>::const_iterator it;
873 for (it = ip_edges_list.begin(); it != ip_edges_list.end(); ++it)
898 double epsilon = 0.05;
899 if( grayLevelPrecision<epsilon )
901 this->grayLevelPrecision = epsilon;
903 else if( grayLevelPrecision>1 )
905 this->grayLevelPrecision = 1.0;
909 this->grayLevelPrecision = precision;
928 const std::list<vpImagePoint> &edges_list,
vpColor color,
929 unsigned int thickness)
932 std::list<vpImagePoint>::const_iterator it;
934 for (it = edges_list.begin(); it != edges_list.end(); ++it)
955 const std::list<vpImagePoint> &edges_list,
vpColor color,
956 unsigned int thickness)
959 std::list<vpImagePoint>::const_iterator it;
961 for (it = edges_list.begin(); it != edges_list.end(); ++it)
972 VISP_EXPORT std::ostream& operator<< (std::ostream& os,
vpDot& d) {
973 return (os <<
"(" << d.
getCog() <<
")" ) ;
bool operator!=(const vpDot &d)
void setMaxDotSize(double percentage)
unsigned int getWidth() const
void setGrayLevelPrecision(const double &grayLevelPrecision)
Class to define colors available for display functionnalities.
void track(const vpImage< unsigned char > &I)
static const unsigned int SPIRAL_SEARCH_SIZE
Class that defines what is a feature generic tracker.
vpImagePoint getCog() const
Error that can be emited by the vpTracker class and its derivates.
vpDot & operator=(const vpDot &d)
Copy operator.
void set_u(const double u)
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1) const
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
void set_v(const double v)
This tracker is meant to track a dot (connected pixels with same gray level) on a vpImage...
unsigned int getHeight() 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 ...
bool operator==(const vpDot &d)
void initTracking(const vpImage< unsigned char > &I)
virtual void displayPoint(const vpImagePoint &ip, const vpColor &color)=0
virtual ~vpDot()
Destructor.