ViSP  2.10.0
displayGTK.cpp
1 /****************************************************************************
2  *
3  * $Id: displayGTK.cpp 5004 2014-11-24 08:24:18Z 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 GTK.
36  *
37  * Authors:
38  * Eric Marchand
39  * Fabien Spindler
40  *
41  *****************************************************************************/
52 #include <visp/vpDebug.h>
53 #include <visp/vpConfig.h>
54 
55 #ifdef VISP_HAVE_GTK
56 
57 #include <stdlib.h>
58 #include <stdio.h>
59 
60 #include <visp/vpImage.h>
61 #include <visp/vpImageIo.h>
62 #include <visp/vpImagePoint.h>
63 #include <visp/vpDisplayGTK.h>
64 #include <visp/vpParseArgv.h>
65 #include <visp/vpIoTools.h>
66 
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 GTK, 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  image.\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(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
133 }
134 
152 bool getOptions(int argc, const char **argv,
153  std::string &ipath, std::string &opath, bool &click_allowed,
154  std::string user, bool &display)
155 {
156  const char *optarg;
157  int c;
158  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg)) > 1) {
159 
160  switch (c) {
161  case 'c': click_allowed = false; break;
162  case 'd': display = false; break;
163  case 'i': ipath = optarg; break;
164  case 'o': opath = optarg; break;
165  case 'h': usage(argv[0], NULL, ipath, opath, user); return false; break;
166 
167  default:
168  usage(argv[0], optarg, ipath, opath, user); return false; break;
169  }
170  }
171 
172  if ((c == 1) || (c == -1)) {
173  // standalone param or error
174  usage(argv[0], NULL, ipath, opath, user);
175  std::cerr << "ERROR: " << std::endl;
176  std::cerr << " Bad argument " << optarg << std::endl << std::endl;
177  return false;
178  }
179 
180  return true;
181 }
182 
183 int
184 main(int argc, const char ** argv)
185 {
186  try {
187  std::string env_ipath;
188  std::string opt_ipath;
189  std::string opt_opath;
190  std::string ipath;
191  std::string opath;
192  std::string filename;
193  std::string username;
194  bool opt_click_allowed = true;
195  bool opt_display = true;
196 
197  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
198  env_ipath = vpIoTools::getViSPImagesDataPath();
199 
200  // Set the default input path
201  if (! env_ipath.empty())
202  ipath = env_ipath;
203 
204  // Set the default output path
205 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
206  opt_opath = "/tmp";
207 #elif defined(_WIN32)
208  opt_opath = "C:\\temp";
209 #endif
210 
211  // Get the user login name
212  vpIoTools::getUserName(username);
213 
214  // Read the command line options
215  if (getOptions(argc, argv, opt_ipath, opt_opath,
216  opt_click_allowed, username, opt_display) == false) {
217  exit (-1);
218  }
219 
220  // Get the option values
221  if (!opt_ipath.empty())
222  ipath = opt_ipath;
223  if (!opt_opath.empty())
224  opath = opt_opath;
225 
226  // Append to the output path string, the login name of the user
227  std::string odirname = vpIoTools::createFilePath(opath, username);
228 
229  // Test if the output path exist. If no try to create it
230  if (vpIoTools::checkDirectory(odirname) == false) {
231  try {
232  // Create the dirname
233  vpIoTools::makeDirectory(odirname);
234  }
235  catch (...) {
236  usage(argv[0], NULL, ipath, opath, username);
237  std::cerr << std::endl
238  << "ERROR:" << std::endl;
239  std::cerr << " Cannot create " << odirname << std::endl;
240  std::cerr << " Check your -o " << opath << " option " << std::endl;
241  exit(-1);
242  }
243  }
244 
245  // Compare ipath and env_ipath. If they differ, we take into account
246  // the input path comming from the command line option
247  if (!opt_ipath.empty() && !env_ipath.empty()) {
248  if (ipath != env_ipath) {
249  std::cout << std::endl
250  << "WARNING: " << std::endl;
251  std::cout << " Since -i <visp image path=" << ipath << "> "
252  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
253  << " we skip the environment variable." << std::endl;
254  }
255  }
256 
257  // Test if an input path is set
258  if (opt_ipath.empty() && env_ipath.empty()){
259  usage(argv[0], NULL, ipath, opath, username);
260  std::cerr << std::endl
261  << "ERROR:" << std::endl;
262  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
263  << std::endl
264  << " environment variable to specify the location of the " << std::endl
265  << " image path where test images are located." << std::endl << std::endl;
266  exit(-1);
267  }
268 
269  // Create a grey level image
271  vpImagePoint ip, ip1, ip2;
272 
273  // Load a grey image from the disk
274  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
275  vpImageIo::read(I, filename) ;
276 
277  // Create a display using X11
278  vpDisplayGTK display;
279 
280  if (opt_display) {
281  // For this grey level image, open a X11 display at position 100,100
282  // in the screen, and with title "X11 display"
283  display.init(I, 100, 100, "X11 display") ;
284 
285  // Display the image
286  vpDisplay::display(I) ;
287 
288  // Display in overlay a red cross at position 10,10 in the
289  // image. The lines are 10 pixels long
290  ip.set_i( 100 );
291  ip.set_j( 10 );
292 
294 
295  // Display in overlay horizontal red lines
296  for (unsigned i=0 ; i < I.getHeight() ; i+=20) {
297  ip1.set_i( i );
298  ip1.set_j( 0 );
299  ip2.set_i( i );
300  ip2.set_j( I.getWidth() );
301  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
302  }
303 
304  // Display a ligne in the diagonal
305  ip1.set_i( -10 );
306  ip1.set_j( -10 );
307  ip2.set_i( I.getHeight() + 10 );
308  ip2.set_j( I.getWidth() + 10 );
309 
310  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
311 
312  // Display in overlay vertical green dot lines
313  for (unsigned i=0 ; i < I.getWidth() ; i+=20) {
314  ip1.set_i( 0 );
315  ip1.set_j( i );
316  ip2.set_i( I.getWidth() );
317  ip2.set_j( i );
319  }
320 
321  // Display a rectangle
322  ip.set_i( I.getHeight() - 45 );
323  ip.set_j( -10 );
325 
326  // Display in overlay a blue arrow
327  ip1.set_i( 0 );
328  ip1.set_j( 0 );
329  ip2.set_i( 100 );
330  ip2.set_j( 100 );
331  vpDisplay::displayArrow(I, ip1, ip2, vpColor::blue) ;
332 
333  // Display in overlay some circles. The position of the center is 200, 200
334  // the radius is increased by 20 pixels for each circle
335 
336  for (unsigned int i=0 ; i < 100 ; i+=20) {
337  ip.set_i( 80 );
338  ip.set_j( 80 );
340  }
341 
342  ip.set_i( -10 );
343  ip.set_j( 300 );
345 
346  // Display in overlay a yellow string
347  ip.set_i( 85 );
348  ip.set_j( 100 );
350  "ViSP is a marvelous software",
351  vpColor::yellow) ;
352  //Flush the display
353  vpDisplay::flush(I);
354 
355  // Create a color image
356  vpImage<vpRGBa> Ioverlay ;
357  // Updates the color image with the original loaded image and the overlay
358  vpDisplay::getImage(I, Ioverlay) ;
359 
360  // Write the color image on the disk
361  filename = vpIoTools::createFilePath(odirname, "Klimt_grey.overlay.ppm");
362  vpImageIo::write(Ioverlay, filename) ;
363 
364  // If click is allowed, wait for a mouse click to close the display
365  if (opt_click_allowed) {
366  std::cout << "\nA click to close the windows..." << std::endl;
367  // Wait for a blocking mouse click
369  }
370 
371  // Close the display
372  vpDisplay::close(I);
373  }
374 
375  // Create a color image
376  vpImage<vpRGBa> Irgba ;
377 
378  // Load a grey image from the disk and convert it to a color image
379  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
380  vpImageIo::read(Irgba, filename) ;
381 
382  // Create a new display
383  vpDisplayGTK displayRGBa;
384 
385  if (opt_display) {
386  // For this color image, open a X11 display at position 100,100
387  // in the screen, and with title "X11 color display"
388  displayRGBa.init(Irgba, 100, 100, "X11 color display");
389 
390  // Display the color image
391  vpDisplay::display(Irgba) ;
392  vpDisplay::flush(Irgba) ;
393 
394  // If click is allowed, wait for a blocking mouse click to display a cross
395  // at the clicked pixel position
396  if (opt_click_allowed) {
397  std::cout << "\nA click to display a cross..." << std::endl;
398  // Blocking wait for a click. Get the position of the selected pixel
399  // (i correspond to the row and j to the column coordinates in the image)
400  vpDisplay::getClick(Irgba, ip);
401  // Display a red cross on the click pixel position
402  std::cout << "Cross position: " << ip << std::endl;
403  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
404  }
405  else {
406  ip.set_i( 10 );
407  ip.set_j( 20 );
408  // Display a red cross at position i, j (i correspond to the row
409  // and j to the column coordinates in the image)
410  std::cout << "Cross position: " << ip << std::endl;
411  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
412 
413  }
414  // Flush the display. Sometimes the display content is
415  // bufferized. Force to display the content that has been bufferized.
416  vpDisplay::flush(Irgba);
417 
418  // Create a color image
419  vpImage<vpRGBa> Ioverlay ;
420  // Updates the color image with the original loaded image and the overlay
421  vpDisplay::getImage(Irgba, Ioverlay) ;
422 
423  // Write the color image on the disk
424  filename = vpIoTools::createFilePath(odirname, "Klimt_color.overlay.ppm");
425  vpImageIo::write(Ioverlay, filename) ;
426 
427  // If click is allowed, wait for a blocking mouse click to exit.
428  if (opt_click_allowed) {
429  std::cout << "\nA click to exit the program..." << std::endl;
430  vpDisplay::getClick(Irgba) ;
431  std::cout << "Bye" << std::endl;
432  }
433  }
434  return 0;
435  }
436  catch(vpException e) {
437  std::cout << "Catch an exception: " << e << std::endl;
438  return 1;
439  }
440 }
441 #else
442 int
443 main()
444 {
445  vpERROR_TRACE("You do not have GTK functionalities to display images...");
446 }
447 
448 #endif
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:476
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:315
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1071
static void close(vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:2269
unsigned int getWidth() const
Definition: vpImage.h:161
#define vpERROR_TRACE
Definition: vpDebug.h:395
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Definition: vpDisplay.cpp:887
error that can be emited by ViSP classes.
Definition: vpException.h:76
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
static const vpColor green
Definition: vpColor.h:170
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:2232
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:80
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:384
void set_i(const double ii)
Definition: vpImagePoint.h:159
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1245
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:210
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
static std::string getUserName()
Definition: vpIoTools.cpp:141
The vpDisplayGTK allows to display image using the GTK+ library version 1.2.
Definition: vpDisplayGTK.h:145
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:328
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:170
unsigned int getHeight() const
Definition: vpImage.h:152
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:93
virtual void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
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