ViSP
 All Classes Functions Variables Enumerations Enumerator Friends Groups Pages
displayXMulti.cpp
1 /****************************************************************************
2  *
3  * $Id: displayXMulti.cpp 4056 2013-01-05 13:04:42Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Read an image on the disk and display it using X11.
36  *
37  * Authors:
38  * Eric Marchand
39  * Fabien Spindler
40  *
41  *****************************************************************************/
51 #include <visp/vpDebug.h>
52 #include <visp/vpConfig.h>
53 
54 #ifdef VISP_HAVE_X11
55 
56 #include <stdlib.h>
57 #include <stdio.h>
58 #include <string.h>
59 #include <visp/vpImage.h>
60 #include <visp/vpImageIo.h>
61 #include <visp/vpDisplayX.h>
62 
63 #include <visp/vpParseArgv.h>
64 #include <visp/vpIoTools.h>
65 
76 // List of allowed command line options
77 #define GETOPTARGS "cdi:o:h"
78 
90 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
91 {
92  fprintf(stdout, "\n\
93 Read an image on the disk, display it using X11, display some\n\
94 features (line, circle, caracters) in overlay and finaly write \n\
95 the image and the overlayed features in an image on the disk.\n\
96 \n\
97 SYNOPSIS\n\
98  %s [-i <input image path>] [-o <output image path>]\n\
99  [-c] [-d] [-h]\n \
100 ", name);
101 
102  fprintf(stdout, "\n\
103 OPTIONS: Default\n\
104  -i <input image path> %s\n\
105  Set image input path.\n\
106  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
107  and \"ViSP-images/Klimt/Klimt.ppm\" images.\n\
108  Setting the VISP_INPUT_IMAGE_PATH environment\n\
109  variable produces the same behaviour than using\n\
110  this option.\n\
111 \n\
112  -o <output image path> %s\n\
113  Set image output path.\n\
114  From this directory, creates the \"%s\"\n\
115  subdirectory depending on the username, where \n\
116  Klimt_grey.overlay.ppm output image is written.\n\
117 \n\
118  -c\n\
119  Disable the mouse click. Useful to automate the \n\
120  execution of this program without humain intervention.\n\
121 \n\
122  -d \n\
123  Disable the image display. This can be useful \n\
124  for automatic tests using crontab under Unix or \n\
125  using the task manager under Windows.\n\
126 \n\
127  -h\n\
128  Print the help.\n\n",
129  ipath.c_str(), opath.c_str(), user.c_str());
130 
131  if (badparam) {
132  fprintf(stderr, "ERROR: \n" );
133  fprintf(stderr, "\nBad parameter [%s]\n", badparam);
134  }
135 }
136 
154 bool getOptions(int argc, const char **argv,
155  std::string &ipath, std::string &opath, bool &click_allowed,
156  std::string user, bool &display)
157 {
158  const char *optarg;
159  int c;
160  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg)) > 1) {
161 
162  switch (c) {
163  case 'c': click_allowed = false; break;
164  case 'd': display = false; break;
165  case 'i': ipath = optarg; break;
166  case 'o': opath = optarg; break;
167  case 'h': usage(argv[0], NULL, ipath, opath, user); return false; break;
168 
169  default:
170  usage(argv[0], optarg, ipath, opath, user); return false; break;
171  }
172  }
173 
174  if ((c == 1) || (c == -1)) {
175  // standalone param or error
176  usage(argv[0], NULL, ipath, opath, user);
177  std::cerr << "ERROR: " << std::endl;
178  std::cerr << " Bad argument " << optarg << std::endl << std::endl;
179  return false;
180  }
181 
182  return true;
183 }
184 
185 int
186 main(int argc, const char ** argv)
187 {
188  std::string env_ipath;
189  std::string opt_ipath;
190  std::string opt_opath;
191  std::string ipath;
192  std::string opath;
193  std::string filename;
194  std::string username;
195  bool opt_click_allowed = true;
196  bool opt_display = true;
197 
198  // Get the VISP_IMAGE_PATH environment variable value
199  char *ptenv = getenv("VISP_INPUT_IMAGE_PATH");
200  if (ptenv != NULL)
201  env_ipath = ptenv;
202  // std::cout << "env_ipath: " << env_ipath << std::endl;
203 
204  // Set the default input path
205  if (! env_ipath.empty())
206  ipath = env_ipath;
207 
208  // Set the default output path
209 #ifdef UNIX
210  opt_opath = "/tmp";
211 #elif WIN32
212  opt_opath = "C:\\temp";
213 #endif
214 
215  // Get the user login name
216  vpIoTools::getUserName(username);
217 
218  // Read the command line options
219  if (getOptions(argc, argv, opt_ipath, opt_opath,
220  opt_click_allowed, username, opt_display) == false) {
221  exit (-1);
222  }
223 
224  // Get the option values
225  if (!opt_ipath.empty())
226  ipath = opt_ipath;
227  if (!opt_opath.empty())
228  opath = opt_opath;
229 
230  // Append to the output path string, the login name of the user
231  std::string odirname = opath + vpIoTools::path("/") + username;
232 
233  // Test if the output path exist. If no try to create it
234  if (vpIoTools::checkDirectory(odirname) == false) {
235  try {
236  // Create the dirname
237  vpIoTools::makeDirectory(odirname);
238  }
239  catch (...) {
240  usage(argv[0], NULL, ipath, opath, username);
241  std::cerr << std::endl
242  << "ERROR:" << std::endl;
243  std::cerr << " Cannot create " << odirname << std::endl;
244  std::cerr << " Check your -o " << opath << " option " << std::endl;
245  exit(-1);
246  }
247  }
248 
249  // Compare ipath and env_ipath. If they differ, we take into account
250  // the input path comming from the command line option
251  if (!opt_ipath.empty() && !env_ipath.empty()) {
252  if (ipath != env_ipath) {
253  std::cout << std::endl
254  << "WARNING: " << std::endl;
255  std::cout << " Since -i <visp image path=" << ipath << "> "
256  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
257  << " we skip the environment variable." << std::endl;
258  }
259  }
260 
261  // Test if an input path is set
262  if (opt_ipath.empty() && env_ipath.empty()){
263  usage(argv[0], NULL, ipath, opath, username);
264  std::cerr << std::endl
265  << "ERROR:" << std::endl;
266  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
267  << std::endl
268  << " environment variable to specify the location of the " << std::endl
269  << " image path where test images are located." << std::endl << std::endl;
270  exit(-1);
271  }
272 
273  // Create two color images
274  vpImage<vpRGBa> I1, I2 ;
275  vpImagePoint ip, ip1, ip2;
276 
277  try {
278  // Load a grey image from the disk
279  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.pgm");
280  vpImageIo::readPGM(I1, filename) ;
281  }
282  catch(...)
283  {
284  std::cerr << std::endl
285  << "ERROR:" << std::endl;
286  std::cerr << " Cannot read " << filename << std::endl;
287  std::cerr << " Check your -i " << ipath << " option " << std::endl
288  << " or VISP_INPUT_IMAGE_PATH environment variable."
289  << std::endl;
290  exit(-1);
291  }
292  try {
293  // Load a color image from the disk
294  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.ppm");
295  vpImageIo::readPPM(I2, filename) ;
296  }
297  catch(...)
298  {
299  std::cerr << std::endl
300  << "ERROR:" << std::endl;
301  std::cerr << " Cannot read " << filename << std::endl;
302  std::cerr << " Check your -i " << ipath << " option " << std::endl
303  << " or VISP_INPUT_IMAGE_PATH environment variable."
304  << std::endl;
305  exit(-1);
306  }
307 
308  // For each image, open a X11 display
309  vpDisplayX display1;
310  vpDisplayX display2;
311 
312  if (opt_display) {
313  // Attach image 1 to display 1
314  display1.init(I1, 0, 0,"X11 Display 1...") ;
315  // Attach image 2 to display 2
316  display2.init(I2, 200, 200,"X11 Display 2...") ;
317  // Display the images
318  vpDisplay::display(I1) ;
319  vpDisplay::display(I2) ;
320 
321  // In the first display, display in overlay horizontal red lines
322  for (unsigned int i=0 ; i < I1.getHeight() ; i+=20) {
323  ip1.set_i( i );
324  ip1.set_j( 0 );
325  ip2.set_i( i );
326  ip2.set_j( I1.getWidth() );
327  vpDisplay::displayLine(I1, ip1, ip2, vpColor::red) ;
328  }
329 
330  // In the first display, display in overlay vertical green dot lines
331  for (unsigned int i=0 ; i < I1.getWidth() ; i+=20) {
332  ip1.set_i( 0 );
333  ip1.set_j( i );
334  ip2.set_i( I1.getWidth() );
335  ip2.set_j( i );
337  }
338 
339  // In the first display, display in overlay a blue arrow
340  ip1.set_i( 0 );
341  ip1.set_j( 0 );
342  ip2.set_i( 100 );
343  ip2.set_j( 100 );
344  vpDisplay::displayArrow(I1, ip1, ip2, vpColor::blue) ;
345 
346  // In the first display, display in overlay some circles. The
347  // position of the center is 200, 200 the radius is increased by 20
348  // pixels for each circle
349  for (unsigned int i=0 ; i < 100 ; i+=20) {
350  ip.set_i( 200 );
351  ip.set_j( 200 );
353  }
354 
355  // In the first display, display in overlay a yellow string
356  ip.set_i( 100 );
357  ip.set_j( 100 );
359  "ViSP is a marvelous software",
360  vpColor::blue) ;
361 
362  //Flush displays. The displays must be flushed to show the overlay.
363  //without this line, nothing will be displayed.
364  vpDisplay::flush(I1);
365  vpDisplay::flush(I2);
366 
367  // If click is allowed, wait for a blocking mouse click in the first
368  // display, to display a cross at the clicked pixel position
369  if (opt_click_allowed) {
370  std::cout << "\nA click in the first display to draw a cross..." << std::endl;
371  // Blocking wait for a click. Get the position of the selected pixel
372  // (i correspond to the row and j to the column coordinates in the image)
373  vpDisplay::getClick(I1, ip);
374  // Display a red cross on the click pixel position
375  std::cout << "Cross position: " << ip << std::endl;
377  vpDisplay::flush(I1);
378  }
379  else {
380  ip.set_i( 50 );
381  ip.set_j( 50 );
382  // Display a red cross at position ip in the first display
383  std::cout << "Cross position: " << ip<< std::endl;
385  vpDisplay::flush(I1);
386  }
387 
388  // Create a color image
389  vpImage<vpRGBa> Ioverlay ;
390  // Updates the color image with the original loaded image 1 and the overlay
391  vpDisplay::getImage(I1, Ioverlay) ;
392 
393  // Write the color image on the disk
394  filename = odirname + vpIoTools::path("/Klimt_grey.overlay.ppm");
395  vpImageIo::writePPM(Ioverlay, filename) ;
396 
397  // If click is allowed, wait for a mouse click to close the display
398  if (opt_click_allowed) {
399  std::cout << "\nA click in the second display to close the windows and exit..." << std::endl;
400  // Wait for a blocking mouse click
401  vpDisplay::getClick(I2) ;
402  }
403  }
404 }
405 #else
406 int
407 main()
408 {
409  vpERROR_TRACE("You do not have X11 functionalities to display images...");
410 }
411 
412 #endif
413