ViSP
 All Classes Functions Variables Enumerations Enumerator Friends Groups Pages
displayXMulti.cpp
1 /****************************************************************************
2  *
3  * $Id: displayXMulti.cpp 4658 2014-02-09 09:50:14Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 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 
79 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user);
80 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, bool &click_allowed,
81  std::string user, bool &display);
82 
94 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
95 {
96  fprintf(stdout, "\n\
97 Read an image on the disk, display it using X11, display some\n\
98 features (line, circle, caracters) in overlay and finaly write \n\
99 the image and the overlayed features in an image on the disk.\n\
100 \n\
101 SYNOPSIS\n\
102  %s [-i <input image path>] [-o <output image path>]\n\
103  [-c] [-d] [-h]\n \
104 ", name);
105 
106  fprintf(stdout, "\n\
107 OPTIONS: Default\n\
108  -i <input image path> %s\n\
109  Set image input path.\n\
110  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
111  and \"ViSP-images/Klimt/Klimt.ppm\" images.\n\
112  Setting the VISP_INPUT_IMAGE_PATH environment\n\
113  variable produces the same behaviour than using\n\
114  this option.\n\
115 \n\
116  -o <output image path> %s\n\
117  Set image output path.\n\
118  From this directory, creates the \"%s\"\n\
119  subdirectory depending on the username, where \n\
120  Klimt_grey.overlay.ppm output image is written.\n\
121 \n\
122  -c\n\
123  Disable the mouse click. Useful to automate the \n\
124  execution of this program without humain intervention.\n\
125 \n\
126  -d \n\
127  Disable the image display. This can be useful \n\
128  for automatic tests using crontab under Unix or \n\
129  using the task manager under Windows.\n\
130 \n\
131  -h\n\
132  Print the help.\n\n",
133  ipath.c_str(), opath.c_str(), user.c_str());
134 
135  if (badparam) {
136  fprintf(stderr, "ERROR: \n" );
137  fprintf(stderr, "\nBad parameter [%s]\n", badparam);
138  }
139 }
140 
158 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, bool &click_allowed,
159  std::string user, bool &display)
160 {
161  const char *optarg_;
162  int c;
163  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
164 
165  switch (c) {
166  case 'c': click_allowed = false; break;
167  case 'd': display = false; break;
168  case 'i': ipath = optarg_; break;
169  case 'o': opath = optarg_; break;
170  case 'h': usage(argv[0], NULL, ipath, opath, user); return false; break;
171 
172  default:
173  usage(argv[0], optarg_, ipath, opath, user); return false; break;
174  }
175  }
176 
177  if ((c == 1) || (c == -1)) {
178  // standalone param or error
179  usage(argv[0], NULL, ipath, opath, user);
180  std::cerr << "ERROR: " << std::endl;
181  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
182  return false;
183  }
184 
185  return true;
186 }
187 
188 int
189 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_IMAGE_PATH environment variable value
203  char *ptenv = getenv("VISP_INPUT_IMAGE_PATH");
204  if (ptenv != NULL)
205  env_ipath = ptenv;
206  // std::cout << "env_ipath: " << env_ipath << std::endl;
207 
208  // Set the default input path
209  if (! env_ipath.empty())
210  ipath = env_ipath;
211 
212  // Set the default output path
213 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
214  opt_opath = "/tmp";
215 #elif defined(_WIN32)
216  opt_opath = "C:\\temp";
217 #endif
218 
219  // Get the user login name
220  vpIoTools::getUserName(username);
221 
222  // Read the command line options
223  if (getOptions(argc, argv, opt_ipath, opt_opath,
224  opt_click_allowed, username, opt_display) == false) {
225  exit (-1);
226  }
227 
228  // Get the option values
229  if (!opt_ipath.empty())
230  ipath = opt_ipath;
231  if (!opt_opath.empty())
232  opath = opt_opath;
233 
234  // Append to the output path string, the login name of the user
235  std::string odirname = opath + vpIoTools::path("/") + username;
236 
237  // Test if the output path exist. If no try to create it
238  if (vpIoTools::checkDirectory(odirname) == false) {
239  try {
240  // Create the dirname
241  vpIoTools::makeDirectory(odirname);
242  }
243  catch (...) {
244  usage(argv[0], NULL, ipath, opath, username);
245  std::cerr << std::endl
246  << "ERROR:" << std::endl;
247  std::cerr << " Cannot create " << odirname << std::endl;
248  std::cerr << " Check your -o " << opath << " option " << std::endl;
249  exit(-1);
250  }
251  }
252 
253  // Compare ipath and env_ipath. If they differ, we take into account
254  // the input path comming from the command line option
255  if (!opt_ipath.empty() && !env_ipath.empty()) {
256  if (ipath != env_ipath) {
257  std::cout << std::endl
258  << "WARNING: " << std::endl;
259  std::cout << " Since -i <visp image path=" << ipath << "> "
260  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
261  << " we skip the environment variable." << std::endl;
262  }
263  }
264 
265  // Test if an input path is set
266  if (opt_ipath.empty() && env_ipath.empty()){
267  usage(argv[0], NULL, ipath, opath, username);
268  std::cerr << std::endl
269  << "ERROR:" << std::endl;
270  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
271  << std::endl
272  << " environment variable to specify the location of the " << std::endl
273  << " image path where test images are located." << std::endl << std::endl;
274  exit(-1);
275  }
276 
277  // Create two color images
278  vpImage<vpRGBa> I1, I2 ;
279  vpImagePoint ip, ip1, ip2;
280 
281  try {
282  // Load a grey image from the disk
283  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.pgm");
284  vpImageIo::read(I1, filename) ;
285  }
286  catch(...)
287  {
288  std::cerr << std::endl
289  << "ERROR:" << std::endl;
290  std::cerr << " Cannot read " << filename << std::endl;
291  std::cerr << " Check your -i " << ipath << " option " << std::endl
292  << " or VISP_INPUT_IMAGE_PATH environment variable."
293  << std::endl;
294  exit(-1);
295  }
296  try {
297  // Load a color image from the disk
298  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.ppm");
299  vpImageIo::read(I2, filename) ;
300  }
301  catch(...)
302  {
303  std::cerr << std::endl
304  << "ERROR:" << std::endl;
305  std::cerr << " Cannot read " << filename << std::endl;
306  std::cerr << " Check your -i " << ipath << " option " << std::endl
307  << " or VISP_INPUT_IMAGE_PATH environment variable."
308  << std::endl;
309  exit(-1);
310  }
311 
312  // For each image, open a X11 display
313  vpDisplayX display1;
314  vpDisplayX display2;
315 
316  if (opt_display) {
317  // Attach image 1 to display 1
318  display1.init(I1, 0, 0,"X11 Display 1...") ;
319  // Attach image 2 to display 2
320  display2.init(I2, 200, 200,"X11 Display 2...") ;
321  // Display the images
322  vpDisplay::display(I1) ;
323  vpDisplay::display(I2) ;
324 
325  // In the first display, display in overlay horizontal red lines
326  for (unsigned int i=0 ; i < I1.getHeight() ; i+=20) {
327  ip1.set_i( i );
328  ip1.set_j( 0 );
329  ip2.set_i( i );
330  ip2.set_j( I1.getWidth() );
331  vpDisplay::displayLine(I1, ip1, ip2, vpColor::red) ;
332  }
333 
334  // In the first display, display in overlay vertical green dot lines
335  for (unsigned int i=0 ; i < I1.getWidth() ; i+=20) {
336  ip1.set_i( 0 );
337  ip1.set_j( i );
338  ip2.set_i( I1.getWidth() );
339  ip2.set_j( i );
341  }
342 
343  // In the first display, display in overlay a blue arrow
344  ip1.set_i( 0 );
345  ip1.set_j( 0 );
346  ip2.set_i( 100 );
347  ip2.set_j( 100 );
348  vpDisplay::displayArrow(I1, ip1, ip2, vpColor::blue) ;
349 
350  // In the first display, display in overlay some circles. The
351  // position of the center is 200, 200 the radius is increased by 20
352  // pixels for each circle
353  for (unsigned int i=0 ; i < 100 ; i+=20) {
354  ip.set_i( 200 );
355  ip.set_j( 200 );
357  }
358 
359  // In the first display, display in overlay a yellow string
360  ip.set_i( 100 );
361  ip.set_j( 100 );
363  "ViSP is a marvelous software",
364  vpColor::blue) ;
365 
366  //Flush displays. The displays must be flushed to show the overlay.
367  //without this line, nothing will be displayed.
368  vpDisplay::flush(I1);
369  vpDisplay::flush(I2);
370 
371  // If click is allowed, wait for a blocking mouse click in the first
372  // display, to display a cross at the clicked pixel position
373  if (opt_click_allowed) {
374  std::cout << "\nA click in the first display to draw a cross..." << std::endl;
375  // Blocking wait for a click. Get the position of the selected pixel
376  // (i correspond to the row and j to the column coordinates in the image)
377  vpDisplay::getClick(I1, ip);
378  // Display a red cross on the click pixel position
379  std::cout << "Cross position: " << ip << std::endl;
381  vpDisplay::flush(I1);
382  }
383  else {
384  ip.set_i( 50 );
385  ip.set_j( 50 );
386  // Display a red cross at position ip in the first display
387  std::cout << "Cross position: " << ip<< std::endl;
389  vpDisplay::flush(I1);
390  }
391 
392  // Create a color image
393  vpImage<vpRGBa> Ioverlay ;
394  // Updates the color image with the original loaded image 1 and the overlay
395  vpDisplay::getImage(I1, Ioverlay) ;
396 
397  // Write the color image on the disk
398  filename = odirname + vpIoTools::path("/Klimt_grey.overlay.ppm");
399  vpImageIo::write(Ioverlay, filename) ;
400 
401  // If click is allowed, wait for a mouse click to close the display
402  if (opt_click_allowed) {
403  std::cout << "\nA click in the second display to close the windows and exit..." << std::endl;
404  // Wait for a blocking mouse click
405  vpDisplay::getClick(I2) ;
406  }
407  }
408  return 0;
409  }
410  catch(vpException e) {
411  std::cout << "Catch an exception: " << e << std::endl;
412  return 1;
413  }
414 }
415 #else
416 int
417 main()
418 {
419  vpERROR_TRACE("You do not have X11 functionalities to display images...");
420 }
421 
422 #endif
423 
virtual void displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)=0
static void write(const vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:452
virtual void displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)=0
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:335
unsigned int getWidth() const
Definition: vpImage.h:159
#define vpERROR_TRACE
Definition: vpDebug.h:395
Define the X11 console to display images.
Definition: vpDisplayX.h:152
error that can be emited by ViSP classes.
Definition: vpException.h:76
static std::string path(const char *pathname)
Definition: vpIoTools.cpp:715
static const vpColor green
Definition: vpColor.h:170
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:1994
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:79
static const vpColor red
Definition: vpColor.h:167
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:404
void set_i(const double ii)
Definition: vpImagePoint.h:158
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:206
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
static std::string getUserName()
Definition: vpIoTools.cpp:140
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
Definition: vpDisplay.cpp:324
virtual void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
void set_j(const double jj)
Definition: vpImagePoint.h:169
virtual void displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color=vpColor::green)=0
unsigned int getHeight() const
Definition: vpImage.h:150
virtual bool getClick(bool blocking=true)=0
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:92
virtual void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
Definition: vpDisplayX.cpp:191
static void read(vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:278
static const vpColor yellow
Definition: vpColor.h:175
static const vpColor blue
Definition: vpColor.h:173