Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
testNurbs.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 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 * Example of a Nurbs curve.
32 */
38
39#include <visp3/core/vpDebug.h>
40
41#include <visp3/me/vpNurbs.h>
42
43#include <visp3/core/vpImage.h>
44#include <visp3/core/vpImagePoint.h>
45#include <visp3/io/vpImageIo.h>
46#ifdef VISP_HAVE_MODULE_GUI
47#include <visp3/gui/vpDisplayD3D.h>
48#include <visp3/gui/vpDisplayGDI.h>
49#include <visp3/gui/vpDisplayGTK.h>
50#include <visp3/gui/vpDisplayOpenCV.h>
51#include <visp3/gui/vpDisplayX.h>
52#endif
53
54#include <cstdlib>
55#include <visp3/core/vpIoTools.h>
56#include <visp3/io/vpParseArgv.h>
57#if defined(VISP_HAVE_DISPLAY) && (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
58
59// List of allowed command line options
60#define GETOPTARGS "cdh"
61
62#ifdef ENABLE_VISP_NAMESPACE
63using namespace VISP_NAMESPACE_NAME;
64#endif
65
66void usage(const char *name, const char *badparam);
67bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
68
77void usage(const char *name, const char *badparam)
78{
79 fprintf(stdout, "\n\
80Describe a curve thanks to a Nurbs.\n\
81\n\
82SYNOPSIS\n\
83 %s [-c] [-d] [-h]\n",
84 name);
85
86 fprintf(stdout, "\n\
87OPTIONS: Default\n\
88 -c\n\
89 Disable the mouse click. Useful to automate the \n\
90 execution of this program without human intervention.\n\
91\n\
92 -d \n\
93 Turn off the display.\n\
94\n\
95 -h\n\
96 Print the help.\n");
97
98 if (badparam)
99 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
100}
101
114bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display)
115{
116 const char *optarg_;
117 int c;
118 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
119
120 switch (c) {
121 case 'c':
122 click_allowed = false;
123 break;
124 case 'd':
125 display = false;
126 break;
127 case 'h':
128 usage(argv[0], nullptr);
129 return false;
130
131 default:
132 usage(argv[0], optarg_);
133 return false;
134 }
135 }
136
137 if ((c == 1) || (c == -1)) {
138 // standalone param or error
139 usage(argv[0], nullptr);
140 std::cerr << "ERROR: " << std::endl;
141 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
142 return false;
143 }
144
145 return true;
146}
147
148int main(int argc, const char **argv)
149{
150 try {
151 bool opt_click_allowed = true;
152 bool opt_display = true;
153
154 // Read the command line options
155 if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
156 return EXIT_FAILURE;
157 }
158
159 // Declare an image, this is a gray level image (unsigned char)
160 // it size is not defined yet, it will be defined when the image will
161 // read on the disk
162 vpImage<unsigned char> I(540, 480);
163 vpImage<unsigned char> I2(540, 480);
164 vpImage<unsigned char> I3(540, 480);
165
166// We open a window using either X11, GTK or GDI.
167#if defined(VISP_HAVE_X11)
168 vpDisplayX display[3];
169#elif defined(VISP_HAVE_GDI)
170 vpDisplayGDI display[3];
171#elif defined(VISP_HAVE_GTK)
172 vpDisplayGTK display[3];
173#elif defined(HAVE_OPENCV_HIGHGUI)
174 vpDisplayOpenCV display[3];
175#endif
176
177 if (opt_display) {
178 // Display size is automatically defined by the image (I) size
179 display[0].init(I, 100, 100, "Points as control points");
182 }
183
184 vpNurbs Nurbs;
185 std::list<double> knots;
186 knots.push_back(0);
187 knots.push_back(0);
188 knots.push_back(0);
189 knots.push_back(1);
190 knots.push_back(2);
191 knots.push_back(3);
192 knots.push_back(4);
193 knots.push_back(4);
194 knots.push_back(5);
195 knots.push_back(5);
196 knots.push_back(5);
197
198 std::list<vpImagePoint> controlPoints;
199 std::list<double> weights;
200 vpImagePoint pt;
201 pt.set_ij(50, 300);
202 controlPoints.push_back(pt);
203 weights.push_back(1);
204 pt.set_ij(100, 130);
205 controlPoints.push_back(pt);
206 weights.push_back(5);
207 pt.set_ij(150, 400);
208 controlPoints.push_back(pt);
209 weights.push_back(0.2);
210 pt.set_ij(200, 370);
211 controlPoints.push_back(pt);
212 weights.push_back(10);
213 pt.set_ij(250, 120);
214 controlPoints.push_back(pt);
215 weights.push_back(1);
216 pt.set_ij(300, 250);
217 controlPoints.push_back(pt);
218 weights.push_back(2);
219 pt.set_ij(350, 200);
220 controlPoints.push_back(pt);
221 weights.push_back(3);
222 pt.set_ij(400, 300);
223 controlPoints.push_back(pt);
224 weights.push_back(1);
225
226 Nurbs.set_p(2);
227 Nurbs.set_knots(knots);
228 Nurbs.set_controlPoints(controlPoints);
229 Nurbs.set_weights(weights);
230
231 std::cout << "The parameters are :" << std::endl;
232 std::cout << "p : " << Nurbs.get_p() << std::endl;
233 std::cout << "" << std::endl;
234 std::cout << "The knot vector :" << std::endl;
235 std::list<double> knots_cur;
236 Nurbs.get_knots(knots_cur);
237 unsigned int i_display = 0;
238 for (std::list<double>::const_iterator it = knots_cur.begin(); it != knots_cur.end(); ++it, ++i_display) {
239 std::cout << i_display << " ---> " << *it << std::endl;
240 }
241 std::cout << "The control points are :" << std::endl;
242 std::list<vpImagePoint> controlPoints_cur;
243 Nurbs.get_controlPoints(controlPoints_cur);
244 i_display = 0;
245 for (std::list<vpImagePoint>::const_iterator it = controlPoints_cur.begin(); it != controlPoints_cur.end();
246 ++it, ++i_display) {
247 std::cout << i_display << " ---> " << *it << std::endl;
248 }
249 std::cout << "The associated weights are :" << std::endl;
250 std::list<double> weights_cur;
251 Nurbs.get_weights(weights_cur);
252 i_display = 0;
253 for (std::list<double>::const_iterator it = weights_cur.begin(); it != weights_cur.end(); ++it, ++i_display) {
254 std::cout << i_display << " ---> " << *it << std::endl;
255 }
256
257 unsigned int i = Nurbs.findSpan(5 / 2.0);
258 std::cout << "The knot interval number for the value u = 5/2 is : " << i << std::endl;
259
260 vpBasisFunction *N = nullptr;
261 N = Nurbs.computeBasisFuns(5 / 2.0);
262 std::cout << "The nonvanishing basis functions N(u=5/2) are :" << std::endl;
263 for (unsigned int j = 0; j < Nurbs.get_p() + 1; j++)
264 std::cout << N[j].value << std::endl;
265
266 vpBasisFunction **N2 = nullptr;
267 N2 = Nurbs.computeDersBasisFuns(5 / 2.0, 2);
268 std::cout << "The first derivatives of the basis functions N'(u=5/2) are :" << std::endl;
269 for (unsigned int j = 0; j < Nurbs.get_p() + 1; j++)
270 std::cout << N2[1][j].value << std::endl;
271
272 std::cout << "The second derivatives of the basis functions N''(u=5/2) are :" << std::endl;
273 for (unsigned int j = 0; j < Nurbs.get_p() + 1; j++)
274 std::cout << N2[2][j].value << std::endl;
275
276 if (opt_display && opt_click_allowed) {
277 double u = 0.0;
278 while (u <= 5) {
279 pt = Nurbs.computeCurvePoint(u);
281 u += 0.01;
282 }
283 for (std::list<vpImagePoint>::const_iterator it = controlPoints.begin(); it != controlPoints.end(); ++it) {
285 }
286
289 }
290
291 if (opt_display) {
292 try {
293 // Display size is automatically defined by the image (I) size
294 display[1].init(I2, 100, 100, "Points interpolation");
297 }
298 catch (...) {
299 vpERROR_TRACE("Error while displaying the image");
300 return EXIT_FAILURE;
301 }
302 }
303
304 Nurbs.globalCurveInterp(controlPoints);
305
306 if (opt_display && opt_click_allowed) {
307 double u = 0.0;
308 while (u <= 1) {
309 pt = Nurbs.computeCurvePoint(u);
311 u += 0.01;
312 }
313
314 for (std::list<vpImagePoint>::const_iterator it = controlPoints.begin(); it != controlPoints.end(); ++it) {
316 }
319 }
320
321 if (opt_display) {
322 try {
323 // Display size is automatically defined by the image (I) size
324 display[2].init(I3, 100, 100, "Points approximation");
327 }
328 catch (...) {
329 vpERROR_TRACE("Error while displaying the image");
330 return EXIT_FAILURE;
331 }
332 }
333
334 Nurbs.globalCurveApprox(controlPoints, 5);
335
336 if (opt_display && opt_click_allowed) {
337 double u = 0.0;
338 while (u <= 1) {
339 pt = Nurbs.computeCurvePoint(u);
341 u += 0.01;
342 }
343
344 for (std::list<vpImagePoint>::const_iterator it = controlPoints.begin(); it != controlPoints.end(); ++it) {
346 }
347
350 }
351
352 if (N != nullptr)
353 delete[] N;
354 if (N2 != nullptr) {
355 for (int j = 0; j <= 2; j++)
356 delete[] N2[j];
357 delete[] N2;
358 }
359
360 return EXIT_SUCCESS;
361 }
362 catch (const vpException &e) {
363 std::cout << "Catch an exception: " << e << std::endl;
364 return EXIT_FAILURE;
365 }
366}
367
368#elif !(defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
369int main()
370{
371 std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
372 return EXIT_SUCCESS;
373}
374#else
375int main()
376{
377 std::cout << "This example requires a video device. " << std::endl
378 << "You should install X11, GTK, OpenCV, GDI or Direct3D" << std::endl
379 << "to be able to execute this example." << std::endl;
380 return EXIT_SUCCESS;
381}
382#endif
void get_controlPoints(std::list< vpImagePoint > &list) const
Definition vpBSpline.h:135
void set_p(unsigned int degree)
Definition vpBSpline.h:175
static unsigned int findSpan(double l_u, unsigned int l_p, const std::vector< double > &l_knots)
Definition vpBSpline.cpp:63
unsigned int get_p() const
Definition vpBSpline.h:127
static vpBasisFunction ** computeDersBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, const std::vector< double > &l_knots)
void set_controlPoints(const std::list< vpImagePoint > &list)
Definition vpBSpline.h:182
void get_knots(std::list< double > &list) const
Definition vpBSpline.h:148
void set_knots(const std::list< double > &list)
Definition vpBSpline.h:195
static vpBasisFunction * computeBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, const std::vector< double > &l_knots)
static const vpColor red
Definition vpColor.h:198
static const vpColor green
Definition vpColor.h:201
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition vpDisplayX.h:135
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
Definition vpException.h:60
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void set_ij(double ii, double jj)
Definition of the vpImage class member functions.
Definition vpImage.h:131
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve.
Definition vpNurbs.h:93
static void globalCurveInterp(std::vector< vpImagePoint > &l_crossingPoints, unsigned int l_p, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
Definition vpNurbs.cpp:466
void get_weights(std::list< double > &list) const
Definition vpNurbs.h:178
static vpImagePoint computeCurvePoint(double l_u, unsigned int l_i, unsigned int l_p, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
Definition vpNurbs.cpp:56
static void globalCurveApprox(std::vector< vpImagePoint > &l_crossingPoints, unsigned int l_p, unsigned int l_n, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
Definition vpNurbs.cpp:595
void set_weights(const std::list< double > &list)
Definition vpNurbs.h:190
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
#define vpERROR_TRACE
Definition vpDebug.h:423