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;
152 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
160 if (std::fabs(
me->
getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
170 if (std::fabs(length_p) <= std::numeric_limits<double>::epsilon())
175 double stepi = diffsi / (double)n_sample;
176 double stepj = diffsj / (double)n_sample;
193 pix.
init((
int)is, (
int)js, delta, 0,
sign);
208 vpCDEBUG(1) <<
"end vpMeLine::sample() : ";
209 vpCDEBUG(1) << n_sample <<
" point inserted in the list " << std::endl;
240 std::cout <<
"Click on the line first point..." << std::endl;
245 std::cout <<
"Click on the line second point..." << std::endl;
280 unsigned int iter = 0;
281 unsigned int nos_1 = 0;
282 double distance = 100;
290 if ((fabs(b) >= 0.9))
296 for (std::list<vpMeSite>::const_iterator it =
list.begin(); it !=
list.end(); ++it) {
306 while (iter < 4 && distance > 0.05) {
307 for (
unsigned int i = 0; i < k ; i++) {
308 for (
unsigned int j = 0; j < 2 ; j++) {
309 DA[i][j] = w[i] * A[i][j];
320 for (
unsigned int i = 0; i < nos_1; i++) {
325 distance = fabs(x[0] - x_1[0]) + fabs(x[1] - x_1[1]);
330 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end(); ++it) {
359 for (std::list<vpMeSite>::const_iterator it =
list.begin(); it !=
list.end(); ++it) {
369 while (iter < 4 && distance > 0.05) {
378 for (
unsigned int i = 0; i < nos_1; i++) {
383 distance = fabs(x[0] - x_1[0]) + fabs(x[1] - x_1[1]);
388 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end(); ++it) {
412 normalizeAngle(delta);
426 vpCDEBUG(1) <<
" begin vpMeLine::initTracking()" << std::endl;
428 int i1s, j1s, i2s, j2s;
445 double angle_ = atan2((
double)(i1s - i2s), (
double)(j1s - j2s));
452 computeDelta(delta, i1s, j1s, i2s, j2s);
471 vpCDEBUG(1) <<
" end vpMeLine::initTracking()" << std::endl;
480 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end();) {
501 for (std::list<vpMeSite>::const_iterator it =
list.begin(); it !=
list.end(); ++it) {
519 if (fabs(imin - imax) < 25) {
520 for (std::list<vpMeSite>::const_iterator it =
list.begin(); it !=
list.end(); ++it) {
552 vpCDEBUG(1) <<
"begin vpMeLine::sample() : " << std::endl;
555 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
564 if (std::fabs(
me->
getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
576 double di = diffsi / sqrt(s);
577 double dj = diffsj / sqrt(s);
594 for (
int i = 0; i < 3; i++) {
623 for (
int i = 0; i < 3; i++) {
651 vpCDEBUG(1) <<
"end vpMeLine::sample() : ";
652 vpCDEBUG(1) << n_sample <<
" point inserted in the list " << std::endl;
668 double i1, j1, i2, j2;
671 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
675 project(a, b, c,
PExt[0].ifloat,
PExt[0].jfloat, i1, j1);
676 project(a, b, c,
PExt[1].ifloat,
PExt[1].jfloat, i2, j2);
689 if ((
double)n < 0.9 * expecteddensity) {
690 double delta_new =
delta;
709 double angle_ = delta + M_PI / 2;
714 while (angle_ > M_PI)
720 if (std::fabs(std::fabs(angle_) - 180) <= std::numeric_limits<double>::epsilon()) {
731 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end(); ++it) {
748 vpCDEBUG(1) <<
"begin vpMeLine::track()" << std::endl;
803 vpCDEBUG(1) <<
"end vpMeLine::track()" << std::endl;
806 void vpMeLine::update_indices(
double theta,
int i,
int j,
int incr,
int &i1,
int &i2,
int &j1,
int &j2)
808 i1 = (int)(i + cos(theta) * incr);
809 j1 = (int)(j + sin(theta) * incr);
811 i2 = (int)(i - cos(theta) * incr);
812 j2 = (int)(j - sin(theta) * incr);
828 while (theta >= M_PI)
861 int i1 = 0, i2 = 0, j1 = 0, j2 = 0;
862 unsigned char v1 = 0, v2 = 0;
866 update_indices(theta, i, j, incr, i1, i2, j1, j2);
868 if (i1 < 0 || i1 >= height_ || i2 < 0 || i2 >= height_ || j1 < 0 || j1 >= width_ || j2 < 0 || j2 >= width_) {
869 double rho_lim1 = fabs((
double)i / cos(theta));
870 double rho_lim2 = fabs((
double)j / sin(theta));
872 double co_rho_lim1 = fabs(((
double)(height_ - i)) / cos(theta));
873 double co_rho_lim2 = fabs(((
double)(width_ - j)) / sin(theta));
875 double rho_lim = (std::min)(rho_lim1, rho_lim2);
876 double co_rho_lim = (std::min)(co_rho_lim1, co_rho_lim2);
877 incr = (int)std::floor((std::min)(rho_lim, co_rho_lim));
878 if (incr < INCR_MIN) {
882 update_indices(theta, i, j, incr, i1, i2, j1, j2);
887 unsigned int i1_ =
static_cast<unsigned int>(i1);
888 unsigned int j1_ =
static_cast<unsigned int>(j1);
889 unsigned int i2_ =
static_cast<unsigned int>(i2);
890 unsigned int j2_ =
static_cast<unsigned int>(j2);
893 if (abs(v1 - v2) < 1) {
898 "there is no gray level difference between both " 899 "sides of the line"));
902 update_indices(theta, i, j, incr, i1, i2, j1, j2);
905 if (theta >= 0 && theta <= M_PI / 2) {
1000 double i = 0, j = 0;
1004 denom = (-(a2 / a1) * b1 + b2);
1007 if (std::fabs(denom) <= std::numeric_limits<double>::epsilon()) {
1008 std::cout <<
"!!!!!!!!!!!!! Problem : Lines are parallel !!!!!!!!!!!!!" << std::endl;
1013 if (std::fabs(denom) > std::numeric_limits<double>::epsilon()) {
1014 j = ((a2 / a1) * c1 - c2) / denom;
1015 i = (-b1 * j - c1) / a1;
1020 denom = (-(b2 / b1) * a1 + a2);
1023 if (std::fabs(denom) <= std::numeric_limits<double>::epsilon()) {
1024 std::cout <<
"!!!!!!!!!!!!! Problem : Lines are parallel !!!!!!!!!!!!!" << std::endl;
1029 if (std::fabs(denom) > std::numeric_limits<double>::epsilon()) {
1030 i = ((b2 / b1) * c1 - c2) / denom;
1031 j = (-a1 * i - c1) / b1;
1064 const double &B,
const double &C,
const vpColor &color,
unsigned int thickness)
1068 if (fabs(A) < fabs(B)) {
1069 double i1, j1, i2, j2;
1071 j1 = (-A * i1 - C) / B;
1073 j2 = (-A * i2 - C) / B;
1083 double i1, j1, i2, j2;
1085 i1 = -(B * j1 + C) / A;
1087 i2 = -(B * j2 + C) / A;
1127 const double &B,
const double &C,
const vpColor &color,
unsigned int thickness)
1131 if (fabs(A) < fabs(B)) {
1132 double i1, j1, i2, j2;
1134 j1 = (-A * i1 - C) / B;
1136 j2 = (-A * i2 - C) / B;
1146 double i1, j1, i2, j2;
1148 i1 = -(B * j1 + C) / A;
1150 i2 = -(B * j2 + C) / A;
1192 const std::list<vpMeSite> &site_list,
const double &A,
const double &B,
const double &C,
1193 const vpColor &color,
unsigned int thickness)
1197 for (std::list<vpMeSite>::const_iterator it = site_list.begin(); it != site_list.end(); ++it) {
1212 if (fabs(A) < fabs(B)) {
1213 double i1, j1, i2, j2;
1215 j1 = (-A * i1 - C) / B;
1217 j2 = (-A * i2 - C) / B;
1227 double i1, j1, i2, j2;
1229 i1 = -(B * j1 + C) / A;
1231 i2 = -(B * j2 + C) / A;
1273 const std::list<vpMeSite> &site_list,
const double &A,
const double &B,
const double &C,
1274 const vpColor &color,
unsigned int thickness)
1278 for (std::list<vpMeSite>::const_iterator it = site_list.begin(); it != site_list.end(); ++it) {
1293 if (fabs(A) < fabs(B)) {
1294 double i1, j1, i2, j2;
1296 j1 = (-A * i1 - C) / B;
1298 j2 = (-A * i2 - C) / B;
1308 double i1, j1, i2, j2;
1310 i1 = -(B * j1 + C) / A;
1312 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
Point removed during virtual visual-servoing because considered as an outlier.
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
#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 RGB 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)
void display(const vpImage< unsigned char > &I, vpColor col)
void computeRhoTheta(const vpImage< unsigned char > &I)
std::list< vpMeSite > list
Error that can be emited by the vpTracker class and its derivates.
Point used by the tracker.
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)
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)
static int round(double x)
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.
vpMe * me
Moving edges initialisation parameters.
Contains an M-estimator and various influence function.
Tukey 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 ...
void setMinMedianAbsoluteDeviation(double mad_min)
void setRange(const unsigned int &r)
void track(const vpImage< unsigned char > &im, const vpMe *me, bool test_contraste=true)
vpMeSite::vpMeSiteDisplayType selectDisplay
unsigned int getWidth() const
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
unsigned int getRange() const
void seekExtremities(const vpImage< unsigned char > &I)
virtual void display(const vpImage< unsigned char > &I, vpColor col)=0
virtual void sample(const vpImage< unsigned char > &image, bool doNotTrack=false)
static const vpColor blue