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