Visual Servoing Platform  version 3.5.0 under development (2022-02-15)
vpMbtDistanceCircle.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Make the complete tracking of an object by using its CAD model. Circle
33  * tracking.
34  *
35  * Authors:
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
40 #include <visp3/core/vpConfig.h>
41 
47 #include <algorithm>
48 #include <stdlib.h>
49 
50 #include <visp3/core/vpMeterPixelConversion.h>
51 #include <visp3/core/vpPixelMeterConversion.h>
52 #include <visp3/core/vpPlane.h>
53 #include <visp3/mbt/vpMbtDistanceCircle.h>
54 #include <visp3/vision/vpPose.h>
55 #include <visp3/visual_features/vpFeatureBuilder.h>
56 #include <visp3/visual_features/vpFeatureEllipse.h>
57 
62  : name(), index(0), cam(), me(NULL), wmean(1), featureEllipse(), isTrackedCircle(true), meEllipse(NULL), circle(NULL),
63  radius(0.), p1(NULL), p2(NULL), p3(NULL), L(), error(), nbFeature(0), Reinit(false), hiddenface(NULL),
64  index_polygon(-1), isvisible(false)
65 {
66 }
67 
72 {
73  if (meEllipse != NULL)
74  delete meEllipse;
75  if (circle != NULL)
76  delete circle;
77  if (p1 != NULL)
78  delete p1;
79  if (p2 != NULL)
80  delete p2;
81  if (p3 != NULL)
82  delete p3;
83 }
84 
91 void vpMbtDistanceCircle::project(const vpHomogeneousMatrix &cMo) { circle->project(cMo); }
92 
103 void vpMbtDistanceCircle::buildFrom(const vpPoint &_p1, const vpPoint &_p2, const vpPoint &_p3, double r)
104 {
105  circle = new vpCircle;
106  p1 = new vpPoint;
107  p2 = new vpPoint;
108  p3 = new vpPoint;
109 
110  // Get the points
111  *p1 = _p1;
112  *p2 = _p2;
113  *p3 = _p3;
114 
115  // Get the radius
116  radius = r;
117 
118  vpPlane plane(*p1, *p2, *p3, vpPlane::object_frame);
119 
120  // Build our circle
121  circle->setWorldCoordinates(plane.getA(), plane.getB(), plane.getC(), _p1.get_oX(), _p1.get_oY(), _p1.get_oZ(), r);
122 }
123 
130 {
131  me = _me;
132  if (meEllipse != NULL) {
133  meEllipse->setMe(me);
134  }
135 }
136 
149  const vpImage<bool> *mask)
150 {
151  if (isvisible) {
152  // Perspective projection
153  circle->changeFrame(cMo);
154 
155  try {
156  circle->projection();
157  } catch (...) {
158  std::cout << "Problem when projecting circle\n";
159  return false;
160  }
161 
162  // Create the moving edges containers
163  meEllipse = new vpMbtMeEllipse;
164  meEllipse->setMask(*mask);
165  meEllipse->setMe(me);
166 
167  // meEllipse->setDisplay(vpMeSite::RANGE_RESULT) ; // TODO only for debug
168  meEllipse->setInitRange(me->getRange()); // TODO: check because set to zero for lines
169 
170  try {
171  vpImagePoint ic;
172  double n20_p, n11_p, n02_p;
173  vpMeterPixelConversion::convertEllipse(cam, *circle, ic, n20_p, n11_p, n02_p);
174  meEllipse->initTracking(I, ic, n20_p, n11_p, n02_p, doNotTrack);
175  } catch (...) {
176  // vpTRACE("the circle can't be initialized");
177  return false;
178  }
179  }
180  return true;
181 }
182 
190 {
191  if (isvisible) {
192  try {
193  meEllipse->track(I);
194  } catch (...) {
195  // std::cout << "Track meEllipse failed" << std::endl;
196  meEllipse->reset();
197  Reinit = true;
198  }
199 
200  // Update the number of features
201  nbFeature = (unsigned int)meEllipse->getMeList().size();
202  }
203 }
204 
214 {
215  if (isvisible) {
216  // Perspective projection
217  circle->changeFrame(cMo);
218 
219  try {
220  circle->projection();
221  } catch (...) {
222  std::cout << "Problem when projecting circle\n";
223  }
224 
225  try {
226 
227  vpImagePoint ic;
228  double n20_p, n11_p, n02_p;
229  vpMeterPixelConversion::convertEllipse(cam, *circle, ic, n20_p, n11_p, n02_p);
230  meEllipse->updateParameters(I, ic, n20_p, n11_p, n02_p);
231  } catch (...) {
232  Reinit = true;
233  }
234  nbFeature = (unsigned int)meEllipse->getMeList().size();
235  }
236 }
237 
249 {
250  if (meEllipse != NULL)
251  delete meEllipse;
252 
253  meEllipse = NULL;
254 
255  if (!initMovingEdge(I, cMo, false, mask))
256  Reinit = true;
257 
258  Reinit = false;
259 }
260 
273  const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
274  bool displayFullModel)
275 {
276  std::vector<double> params = getModelForDisplay(cMo, camera, displayFullModel);
277 
278  vpImagePoint center(params[0], params[1]);
279  double n20_p = params[2];
280  double n11_p = params[3];
281  double n02_p = params[4];
282  vpDisplay::displayEllipse(I, center, n20_p, n11_p, n02_p, true, col, thickness);
283 }
284 
297  const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
298  bool displayFullModel)
299 {
300  std::vector<double> params = getModelForDisplay(cMo, camera, displayFullModel);
301 
302  vpImagePoint center(params[1], params[2]);
303  double n20_p = params[3];
304  double n11_p = params[4];
305  double n02_p = params[5];
306  vpDisplay::displayEllipse(I, center, n20_p, n11_p, n02_p, true, col, thickness);
307 }
308 
313 std::vector<std::vector<double> > vpMbtDistanceCircle::getFeaturesForDisplay()
314 {
315  std::vector<std::vector<double> > features;
316 
317  if (meEllipse != NULL) {
318  for (std::list<vpMeSite>::const_iterator it = meEllipse->getMeList().begin(); it != meEllipse->getMeList().end(); ++it) {
319  vpMeSite p_me = *it;
320 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
321  std::vector<double> params = {0, //ME
322  p_me.get_ifloat(),
323  p_me.get_jfloat(),
324  static_cast<double>(p_me.getState())};
325 #else
326  std::vector<double> params;
327  params.push_back(0); //ME
328  params.push_back(p_me.get_ifloat());
329  params.push_back(p_me.get_jfloat());
330  params.push_back(static_cast<double>(p_me.getState()));
331 #endif
332  features.push_back(params);
333  }
334  }
335 
336  return features;
337 }
338 
351  const vpCameraParameters &camera,
352  bool displayFullModel)
353 {
354  std::vector<double> params;
355 
356  if ((isvisible && isTrackedCircle) || displayFullModel) {
357  // Perspective projection
358  circle->changeFrame(cMo);
359 
360  try {
361  circle->projection();
362  } catch (...) {
363  std::cout << "Cannot project the circle";
364  }
365 
366  vpImagePoint center;
367  double n20_p, n11_p, n02_p;
368  vpMeterPixelConversion::convertEllipse(camera, *circle, center, n20_p, n11_p, n02_p);
369  params.push_back(1); //1 for ellipse parameters
370  params.push_back(center.get_i());
371  params.push_back(center.get_j());
372  params.push_back(n20_p);
373  params.push_back(n11_p);
374  params.push_back(n02_p);
375  }
376 
377  return params;
378 }
379 
392 {
393  if (meEllipse != NULL) {
394  meEllipse->display(I); // display the me
395  if (vpDEBUG_ENABLE(3))
396  vpDisplay::flush(I);
397  }
398 }
399 
401 {
402  if (meEllipse != NULL) {
403  meEllipse->display(I); // display the me
404  if (vpDEBUG_ENABLE(3))
405  vpDisplay::flush(I);
406  }
407 }
408 
413 {
414  if (isvisible) {
415  nbFeature = (unsigned int)meEllipse->getMeList().size();
416  L.resize(nbFeature, 6);
418  } else
419  nbFeature = 0;
420 }
421 
427 {
428  if (isvisible) {
429  // Perspective projection
430  circle->changeFrame(cMo);
431  try {
432  circle->projection();
433  } catch (...) {
434  std::cout << "Problem projection circle\n";
435  }
436 
437  vpFeatureBuilder::create(featureEllipse, *circle);
438 
439  vpMatrix H1 = featureEllipse.interaction();
440 
441  vpRowVector H(5);
442  double x = 0, y = 0;
443 
444  // Get the parameters of the ellipse in the image plane
445  double xg = circle->p[0];
446  double yg = circle->p[1];
447  double n20 = circle->p[2];
448  double n11 = circle->p[3];
449  double n02 = circle->p[4];
450 
451  unsigned int j = 0;
452 
453  for (std::list<vpMeSite>::const_iterator it = meEllipse->getMeList().begin(); it != meEllipse->getMeList().end();
454  ++it) {
455  vpPixelMeterConversion::convertPoint(cam, it->j, it->i, x, y);
456  H[0] = 2 * (n11 * (y - yg) + n02 * (xg - x));
457  H[1] = 2 * (n20 * (yg - y) + n11 * (x - xg));
458  H[2] = vpMath::sqr(y - yg) - n02;
459  H[3] = 2 * (yg * (x - xg) + y * xg + n11 - x * y);
460  H[4] = vpMath::sqr(x - xg) - n20;
461 
462  for (unsigned int k = 0; k < 6; k++)
463  L[j][k] = H[0] * H1[0][k] + H[1] * H1[1][k] + H[2] * H1[2][k] + H[3] * H1[3][k] + H[4] * H1[4][k];
464 
465  error[j] = n02 * vpMath::sqr(x) + n20 * vpMath::sqr(y) - 2 * n11 * x * y + 2 * (n11 * yg - n02 * xg) * x +
466  2 * (n11 * xg - n20 * yg) * y + n02 * vpMath::sqr(xg) + n20 * vpMath::sqr(yg) -
467  2 * n11 * xg * yg + vpMath::sqr(n11) - n20 * n02;
468 
469  j++;
470  }
471  }
472 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:153
double get_i() const
Definition: vpImagePoint.h:203
double get_oY() const
Get the point oY coordinate in the object frame.
Definition: vpPoint.cpp:463
vpMeSiteState getState() const
Definition: vpMeSite.h:190
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:304
unsigned int nbFeature
The number of moving edges.
static void convertEllipse(const vpCameraParameters &cam, const vpSphere &sphere, vpImagePoint &center_p, double &n20_p, double &n11_p, double &n02_p)
vpPoint * p3
An other point on the plane containing the circle.
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false)
#define vpDEBUG_ENABLE(level)
Definition: vpDebug.h:538
Implementation of an homogeneous matrix and operations on such kind of matrices.
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const vpPoint &_p3, double r)
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:115
vpMatrix L
The interaction matrix.
Performs search in a given direction(normal) for a given distance(pixels) for a given &#39;site&#39;...
Definition: vpMeSite.h:71
std::vector< double > getModelForDisplay(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false)
Class to define RGB colors available for display functionnalities.
Definition: vpColor.h:157
vpMatrix interaction(unsigned int select=FEATURE_ALL)
compute the interaction matrix from a subset a the possible features
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=NULL)
vpColVector error
The error vector.
vpMbtMeEllipse * meEllipse
The moving edge containers.
Definition: vpMe.h:60
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
vpPoint * p2
A point on the plane containing the circle.
static void flush(const vpImage< unsigned char > &I)
double get_oX() const
Get the point oX coordinate in the object frame.
Definition: vpPoint.cpp:461
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:81
void projection()
Definition: vpCircle.cpp:140
bool Reinit
Indicates if the circle has to be reinitialized.
bool isvisible
Indicates if the circle is visible or not.
static double sqr(double x)
Definition: vpMath.h:116
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
double getB() const
Definition: vpPlane.h:104
double get_j() const
Definition: vpImagePoint.h:214
Generic class defining intrinsic camera parameters.
std::vector< std::vector< double > > getFeaturesForDisplay()
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
static void displayEllipse(const vpImage< unsigned char > &I, const vpImagePoint &center, 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)
double get_jfloat() const
Definition: vpMeSite.h:167
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
double get_oZ() const
Get the point oZ coordinate in the object frame.
Definition: vpPoint.cpp:465
vpCircle * circle
The circle to track.
void displayMovingEdges(const vpImage< unsigned char > &I)
void changeFrame(const vpHomogeneousMatrix &noMo, vpColVector &noP) const
Definition: vpCircle.cpp:248
double getA() const
Definition: vpPlane.h:102
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:310
double getC() const
Definition: vpPlane.h:106
double get_ifloat() const
Definition: vpMeSite.h:160
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpImage< bool > *mask=NULL)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:87
This class defines the container for a plane geometrical structure.
Definition: vpPlane.h:58
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
double radius
The radius of the circle.
Class that defines a 3D circle in the object frame and allows forward projection of a 3D circle in th...
Definition: vpCircle.h:91
unsigned int getRange() const
Definition: vpMe.h:179
vpPoint * p1
The center of the circle.
vpColVector p
Definition: vpTracker.h:73
void setWorldCoordinates(const vpColVector &oP)
Definition: vpCircle.cpp:60