ViSP
 All Classes Functions Variables Enumerations Enumerator Friends Groups Pages
displayX.cpp
1 /****************************************************************************
2  *
3  * $Id: displayX.cpp 4323 2013-07-18 09:24:01Z 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 #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 
87 void usage(const char *name, const char *badparam, std::string ipath,
88  std::string opath, std::string user)
89 {
90  fprintf(stdout, "\n\
91 Read an image on the disk, display it using X11, display some\n\
92 features (line, circle, caracters) in overlay and finaly write \n\
93 the image and the overlayed features in an image on the disk.\n\
94 \n\
95 SYNOPSIS\n\
96  %s [-i <input image path>] [-o <output image path>]\n\
97  [-c] [-d] [-h]\n \
98 ", name);
99 
100  fprintf(stdout, "\n\
101 OPTIONS: Default\n\
102  -i <input image path> %s\n\
103  Set image input path.\n\
104  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
105  image.\n\
106  Setting the VISP_INPUT_IMAGE_PATH environment\n\
107  variable produces the same behaviour than using\n\
108  this option.\n\
109 \n\
110  -o <output image path> %s\n\
111  Set image output path.\n\
112  From this directory, creates the \"%s\"\n\
113  subdirectory depending on the username, where \n\
114  Klimt_grey.overlay.ppm output image is written.\n\
115 \n\
116  -c\n\
117  Disable the mouse click. Useful to automate the \n\
118  execution of this program without humain intervention.\n\
119 \n\
120  -d \n\
121  Disable the image display. This can be useful \n\
122  for automatic tests using crontab under Unix or \n\
123  using the task manager under Windows.\n\
124 \n\
125  -h\n\
126  Print the help.\n\n",
127  ipath.c_str(), opath.c_str(), user.c_str());
128 
129  if (badparam) {
130  fprintf(stderr, "ERROR: \n" );
131  fprintf(stderr, "\nBad parameter [%s]\n", badparam);
132  }
133 
134 }
135 
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 a grey level image
275  vpImagePoint ip, ip1, ip2;
276 
277  // Load a grey image from the disk
278  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.pgm");
279  try {
280  vpImageIo::read(I, filename) ;
281  }
282  catch (...) {
283  return -1;
284  }
285 
286  // Create a display using X11
287  vpDisplayX display;
288 
289  if (opt_display) {
290  // For this grey level image, open a X11 display at position 100,100
291  // in the screen, and with title "X11 display"
292  display.init(I, 100, 100, "X11 display") ;
293 
294  // Display the image
295  vpDisplay::display(I) ;
296 
297  // Display in overlay a red cross at position 10,10 in the
298  // image. The lines are 10 pixels long
299  ip.set_i( 100 );
300  ip.set_j( 10 );
301 
303 
304  // Display in overlay horizontal red lines
305  for (unsigned i=0 ; i < I.getHeight() ; i+=20) {
306  ip1.set_i( i );
307  ip1.set_j( 0 );
308  ip2.set_i( i );
309  ip2.set_j( I.getWidth() );
310  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
311  }
312 
313  // Display a ligne in the diagonal
314  ip1.set_i( -10 );
315  ip1.set_j( -10 );
316  ip2.set_i( I.getHeight() + 10 );
317  ip2.set_j( I.getWidth() + 10 );
318 
319  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
320 
321  // Display in overlay vertical green dot lines
322  for (unsigned i=0 ; i < I.getWidth() ; i+=20) {
323  ip1.set_i( 0 );
324  ip1.set_j( i );
325  ip2.set_i( I.getWidth() );
326  ip2.set_j( i );
328  }
329 
330  // Display a rectangle
331  ip.set_i( I.getHeight() - 45 );
332  ip.set_j( -10 );
334 
335  // Display in overlay a blue arrow
336  ip1.set_i( 0 );
337  ip1.set_j( 0 );
338  ip2.set_i( 100 );
339  ip2.set_j( 100 );
340  vpDisplay::displayArrow(I, ip1, ip2, vpColor::blue) ;
341 
342  // Display in overlay some circles. The position of the center is 200, 200
343  // the radius is increased by 20 pixels for each circle
344 
345  for (unsigned int i=0 ; i < 100 ; i+=20) {
346  ip.set_i( 80 );
347  ip.set_j( 80 );
349  }
350 
351  ip.set_i( -10 );
352  ip.set_j( 300 );
354 
355  // Display in overlay a yellow string
356  ip.set_i( 85 );
357  ip.set_j( 100 );
359  "ViSP is a marvelous software",
360  vpColor::yellow) ;
361  //Flush the display
362  vpDisplay::flush(I);
363 
364  // Create a color image
365  vpImage<vpRGBa> Ioverlay ;
366  // Updates the color image with the original loaded image and the overlay
367  vpDisplay::getImage(I, Ioverlay) ;
368 
369  // Write the color image on the disk
370  filename = odirname + vpIoTools::path("/Klimt_grey.overlay.ppm");
371  vpImageIo::write(Ioverlay, filename) ;
372 
373  // If click is allowed, wait for a mouse click to close the display
374  if (opt_click_allowed) {
375  std::cout << "\nA click to close the windows..." << std::endl;
376  // Wait for a blocking mouse click
378  }
379 
380  // Close the display
381  vpDisplay::close(I);
382  }
383 
384  // Create a color image
385  vpImage<vpRGBa> Irgba ;
386 
387  // Load a grey image from the disk and convert it to a color image
388  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.pgm");
389  try {
390  vpImageIo::read(Irgba, filename) ;
391  }
392  catch (...) {
393  return -1;
394  }
395 
396  // Create a new display
397  vpDisplayX displayRGBa;
398 
399  if (opt_display) {
400  // For this color image, open a X11 display at position 100,100
401  // in the screen, and with title "X11 color display"
402  displayRGBa.init(Irgba, 100, 100, "X11 color display");
403 
404  // Display the color image
405  vpDisplay::display(Irgba) ;
406  vpDisplay::flush(Irgba) ;
407 
408  // If click is allowed, wait for a blocking mouse click to display a cross
409  // at the clicked pixel position
410  if (opt_click_allowed) {
411  std::cout << "\nA click to display a cross..." << std::endl;
412  // Blocking wait for a click. Get the position of the selected pixel
413  // (i correspond to the row and j to the column coordinates in the image)
414  vpDisplay::getClick(Irgba, ip);
415  // Display a red cross on the click pixel position
416  std::cout << "Cross position: " << ip << std::endl;
417  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
418  }
419  else {
420  ip.set_i( 10 );
421  ip.set_j( 20 );
422  // Display a red cross at position i, j (i correspond to the row
423  // and j to the column coordinates in the image)
424  std::cout << "Cross position: " << ip << std::endl;
425  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
426 
427  }
428  // Flush the display. Sometimes the display content is
429  // bufferized. Force to display the content that has been bufferized.
430  vpDisplay::flush(Irgba);
431 
432  // If click is allowed, wait for a blocking mouse click to exit.
433  if (opt_click_allowed) {
434  std::cout << "\nA click to exit the program..." << std::endl;
435  vpDisplay::getClick(Irgba) ;
436  std::cout << "Bye" << std::endl;
437  }
438  }
439 }
440 #else
441 int
442 main()
443 {
444  vpERROR_TRACE("You do not have X11 functionalities to display images...");
445 }
446 
447 #endif
448 
void set_j(const double j)
Definition: vpImagePoint.h:156
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:442
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:2028
unsigned int getWidth() const
Definition: vpImage.h:159
#define vpERROR_TRACE
Definition: vpDebug.h:379
Define the X11 console to display images.
Definition: vpDisplayX.h:152
void set_i(const double i)
Definition: vpImagePoint.h:145
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:1991
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
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:203
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:321
virtual void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
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:184
static void read(vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:277
static const vpColor yellow
Definition: vpColor.h:175
static const vpColor blue
Definition: vpColor.h:173