31 #include <visp3/core/vpConfig.h>
32 #include <visp3/me/vpMeEllipse.h>
33 #include <visp3/core/vpMatrixException.h>
34 #include <visp3/core/vpRobust.h>
35 #include <visp3/core/vpTrackingException.h>
43 unsigned int n =
static_cast<unsigned int>(iP.size());
44 const unsigned int index_0 = 0;
45 const unsigned int index_1 = 1;
46 const unsigned int index_2 = 2;
47 const unsigned int index_3 = 3;
48 const unsigned int index_4 = 4;
49 const unsigned int index_5 = 5;
52 const unsigned int circleDims = 3;
62 for (
unsigned int k = 0; k < n; ++k) {
64 double u = (iP[k].get_u() - um) / um;
65 double v = (iP[k].get_v() - vm) / um;
69 b[k] = (u * u) + (v * v);
75 double ratio = vm / um;
76 m_K[index_0] = (
m_K[index_1] = (1.0 / (um * um)));
78 m_K[index_3] = -(1.0 + (x[index_0] / 2.0)) / um;
79 m_K[index_4] = -(ratio + (x[index_1] / 2.0)) / um;
80 m_K[index_5] = -x[index_2] + 1.0 + (ratio * ratio) + x[index_0] + (ratio * x[index_1]);
83 const unsigned int npoints_min = 5;
84 if (n < npoints_min) {
100 for (
unsigned int k = 0; k < n; ++k) {
102 double u = (iP[k].get_u() - um) / um;
103 double v = (iP[k].get_v() - vm) / vm;
104 A[k][index_0] = u * u;
105 A[k][index_1] = v * v;
106 A[k][index_2] = 2.0 * u * v;
107 A[k][index_3] = 2.0 * u;
108 A[k][index_4] = 2.0 * v;
117 for (
unsigned int i = 0; i < nbRows; ++i) {
122 m_K[index_0] *= vm / um;
123 m_K[index_1] *= um / vm;
124 m_K[index_3] = (
m_K[index_3] * vm) - (
m_K[index_0] * um) - (
m_K[index_2] * vm);
125 m_K[index_4] = (
m_K[index_4] * um) - (
m_K[index_1] * vm) - (
m_K[index_2] * um);
126 m_K[index_5] = (
m_K[index_5] * um * vm) - (
m_K[index_0] * um * um) - (
m_K[index_1] * vm * vm) -
127 (2.0 *
m_K[index_2] * um * vm) - (2.0 *
m_K[index_3] * um) - (2.0 *
m_K[index_4] * vm);
135 const unsigned int index_0 = 0;
136 const unsigned int index_1 = 1;
137 const unsigned int index_2 = 2;
138 const unsigned int index_3 = 3;
139 const unsigned int index_4 = 4;
140 const unsigned int index_5 = 5;
152 std::list<vpMeSite>::const_iterator end =
m_meList.end();
154 for (std::list<vpMeSite>::const_iterator it =
m_meList.begin(); it != end; ++it) {
163 b[k] = (u * u) + (v * v);
172 const unsigned int minRequiredNbMe = 3;
173 if (k < minRequiredNbMe) {
181 unsigned int iter = 0;
190 const unsigned int maxNbIter = 4;
191 const unsigned int widthDA = DA.
getCols();
192 while ((iter < maxNbIter) && (var > 0.1)) {
193 for (
unsigned int i = 0; i < k; ++i) {
194 for (
unsigned int j = 0; j < widthDA; ++j) {
195 DA[i][j] = w[i] * A[i][j];
203 double ratio = vm / um;
204 m_K[index_0] = (
m_K[index_1] = (1.0 / (um * um)));
206 m_K[index_3] = -(1.0 + (x[index_0] / 2.0)) / um;
207 m_K[index_4] = -(ratio + (x[index_1] / 2.0)) / um;
208 m_K[index_5] = -x[index_2] + 1.0 + (ratio * ratio) + x[index_0] + (ratio * x[index_1]);
214 var = (xg - xg_prev).frobeniusNorm();
218 for (
unsigned int i = 0; i < k; ++i) {
221 double sign = (
m_K[index_0] * x * x) + (
m_K[index_1] * y * y) + (2. *
m_K[index_2] * x * y)
222 + (2. *
m_K[index_3] * x) + (2. *
m_K[index_4] * y) +
m_K[index_5];
244 const unsigned int index_0 = 0;
245 const unsigned int index_1 = 1;
246 const unsigned int index_2 = 2;
247 const unsigned int index_3 = 3;
248 const unsigned int index_4 = 4;
249 const unsigned int index_5 = 5;
260 const unsigned int nbColsA = 6;
264 std::list<vpMeSite>::const_iterator end =
m_meList.end();
266 for (std::list<vpMeSite>::const_iterator it =
m_meList.begin(); it != end; ++it) {
272 A[k][index_0] = u * u;
273 A[k][index_1] = v * v;
274 A[k][index_2] = 2.0 * u * v;
275 A[k][index_3] = 2.0 * u;
276 A[k][index_4] = 2.0 * v;
286 const unsigned int minRequiredMe = 5;
287 if (k < minRequiredMe) {
294 unsigned int iter = 0;
302 const unsigned int maxIter = 4;
303 const unsigned int widthDA = DA.
getCols();
304 while ((iter < maxIter) && (var > 0.1)) {
305 for (
unsigned int i = 0; i < k; ++i) {
306 for (
unsigned int j = 0; j < widthDA; ++j) {
307 DA[i][j] = w[i] * A[i][j];
310 unsigned int dim = DA.
nullSpace(KerDA, 1);
315 const unsigned int nparam = 6;
316 for (
unsigned int i = 0; i < nparam; ++i) {
317 m_K[i] = KerDA[i][0];
321 m_K[index_0] *= vm / um;
322 m_K[index_1] *= um / vm;
323 m_K[index_3] = (
m_K[index_3] * vm) - (
m_K[0] * um) - (
m_K[index_2] * vm);
324 m_K[index_4] = (
m_K[index_4] * um) - (
m_K[1] * vm) - (
m_K[index_2] * um);
325 m_K[index_5] = (
m_K[index_5] * um * vm) - (
m_K[index_0] * um * um) - (
m_K[index_1] * vm * vm)
326 - (2.0 *
m_K[index_2] * um * vm) - (2.0 *
m_K[index_3] * um) - (2.0 *
m_K[index_4] * vm);
332 var = (xg - xg_prev).frobeniusNorm();
336 for (
unsigned int i = 0; i < k; ++i) {
339 double sign = (
m_K[0] * x * x) + (
m_K[1] * y * y) + (2. *
m_K[2] * x * y) + (2. *
m_K[3] * x) + (2. *
m_K[4] * y) +
m_K[5];
379 double previous_ang = -4.0 * M_PI;
381 std::list<double>::iterator angleList =
m_angleList.begin();
382 std::list<vpMeSite>::iterator end =
m_meList.end();
383 std::list<vpMeSite>::iterator meList =
m_meList.begin();
384 while (meList != end) {
397 double ang = *angleList;
401 if ((new_ang - ang) > M_PI) {
402 new_ang -= 2.0 * M_PI;
404 else if ((ang - new_ang) > M_PI) {
405 new_ang += 2.0 * M_PI;
407 previous_ang = new_ang;
408 *angleList = new_ang;
424 std::list<double> finAngle;
426 std::list<vpMeSite> finMe;
428 std::list<double>::iterator debutAngleList;
429 std::list<vpMeSite>::iterator debutMeList;
433 while (meList != end) {
435 double ang = *angleList;
441 finAngle.push_back(ang);
443 finMe.push_back(p_me);
462 debutAngleList =
m_angleList.insert(debutAngleList, ang);
464 debutMeList =
m_meList.insert(debutMeList, p_me);
479 unsigned int numberOfGoodPoints = 0;
480 previous_ang = -4.0 * M_PI;
483 double perim = M_PI * ((3.0 * (
m_a +
m_b)) - sqrt(((3.0 *
m_a) +
m_b) * (
m_a + (3.0 *
m_b))));
484 unsigned int nb_pt =
static_cast<unsigned int>(floor(perim /
m_me->
getSampleStep()));
485 double incr = (2.0 * M_PI) / nb_pt;
499 while (meList != end) {
501 double new_ang = *angleList;
503 if ((new_ang - previous_ang) >= (0.6 * incr)) {
504 previous_ang = new_ang;
505 ++numberOfGoodPoints;
520 if ((
m_meList.size() != numberOfGoodPoints) || (
m_angleList.size() != numberOfGoodPoints)) {
530 return numberOfGoodPoints;
unsigned int getCols() const
unsigned int getRows() const
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
@ dimensionError
Bad dimension.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void set_ij(double ii, double jj)
void set_uv(double u, double v)
unsigned int getWidth() const
unsigned int getHeight() const
error that can be emitted by the vpMatrix class and its derivatives
@ rankDeficient
Rank deficient.
Implementation of a matrix and operations on matrices.
void solveBySVD(const vpColVector &B, vpColVector &x) const
unsigned int nullSpace(vpMatrix &kerA, double svThreshold=1e-6) const
void leastSquareRobustEllipse(const double &um, const double &vm, unsigned int &k, vpColVector &w)
void computePointOnEllipse(const double angle, vpImagePoint &iP)
void leastSquareRobustCircle(const double &um, const double &vm, unsigned int &k, vpColVector &w)
double m_vc
Value of v coordinate of iPc.
double m_uc
Value of u coordinate of iPc.
bool m_trackCircle
Track a circle (true) or an ellipse (false).
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).
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.
unsigned int m_expectedDensity
Expected number of points to track along the ellipse.
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.
double m_ifloat
Subpixel coordinates along i of a site.
vpMeSiteState getState() const
double get_ifloat() const
double m_jfloat
Subpixel coordinates along j of a site.
double get_jfloat() const
unsigned int numberOfSignal()
vpMe * m_me
Moving edges initialisation parameters.
std::list< vpMeSite > m_meList
double getSampleStep() const
Contains an M-estimator and various influence function.
@ TUKEY
Tukey influence function.
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
void setMinMedianAbsoluteDeviation(double mad_min)
Error that can be emitted by the vpTracker class and its derivatives.
@ fatalError
Tracker fatal error.