46 #include <visp3/me/vpMeTracker.h>
47 #include <visp3/me/vpMe.h>
48 #include <visp3/me/vpMeSite.h>
49 #include <visp3/me/vpMeLine.h>
50 #include <visp3/core/vpRobust.h>
51 #include <visp3/core/vpTrackingException.h>
52 #include <visp3/core/vpImagePoint.h>
53 #include <visp3/core/vpMath.h>
61 void computeDelta(
double &delta,
int i1,
int j1,
int i2,
int j2);
64 normalizeAngle(
double &delta)
66 while (delta > M_PI) { delta -= M_PI ; }
67 while (delta < -M_PI) { delta += M_PI ; }
71 computeDelta(
double &delta,
int i1,
int j1,
int i2,
int j2)
74 double B = double(i1-i2) ;
75 double A = double(j1-j2) ;
79 normalizeAngle(delta) ;
84 project(
double a,
double b,
double c,
85 double i,
double j,
double &ip,
double &jp)
105 : rho(0.), theta(0.), delta(0.), delta_1(0.), angle(0.), angle_1(90), sign(1),
106 _useIntensityForRho(true), a(0.), b(0.), c(0.)
116 rho(0.), theta(0.), delta(0.), delta_1(0.), angle(0.), angle_1(90), sign(1),
117 _useIntensityForRho(true), a(0.), b(0.), c(0.)
122 delta = meline.
delta;
160 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
162 "Moving edges not initialized")) ;
169 if (std::fabs(
me->
getSampleStep()) <= std::numeric_limits<double>::epsilon())
173 "sample step = 0")) ;
181 if(std::fabs(length_p)<=std::numeric_limits<double>::epsilon())
186 double stepi = diffsi/(double)n_sample;
187 double stepj = diffsj/(double)n_sample;
206 pix.
init((
int)is, (
int)js, delta, 0,
sign) ;
223 vpCDEBUG(1) <<
"end vpMeLine::sample() : ";
224 vpCDEBUG(1) << n_sample <<
" point inserted in the list " << std::endl ;
259 std::cout <<
"Click on the line first point..." <<std::endl ;
263 std::cout <<
"Click on the line second point..." <<std::endl ;
307 unsigned int iter =0 ;
308 unsigned int nos_1 = 0 ;
309 double distance = 100;
316 "not enough point")) ;
325 for(std::list<vpMeSite>::const_iterator it=
list.begin(); it!=
list.end(); ++it){
336 while (iter < 4 && distance > 0.05)
347 for (i=0 ; i < nos_1 ; i++)
353 distance = fabs(x[0]-x_1[0])+fabs(x[1]-x_1[1]);
358 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ++it){
390 for(std::list<vpMeSite>::const_iterator it=
list.begin(); it!=
list.end(); ++it){
401 while (iter < 4 && distance > 0.05)
412 for (i=0 ; i < nos_1 ; i++)
418 distance = fabs(x[0]-x_1[0])+fabs(x[1]-x_1[1]);
423 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ++it){
449 normalizeAngle(delta) ;
468 vpCDEBUG(1) <<
" begin vpMeLine::initTracking()"<<std::endl ;
470 int i1s, j1s, i2s, j2s;
487 double angle_ = atan2((
double)(i1s-i2s),(
double)(j1s-j2s)) ;
494 computeDelta(delta,i1s,j1s,i2s,j2s) ;
514 vpCDEBUG(1) <<
" end vpMeLine::initTracking()"<<std::endl ;
525 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
549 for(std::list<vpMeSite>::const_iterator it=
list.begin(); it!=
list.end(); ++it){
569 if (fabs(imin-imax) < 25)
571 for(std::list<vpMeSite>::const_iterator it=
list.begin(); it!=
list.end(); ++it){
605 vpCDEBUG(1) <<
"begin vpMeLine::sample() : "<<std::endl ;
608 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
610 "Moving edges not initialized")) ;
618 if (std::fabs(
me->
getSampleStep()) <= std::numeric_limits<double>::epsilon())
623 "sample step = 0")) ;
632 double di = diffsi/sqrt(s) ;
633 double dj = diffsj/sqrt(s) ;
650 for (
int i=0 ; i < 3 ; i++)
681 for (
int i=0 ; i < 3 ; i++)
711 vpCDEBUG(1) <<
"end vpMeLine::sample() : " ;
712 vpCDEBUG(1) << n_sample <<
" point inserted in the list " << std::endl ;
733 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
735 "Moving edges not initialized")) ;
738 project(a,b,c,
PExt[0].ifloat,
PExt[0].jfloat,i1,j1) ;
739 project(a,b,c,
PExt[1].ifloat,
PExt[1].jfloat,i2,j2) ;
752 if ((
double)n<0.9*expecteddensity)
754 double delta_new =
delta;
774 double angle_ = delta + M_PI/2;
777 while (angle_<0) angle_ += M_PI;
778 while (angle_>M_PI) angle_ -= M_PI;
783 if(std::fabs(std::fabs(angle_) - 180) <= std::numeric_limits<double>::epsilon())
795 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ++it){
814 vpCDEBUG(1) <<
"begin vpMeLine::track()"<<std::endl ;
882 vpCDEBUG(1) <<
"end vpMeLine::track()"<<std::endl ;
885 void vpMeLine::update_indices(
double theta,
int i,
int j,
int incr,
int& i1,
int& i2,
int& j1,
int& j2){
886 i1 = (int)(i + cos(theta) *incr) ;
887 j1 = (int)(j + sin(theta) *incr) ;
889 i2 = (int)(i - cos(theta) *incr) ;
890 j2 = (int)(j - sin(theta) *incr) ;
907 while (theta >= M_PI) theta -=M_PI ;
908 while (theta < 0) theta +=M_PI ;
938 int i1=0,i2=0,j1=0,j2=0 ;
939 unsigned char v1=0,v2=0 ;
943 update_indices(theta,i,j,incr,i1,i2,j1,j2);
945 if(i1<0 || i1>=height_ || i2<0 || i2>=height_ ||
946 j1<0 || j1>=width_ || j2<0 || j2>=width_){
947 double rho_lim1 = fabs((
double)i/cos(theta));
948 double rho_lim2 = fabs((
double)j/sin(theta));
950 double co_rho_lim1 = fabs(((
double)(height_-i))/cos(theta));
951 double co_rho_lim2 = fabs(((
double)(width_-j))/sin(theta));
953 double rho_lim = std::min(rho_lim1,rho_lim2);
954 double co_rho_lim = std::min(co_rho_lim1,co_rho_lim2);
955 incr = (int)std::floor(std::min(rho_lim,co_rho_lim));
959 "increment is too small")) ;
961 update_indices(theta,i,j,incr,i1,i2,j1,j2);
967 unsigned int i1_ =
static_cast<unsigned int>(i1);
968 unsigned int j1_ =
static_cast<unsigned int>(j1);
969 unsigned int i2_ =
static_cast<unsigned int>(i2);
970 unsigned int j2_ =
static_cast<unsigned int>(j2);
980 "In vpMeLine cannot determine rho sign, since there is no gray level difference between both sides of the line"));
983 update_indices(theta,i,j,incr,i1,i2,j1,j2);
986 if (theta >=0 && theta <= M_PI/2)
1094 double a1 = line1.
a;
1095 double b1 = line1.
b;
1096 double c1 = line1.
c;
1097 double a2 = line2.
a;
1098 double b2 = line2.
b;
1099 double c2 = line2.
c;
1107 denom = (-(a2/a1) * b1 + b2);
1110 if (std::fabs(denom) <= std::numeric_limits<double>::epsilon())
1112 std::cout <<
"!!!!!!!!!!!!! Problem : Lines are parallel !!!!!!!!!!!!!" << std::endl;
1117 if (std::fabs(denom) > std::numeric_limits<double>::epsilon())
1119 j = ( (a2/a1)*c1 - c2 ) / denom;
1120 i = (-b1*j - c1) / a1;
1126 denom = (-(b2/b1) * a1 + a2);
1129 if (std::fabs(denom) <= std::numeric_limits<double>::epsilon())
1131 std::cout <<
"!!!!!!!!!!!!! Problem : Lines are parallel !!!!!!!!!!!!!" << std::endl;
1136 if (std::fabs(denom) > std::numeric_limits<double>::epsilon())
1138 i = ( (b2/b1)*c1 - c2 ) / denom;
1139 j = (-a1*i - c1) / b1;
1173 const double &A,
const double &B,
const double &C,
1174 const vpColor &color,
unsigned int thickness)
1178 if (fabs(A) < fabs(B)) {
1179 double i1, j1, i2, j2;
1181 j1 = (-A*i1 -C) / B;
1183 j2 = (-A*i2 -C) / B;
1194 double i1, j1, i2, j2;
1196 i1 = -(B * j1 + C) / A;
1198 i2 = -(B * j2 + C) / A;
1237 const double &A,
const double &B,
const double &C,
1238 const vpColor &color,
unsigned int thickness)
1242 if (fabs(A) < fabs(B)) {
1243 double i1, j1, i2, j2;
1245 j1 = (-A*i1 -C) / B;
1247 j2 = (-A*i2 -C) / B;
1258 double i1, j1, i2, j2;
1260 i1 = -(B * j1 + C) / A;
1262 i2 = -(B * j2 + C) / A;
1303 const std::list<vpMeSite> &site_list,
1304 const double &A,
const double &B,
const double &C,
1305 const vpColor &color,
unsigned int thickness)
1309 for(std::list<vpMeSite>::const_iterator it=site_list.begin(); it!=site_list.end(); ++it){
1324 if (fabs(A) < fabs(B)) {
1325 double i1, j1, i2, j2;
1327 j1 = (-A*i1 -C) / B;
1329 j2 = (-A*i2 -C) / B;
1340 double i1, j1, i2, j2;
1342 i1 = -(B * j1 + C) / A;
1344 i2 = -(B * j2 + C) / A;
1385 const std::list<vpMeSite> &site_list,
1386 const double &A,
const double &B,
const double &C,
1387 const vpColor &color,
unsigned int thickness)
1391 for(std::list<vpMeSite>::const_iterator it=site_list.begin(); it!=site_list.end(); ++it){
1406 if (fabs(A) < fabs(B)) {
1407 double i1, j1, i2, j2;
1409 j1 = (-A*i1 -C) / B;
1411 j2 = (-A*i2 -C) / B;
1422 double i1, j1, i2, j2;
1424 i1 = -(B * j1 + C) / A;
1426 i2 = -(B * j2 + C) / A;
void reSample(const vpImage< unsigned char > &I)
unsigned int getRange() const
Implementation of a matrix and operations on matrices.
double c
Parameter c of the line equation a*i + b*j + c = 0.
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Compute the weights according a residue vector and a PsiFunction.
unsigned int getWidth() const
#define vpDEBUG_ENABLE(level)
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 ...
error that can be emited by ViSP classes.
void track(const vpImage< unsigned char > &Im)
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)
std::list< vpMeSite > list
Error that can be emited by the vpTracker class and its derivates.
static void displayArrow(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
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.
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)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
Implementation of column vector and the associated operations.
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.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
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