48 #include <visp3/core/vpImagePoint.h> 49 #include <visp3/core/vpMath.h> 50 #include <visp3/core/vpRobust.h> 51 #include <visp3/core/vpTrackingException.h> 52 #include <visp3/me/vpMe.h> 53 #include <visp3/me/vpMeLine.h> 54 #include <visp3/me/vpMeSite.h> 55 #include <visp3/me/vpMeTracker.h> 59 void computeDelta(
double &delta,
int i1,
int j1,
int i2,
int j2);
61 static void normalizeAngle(
double &delta)
63 while (delta > M_PI) {
66 while (delta < -M_PI) {
71 void 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);
82 static void project(
double a,
double b,
double c,
double i,
double j,
double &ip,
double &jp)
84 if (fabs(a) > fabs(b)) {
86 ip = (-c - b * jp) / a;
89 jp = (-c - a * ip) / b;
99 : rho(0.), theta(0.), delta(0.), delta_1(0.), angle(0.), angle_1(90), sign(1), _useIntensityForRho(true), a(0.),
115 delta = meline.
delta;
150 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
158 if (std::fabs(
me->
getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
168 if (std::fabs(length_p) <= std::numeric_limits<double>::epsilon())
173 double stepi = diffsi / (double)n_sample;
174 double stepj = diffsj / (double)n_sample;
191 pix.
init((
int)is, (
int)js, delta, 0,
sign);
206 vpCDEBUG(1) <<
"end vpMeLine::sample() : ";
207 vpCDEBUG(1) << n_sample <<
" point inserted in the list " << std::endl;
238 std::cout <<
"Click on the line first point..." << std::endl;
243 std::cout <<
"Click on the line second point..." << std::endl;
282 unsigned int iter = 0;
283 unsigned int nos_1 = 0;
284 double distance = 100;
292 if ((fabs(b) >= 0.9))
298 for (std::list<vpMeSite>::const_iterator it =
list.begin(); it !=
list.end(); ++it) {
308 while (iter < 4 && distance > 0.05) {
318 for (i = 0; i < nos_1; i++) {
323 distance = fabs(x[0] - x_1[0]) + fabs(x[1] - x_1[1]);
328 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end(); ++it) {
357 for (std::list<vpMeSite>::const_iterator it =
list.begin(); it !=
list.end(); ++it) {
367 while (iter < 4 && distance > 0.05) {
377 for (i = 0; i < nos_1; i++) {
382 distance = fabs(x[0] - x_1[0]) + fabs(x[1] - x_1[1]);
387 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end(); ++it) {
411 normalizeAngle(delta);
425 vpCDEBUG(1) <<
" begin vpMeLine::initTracking()" << std::endl;
427 int i1s, j1s, i2s, j2s;
444 double angle_ = atan2((
double)(i1s - i2s), (
double)(j1s - j2s));
451 computeDelta(delta, i1s, j1s, i2s, j2s);
470 vpCDEBUG(1) <<
" end vpMeLine::initTracking()" << std::endl;
479 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end();) {
500 for (std::list<vpMeSite>::const_iterator it =
list.begin(); it !=
list.end(); ++it) {
518 if (fabs(imin - imax) < 25) {
519 for (std::list<vpMeSite>::const_iterator it =
list.begin(); it !=
list.end(); ++it) {
551 vpCDEBUG(1) <<
"begin vpMeLine::sample() : " << std::endl;
554 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
563 if (std::fabs(
me->
getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
575 double di = diffsi / sqrt(s);
576 double dj = diffsj / sqrt(s);
593 for (
int i = 0; i < 3; i++) {
622 for (
int i = 0; i < 3; i++) {
650 vpCDEBUG(1) <<
"end vpMeLine::sample() : ";
651 vpCDEBUG(1) << n_sample <<
" point inserted in the list " << std::endl;
667 double i1, j1, i2, j2;
670 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
674 project(a, b, c,
PExt[0].ifloat,
PExt[0].jfloat, i1, j1);
675 project(a, b, c,
PExt[1].ifloat,
PExt[1].jfloat, i2, j2);
688 if ((
double)n < 0.9 * expecteddensity) {
689 double delta_new =
delta;
708 double angle_ = delta + M_PI / 2;
713 while (angle_ > M_PI)
719 if (std::fabs(std::fabs(angle_) - 180) <= std::numeric_limits<double>::epsilon()) {
730 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end(); ++it) {
747 vpCDEBUG(1) <<
"begin vpMeLine::track()" << std::endl;
802 vpCDEBUG(1) <<
"end vpMeLine::track()" << std::endl;
805 void vpMeLine::update_indices(
double theta,
int i,
int j,
int incr,
int &i1,
int &i2,
int &j1,
int &j2)
807 i1 = (int)(i + cos(theta) * incr);
808 j1 = (int)(j + sin(theta) * incr);
810 i2 = (int)(i - cos(theta) * incr);
811 j2 = (int)(j - sin(theta) * incr);
827 while (theta >= M_PI)
860 int i1 = 0, i2 = 0, j1 = 0, j2 = 0;
861 unsigned char v1 = 0, v2 = 0;
865 update_indices(theta, i, j, incr, i1, i2, j1, j2);
867 if (i1 < 0 || i1 >= height_ || i2 < 0 || i2 >= height_ || j1 < 0 || j1 >= width_ || j2 < 0 || j2 >= width_) {
868 double rho_lim1 = fabs((
double)i / cos(theta));
869 double rho_lim2 = fabs((
double)j / sin(theta));
871 double co_rho_lim1 = fabs(((
double)(height_ - i)) / cos(theta));
872 double co_rho_lim2 = fabs(((
double)(width_ - j)) / sin(theta));
874 double rho_lim = (std::min)(rho_lim1, rho_lim2);
875 double co_rho_lim = (std::min)(co_rho_lim1, co_rho_lim2);
876 incr = (int)std::floor((std::min)(rho_lim, co_rho_lim));
877 if (incr < INCR_MIN) {
881 update_indices(theta, i, j, incr, i1, i2, j1, j2);
886 unsigned int i1_ =
static_cast<unsigned int>(i1);
887 unsigned int j1_ =
static_cast<unsigned int>(j1);
888 unsigned int i2_ =
static_cast<unsigned int>(i2);
889 unsigned int j2_ =
static_cast<unsigned int>(j2);
892 if (abs(v1 - v2) < 1) {
897 "there is no gray level difference between both " 898 "sides of the line"));
901 update_indices(theta, i, j, incr, i1, i2, j1, j2);
904 if (theta >= 0 && theta <= M_PI / 2) {
1003 denom = (-(a2 / a1) * b1 + b2);
1006 if (std::fabs(denom) <= std::numeric_limits<double>::epsilon()) {
1007 std::cout <<
"!!!!!!!!!!!!! Problem : Lines are parallel !!!!!!!!!!!!!" << std::endl;
1012 if (std::fabs(denom) > std::numeric_limits<double>::epsilon()) {
1013 j = ((a2 / a1) * c1 - c2) / denom;
1014 i = (-b1 * j - c1) / a1;
1019 denom = (-(b2 / b1) * a1 + a2);
1022 if (std::fabs(denom) <= std::numeric_limits<double>::epsilon()) {
1023 std::cout <<
"!!!!!!!!!!!!! Problem : Lines are parallel !!!!!!!!!!!!!" << std::endl;
1028 if (std::fabs(denom) > std::numeric_limits<double>::epsilon()) {
1029 i = ((b2 / b1) * c1 - c2) / denom;
1030 j = (-a1 * i - c1) / b1;
1063 const double &B,
const double &C,
const vpColor &color,
unsigned int thickness)
1067 if (fabs(A) < fabs(B)) {
1068 double i1, j1, i2, j2;
1070 j1 = (-A * i1 - C) / B;
1072 j2 = (-A * i2 - C) / B;
1082 double i1, j1, i2, j2;
1084 i1 = -(B * j1 + C) / A;
1086 i2 = -(B * j2 + C) / A;
1126 const double &B,
const double &C,
const vpColor &color,
unsigned int thickness)
1130 if (fabs(A) < fabs(B)) {
1131 double i1, j1, i2, j2;
1133 j1 = (-A * i1 - C) / B;
1135 j2 = (-A * i2 - C) / B;
1145 double i1, j1, i2, j2;
1147 i1 = -(B * j1 + C) / A;
1149 i2 = -(B * j2 + C) / A;
1191 const std::list<vpMeSite> &site_list,
const double &A,
const double &B,
const double &C,
1192 const vpColor &color,
unsigned int thickness)
1196 for (std::list<vpMeSite>::const_iterator it = site_list.begin(); it != site_list.end(); ++it) {
1211 if (fabs(A) < fabs(B)) {
1212 double i1, j1, i2, j2;
1214 j1 = (-A * i1 - C) / B;
1216 j2 = (-A * i2 - C) / B;
1226 double i1, j1, i2, j2;
1228 i1 = -(B * j1 + C) / A;
1230 i2 = -(B * j2 + C) / A;
1272 const std::list<vpMeSite> &site_list,
const double &A,
const double &B,
const double &C,
1273 const vpColor &color,
unsigned int thickness)
1277 for (std::list<vpMeSite>::const_iterator it = site_list.begin(); it != site_list.end(); ++it) {
1292 if (fabs(A) < fabs(B)) {
1293 double i1, j1, i2, j2;
1295 j1 = (-A * i1 - C) / B;
1297 j2 = (-A * i2 - C) / B;
1307 double i1, j1, i2, j2;
1309 i1 = -(B * j1 + C) / A;
1311 i2 = -(B * j2 + C) / A;
void reSample(const vpImage< unsigned char > &I)
Implementation of a matrix and operations on matrices.
vpMatrix pseudoInverse(double svThreshold=1e-6) const
double c
Parameter c of the line equation a*i + b*j + c = 0.
vpMeSiteState getState() const
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.
#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.
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)
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.
double getSampleStep() const
int outOfImage(int i, int j, int half, int row, int cols)
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)
unsigned int getHeight() const
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)
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)
vpMeSite::vpMeSiteDisplayType selectDisplay
unsigned int getWidth() const
void setIteration(const unsigned int iter)
Set iteration.
unsigned int getRange() const
void seekExtremities(const vpImage< unsigned char > &I)
virtual void display(const vpImage< unsigned char > &I, vpColor col)=0
static const vpColor blue