Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testNurbs.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
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 http://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  * Exemple of a Nurbs curve.
32  *
33  * Authors:
34  * Nicolas Melchior
35  *
36  *****************************************************************************/
43 #include <visp3/core/vpDebug.h>
44 
45 #include <visp3/me/vpNurbs.h>
46 
47 #include <visp3/core/vpImage.h>
48 #include <visp3/io/vpImageIo.h>
49 #include <visp3/core/vpImagePoint.h>
50 #ifdef VISP_HAVE_MODULE_GUI
51 # include <visp3/gui/vpDisplayGTK.h>
52 # include <visp3/gui/vpDisplayGDI.h>
53 # include <visp3/gui/vpDisplayOpenCV.h>
54 # include <visp3/gui/vpDisplayD3D.h>
55 # include <visp3/gui/vpDisplayX.h>
56 #endif
57 
58 #include <visp3/io/vpParseArgv.h>
59 #include <visp3/core/vpIoTools.h>
60 #include <cstdlib>
61 #if defined(VISP_HAVE_DISPLAY)
62 
63 // List of allowed command line options
64 #define GETOPTARGS "cdh"
65 
66 void usage(const char *name, const char *badparam);
67 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
68 
77 void usage(const char *name, const char *badparam)
78 {
79  fprintf(stdout, "\n\
80 Describe a curve thanks to a Nurbs.\n\
81 \n\
82 SYNOPSIS\n\
83  %s [-c] [-d] [-h]\n", name);
84 
85  fprintf(stdout, "\n\
86 OPTIONS: Default\n\
87  -c\n\
88  Disable the mouse click. Useful to automaze the \n\
89  execution of this program without humain intervention.\n\
90 \n\
91  -d \n\
92  Turn off the display.\n\
93 \n\
94  -h\n\
95  Print the help.\n");
96 
97  if (badparam)
98  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
99 }
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': click_allowed = false; break;
122  case 'd': display = false; break;
123  case 'h': usage(argv[0], NULL); return false; break;
124 
125  default:
126  usage(argv[0], optarg_);
127  return false; break;
128  }
129  }
130 
131  if ((c == 1) || (c == -1)) {
132  // standalone param or error
133  usage(argv[0], NULL);
134  std::cerr << "ERROR: " << std::endl;
135  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
136  return false;
137  }
138 
139  return true;
140 }
141 
142 
143 int
144 main(int argc, const char ** argv)
145 {
146  try {
147  bool opt_click_allowed = true;
148  bool opt_display = true;
149 
150  // Read the command line options
151  if (getOptions(argc, argv, opt_click_allowed,
152  opt_display) == false) {
153  exit (-1);
154  }
155 
156  // Declare an image, this is a gray level image (unsigned char)
157  // it size is not defined yet, it will be defined when the image will
158  // read on the disk
159  vpImage<unsigned char> I(540,480);
160  vpImage<unsigned char> I2(540,480);
161  vpImage<unsigned char> I3(540,480);
162 
163  // We open a window using either X11, GTK or GDI.
164 #if defined VISP_HAVE_X11
165  vpDisplayX display[3];
166 #elif defined VISP_HAVE_GDI
167  vpDisplayGDI display[3];
168 #elif defined VISP_HAVE_GTK
169  vpDisplayGTK display[3];
170 #elif defined VISP_HAVE_OPENCV
171  vpDisplayOpenCV display[3];
172 #endif
173 
174  if (opt_display) {
175  // Display size is automatically defined by the image (I) size
176  display[0].init(I, 100, 100,"Points as control points") ;
177  vpDisplay::display(I) ;
178  vpDisplay::flush(I) ;
179  }
180 
181  vpNurbs Nurbs;
182  std::list<double> knots;
183  knots.push_back(0);
184  knots.push_back(0);
185  knots.push_back(0);
186  knots.push_back(1);
187  knots.push_back(2);
188  knots.push_back(3);
189  knots.push_back(4);
190  knots.push_back(4);
191  knots.push_back(5);
192  knots.push_back(5);
193  knots.push_back(5);
194 
195  std::list<vpImagePoint> controlPoints;
196  std::list<double> weights;
197  vpImagePoint pt;
198  pt.set_ij(50,300);
199  controlPoints.push_back(pt);
200  weights.push_back(1);
201  pt.set_ij(100,130);
202  controlPoints.push_back(pt);
203  weights.push_back(5);
204  pt.set_ij(150,400);
205  controlPoints.push_back(pt);
206  weights.push_back(0.2);
207  pt.set_ij(200,370);
208  controlPoints.push_back(pt);
209  weights.push_back(10);
210  pt.set_ij(250,120);
211  controlPoints.push_back(pt);
212  weights.push_back(1);
213  pt.set_ij(300,250);
214  controlPoints.push_back(pt);
215  weights.push_back(2);
216  pt.set_ij(350,200);
217  controlPoints.push_back(pt);
218  weights.push_back(3);
219  pt.set_ij(400,300);
220  controlPoints.push_back(pt);
221  weights.push_back(1);
222 
223  Nurbs.set_p(2);
224  Nurbs.set_knots(knots);
225  Nurbs.set_controlPoints(controlPoints);
226  Nurbs.set_weights(weights);
227 
228  std::cout << "The parameters are :" <<std::endl;
229  std::cout << "p : " << Nurbs.get_p() <<std::endl;
230  std::cout << "" <<std::endl;
231  std::cout << "The knot vector :" <<std::endl;
232  std::list<double> knots_cur;
233  Nurbs.get_knots(knots_cur);
234  unsigned int i_display=0;
235  for(std::list<double>::const_iterator it=knots_cur.begin(); it!=knots_cur.end(); ++it, ++i_display){
236  std::cout << i_display << " ---> " << *it << std::endl;
237  }
238  std::cout << "The control points are :" <<std::endl;
239  std::list<vpImagePoint> controlPoints_cur;
240  Nurbs.get_controlPoints(controlPoints_cur);
241  i_display=0;
242  for(std::list<vpImagePoint>::const_iterator it=controlPoints_cur.begin(); it!=controlPoints_cur.end(); ++it, ++i_display){
243  std::cout << i_display << " ---> " << *it << std::endl;
244  }
245  std::cout << "The associated weights are :" <<std::endl;
246  std::list<double> weights_cur;
247  Nurbs.get_weights(weights_cur);
248  i_display=0;
249  for(std::list<double>::const_iterator it=weights_cur.begin(); it!=weights_cur.end(); ++it, ++i_display){
250  std::cout << i_display << " ---> " << *it << std::endl;
251  }
252 
253  unsigned int i = Nurbs.findSpan(5/2.0);
254  std::cout << "The knot interval number for the value u = 5/2 is : " << i <<std::endl;
255 
256  vpBasisFunction *N = NULL;
257  N = Nurbs.computeBasisFuns(5/2.0);
258  std::cout << "The nonvanishing basis functions N(u=5/2) are :" << std::endl;
259  for (unsigned int j = 0; j < Nurbs.get_p()+1; j++)
260  std::cout << N[j].value << std::endl;
261 
262  vpBasisFunction **N2 = NULL;
263  N2 = Nurbs.computeDersBasisFuns(5/2.0, 2);
264  std::cout << "The first derivatives of the basis functions N'(u=5/2) are :" << std::endl;
265  for (unsigned int j = 0; j < Nurbs.get_p()+1; j++)
266  std::cout << N2[1][j].value << std::endl;
267 
268  std::cout << "The second 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[2][j].value << std::endl;
271 
272  if (opt_display && opt_click_allowed)
273  {
274  double u = 0.0;
275  while (u <= 5)
276  {
277  pt = Nurbs.computeCurvePoint(u);
279  u+=0.01;
280  }
281  for(std::list<vpImagePoint>::const_iterator it=controlPoints.begin(); it!=controlPoints.end(); ++it){
283  }
284 
285  vpDisplay::flush(I) ;
287  }
288 
289  if (opt_display) {
290  try{
291  // Display size is automatically defined by the image (I) size
292  display[1].init(I2, 100, 100,"Points interpolation") ;
293  vpDisplay::display(I2) ;
294  vpDisplay::flush(I2) ;
295  }
296  catch(...)
297  {
298  vpERROR_TRACE("Error while displaying the image") ;
299  exit(-1);
300  }
301  }
302 
303  Nurbs.globalCurveInterp(controlPoints);
304 
305  if (opt_display && opt_click_allowed)
306  {
307  double u = 0.0;
308  while (u <= 1)
309  {
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 
323  if (opt_display) {
324  try{
325  // Display size is automatically defined by the image (I) size
326  display[2].init(I3, 100, 100,"Points approximation") ;
327  vpDisplay::display(I3) ;
328  vpDisplay::flush(I3) ;
329  }
330  catch(...)
331  {
332  vpERROR_TRACE("Error while displaying the image") ;
333  exit(-1);
334  }
335  }
336 
337  Nurbs.globalCurveApprox(controlPoints,5);
338 
339  if (opt_display && opt_click_allowed)
340  {
341  double u = 0.0;
342  while (u <= 1)
343  {
344  pt = Nurbs.computeCurvePoint(u);
346  u+=0.01;
347  }
348 
349  for(std::list<vpImagePoint>::const_iterator it=controlPoints.begin(); it!=controlPoints.end(); ++it){
351  }
352 
353  vpDisplay::flush(I3) ;
355  }
356 
357  if (N != NULL) delete[] N;
358  if (N2 != NULL)
359  {
360  for (int j = 0; j <= 2; j++)
361  delete[] N2[j];
362  delete[] N2;
363  }
364 
365  return 0;
366  }
367  catch(vpException &e) {
368  std::cout << "Catch an exception: " << e << std::endl;
369  return 1;
370  }
371 }
372 
373 #else
374 int main()
375 {
376  std::cout << "This example requires a video device. "
377  << std::endl
378  << "You should install X11, GTK, OpenCV, GDI or Direct3D"
379  << std::endl
380  << "to be able to execute this example."
381  << std::endl;
382  return 0;
383 }
384 #endif
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
void get_controlPoints(std::list< vpImagePoint > &list) const
Definition: vpBSpline.h:130
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:96
#define vpERROR_TRACE
Definition: vpDebug.h:391
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:153
error that can be emited by ViSP classes.
Definition: vpException.h:73
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:695
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
static const vpColor green
Definition: vpColor.h:166
static void flush(const vpImage< unsigned char > &I)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
static const vpColor red
Definition: vpColor.h:163
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:228
static unsigned int findSpan(double l_u, unsigned int l_p, std::vector< double > &l_knots)
Definition: vpBSpline.cpp:88
void get_weights(std::list< double > &list) const
Definition: vpNurbs.h:106
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:164
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:138
unsigned int get_p() const
Definition: vpBSpline.h:123
void set_controlPoints(const std::list< vpImagePoint > &list)
Definition: vpBSpline.h:172
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:872
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
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:117
void get_knots(std::list< double > &list) const
Definition: vpBSpline.h:141
void set_knots(const std::list< double > &list)
Definition: vpBSpline.h:184
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve...
Definition: vpNurbs.h:85
void set_ij(const double ii, const double jj)
Definition: vpImagePoint.h:185