Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
testNurbs.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  * Exemple of a Nurbs curve.
33  *
34  * Authors:
35  * Nicolas Melchior
36  *
37  *****************************************************************************/
44 #include <visp3/core/vpDebug.h>
45 
46 #include <visp3/me/vpNurbs.h>
47 
48 #include <visp3/core/vpImage.h>
49 #include <visp3/core/vpImagePoint.h>
50 #include <visp3/io/vpImageIo.h>
51 #ifdef VISP_HAVE_MODULE_GUI
52 #include <visp3/gui/vpDisplayD3D.h>
53 #include <visp3/gui/vpDisplayGDI.h>
54 #include <visp3/gui/vpDisplayGTK.h>
55 #include <visp3/gui/vpDisplayOpenCV.h>
56 #include <visp3/gui/vpDisplayX.h>
57 #endif
58 
59 #include <cstdlib>
60 #include <visp3/core/vpIoTools.h>
61 #include <visp3/io/vpParseArgv.h>
62 #if defined(VISP_HAVE_DISPLAY)
63 
64 // List of allowed command line options
65 #define GETOPTARGS "cdh"
66 
67 void usage(const char *name, const char *badparam);
68 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
69 
78 void usage(const char *name, const char *badparam)
79 {
80  fprintf(stdout, "\n\
81 Describe a curve thanks to a Nurbs.\n\
82 \n\
83 SYNOPSIS\n\
84  %s [-c] [-d] [-h]\n", name);
85 
86  fprintf(stdout, "\n\
87 OPTIONS: Default\n\
88  -c\n\
89  Disable the mouse click. Useful to automaze the \n\
90  execution of this program without humain 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 
114 bool 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], NULL);
129  return false;
130  break;
131 
132  default:
133  usage(argv[0], optarg_);
134  return false;
135  break;
136  }
137  }
138 
139  if ((c == 1) || (c == -1)) {
140  // standalone param or error
141  usage(argv[0], NULL);
142  std::cerr << "ERROR: " << std::endl;
143  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
144  return false;
145  }
146 
147  return true;
148 }
149 
150 int main(int argc, const char **argv)
151 {
152  try {
153  bool opt_click_allowed = true;
154  bool opt_display = true;
155 
156  // Read the command line options
157  if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
158  exit(-1);
159  }
160 
161  // Declare an image, this is a gray level image (unsigned char)
162  // it size is not defined yet, it will be defined when the image will
163  // read on the disk
164  vpImage<unsigned char> I(540, 480);
165  vpImage<unsigned char> I2(540, 480);
166  vpImage<unsigned char> I3(540, 480);
167 
168 // We open a window using either X11, GTK or GDI.
169 #if defined VISP_HAVE_X11
170  vpDisplayX display[3];
171 #elif defined VISP_HAVE_GDI
172  vpDisplayGDI display[3];
173 #elif defined VISP_HAVE_GTK
174  vpDisplayGTK display[3];
175 #elif defined VISP_HAVE_OPENCV
176  vpDisplayOpenCV display[3];
177 #endif
178 
179  if (opt_display) {
180  // Display size is automatically defined by the image (I) size
181  display[0].init(I, 100, 100, "Points as control points");
183  vpDisplay::flush(I);
184  }
185 
186  vpNurbs Nurbs;
187  std::list<double> knots;
188  knots.push_back(0);
189  knots.push_back(0);
190  knots.push_back(0);
191  knots.push_back(1);
192  knots.push_back(2);
193  knots.push_back(3);
194  knots.push_back(4);
195  knots.push_back(4);
196  knots.push_back(5);
197  knots.push_back(5);
198  knots.push_back(5);
199 
200  std::list<vpImagePoint> controlPoints;
201  std::list<double> weights;
202  vpImagePoint pt;
203  pt.set_ij(50, 300);
204  controlPoints.push_back(pt);
205  weights.push_back(1);
206  pt.set_ij(100, 130);
207  controlPoints.push_back(pt);
208  weights.push_back(5);
209  pt.set_ij(150, 400);
210  controlPoints.push_back(pt);
211  weights.push_back(0.2);
212  pt.set_ij(200, 370);
213  controlPoints.push_back(pt);
214  weights.push_back(10);
215  pt.set_ij(250, 120);
216  controlPoints.push_back(pt);
217  weights.push_back(1);
218  pt.set_ij(300, 250);
219  controlPoints.push_back(pt);
220  weights.push_back(2);
221  pt.set_ij(350, 200);
222  controlPoints.push_back(pt);
223  weights.push_back(3);
224  pt.set_ij(400, 300);
225  controlPoints.push_back(pt);
226  weights.push_back(1);
227 
228  Nurbs.set_p(2);
229  Nurbs.set_knots(knots);
230  Nurbs.set_controlPoints(controlPoints);
231  Nurbs.set_weights(weights);
232 
233  std::cout << "The parameters are :" << std::endl;
234  std::cout << "p : " << Nurbs.get_p() << std::endl;
235  std::cout << "" << std::endl;
236  std::cout << "The knot vector :" << std::endl;
237  std::list<double> knots_cur;
238  Nurbs.get_knots(knots_cur);
239  unsigned int i_display = 0;
240  for (std::list<double>::const_iterator it = knots_cur.begin(); it != knots_cur.end(); ++it, ++i_display) {
241  std::cout << i_display << " ---> " << *it << std::endl;
242  }
243  std::cout << "The control points are :" << std::endl;
244  std::list<vpImagePoint> controlPoints_cur;
245  Nurbs.get_controlPoints(controlPoints_cur);
246  i_display = 0;
247  for (std::list<vpImagePoint>::const_iterator it = controlPoints_cur.begin(); it != controlPoints_cur.end();
248  ++it, ++i_display) {
249  std::cout << i_display << " ---> " << *it << std::endl;
250  }
251  std::cout << "The associated weights are :" << std::endl;
252  std::list<double> weights_cur;
253  Nurbs.get_weights(weights_cur);
254  i_display = 0;
255  for (std::list<double>::const_iterator it = weights_cur.begin(); it != weights_cur.end(); ++it, ++i_display) {
256  std::cout << i_display << " ---> " << *it << std::endl;
257  }
258 
259  unsigned int i = Nurbs.findSpan(5 / 2.0);
260  std::cout << "The knot interval number for the value u = 5/2 is : " << i << std::endl;
261 
262  vpBasisFunction *N = NULL;
263  N = Nurbs.computeBasisFuns(5 / 2.0);
264  std::cout << "The nonvanishing basis functions N(u=5/2) are :" << std::endl;
265  for (unsigned int j = 0; j < Nurbs.get_p() + 1; j++)
266  std::cout << N[j].value << std::endl;
267 
268  vpBasisFunction **N2 = NULL;
269  N2 = Nurbs.computeDersBasisFuns(5 / 2.0, 2);
270  std::cout << "The first derivatives of the basis functions N'(u=5/2) are :" << std::endl;
271  for (unsigned int j = 0; j < Nurbs.get_p() + 1; j++)
272  std::cout << N2[1][j].value << std::endl;
273 
274  std::cout << "The second derivatives of the basis functions N''(u=5/2) are :" << std::endl;
275  for (unsigned int j = 0; j < Nurbs.get_p() + 1; j++)
276  std::cout << N2[2][j].value << std::endl;
277 
278  if (opt_display && opt_click_allowed) {
279  double u = 0.0;
280  while (u <= 5) {
281  pt = Nurbs.computeCurvePoint(u);
283  u += 0.01;
284  }
285  for (std::list<vpImagePoint>::const_iterator it = controlPoints.begin(); it != controlPoints.end(); ++it) {
287  }
288 
289  vpDisplay::flush(I);
291  }
292 
293  if (opt_display) {
294  try {
295  // Display size is automatically defined by the image (I) size
296  display[1].init(I2, 100, 100, "Points interpolation");
297  vpDisplay::display(I2);
298  vpDisplay::flush(I2);
299  } catch (...) {
300  vpERROR_TRACE("Error while displaying the image");
301  exit(-1);
302  }
303  }
304 
305  Nurbs.globalCurveInterp(controlPoints);
306 
307  if (opt_display && opt_click_allowed) {
308  double u = 0.0;
309  while (u <= 1) {
310  pt = Nurbs.computeCurvePoint(u);
312  u += 0.01;
313  }
314 
315  for (std::list<vpImagePoint>::const_iterator it = controlPoints.begin(); it != controlPoints.end(); ++it) {
317  }
318  vpDisplay::flush(I2);
320  }
321 
322  if (opt_display) {
323  try {
324  // Display size is automatically defined by the image (I) size
325  display[2].init(I3, 100, 100, "Points approximation");
326  vpDisplay::display(I3);
327  vpDisplay::flush(I3);
328  } catch (...) {
329  vpERROR_TRACE("Error while displaying the image");
330  exit(-1);
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 
348  vpDisplay::flush(I3);
350  }
351 
352  if (N != NULL)
353  delete[] N;
354  if (N2 != NULL) {
355  for (int j = 0; j <= 2; j++)
356  delete[] N2[j];
357  delete[] N2;
358  }
359 
360  return 0;
361  } catch (const vpException &e) {
362  std::cout << "Catch an exception: " << e << std::endl;
363  return 1;
364  }
365 }
366 
367 #else
368 int main()
369 {
370  std::cout << "This example requires a video device. " << std::endl
371  << "You should install X11, GTK, OpenCV, GDI or Direct3D" << std::endl
372  << "to be able to execute this example." << std::endl;
373  return 0;
374 }
375 #endif
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
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:85
#define vpERROR_TRACE
Definition: vpDebug.h:393
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:150
error that can be emited by ViSP classes.
Definition: vpException.h:71
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:685
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
static const vpColor green
Definition: vpColor.h:182
static void flush(const vpImage< unsigned char > &I)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
static const vpColor red
Definition: vpColor.h:179
unsigned int get_p() const
Definition: vpBSpline.h:132
static vpBasisFunction ** computeDersBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, std::vector< double > &l_knots)
Definition: vpBSpline.cpp:234
static unsigned int findSpan(double l_u, unsigned int l_p, std::vector< double > &l_knots)
Definition: vpBSpline.cpp:84
void get_controlPoints(std::list< vpImagePoint > &list) const
Definition: vpBSpline.h:140
void get_weights(std::list< double > &list) const
Definition: vpNurbs.h:120
static void display(const vpImage< unsigned char > &I)
static vpBasisFunction * computeBasisFuns(double l_u, unsigned int l_i, unsigned int l_p, std::vector< double > &l_knots)
Definition: vpBSpline.cpp:148
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
void set_p(unsigned int degree)
Definition: vpBSpline.h:180
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:137
void set_controlPoints(const std::list< vpImagePoint > &list)
Definition: vpBSpline.h:187
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:866
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
void set_ij(double ii, double jj)
Definition: vpImagePoint.h:189
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void set_weights(const std::list< double > &list)
Definition: vpNurbs.h:132
void set_knots(const std::list< double > &list)
Definition: vpBSpline.h:200
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve...
Definition: vpNurbs.h:97
void get_knots(std::list< double > &list) const
Definition: vpBSpline.h:153