Visual Servoing Platform version 3.5.0
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
91void vpMbtDistanceCircle::project(const vpHomogeneousMatrix &cMo) { circle->project(cMo); }
92
103void 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 {
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 {
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
313std::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 {
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))
397 }
398}
399
401{
402 if (meEllipse != NULL) {
403 meEllipse->display(I); // display the me
404 if (vpDEBUG_ENABLE(3))
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 {
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}
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:304
Generic class defining intrinsic camera parameters.
Class that defines a 3D circle in the object frame and allows forward projection of a 3D circle in th...
Definition: vpCircle.h:92
void changeFrame(const vpHomogeneousMatrix &noMo, vpColVector &noP) const
Definition: vpCircle.cpp:248
void setWorldCoordinates(const vpColVector &oP)
Definition: vpCircle.cpp:60
void projection()
Definition: vpCircle.cpp:140
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:310
Class to define RGB colors available for display functionnalities.
Definition: vpColor.h:158
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)
static void flush(const vpImage< unsigned char > &I)
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
vpMatrix interaction(unsigned int select=FEATURE_ALL)
compute the interaction matrix from a subset a the possible features
Implementation of an homogeneous matrix and operations on such kind of matrices.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
double get_j() const
Definition: vpImagePoint.h:214
double get_i() const
Definition: vpImagePoint.h:203
static double sqr(double x)
Definition: vpMath.h:116
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:154
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
std::vector< std::vector< double > > getFeaturesForDisplay()
vpColVector error
The error vector.
vpPoint * p1
The center of the circle.
unsigned int nbFeature
The number of moving edges.
vpMatrix L
The interaction matrix.
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpImage< bool > *mask=NULL)
vpCircle * circle
The circle to track.
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, const vpPoint &_p3, double r)
vpPoint * p2
A point on the plane containing the circle.
bool isvisible
Indicates if the circle is visible or not.
void displayMovingEdges(const vpImage< unsigned char > &I)
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false)
bool Reinit
Indicates if the circle has to be reinitialized.
double radius
The radius of the circle.
vpPoint * p3
An other point on the plane containing the circle.
std::vector< double > getModelForDisplay(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false)
vpMbtMeEllipse * meEllipse
The moving edge containers.
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=NULL)
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition: vpMeSite.h:72
vpMeSiteState getState() const
Definition: vpMeSite.h:190
double get_ifloat() const
Definition: vpMeSite.h:160
double get_jfloat() const
Definition: vpMeSite.h:167
Definition: vpMe.h:61
unsigned int getRange() const
Definition: vpMe.h:179
static void convertEllipse(const vpCameraParameters &cam, const vpSphere &sphere, vpImagePoint &center_p, double &n20_p, double &n11_p, double &n02_p)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
This class defines the container for a plane geometrical structure.
Definition: vpPlane.h:59
@ object_frame
Definition: vpPlane.h:70
double getA() const
Definition: vpPlane.h:102
double getC() const
Definition: vpPlane.h:106
double getB() const
Definition: vpPlane.h:104
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:82
double get_oX() const
Get the point oX coordinate in the object frame.
Definition: vpPoint.cpp:461
double get_oZ() const
Get the point oZ coordinate in the object frame.
Definition: vpPoint.cpp:465
double get_oY() const
Get the point oY coordinate in the object frame.
Definition: vpPoint.cpp:463
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:116
vpColVector p
Definition: vpTracker.h:73
#define vpDEBUG_ENABLE(level)
Definition: vpDebug.h:538