Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpFeatureEllipse.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 * 2D ellipse visual feature.
32 */
33
38
39#include <visp3/visual_features/vpBasicFeature.h>
40#include <visp3/visual_features/vpFeatureEllipse.h>
41
42// Exception
43#include <visp3/core/vpException.h>
44#include <visp3/visual_features/vpFeatureException.h>
45
46// Debug trace
47#include <visp3/core/vpDebug.h>
48
49// math
50#include <visp3/core/vpMath.h>
51
52#include <visp3/core/vpFeatureDisplay.h>
53
54/*
55
56attributes and members directly related to the vpBasicFeature needs
57other functionalities ar useful but not mandatory
58
59*/
60
62
64{
65 // feature dimension
66 dim_s = 5;
67 nbParameters = 8;
68
69 // memory allocation
70 s.resize(dim_s);
71 if (flags == nullptr)
72 flags = new bool[nbParameters];
73 for (unsigned int i = 0; i < nbParameters; i++)
74 flags[i] = false;
75
76 // default depth values
77 A = B = 0;
78 C = 1;
79}
80
81vpFeatureEllipse::vpFeatureEllipse() : A(0), B(0), C(0) { init(); }
82vpFeatureEllipse::vpFeatureEllipse(double x, double y, double n20, double n11, double n02) { this->buildFrom(x, y, n20, n11, n02); }
83
84
87{
88 vpMatrix L;
89
90 L.resize(0, 6);
91
93 for (unsigned int i = 0; i < nbParameters; i++) {
94 if (flags[i] == false) {
95 switch (i) {
96 case 0:
97 vpTRACE("Warning !!! The interaction matrix is computed but x was "
98 "not set yet");
99 break;
100 case 1:
101 vpTRACE("Warning !!! The interaction matrix is computed but y was "
102 "not set yet");
103 break;
104 case 2:
105 vpTRACE("Warning !!! The interaction matrix is computed but n20 "
106 "was not set yet");
107 break;
108 case 3:
109 vpTRACE("Warning !!! The interaction matrix is computed but n11 "
110 "was not set yet");
111 break;
112 case 4:
113 vpTRACE("Warning !!! The interaction matrix is computed but n02 "
114 "was not set yet");
115 break;
116 case 5:
117 vpTRACE("Warning !!! The interaction matrix is computed but A was "
118 "not set yet");
119 break;
120 case 6:
121 vpTRACE("Warning !!! The interaction matrix is computed but B was "
122 "not set yet");
123 break;
124 case 7:
125 vpTRACE("Warning !!! The interaction matrix is computed but C was "
126 "not set yet");
127 break;
128 default:
129 vpTRACE("Problem during the reading of the variable flags");
130 }
131 }
132 }
133 resetFlags();
134 }
135
136 double xc = s[0];
137 double yc = s[1];
138 double n20 = s[2];
139 double n11 = s[3];
140 double n02 = s[4];
141
142 double Zinv = A * xc + B * yc + C;
143
144 if (vpFeatureEllipse::selectX() & select) {
145 vpMatrix H(1, 6);
146 H = 0;
147 // Eq (14) of Chaumette 2004 TRO paper on moments
148 H[0][0] = -Zinv;
149 H[0][1] = 0;
150 H[0][2] = xc * Zinv + 4.0 * (A * n20 + B * n11);
151 H[0][3] = xc * yc + 4.0 * n11;
152 H[0][4] = -1 - vpMath::sqr(xc) - 4.0 * n20;
153 H[0][5] = yc;
154
155 L = vpMatrix::stack(L, H);
156 }
157
158 if (vpFeatureEllipse::selectY() & select) {
159 vpMatrix H(1, 6);
160 H = 0;
161 // Eq (14) of Chaumette 2004 TRO paper on moments
162 H[0][0] = 0;
163 H[0][1] = -Zinv;
164 H[0][2] = yc * Zinv + 4.0 * (A * n11 + B * n02);
165 H[0][3] = 1 + vpMath::sqr(yc) + 4.0 * n02;
166 H[0][4] = -xc * yc - 4.0 * n11;
167 H[0][5] = -xc;
168
169 L = vpMatrix::stack(L, H);
170 }
171
172 if (vpFeatureEllipse::select_n20() & select) {
173 vpMatrix H(1, 6);
174 H = 0;
175 // Eq (26) of Chaumette 2004 TRO paper on moments
176 H[0][0] = -2.0 * (A * n20 + B * n11);
177 H[0][1] = 0;
178 H[0][2] = 2 * ((Zinv + A * xc) * n20 + B * xc * n11);
179 H[0][3] = 2 * (yc * n20 + xc * n11);
180 H[0][4] = -4 * n20 * xc;
181 H[0][5] = 2 * n11;
182
183 L = vpMatrix::stack(L, H);
184 }
185
186 if (vpFeatureEllipse::select_n11() & select) {
187 vpMatrix H(1, 6);
188 H = 0;
189 // Eq (26) of Chaumette 2004 TRO paper on moments
190 H[0][0] = -A * n11 - B * n02;
191 H[0][1] = -A * n20 - B * n11;
192 H[0][2] = A * yc * n20 + (3 * Zinv - C) * n11 + B * xc * n02;
193 H[0][3] = 3 * yc * n11 + xc * n02;
194 H[0][4] = -yc * n20 - 3 * xc * n11;
195 H[0][5] = n02 - n20;
196
197 L = vpMatrix::stack(L, H);
198 }
199
200 if (vpFeatureEllipse::select_n02() & select) {
201 vpMatrix H(1, 6);
202 H = 0;
203 // Eq (26) of Chaumette 2004 TRO paper on moments
204 H[0][0] = 0;
205 H[0][1] = -2 * (A * n11 + B * n02);
206 H[0][2] = 2 * ((Zinv + B * yc) * n02 + A * yc * n11);
207 H[0][3] = 4 * yc * n02;
208 H[0][4] = -2 * (yc * n11 + xc * n02);
209 H[0][5] = -2 * n11;
210 L = vpMatrix::stack(L, H);
211 }
212
213 return L;
214}
215
218vpColVector vpFeatureEllipse::error(const vpBasicFeature &s_star, unsigned int select)
219{
220 vpColVector e(0);
221
222 try {
223 if (vpFeatureEllipse::selectX() & select) {
224 vpColVector ex(1);
225 ex[0] = s[0] - s_star[0];
226
227 e = vpColVector::stack(e, ex);
228 }
229
230 if (vpFeatureEllipse::selectY() & select) {
231 vpColVector ey(1);
232 ey[0] = s[1] - s_star[1];
233 e = vpColVector::stack(e, ey);
234 }
235
236 if (vpFeatureEllipse::select_n20() & select) {
237 vpColVector ex(1);
238 ex[0] = s[2] - s_star[2];
239
240 e = vpColVector::stack(e, ex);
241 }
242
243 if (vpFeatureEllipse::select_n11() & select) {
244 vpColVector ey(1);
245 ey[0] = s[3] - s_star[3];
246 e = vpColVector::stack(e, ey);
247 }
248
249 if (vpFeatureEllipse::select_n02() & select) {
250 vpColVector ey(1);
251 ey[0] = s[4] - s_star[4];
252 e = vpColVector::stack(e, ey);
253 }
254
255 }
256 catch (...) {
257 throw;
258 }
259
260 return e;
261}
262
263void vpFeatureEllipse::print(unsigned int select) const
264{
265
266 std::cout << "Ellipse: " << std::endl;
267 if (vpFeatureEllipse::selectX() & select)
268 std::cout << " x=" << s[0] << std::endl;
269 if (vpFeatureEllipse::selectY() & select)
270 std::cout << " y=" << s[1] << std::endl;
271 if (vpFeatureEllipse::select_n20() & select)
272 std::cout << " n20=" << s[2] << std::endl;
273 if (vpFeatureEllipse::select_n11() & select)
274 std::cout << " n11=" << s[3] << std::endl;
275 if (vpFeatureEllipse::select_n02() & select)
276 std::cout << " n02=" << s[4] << std::endl;
277 std::cout << "A = " << A << " B = " << B << " C = " << C << std::endl;
278}
279
280vpFeatureEllipse &vpFeatureEllipse::buildFrom(const double &x, const double &y, const double &n20, const double &n11, const double &n02)
281{
282 s[0] = x;
283 s[1] = y;
284 s[2] = n20;
285 s[3] = n11;
286 s[4] = n02;
287
288 for (int i = 0; i < 5; ++i) {
289 flags[i] = true;
290 }
291 return *this;
292}
293
294vpFeatureEllipse &vpFeatureEllipse::buildFrom(const double &x, const double &y, const double &n20, const double &n11, const double &n02, const double &a, const double &b, const double &c)
295{
296 s[0] = x;
297 s[1] = y;
298 s[2] = n20;
299 s[3] = n11;
300 s[4] = n02;
301
302 this->A = a;
303 this->B = b;
304 this->C = c;
305
306 for (unsigned int i = 0; i < nbParameters; ++i) {
307 flags[i] = true;
308 }
309 return *this;
310}
311
313{
314 s[0] = x;
315 flags[0] = true;
316}
317
319{
320 s[1] = y;
321 flags[1] = true;
322}
323
324void vpFeatureEllipse::set_xy(double x, double y)
325{
326 s[0] = x;
327 s[1] = y;
328 for (int i = 0; i < 2; i++)
329 flags[i] = true;
330}
331
332void vpFeatureEllipse::setABC(double a, double b, double c)
333{
334 this->A = a;
335 this->B = b;
336 this->C = c;
337 for (unsigned int i = 5; i < nbParameters; i++)
338 flags[i] = true;
339}
340
349void vpFeatureEllipse::setMoments(double n20, double n11, double n02)
350{
351 s[2] = n20;
352 s[3] = n11;
353 s[4] = n02;
354 for (int i = 2; i < 5; i++)
355 flags[i] = true;
356}
357
358#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
365void vpFeatureEllipse::setMu(double mu20, double mu11, double mu02) { setMoments(mu20, mu11, mu02); }
366#endif
367
378 unsigned int thickness) const
379{
380 double x = s[0];
381 double y = s[1];
382
383 double n20 = s[2];
384 double n11 = s[3];
385 double n02 = s[4];
386
387 vpFeatureDisplay::displayEllipse(x, y, n20, n11, n02, cam, I, color, thickness);
388}
389
400 unsigned int thickness) const
401{
402 double x = s[0];
403 double y = s[1];
404
405 double n20 = s[2];
406 double n11 = s[3];
407 double n02 = s[4];
408
409 vpFeatureDisplay::displayEllipse(x, y, n20, n11, n02, cam, I, color, thickness);
410}
411
414{
415 vpFeatureEllipse *feature = new vpFeatureEllipse;
416 return feature;
417}
418
422unsigned int vpFeatureEllipse::selectX() { return FEATURE_LINE[0]; }
426unsigned int vpFeatureEllipse::selectY() { return FEATURE_LINE[1]; }
427
432unsigned int vpFeatureEllipse::select_n20() { return FEATURE_LINE[2]; }
437unsigned int vpFeatureEllipse::select_n11() { return FEATURE_LINE[3]; }
442unsigned int vpFeatureEllipse::select_n02() { return FEATURE_LINE[4]; }
443
444#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
451VP_DEPRECATED unsigned int vpFeatureEllipse::selectMu20() { return FEATURE_LINE[2]; }
458VP_DEPRECATED unsigned int vpFeatureEllipse::selectMu11() { return FEATURE_LINE[3]; }
465VP_DEPRECATED unsigned int vpFeatureEllipse::selectMu02() { return FEATURE_LINE[4]; }
466#endif
467END_VISP_NAMESPACE
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition vpArray2D.h:448
vpColVector s
State of the visual feature.
unsigned int nbParameters
Number of parameters needed to compute the interaction matrix.
unsigned int dim_s
Dimension of the visual feature.
static const unsigned int FEATURE_LINE[32]
vpBasicFeatureDeallocatorType deallocate
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
void stack(double d)
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
static void displayEllipse(double x, double y, double n20, double n11, double n02, const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpColor &color=vpColor::green, unsigned int thickness=1)
static VP_DEPRECATED unsigned int selectMu20()
void print(unsigned int select=FEATURE_ALL) const VP_OVERRIDE
Print the name of the feature.
static unsigned int selectX()
vpFeatureEllipse & buildFrom(const double &x, const double &y, const double &n20, const double &n11, const double &n02)
void init() VP_OVERRIDE
Default initialization.
static VP_DEPRECATED unsigned int selectMu02()
vpFeatureEllipse()
Default constructor.
void display(const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpColor &color=vpColor::green, unsigned int thickness=1) const VP_OVERRIDE
static unsigned int selectY()
void setABC(double A, double B, double C)
vpFeatureEllipse * duplicate() const VP_OVERRIDE
Feature duplication.
VP_DEPRECATED void setMu(double mu20, double mu11, double mu02)
static unsigned int select_n20()
static VP_DEPRECATED unsigned int selectMu11()
void setMoments(double n20, double n11, double n02)
vpMatrix interaction(unsigned int select=FEATURE_ALL) VP_OVERRIDE
compute the interaction matrix from a subset a the possible features
static unsigned int select_n02()
static unsigned int select_n11()
vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL) VP_OVERRIDE
void set_xy(double x, double y)
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 stack(const vpMatrix &A)
#define vpTRACE
Definition vpDebug.h:450