50 #include <visp/vpMeTracker.h>
51 #include <visp/vpMe.h>
52 #include <visp/vpMeSite.h>
53 #include <visp/vpMeLine.h>
54 #include <visp/vpRobust.h>
55 #include <visp/vpTrackingException.h>
56 #include <visp/vpImagePoint.h>
57 #include <visp/vpMath.h>
65 void computeDelta(
double &delta,
int i1,
int j1,
int i2,
int j2);
68 normalizeAngle(
double &delta)
70 while (delta > M_PI) { delta -= M_PI ; }
71 while (delta < -M_PI) { delta += M_PI ; }
75 computeDelta(
double &delta,
int i1,
int j1,
int i2,
int j2)
78 double B = double(i1-i2) ;
79 double A = double(j1-j2) ;
83 normalizeAngle(delta) ;
88 project(
double a,
double b,
double c,
89 double i,
double j,
double &ip,
double &jp)
109 : rho(0.), theta(0.), delta(0.), delta_1(0.), angle(0.), angle_1(90), sign(1),
110 _useIntensityForRho(true), a(0.), b(0.), c(0.)
120 rho(0.), theta(0.), delta(0.), delta_1(0.), angle(0.), angle_1(90), sign(1),
121 _useIntensityForRho(true), a(0.), b(0.), c(0.)
126 delta = meline.
delta;
164 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
166 "Moving edges not initialized")) ;
173 if (std::fabs(
me->
getSampleStep()) <= std::numeric_limits<double>::epsilon())
177 "sample step = 0")) ;
185 if(std::fabs(length_p)<=std::numeric_limits<double>::epsilon())
190 double stepi = diffsi/(double)n_sample;
191 double stepj = diffsj/(double)n_sample;
210 pix.
init((
int)is, (
int)js, delta, 0,
sign) ;
227 vpCDEBUG(1) <<
"end vpMeLine::sample() : ";
228 vpCDEBUG(1) << n_sample <<
" point inserted in the list " << std::endl ;
263 std::cout <<
"Click on the line first point..." <<std::endl ;
267 std::cout <<
"Click on the line second point..." <<std::endl ;
311 unsigned int iter =0 ;
312 unsigned int nos_1 = 0 ;
313 double distance = 100;
320 "not enough point")) ;
329 for(std::list<vpMeSite>::const_iterator it=
list.begin(); it!=
list.end(); ++it){
340 while (iter < 4 && distance > 0.05)
351 for (i=0 ; i < nos_1 ; i++)
357 distance = fabs(x[0]-x_1[0])+fabs(x[1]-x_1[1]);
362 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ++it){
394 for(std::list<vpMeSite>::const_iterator it=
list.begin(); it!=
list.end(); ++it){
405 while (iter < 4 && distance > 0.05)
416 for (i=0 ; i < nos_1 ; i++)
422 distance = fabs(x[0]-x_1[0])+fabs(x[1]-x_1[1]);
427 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ++it){
453 normalizeAngle(delta) ;
472 vpCDEBUG(1) <<
" begin vpMeLine::initTracking()"<<std::endl ;
474 int i1s, j1s, i2s, j2s;
491 double angle_ = atan2((
double)(i1s-i2s),(
double)(j1s-j2s)) ;
498 computeDelta(delta,i1s,j1s,i2s,j2s) ;
518 vpCDEBUG(1) <<
" end vpMeLine::initTracking()"<<std::endl ;
529 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
553 for(std::list<vpMeSite>::const_iterator it=
list.begin(); it!=
list.end(); ++it){
573 if (fabs(imin-imax) < 25)
575 for(std::list<vpMeSite>::const_iterator it=
list.begin(); it!=
list.end(); ++it){
609 vpCDEBUG(1) <<
"begin vpMeLine::sample() : "<<std::endl ;
612 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
614 "Moving edges not initialized")) ;
622 if (std::fabs(
me->
getSampleStep()) <= std::numeric_limits<double>::epsilon())
627 "sample step = 0")) ;
636 double di = diffsi/sqrt(s) ;
637 double dj = diffsj/sqrt(s) ;
654 for (
int i=0 ; i < 3 ; i++)
685 for (
int i=0 ; i < 3 ; i++)
715 vpCDEBUG(1) <<
"end vpMeLine::sample() : " ;
716 vpCDEBUG(1) << n_sample <<
" point inserted in the list " << std::endl ;
737 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
739 "Moving edges not initialized")) ;
742 project(a,b,c,
PExt[0].ifloat,
PExt[0].jfloat,i1,j1) ;
743 project(a,b,c,
PExt[1].ifloat,
PExt[1].jfloat,i2,j2) ;
756 if ((
double)n<0.9*expecteddensity)
758 double delta_new =
delta;
778 double angle_ = delta + M_PI/2;
781 while (angle_<0) angle_ += M_PI;
782 while (angle_>M_PI) angle_ -= M_PI;
787 if(std::fabs(std::fabs(angle_) - 180) <= std::numeric_limits<double>::epsilon())
799 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ++it){
818 vpCDEBUG(1) <<
"begin vpMeLine::track()"<<std::endl ;
886 vpCDEBUG(1) <<
"end vpMeLine::track()"<<std::endl ;
889 void vpMeLine::update_indices(
double theta,
int i,
int j,
int incr,
int& i1,
int& i2,
int& j1,
int& j2){
890 i1 = (int)(i + cos(theta) *incr) ;
891 j1 = (int)(j + sin(theta) *incr) ;
893 i2 = (int)(i - cos(theta) *incr) ;
894 j2 = (int)(j - sin(theta) *incr) ;
911 while (theta >= M_PI) theta -=M_PI ;
912 while (theta < 0) theta +=M_PI ;
943 int i1=0,i2=0,j1=0,j2=0 ;
944 unsigned char v1=0,v2=0 ;
948 update_indices(theta,i,j,incr,i1,i2,j1,j2);
950 if(i1<0 || i1>=height_ || i2<0 || i2>=height_ ||
951 j1<0 || j1>=width_ || j2<0 || j2>=width_){
952 double rho_lim1 = fabs((
double)i/cos(theta));
953 double rho_lim2 = fabs((
double)j/sin(theta));
955 double co_rho_lim1 = fabs(((
double)(height_-i))/cos(theta));
956 double co_rho_lim2 = fabs(((
double)(width_-j))/sin(theta));
958 double rho_lim = std::min(rho_lim1,rho_lim2);
959 double co_rho_lim = std::min(co_rho_lim1,co_rho_lim2);
960 incr = (int)std::floor(std::min(rho_lim,co_rho_lim));
964 "increment is too small")) ;
966 update_indices(theta,i,j,incr,i1,i2,j1,j2);
972 unsigned int i1_ =
static_cast<unsigned int>(i1);
973 unsigned int j1_ =
static_cast<unsigned int>(j1);
974 unsigned int i2_ =
static_cast<unsigned int>(i2);
975 unsigned int j2_ =
static_cast<unsigned int>(j2);
985 std::cout <<
"In CStraightLine::GetParameters() " ;
986 std::cout <<
" Error Tracking " << abs(v1-v2) << std::endl ;
989 update_indices(theta,i,j,incr,i1,i2,j1,j2);
992 if (theta >=0 && theta <= M_PI/2)
1101 double a1 = line1.
a;
1102 double b1 = line1.
b;
1103 double c1 = line1.
c;
1104 double a2 = line2.
a;
1105 double b2 = line2.
b;
1106 double c2 = line2.
c;
1113 denom = (-(a2/a1) * b1 + b2);
1116 if (std::fabs(denom) <= std::numeric_limits<double>::epsilon())
1118 std::cout <<
"!!!!!!!!!!!!! Problem : Lines are parallel !!!!!!!!!!!!!" << std::endl;
1123 if (std::fabs(denom) > std::numeric_limits<double>::epsilon())
1125 j = ( (a2/a1)*c1 - c2 ) / denom;
1126 i = (-b1*j - c1) / a1;
1132 denom = (-(b2/b1) * a1 + a2);
1135 if (std::fabs(denom) <= std::numeric_limits<double>::epsilon())
1137 std::cout <<
"!!!!!!!!!!!!! Problem : Lines are parallel !!!!!!!!!!!!!" << std::endl;
1142 if (std::fabs(denom) > std::numeric_limits<double>::epsilon())
1144 i = ( (b2/b1)*c1 - c2 ) / denom;
1145 j = (-a1*i - c1) / b1;
1179 const double &A,
const double &B,
const double &C,
1180 const vpColor &color,
unsigned int thickness)
1184 if (fabs(A) < fabs(B)) {
1185 double i1, j1, i2, j2;
1187 j1 = (-A*i1 -C) / B;
1189 j2 = (-A*i2 -C) / B;
1200 double i1, j1, i2, j2;
1202 i1 = -(B * j1 + C) / A;
1204 i2 = -(B * j2 + C) / A;
1243 const double &A,
const double &B,
const double &C,
1244 const vpColor &color,
unsigned int thickness)
1248 if (fabs(A) < fabs(B)) {
1249 double i1, j1, i2, j2;
1251 j1 = (-A*i1 -C) / B;
1253 j2 = (-A*i2 -C) / B;
1264 double i1, j1, i2, j2;
1266 i1 = -(B * j1 + C) / A;
1268 i2 = -(B * j2 + C) / A;
1309 const std::list<vpMeSite> &site_list,
1310 const double &A,
const double &B,
const double &C,
1311 const vpColor &color,
unsigned int thickness)
1315 for(std::list<vpMeSite>::const_iterator it=site_list.begin(); it!=site_list.end(); ++it){
1330 if (fabs(A) < fabs(B)) {
1331 double i1, j1, i2, j2;
1333 j1 = (-A*i1 -C) / B;
1335 j2 = (-A*i2 -C) / B;
1346 double i1, j1, i2, j2;
1348 i1 = -(B * j1 + C) / A;
1350 i2 = -(B * j2 + C) / A;
1391 const std::list<vpMeSite> &site_list,
1392 const double &A,
const double &B,
const double &C,
1393 const vpColor &color,
unsigned int thickness)
1397 for(std::list<vpMeSite>::const_iterator it=site_list.begin(); it!=site_list.end(); ++it){
1412 if (fabs(A) < fabs(B)) {
1413 double i1, j1, i2, j2;
1415 j1 = (-A*i1 -C) / B;
1417 j2 = (-A*i2 -C) / B;
1428 double i1, j1, i2, j2;
1430 i1 = -(B * j1 + C) / A;
1432 i2 = -(B * j2 + C) / A;
void reSample(const vpImage< unsigned char > &I)
unsigned int getRange() const
Definition of the vpMatrix class.
double c
Parameter c of the line equation a*i + b*j + c = 0.
virtual void displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)=0
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Compute the weights according a residue vector and a PsiFunction.
unsigned int getWidth() const
unsigned int numberOfSignal()
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'...
Class to define colors available for display functionnalities.
int outOfImage(int i, int j, int half, int rows, int cols)
bool _useIntensityForRho
Flag to specify wether the intensity of the image at the middle point is used to compute the sign of ...
void track(const vpImage< unsigned char > &Im)
#define vpDEBUG_ENABLE(level)
static const vpColor green
static void flush(const vpImage< unsigned char > &I)
static int round(const double x)
vpMeSiteState getState() const
void display(const vpImage< unsigned char > &I, vpColor col)
void set_i(const double ii)
void computeRhoTheta(const vpImage< unsigned char > &I)
void setIdentity(const double &val=1.0)
std::list< vpMeSite > list
Error that can be emited by the vpTracker class and its derivates.
void getExtremities(vpImagePoint &ip1, vpImagePoint &ip2)
static double sqr(double x)
void sample(const vpImage< unsigned char > &image)
Class that tracks in an image a line moving edges.
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
void setDisplay(vpMeSiteDisplayType select)
void track(const vpImage< unsigned char > &I)
Track sampled pixels.
Contains abstract elements for a Distance to Feature type feature.
void initTracking(const vpImage< unsigned char > &I)
double a
Parameter a of the line equation a*i + b*j + c = 0.
void setState(const vpMeSiteState &flag)
void set_j(const double jj)
Class that provides a data structure for the column vectors as well as a set of operations on these v...
double b
Parameter b of the line equation a*i + b*j + c = 0.
void track(const vpImage< unsigned char > &im, const vpMe *me, const bool test_contraste=true)
vpMe * me
Moving edges initialisation parameters.
Contains an M-Estimator and various influence function.
void initTracking(const vpImage< unsigned char > &I)
static bool intersection(const vpMeLine &line1, const vpMeLine &line2, vpImagePoint &ip)
unsigned int getHeight() const
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
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 ...
virtual void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
void setRange(const unsigned int &r)
void setThreshold(const double noise_threshold)
double getSampleStep() const
vpMeSite::vpMeSiteDisplayType selectDisplay
void setIteration(const unsigned int iter)
Set iteration.
void seekExtremities(const vpImage< unsigned char > &I)
virtual void display(const vpImage< unsigned char > &I, vpColor col)=0
static const vpColor blue