Visual Servoing Platform  version 3.1.0
vpMbtDistanceCircle.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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, const 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 
147 {
148  if (isvisible) {
149  // Perspective projection
150  circle->changeFrame(cMo);
151 
152  try {
153  circle->projection();
154  } catch (...) {
155  std::cout << "Problem when projecting circle\n";
156  return false;
157  }
158 
159  // Create the moving edges containers
160  meEllipse = new vpMbtMeEllipse;
161  meEllipse->setMe(me);
162 
163  // meEllipse->setDisplay(vpMeSite::RANGE_RESULT) ; // TODO only for debug
164  meEllipse->setInitRange(me->getRange()); // TODO: check because set to zero for lines
165 
166  try {
167  vpImagePoint ic;
168  double mu20_p, mu11_p, mu02_p;
169  vpMeterPixelConversion::convertEllipse(cam, *circle, ic, mu20_p, mu11_p, mu02_p);
170  meEllipse->initTracking(I, ic, mu20_p, mu11_p, mu02_p);
171  } catch (...) {
172  // vpTRACE("the circle can't be initialized");
173  return false;
174  }
175  }
176  return true;
177 }
178 
186 {
187  if (isvisible) {
188  try {
189  meEllipse->track(I);
190  } catch (...) {
191  // std::cout << "Track meEllipse failed" << std::endl;
192  meEllipse->reset();
193  Reinit = true;
194  }
195 
196  // Update the number of features
197  nbFeature = (unsigned int)meEllipse->getMeList().size();
198  }
199 }
200 
210 {
211  if (isvisible) {
212  // Perspective projection
213  circle->changeFrame(cMo);
214 
215  try {
216  circle->projection();
217  } catch (...) {
218  std::cout << "Problem when projecting circle\n";
219  }
220 
221  try {
222 
223  vpImagePoint ic;
224  double mu20_p, mu11_p, mu02_p;
225  vpMeterPixelConversion::convertEllipse(cam, *circle, ic, mu20_p, mu11_p, mu02_p);
226  meEllipse->updateParameters(I, ic, mu20_p, mu11_p, mu02_p);
227  } catch (...) {
228  Reinit = true;
229  }
230  nbFeature = (unsigned int)meEllipse->getMeList().size();
231  }
232 }
233 
244 {
245  if (meEllipse != NULL)
246  delete meEllipse;
247 
248  meEllipse = NULL;
249 
250  if (initMovingEdge(I, cMo) == false)
251  Reinit = true;
252 
253  Reinit = false;
254 }
255 
268  const vpCameraParameters &camera, const vpColor &col, const unsigned int thickness,
269  const bool displayFullModel)
270 {
271  if ((isvisible && isTrackedCircle) || displayFullModel) {
272  // Perspective projection
273  circle->changeFrame(cMo);
274 
275  try {
276  circle->projection();
277  } catch (...) {
278  std::cout << "Cannot project the circle";
279  }
280 
281  vpImagePoint center;
282  double mu20_p, mu11_p, mu02_p;
283  vpMeterPixelConversion::convertEllipse(camera, *circle, center, mu20_p, mu11_p, mu02_p);
284  vpDisplay::displayEllipse(I, center, mu20_p, mu11_p, mu02_p, true, col, thickness);
285  }
286 }
287 
300  const vpCameraParameters &camera, const vpColor &col, const unsigned int thickness,
301  const bool displayFullModel)
302 {
303  if ((isvisible && isTrackedCircle) || displayFullModel) {
304  // Perspective projection
305  circle->changeFrame(cMo);
306 
307  try {
308  circle->projection();
309  } catch (...) {
310  std::cout << "Cannot project the circle";
311  }
312 
313  vpImagePoint center;
314  double mu20_p, mu11_p, mu02_p;
315  vpMeterPixelConversion::convertEllipse(camera, *circle, center, mu20_p, mu11_p, mu02_p);
316  vpDisplay::displayEllipse(I, center, mu20_p, mu11_p, mu02_p, true, col, thickness);
317  }
318 }
319 
335 {
336  if (meEllipse != NULL) {
337  meEllipse->display(I); // display the me
338  if (vpDEBUG_ENABLE(3))
339  vpDisplay::flush(I);
340  }
341 }
342 
347 {
348  if (isvisible) {
349  nbFeature = (unsigned int)meEllipse->getMeList().size();
350  L.resize(nbFeature, 6);
352  } else
353  nbFeature = 0;
354 }
355 
361 {
362  if (isvisible) {
363  // Perspective projection
364  circle->changeFrame(cMo);
365  try {
366  circle->projection();
367  } catch (...) {
368  std::cout << "Problem projection circle\n";
369  }
370 
371  vpFeatureBuilder::create(featureEllipse, *circle);
372 
373  vpMatrix H1 = featureEllipse.interaction();
374 
375  vpRowVector H(5);
376  double x = 0, y = 0;
377 
378  // Get the parameters of the ellipse in the image plane
379  double xg = circle->p[0];
380  double yg = circle->p[1];
381  double mu20 = circle->p[2];
382  double mu11 = circle->p[3];
383  double mu02 = circle->p[4];
384 
385  unsigned int j = 0;
386 
387  for (std::list<vpMeSite>::const_iterator it = meEllipse->getMeList().begin(); it != meEllipse->getMeList().end();
388  ++it) {
389  vpPixelMeterConversion::convertPoint(cam, it->j, it->i, x, y);
390  H[0] = 2 * (mu11 * (y - yg) + mu02 * (xg - x));
391  H[1] = 2 * (mu20 * (yg - y) + mu11 * (x - xg));
392  H[2] = vpMath::sqr(y - yg) - mu02;
393  H[3] = 2 * (yg * (x - xg) + y * xg + mu11 - x * y);
394  H[4] = vpMath::sqr(x - xg) - mu20;
395 
396  for (unsigned int k = 0; k < 6; k++)
397  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];
398 
399  error[j] = mu02 * vpMath::sqr(x) + mu20 * vpMath::sqr(y) - 2 * mu11 * x * y + 2 * (mu11 * yg - mu02 * xg) * x +
400  2 * (mu11 * xg - mu20 * yg) * y + mu02 * vpMath::sqr(xg) + mu20 * vpMath::sqr(yg) -
401  2 * mu11 * xg * yg + vpMath::sqr(mu11) - mu20 * mu02;
402 
403  j++;
404  }
405  }
406 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
static void displayEllipse(const vpImage< unsigned char > &I, const vpImagePoint &center, const double &coef1, const double &coef2, const double &coef3, bool use_centered_moments, const vpColor &color, unsigned int thickness=1)
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.cpp:422
unsigned int nbFeature
The number of moving edges.
vpPoint * p3
An other point on the plane containing the circle.
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP)
perspective projection of the circle
Definition: vpCircle.cpp:239
#define vpDEBUG_ENABLE(level)
Definition: vpDebug.h:538
Implementation of an homogeneous matrix and operations on such kind of matrices.
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:72
vpMatrix L
The interaction matrix.
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true, const bool recopy_=true)
Definition: vpArray2D.h:171
Class to define colors available for display functionnalities.
Definition: vpColor.h:120
vpColVector error
The error vector.
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const vpPoint &_p3, const double r)
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)
Point coordinates conversion from pixel coordinates to normalized coordinates in meter...
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 X coordinate in the object frame.
Definition: vpPoint.cpp:420
Class that defines what is a point.
Definition: vpPoint.h:58
void projection()
Definition: vpCircle.cpp:138
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:108
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
double getB() const
Definition: vpPlane.h:104
Generic class defining intrinsic camera parameters.
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.cpp:424
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpCircle * circle
The circle to track.
static void convertEllipse(const vpCameraParameters &cam, const vpCircle &circle, vpImagePoint &center, double &mu20_p, double &mu11_p, double &mu02_p)
void displayMovingEdges(const vpImage< unsigned char > &I)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
double getA() const
Definition: vpPlane.h:102
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
compute the interaction matrix from a subset a the possible features
double getC() const
Definition: vpPlane.h:106
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
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 what is a circle.
Definition: vpCircle.h:58
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, const unsigned int thickness=1, const bool displayFullModel=false)
unsigned int getRange() const
Definition: vpMe.h:179
vpPoint * p1
The center of the circle.
vpColVector p
Definition: vpTracker.h:71
void setWorldCoordinates(const vpColVector &oP)
Definition: vpCircle.cpp:61
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:241