35#include <visp3/core/vpMatrixException.h>
36#include <visp3/core/vpTrackingException.h>
37#include <visp3/core/vpImagePoint.h>
38#include <visp3/me/vpMe.h>
39#include <visp3/me/vpMeEllipse.h>
41#ifndef VP_ME_ELLIPSE_REGULAR_SAMPLING
42#define VP_ME_ELLIPSE_TWO_CONCENTRIC_CIRCLES
48 :
m_K(),
m_iPc(),
m_a(0.),
m_b(0.),
m_e(0.),
m_iP1(),
m_iP2(),
m_alpha1(0),
m_ce(0.),
m_se(0.),
m_angleList(),
m_m00(0.),
52 const unsigned int val_2 = 2;
53 const unsigned int val_6 = 6;
107 double u = iP.
get_u();
108 double v = iP.
get_v();
115 double A = (
m_K[0] * u) + (
m_K[2] * v) +
m_K[3];
116 double B = (
m_K[1] * v) + (
m_K[2] * u) +
m_K[4];
118 double theta = atan2(B, A);
129 std::list<vpMeSite>::iterator end =
m_meList.end();
130 for (std::list<vpMeSite>::iterator it =
m_meList.begin(); it != end; ++it) {
147#ifdef VP_ME_ELLIPSE_REGULAR_SAMPLING
150 double co = cos(angle);
151 double si = sin(angle);
153 double u = co * coef;
154 double v = si * coef;
157#elif defined(VP_ME_ELLIPSE_TWO_CONCENTRIC_CIRCLES)
163 double u =
m_a * cos(angle);
164 double v =
m_b * sin(angle);
178#ifdef VP_ME_ELLIPSE_REGULAR_SAMPLING
180 double du = pt.
get_u() - uc;
181 double dv = pt.
get_v() - vc;
182 double ang = atan2(dv, du) -
m_e;
186 else if (ang < -M_PI) {
189#ifdef VP_ME_ELLIPSE_TWO_CONCENTRIC_CIRCLES
194 double co = cos(ang);
195 double si = sin(ang);
196 double coeff = 1.0 / sqrt((
m_b *
m_b * co * co) + (
m_a *
m_a * si * si));
201#elif defined(VP_ME_ELLIPSE_TWO_CONCENTRIC_CIRCLES)
207 double angle = atan2(si, co);
216 double d = (num * num) + (4.0 *
m_n11 *
m_n11);
217 if (d <= std::numeric_limits<double>::epsilon()) {
224 m_e = atan2(2.0 *
m_n11, num) / 2.0;
230 m_a = sqrt(2.0 * (num + d));
231 m_b = sqrt(2.0 * (num - d));
237 const unsigned int index_0 = 0;
238 const unsigned int index_1 = 1;
239 const unsigned int index_2 = 2;
240 const unsigned int index_3 = 3;
241 const unsigned int index_4 = 4;
242 const unsigned int index_5 = 5;
260 const unsigned int index_0 = 0;
261 const unsigned int index_1 = 1;
262 const unsigned int index_2 = 2;
263 const unsigned int index_3 = 3;
264 const unsigned int index_4 = 4;
265 const unsigned int index_5 = 5;
267 double num = (
m_K[index_0] *
m_K[index_1]) - (
m_K[index_2] *
m_K[index_2]);
272 m_uc = ((
m_K[index_2] *
m_K[index_4]) - (
m_K[index_1] *
m_K[index_3])) / num;
273 m_vc = ((
m_K[index_2] *
m_K[index_3]) - (
m_K[index_0] *
m_K[index_4])) / num;
285 unsigned int Ksize =
m_K.size();
286 for (
unsigned int i = 0; i < Ksize; ++i) {
293 std::cout <<
"K :" <<
m_K.t() << std::endl;
294 std::cout <<
"xc = " <<
m_uc <<
", yc = " <<
m_vc << std::endl;
295 std::cout <<
"n20 = " <<
m_n20 <<
", n11 = " <<
m_n11 <<
", n02 = " <<
m_n02 << std::endl;
309 int nbrows =
static_cast<int>(I.getHeight());
310 int nbcols =
static_cast<int>(I.getWidth());
312 if (std::fabs(
m_me->getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
313 std::cout <<
"Warning: In vpMeEllipse::sample() ";
314 std::cout <<
"function called with sample step = 0. We set it rather to 10 pixels";
316 m_me->setSampleStep(10.0);
319 double perim = M_PI * ((3.0 * (
m_a +
m_b)) - sqrt(((3.0 *
m_a) +
m_b) * (
m_a + (3.0 *
m_b))));
321 unsigned int nb_pt =
static_cast<unsigned int>(floor(perim /
m_me->getSampleStep()));
322 double incr = (2.0 * M_PI) / nb_pt;
332 double ang =
m_alpha1 + (incr / 2.0);
341 unsigned int is_uint =
static_cast<unsigned int>(iP.
get_i());
342 unsigned int js_uint =
static_cast<unsigned int>(iP.
get_j());
344 const unsigned int crossSize = 5;
353 const double marginRatio =
m_me->getThresholdMarginRatio();
355 double contrastThreshold = fabs(convolution) * marginRatio;
374 unsigned int nb_pts_added = 0;
375 int nbrows =
static_cast<int>(I.getHeight());
376 int nbcols =
static_cast<int>(I.getWidth());
377 const unsigned int range_default = 2;
379 unsigned int memory_range =
m_me->getRange();
380 m_me->setRange(range_default);
383 double perim = M_PI * ((3.0 * (
m_a +
m_b)) - sqrt(((3.0 *
m_a) +
m_b) * (
m_a + (3.0 *
m_b))));
385 unsigned int nb_pt =
static_cast<unsigned int>(floor(perim /
m_me->getSampleStep()));
386 double incr = (2.0 * M_PI) / nb_pt;
390 std::list<double>::iterator angleList =
m_angleList.begin();
391 std::list<vpMeSite>::iterator meList =
m_meList.begin();
392 const double marginRatio =
m_me->getThresholdMarginRatio();
393 double ang = *angleList;
398 double nextang = *angleList;
399 if ((nextang - ang) > (2.0 * incr)) {
402 while (ang < (nextang - incr)) {
406 unsigned int is_uint =
static_cast<unsigned int>(iP.
get_i());
407 unsigned int js_uint =
static_cast<unsigned int>(iP.
get_j());
415 double contrastThreshold = fabs(convolution) * marginRatio;
422 if ((new_ang - ang) > M_PI) {
423 new_ang -= 2.0 * M_PI;
425 else if ((ang - new_ang) > M_PI) {
426 new_ang += 2.0 * M_PI;
449 double nextang = *angleList;
454 if (dist > (2.0 *
m_me->getSampleStep())) {
455 ang = (nextang + ang) / 2.0;
459 unsigned int is_uint =
static_cast<unsigned int>(iP.
get_i());
460 unsigned int js_uint =
static_cast<unsigned int>(iP.
get_j());
468 double contrastThreshold = fabs(convolution) * marginRatio;
475 if ((new_ang - ang) > M_PI) {
476 new_ang -= 2.0 * M_PI;
478 else if ((ang - new_ang) > M_PI) {
479 new_ang += 2.0 * M_PI;
496 unsigned int nbpts = 0;
499 nbpts =
static_cast<unsigned int>(floor((
m_alphamin -
m_alpha1 - (incr / 2.0)) / incr));
502 for (
unsigned int i = 0; i < nbpts; ++i) {
506 unsigned int is_uint =
static_cast<unsigned int>(iP.
get_i());
507 unsigned int js_uint =
static_cast<unsigned int>(iP.
get_j());
516 double contrastThreshold = fabs(convolution) * marginRatio;
523 if ((new_ang - ang) > M_PI) {
524 new_ang -= 2.0 * M_PI;
526 else if ((ang - new_ang) > M_PI) {
527 new_ang += 2.0 * M_PI;
541 nbpts =
static_cast<unsigned int>(floor((
m_alpha2 - (incr / 2.0) -
m_alphamax) / incr));
545 for (
unsigned int i = 0; i < nbpts; ++i) {
549 unsigned int is_uint =
static_cast<unsigned int>(iP.
get_i());
550 unsigned int js_uint =
static_cast<unsigned int>(iP.
get_j());
558 double contrastThreshold = fabs(convolution) * marginRatio;
565 if ((new_ang - ang) > M_PI) {
566 new_ang -= 2.0 * M_PI;
568 else if ((ang - new_ang) > M_PI) {
569 new_ang += 2.0 * M_PI;
578 m_me->setRange(memory_range);
602 const unsigned int nForCircle = 3;
607 std::vector<vpImagePoint> iP(n);
614 std::cout <<
"First and third points specify the extremities of the arc of circle (clockwise)" << std::endl;
616 for (
unsigned int k = 0; k < n; ++k) {
617 std::cout <<
"Click point " << (k + 1) <<
"/" << n <<
" on the circle " << std::endl;
619 const unsigned int crossSize = 10;
622 std::cout << iP[k] << std::endl;
627 std::cout <<
"First and fifth points specify the extremities of the arc of ellipse (clockwise)" << std::endl;
629 for (
unsigned int k = 0; k < n; ++k) {
630 std::cout <<
"Click point " << (k + 1) <<
"/" << n <<
" on the ellipse " << std::endl;
632 const unsigned int crossSize = 10;
635 std::cout << iP[k] << std::endl;
642 bool trackCircle,
bool trackArc)
677 const unsigned int index_0 = 0;
678 const unsigned int index_1 = 1;
679 const unsigned int index_2 = 2;
680 const unsigned int index_3 = 3;
681 const unsigned int index_4 = 4;
684 if ((pt1 !=
nullptr) && (pt2 !=
nullptr)) {
688 m_uc = param[index_0];
689 m_vc = param[index_1];
690 m_n20 = param[index_2];
691 m_n11 = param[index_3];
692 m_n02 = param[index_4];
748 const unsigned int minNbGoodPoints = 5;
770#ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
797 const double &B,
const double &E,
const double &smallalpha,
const double &highalpha,
798 const vpColor &color,
unsigned int thickness)
831 const double &E,
const double &smallalpha,
const double &highalpha,
832 const vpColor &color,
unsigned int thickness)
840 const double &B,
const double &E,
const double &smallalpha,
const double &highalpha,
841 const vpColor &color,
unsigned int thickness)
843 vpDisplay::displayEllipse(I, center, A, B, E, smallalpha, highalpha,
false, color, thickness,
true,
true);
847 const double &E,
const double &smallalpha,
const double &highalpha,
848 const vpColor &color,
unsigned int thickness)
850 vpDisplay::displayEllipse(I, center, A, B, E, smallalpha, highalpha,
false, color, thickness,
true,
true);
Implementation of column vector and the associated operations.
Class to define RGB colors available for display functionalities.
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void displayEllipse(const vpImage< unsigned char > &I, const vpImagePoint ¢er, const double &coef1, const double &coef2, const double &coef3, bool use_normalized_centered_moments, const vpColor &color, unsigned int thickness=1, bool display_center=false, bool display_arc=false)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void set_ij(double ii, double jj)
void set_uv(double u, double v)
Definition of the vpImage class member functions.
static double deg(double rad)
double m_n20
Second order centered and normalized moments .
double m_arcEpsilon
Epsilon value used to check if arc angles are the same.
void computePointOnEllipse(const double angle, vpImagePoint &iP)
void display(const vpImage< unsigned char > &I, const vpColor &col, unsigned int thickness=1)
vpImagePoint m_iPc
The coordinates of the ellipse center.
double m_vc
Value of v coordinate of iPc.
unsigned int m_numberOfGoodPoints
Number of correct points tracked along the ellipse.
unsigned int plugHoles(const vpImage< unsigned char > &I)
vpMeEllipse & operator=(const vpMeEllipse &me_ellipse)
void printParameters() const
double m_uc
Value of u coordinate of iPc.
bool m_trackCircle
Track a circle (true) or an ellipse (false).
double m_m00
Ellipse area.
std::list< double > m_angleList
Stores the value in increasing order of the angle on the ellipse for each vpMeSite.
bool m_trackArc
Track an arc of ellipse/circle (true) or a complete one (false).
void initTracking(const vpImage< unsigned char > &I, bool trackCircle=false, bool trackArc=false)
double m_a
is the semi major axis of the ellipse.
unsigned int leastSquareRobust(const vpImage< unsigned char > &I)
void leastSquare(const vpImage< unsigned char > &I, const std::vector< vpImagePoint > &iP)
double m_b
is the semi minor axis of the ellipse.
double computeTheta(const vpImagePoint &iP) const
double m_se
Value of sin(e).
double m_n02
Second order centered and normalized moments .
unsigned int m_expectedDensity
Expected number of points to track along the ellipse.
double m_n11
Second order centered and normalized moments .
virtual void sample(const vpImage< unsigned char > &I, bool doNotTrack=false) VP_OVERRIDE
void track(const vpImage< unsigned char > &I)
virtual ~vpMeEllipse() VP_OVERRIDE
double m_ce
Value of cos(e).
static void displayEllipse(const vpImage< unsigned char > &I, const vpImagePoint ¢er, const double &A, const double &B, const double &E, const double &smallalpha, const double &highalpha, const vpColor &color=vpColor::green, unsigned int thickness=1)
double m_thresholdWeight
Threshold on the weights for the robust least square.
double computeAngleOnEllipse(const vpImagePoint &pt) const
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
@ NO_SUPPRESSION
Point successfully tracked.
void setDisplay(vpMeSiteDisplayType select)
double m_ifloat
Subpixel coordinates along i of a site.
double convolution(const vpImage< unsigned char > &ima, const vpMe *me)
double m_alpha
Angle of tangent at site.
vpMeSiteState getState() const
double get_ifloat() const
double m_jfloat
Subpixel coordinates along j of a site.
double get_jfloat() const
void setContrastThreshold(const double &thresh, const vpMe &me)
void track(const vpImage< unsigned char > &I, const vpMe *me, const bool &test_contrast=true)
void setState(const vpMeSiteState &flag)
void initTracking(const vpImage< unsigned char > &I)
const vpImage< bool > * m_mask
Mask used to disable tracking on a part of image.
vpMeSite::vpMeSiteDisplayType m_selectDisplay
Moving-edges display type.
void track(const vpImage< unsigned char > &I)
vpMe * m_me
Moving edges initialisation parameters.
static bool inRoiMask(const vpImage< bool > *mask, unsigned int i, unsigned int j)
void display(const vpImage< unsigned char > &I)
bool outOfImage(int i, int j, int border, int nrows, int ncols)
const vpImage< bool > * m_maskCandidates
Mask used to determine candidate points for initialization in an image.
std::list< vpMeSite > m_meList
static bool inMeMaskCandidates(const vpImage< bool > *meMaskCandidates, unsigned int i, unsigned int j)
Error that can be emitted by the vpTracker class and its derivatives.
@ notEnoughPointError
Not enough point to track.
@ fatalError
Tracker fatal error.