Visual Servoing Platform  version 3.0.1
displayD3D.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  * Windows' D3D Display Test
32  *
33  * Authors:
34  * Bruno Renier
35  * Anthony Saunier
36  *
37  *****************************************************************************/
47 #include <visp3/core/vpDebug.h>
48 #include <visp3/core/vpConfig.h>
49 
50 #if ( defined(VISP_HAVE_D3D9) )
51 
52 #include <visp3/gui/vpDisplayD3D.h>
53 
54 #include <visp3/core/vpImage.h>
55 #include <visp3/io/vpImageIo.h>
56 #include <visp3/io/vpParseArgv.h>
57 #include <visp3/core/vpIoTools.h>
58 
68 // List of allowed command line options
69 #define GETOPTARGS "cdi:o:h"
70 
84 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
85 {
86  fprintf(stdout, "\n\
87 Read an image on the disk, display it using D3D, display some\n\
88 features (line, circle, caracters) in overlay and finaly write \n\
89 the image and the overlayed features in an image on the disk\n\
90 \n\
91 SYNOPSIS\n\
92  %s [-i <input image path>] [-o <output image path>]\n\
93  [-c] [-d] [-h]\n \
94 ", name);
95 
96  fprintf(stdout, "\n\
97 OPTIONS: Default\n\
98  -i <input image path> %s\n\
99  Set image input path.\n\
100  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
101  image.\n\
102  Setting the VISP_INPUT_IMAGE_PATH environment\n\
103  variable produces the same behaviour than using\n\
104  this option.\n\
105 \n\
106  -o <output image path> %s\n\
107  Set image output path.\n\
108  From this directory, creates the \"%s\"\n\
109  subdirectory depending on the username, where \n\
110  Klimt_grey.overlay.ppm output image is written.\n\
111 \n\
112  -c\n\
113  Disable the mouse click. Useful to automate the \n\
114  execution of this program without humain intervention.\n\
115 \n\
116  -d \n\
117  Disable the image display. This can be useful \n\
118  for automatic tests using the task manager under \n\
119  Windows.\n\
120 \n\
121  -h\n\
122  Print the help.\n\n",
123  ipath.c_str(), opath.c_str(), user.c_str());
124  if (badparam) {
125  fprintf(stderr, "ERROR: \n" );
126  fprintf(stderr, "\nBad parameter [%s]\n", badparam);
127  }
128 }
129 
145 bool getOptions(int argc, const char **argv,
146  std::string &ipath, std::string &opath, bool &click_allowed,
147  std::string user, bool &display)
148 {
149  const char *optarg;
150  int c;
151  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg)) > 1) {
152 
153  switch (c) {
154  case 'c': click_allowed = false; break;
155  case 'd': display = false; break;
156  case 'i': ipath = optarg; break;
157  case 'o': opath = optarg; break;
158  case 'h': usage(argv[0], NULL, ipath, opath, user); return false; break;
159 
160  default:
161  usage(argv[0], optarg, ipath, opath, user); return false; break;
162  }
163  }
164 
165  if ((c == 1) || (c == -1)) {
166  // standalone param or error
167  usage(argv[0], NULL, ipath, opath, user);
168  std::cerr << "ERROR: " << std::endl;
169  std::cerr << " Bad argument " << optarg << std::endl << std::endl;
170  return false;
171  }
172 
173  return true;
174 }
175 
176 int
177 main(int argc, const char ** argv)
178 {
179  try {
180  std::string env_ipath;
181  std::string opt_ipath;
182  std::string opt_opath;
183  std::string ipath;
184  std::string opath;
185  std::string filename;
186  std::string username;
187  bool opt_click_allowed = true;
188  bool opt_display = true;
189 
190  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
191  env_ipath = vpIoTools::getViSPImagesDataPath();
192 
193  // Set the default input path
194  if (! env_ipath.empty())
195  ipath = env_ipath;
196 
197  // Set the default output path
198  opt_opath = "C:\\temp";
199 
200 
201  // Get the user login name
202  vpIoTools::getUserName(username);
203 
204  // Read the command line options
205  if (getOptions(argc, argv, opt_ipath, opt_opath,
206  opt_click_allowed, username, opt_display) == false) {
207  exit (-1);
208  }
209 
210  // Get the option values
211  if (!opt_ipath.empty())
212  ipath = opt_ipath;
213  if (!opt_opath.empty())
214  opath = opt_opath;
215 
216  // Append to the output path string, the login name of the user
217  std::string odirname = vpIoTools::createFilePath(opath, username);
218 
219  // Test if the output path exist. If no try to create it
220  if (vpIoTools::checkDirectory(odirname) == false) {
221  try {
222  // Create the dirname
223  vpIoTools::makeDirectory(odirname);
224  }
225  catch (...) {
226  usage(argv[0], NULL, ipath, opath, username);
227  std::cerr << std::endl
228  << "ERROR:" << std::endl;
229  std::cerr << " Cannot create " << odirname << std::endl;
230  std::cerr << " Check your -o " << opath << " option " << std::endl;
231  exit(-1);
232  }
233  }
234 
235  // Compare ipath and env_ipath. If they differ, we take into account
236  // the input path comming from the command line option
237  if (!opt_ipath.empty() && !env_ipath.empty()) {
238  if (ipath != env_ipath) {
239  std::cout << std::endl
240  << "WARNING: " << std::endl;
241  std::cout << " Since -i <visp image path=" << ipath << "> "
242  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
243  << " we skip the environment variable." << std::endl;
244  }
245  }
246 
247  // Test if an input path is set
248  if (opt_ipath.empty() && env_ipath.empty()){
249  usage(argv[0], NULL, ipath, opath, username);
250  std::cerr << std::endl
251  << "ERROR:" << std::endl;
252  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
253  << std::endl
254  << " environment variable to specify the location of the " << std::endl
255  << " image path where test images are located." << std::endl << std::endl;
256  exit(-1);
257  }
258 
259  // Create a grey level image
261  vpImagePoint ip, ip1, ip2;
262 
263  // Load a grey image from the disk
264  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
265  vpImageIo::read(I, filename) ;
266 
267  // Create a display using X11
268  vpDisplayD3D display;
269 
270  if (opt_display) {
271  // For this grey level image, open a X11 display at position 100,100
272  // in the screen, and with title "X11 display"
273  display.init(I, 100, 100, "X11 display") ;
274 
275  // Display the image
276  vpDisplay::display(I) ;
277 
278  // Display in overlay a red cross at position 10,10 in the
279  // image. The lines are 10 pixels long
280  ip.set_i( 100 );
281  ip.set_j( 10 );
282 
284 
285  // Display in overlay horizontal red lines
286  for (unsigned i=0 ; i < I.getHeight() ; i+=20) {
287  ip1.set_i( i );
288  ip1.set_j( 0 );
289  ip2.set_i( i );
290  ip2.set_j( I.getWidth() );
291  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
292  }
293 
294  // Display a ligne in the diagonal
295  ip1.set_i( -10 );
296  ip1.set_j( -10 );
297  ip2.set_i( I.getHeight() + 10 );
298  ip2.set_j( I.getWidth() + 10 );
299 
300  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
301 
302  // Display in overlay vertical green dot lines
303  for (unsigned i=0 ; i < I.getWidth() ; i+=20) {
304  ip1.set_i( 0 );
305  ip1.set_j( i );
306  ip2.set_i( I.getWidth() );
307  ip2.set_j( i );
309  }
310 
311  // Display a rectangle
312  ip.set_i( I.getHeight() - 45 );
313  ip.set_j( -10 );
315 
316  // Display in overlay a blue arrow
317  ip1.set_i( 0 );
318  ip1.set_j( 0 );
319  ip2.set_i( 100 );
320  ip2.set_j( 100 );
321  vpDisplay::displayArrow(I, ip1, ip2, vpColor::blue) ;
322 
323  // Display in overlay some circles. The position of the center is 200, 200
324  // the radius is increased by 20 pixels for each circle
325 
326  for (unsigned int i=0 ; i < 100 ; i+=20) {
327  ip.set_i( 80 );
328  ip.set_j( 80 );
330  }
331 
332  ip.set_i( -10 );
333  ip.set_j( 300 );
335 
336  // Display in overlay a yellow string
337  ip.set_i( 85 );
338  ip.set_j( 100 );
340  "ViSP is a marvelous software",
341  vpColor::yellow) ;
342  //Flush the display
343  vpDisplay::flush(I);
344 
345  // Create a color image
346  vpImage<vpRGBa> Ioverlay ;
347  // Updates the color image with the original loaded image and the overlay
348  vpDisplay::getImage(I, Ioverlay) ;
349 
350  // Write the color image on the disk
351  filename = vpIoTools::createFilePath(odirname, "Klimt_grey.overlay.ppm");
352  vpImageIo::write(Ioverlay, filename) ;
353 
354  // If click is allowed, wait for a mouse click to close the display
355  if (opt_click_allowed) {
356  std::cout << "\nA click to close the windows..." << std::endl;
357  // Wait for a blocking mouse click
359  }
360 
361  // Close the display
362  vpDisplay::close(I);
363  }
364 
365  // Create a color image
366  vpImage<vpRGBa> Irgba ;
367 
368  // Load a grey image from the disk and convert it to a color image
369  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
370  vpImageIo::read(Irgba, filename) ;
371 
372  // Create a new display
373  vpDisplayD3D displayRGBa;
374 
375  if (opt_display) {
376  // For this color image, open a X11 display at position 100,100
377  // in the screen, and with title "X11 color display"
378  displayRGBa.init(Irgba, 100, 100, "X11 color display");
379 
380  // Display the color image
381  vpDisplay::display(Irgba) ;
382  vpDisplay::flush(Irgba) ;
383 
384  // If click is allowed, wait for a blocking mouse click to display a cross
385  // at the clicked pixel position
386  if (opt_click_allowed) {
387  std::cout << "\nA click to display a cross..." << std::endl;
388  // Blocking wait for a click. Get the position of the selected pixel
389  // (i correspond to the row and j to the column coordinates in the image)
390  vpDisplay::getClick(Irgba, ip);
391  // Display a red cross on the click pixel position
392  std::cout << "Cross position: " << ip << std::endl;
393  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
394  }
395  else {
396  ip.set_i( 10 );
397  ip.set_j( 20 );
398  // Display a red cross at position i, j (i correspond to the row
399  // and j to the column coordinates in the image)
400  std::cout << "Cross position: " << ip << std::endl;
401  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
402 
403  }
404  // Flush the display. Sometimes the display content is
405  // bufferized. Force to display the content that has been bufferized.
406  vpDisplay::flush(Irgba);
407 
408  // Create a color image
409  vpImage<vpRGBa> Ioverlay ;
410  // Updates the color image with the original loaded image and the overlay
411  vpDisplay::getImage(Irgba, Ioverlay) ;
412 
413  // Write the color image on the disk
414  filename = vpIoTools::createFilePath(odirname, "Klimt_color.overlay.ppm");
415  vpImageIo::write(Ioverlay, filename) ;
416 
417  // If click is allowed, wait for a blocking mouse click to exit.
418  if (opt_click_allowed) {
419  std::cout << "\nA click to exit the program..." << std::endl;
420  vpDisplay::getClick(Irgba) ;
421  std::cout << "Bye" << std::endl;
422  }
423  }
424  return 0;
425  }
426  catch(vpException &e) {
427  std::cout << "Catch an exception: " << e << std::endl;
428  return 1;
429  }
430 }
431 #else
432 int
433 main()
434 {
435  vpERROR_TRACE("Direct 3D library is not available...");
436 }
437 #endif
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:358
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1157
static void close(vpImage< unsigned char > &I)
#define vpERROR_TRACE
Definition: vpDebug.h:391
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emited by ViSP classes.
Definition: vpException.h:73
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 const vpColor orange
Definition: vpColor.h:173
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:368
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:427
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
Definition: vpDisplayD3D.h:107
void set_i(const double ii)
Definition: vpImagePoint.h:163
static void displayArrow(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1366
static void display(const vpImage< unsigned char > &I)
static std::string getUserName()
Definition: vpIoTools.cpp:177
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
Definition: vpDisplay.cpp:155
void set_j(const double jj)
Definition: vpImagePoint.h:174
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
unsigned int getHeight() const
Definition: vpImage.h:175
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:205
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static const vpColor yellow
Definition: vpColor.h:171
unsigned int getWidth() const
Definition: vpImage.h:226
static void displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static const vpColor blue
Definition: vpColor.h:169