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