Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMbtDistanceCircle.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Make the complete tracking of an object by using its CAD model. Circle
32 * tracking.
33 */
34
35#include <visp3/core/vpConfig.h>
36
41
42#include <algorithm>
43#include <stdlib.h>
44
45#include <visp3/core/vpMeterPixelConversion.h>
46#include <visp3/core/vpPixelMeterConversion.h>
47#include <visp3/core/vpPlane.h>
48#include <visp3/mbt/vpMbtDistanceCircle.h>
49#include <visp3/vision/vpPose.h>
50#include <visp3/visual_features/vpFeatureBuilder.h>
51#include <visp3/visual_features/vpFeatureEllipse.h>
52
54namespace
55{
56const unsigned int defaultRange = 1U;
57}
58
63 : name(), index(0), cam(), me(nullptr), wmean(1), featureEllipse(), isTrackedCircle(true), meEllipse(nullptr), circle(nullptr),
64 radius(0.), p1(nullptr), p2(nullptr), p3(nullptr), L(), error(), nbFeature(0), Reinit(false), hiddenface(nullptr),
65 index_polygon(-1), isvisible(false)
66{ }
67
72{
73 if (meEllipse != nullptr)
74 delete meEllipse;
75 if (circle != nullptr)
76 delete circle;
77 if (p1 != nullptr)
78 delete p1;
79 if (p2 != nullptr)
80 delete p2;
81 if (p3 != nullptr)
82 delete p3;
83}
84
91void vpMbtDistanceCircle::project(const vpHomogeneousMatrix &cMo) { circle->project(cMo); }
92
105void vpMbtDistanceCircle::buildFrom(const vpPoint &_p1, const vpPoint &_p2, const vpPoint &_p3, double r)
106{
107 circle = new vpCircle;
108 p1 = new vpPoint;
109 p2 = new vpPoint;
110 p3 = new vpPoint;
111
112 // Get the points
113 *p1 = _p1;
114 *p2 = _p2;
115 *p3 = _p3;
116
117 // Get the radius
118 radius = r;
119
120 vpPlane plane(*p1, *p2, *p3, vpPlane::object_frame);
121
122 // Build our circle
123 circle->setWorldCoordinates(plane.getA(), plane.getB(), plane.getC(), _p1.get_oX(), _p1.get_oY(), _p1.get_oZ(), r);
124}
125
132{
133 me = _me;
134 if (meEllipse != nullptr) {
135 meEllipse->setMe(me);
136 }
137}
138
153 bool doNotTrack, const vpImage<bool> *mask, const int &initRange)
154{
155 if (isvisible) {
156 // Perspective projection
157 circle->changeFrame(cMo);
158
159 try {
160 circle->projection();
161 }
162 catch (...) {
163 std::cout << "Problem when projecting circle\n";
164 return false;
165 }
166
167 // Create the moving edges containers
168 unsigned int initRange_;
169 if (initRange < 0) {
170 initRange_ = defaultRange;
171 }
172 else {
173 initRange_ = static_cast<unsigned int>(initRange);
174 }
175
176 meEllipse = new vpMbtMeEllipse;
177 meEllipse->setMask(*mask);
178 meEllipse->setMe(me);
179 int oldInitRange = me->getInitRange();
180 me->setInitRange(initRange_);
181
182 // meEllipse->setDisplay(vpMeSite::RANGE_RESULT) ; // TODO only for debug
183
184 try {
185 vpImagePoint ic;
186 double n20_p, n11_p, n02_p;
187 vpMeterPixelConversion::convertEllipse(cam, *circle, ic, n20_p, n11_p, n02_p);
188 meEllipse->initTracking(I, ic, n20_p, n11_p, n02_p, doNotTrack);
189 me->setInitRange(oldInitRange);
190 }
191 catch (...) {
192 // vpTRACE("the circle can't be initialized");
193 me->setInitRange(oldInitRange);
194 return false;
195 }
196 }
197 return true;
198}
199
207{
208 (void)cMo;
209 int oldInitRange = me->getInitRange();
210 me->setInitRange(defaultRange);
211 if (isvisible) {
212 try {
213 meEllipse->track(I);
214 }
215 catch (...) {
216 // std::cout << "Track meEllipse failed" << std::endl;
217 meEllipse->reset();
218 Reinit = true;
219 }
220
221 // Update the number of features
222 nbFeature = static_cast<unsigned int>(meEllipse->getMeList().size());
223 }
224 me->setInitRange(oldInitRange);
225}
226
236{
237 int oldInitRange = me->getInitRange();
238 me->setInitRange(defaultRange);
239 if (isvisible) {
240 // Perspective projection
241 circle->changeFrame(cMo);
242
243 try {
244 circle->projection();
245 }
246 catch (...) {
247 std::cout << "Problem when projecting circle\n";
248 }
249
250 try {
251 vpImagePoint ic;
252 double n20_p, n11_p, n02_p;
253 vpMeterPixelConversion::convertEllipse(cam, *circle, ic, n20_p, n11_p, n02_p);
254 meEllipse->updateParameters(I, ic, n20_p, n11_p, n02_p);
255 }
256 catch (...) {
257 Reinit = true;
258 }
259 nbFeature = static_cast<unsigned int>(meEllipse->getMeList().size());
260 }
261 me->setInitRange(oldInitRange);
262}
263
276 const vpImage<bool> *mask)
277{
278 if (meEllipse != nullptr)
279 delete meEllipse;
280
281 meEllipse = nullptr;
282
283 if (!initMovingEdge(I, cMo, false, mask))
284 Reinit = true;
285
286 Reinit = false;
287}
288
301 const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
302 bool displayFullModel)
303{
304 std::vector<double> params = getModelForDisplay(cMo, camera, displayFullModel);
305
306 vpImagePoint center(params[0], params[1]);
307 double n20_p = params[2];
308 double n11_p = params[3];
309 double n02_p = params[4];
310 vpDisplay::displayEllipse(I, center, n20_p, n11_p, n02_p, true, col, thickness);
311}
312
325 const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
326 bool displayFullModel)
327{
328 std::vector<double> params = getModelForDisplay(cMo, camera, displayFullModel);
329
330 vpImagePoint center(params[1], params[2]);
331 double n20_p = params[3];
332 double n11_p = params[4];
333 double n02_p = params[5];
334 vpDisplay::displayEllipse(I, center, n20_p, n11_p, n02_p, true, col, thickness);
335}
336
341std::vector<std::vector<double> > vpMbtDistanceCircle::getFeaturesForDisplay()
342{
343 std::vector<std::vector<double> > features;
344
345 if (meEllipse != nullptr) {
346 for (std::list<vpMeSite>::const_iterator it = meEllipse->getMeList().begin(); it != meEllipse->getMeList().end();
347 ++it) {
348 vpMeSite p_me = *it;
349#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
350 std::vector<double> params = { 0, //ME
351 p_me.get_ifloat(),
352 p_me.get_jfloat(),
353 static_cast<double>(p_me.getState())
354 };
355#else
356 std::vector<double> params;
357 params.push_back(0); //ME
358 params.push_back(p_me.get_ifloat());
359 params.push_back(p_me.get_jfloat());
360 params.push_back(static_cast<double>(p_me.getState()));
361#endif
362
363 features.push_back(params);
364 }
365 }
366
367 return features;
368}
369
382 const vpCameraParameters &camera, bool displayFullModel)
383{
384 std::vector<double> params;
385
386 if ((isvisible && isTrackedCircle) || displayFullModel) {
387 // Perspective projection
388 circle->changeFrame(cMo);
389
390 try {
391 circle->projection();
392 }
393 catch (...) {
394 std::cout << "Cannot project the circle";
395 }
396
397 vpImagePoint center;
398 double n20_p, n11_p, n02_p;
399 vpMeterPixelConversion::convertEllipse(camera, *circle, center, n20_p, n11_p, n02_p);
400 params.push_back(1); // 1 for ellipse parameters
401 params.push_back(center.get_i());
402 params.push_back(center.get_j());
403 params.push_back(n20_p);
404 params.push_back(n11_p);
405 params.push_back(n02_p);
406 }
407
408 return params;
409}
410
423{
424 if (meEllipse != nullptr) {
425 meEllipse->display(I); // display the me
426 if (vpDEBUG_ENABLE(3))
428 }
429}
430
432{
433 if (meEllipse != nullptr) {
434 meEllipse->display(I); // display the me
435 if (vpDEBUG_ENABLE(3))
437 }
438}
439
444{
445 if (isvisible) {
446 nbFeature = static_cast<unsigned int>(meEllipse->getMeList().size());
447 L.resize(nbFeature, 6);
448 error.resize(nbFeature);
449 }
450 else
451 nbFeature = 0;
452}
453
459{
460 if (isvisible) {
461 // Perspective projection
462 circle->changeFrame(cMo);
463 try {
464 circle->projection();
465 }
466 catch (...) {
467 std::cout << "Problem projection circle\n";
468 }
469
470 vpFeatureBuilder::create(featureEllipse, *circle);
471
472 vpMatrix H1 = featureEllipse.interaction();
473
474 vpRowVector H(5);
475 double x = 0, y = 0;
476
477 // Get the parameters of the ellipse in the image plane
478 double xg = circle->p[0];
479 double yg = circle->p[1];
480 double n20 = circle->p[2];
481 double n11 = circle->p[3];
482 double n02 = circle->p[4];
483
484 unsigned int j = 0;
485
486 for (std::list<vpMeSite>::const_iterator it = meEllipse->getMeList().begin(); it != meEllipse->getMeList().end();
487 ++it) {
488 vpPixelMeterConversion::convertPoint(cam, it->m_j, it->m_i, x, y);
489 // TRO Chaumette 2004 eq 25
490 H[0] = 2 * (n11 * (y - yg) + n02 * (xg - x));
491 H[1] = 2 * (n20 * (yg - y) + n11 * (x - xg));
492 H[2] = vpMath::sqr(y - yg) - 4.0 * n02;
493 H[3] = 2 * (yg * (x - xg) + y * xg + 4.0 * n11 - x * y);
494 H[4] = vpMath::sqr(x - xg) - 4.0 * n20;
495
496 for (unsigned int k = 0; k < 6; k++)
497 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];
498
499 error[j] = n02 * vpMath::sqr(x) + n20 * vpMath::sqr(y) - 2 * n11 * x * y + 2 * (n11 * yg - n02 * xg) * x +
500 2 * (n11 * xg - n20 * yg) * y + n02 * vpMath::sqr(xg) + n20 * vpMath::sqr(yg) - 2 * n11 * xg * yg +
501 4.0 * vpMath::sqr(n11) - 4.0 * n20 * n02;
502 j++;
503 }
504 }
505}
506END_VISP_NAMESPACE
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:87
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
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)
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 ...
double get_j() const
double get_i() const
Definition of the vpImage class member functions.
Definition vpImage.h:131
static double sqr(double x)
Definition vpMath.h:203
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
std::vector< std::vector< double > > getFeaturesForDisplay()
vpColVector error
The error vector.
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
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)
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.
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpImage< bool > *mask=nullptr)
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=nullptr, const int &initRange=1U)
double radius
The radius of the circle.
int index_polygon
Index of the faces which contain the line.
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.
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition vpMeSite.h:75
vpMeSiteState getState() const
Definition vpMeSite.h:306
double get_ifloat() const
Definition vpMeSite.h:212
double get_jfloat() const
Definition vpMeSite.h:218
Definition vpMe.h:143
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:56
@ object_frame
Definition vpPlane.h:64
double getA() const
Definition vpPlane.h:100
double getC() const
Definition vpPlane.h:104
double getB() const
Definition vpPlane.h:102
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
double get_oX() const
Get the point oX coordinate in the object frame.
Definition vpPoint.cpp:418
double get_oZ() const
Get the point oZ coordinate in the object frame.
Definition vpPoint.cpp:422
double get_oY() const
Get the point oY coordinate in the object frame.
Definition vpPoint.cpp:420
Implementation of row vector and the associated operations.
#define vpDEBUG_ENABLE(level)
Definition vpDebug.h:585
const unsigned int defaultRange