ViSP
 All Classes Functions Variables Enumerations Enumerator Friends Groups Pages
displayGTK.cpp
1 /****************************************************************************
2  *
3  * $Id: displayGTK.cpp 4604 2014-01-21 14:15:23Z 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_IMAGE_PATH environment variable value
198  char *ptenv = getenv("VISP_INPUT_IMAGE_PATH");
199  if (ptenv != NULL)
200  env_ipath = ptenv;
201 
202  // Set the default input path
203  if (! env_ipath.empty())
204  ipath = env_ipath;
205 
206  // Set the default output path
207 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
208  opt_opath = "/tmp";
209 #elif defined(_WIN32)
210  opt_opath = "C:\\temp";
211 #endif
212 
213  // Get the user login name
214  vpIoTools::getUserName(username);
215 
216  // Read the command line options
217  if (getOptions(argc, argv, opt_ipath, opt_opath,
218  opt_click_allowed, username, opt_display) == false) {
219  exit (-1);
220  }
221 
222  // Get the option values
223  if (!opt_ipath.empty())
224  ipath = opt_ipath;
225  if (!opt_opath.empty())
226  opath = opt_opath;
227 
228  // Append to the output path string, the login name of the user
229  std::string odirname = opath + vpIoTools::path("/") + username;
230 
231  // Test if the output path exist. If no try to create it
232  if (vpIoTools::checkDirectory(odirname) == false) {
233  try {
234  // Create the dirname
235  vpIoTools::makeDirectory(odirname);
236  }
237  catch (...) {
238  usage(argv[0], NULL, ipath, opath, username);
239  std::cerr << std::endl
240  << "ERROR:" << std::endl;
241  std::cerr << " Cannot create " << odirname << std::endl;
242  std::cerr << " Check your -o " << opath << " option " << std::endl;
243  exit(-1);
244  }
245  }
246 
247  // Compare ipath and env_ipath. If they differ, we take into account
248  // the input path comming from the command line option
249  if (!opt_ipath.empty() && !env_ipath.empty()) {
250  if (ipath != env_ipath) {
251  std::cout << std::endl
252  << "WARNING: " << std::endl;
253  std::cout << " Since -i <visp image path=" << ipath << "> "
254  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
255  << " we skip the environment variable." << std::endl;
256  }
257  }
258 
259  // Test if an input path is set
260  if (opt_ipath.empty() && env_ipath.empty()){
261  usage(argv[0], NULL, ipath, opath, username);
262  std::cerr << std::endl
263  << "ERROR:" << std::endl;
264  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
265  << std::endl
266  << " environment variable to specify the location of the " << std::endl
267  << " image path where test images are located." << std::endl << std::endl;
268  exit(-1);
269  }
270 
271  // Create a grey level image
273  vpImagePoint ip, ip1, ip2;
274 
275  // Load a grey image from the disk
276  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.png");
277  vpImageIo::read(I, filename) ;
278 
279  // Create a display using GTK
280  vpDisplayGTK display;
281 
282  if (opt_display) {
283  // For this grey level image, open a GTK display at position 100,100
284  // in the screen, and with title "GTK display"
285  display.init(I, 100, 100, "GTK display") ;
286 
287  // Display the image
288  vpDisplay::display(I) ;
289 
290  // Display in overlay a red cross at position 10,10 in the
291  // image. The lines are 10 pixels long
292  ip.set_i( 100 );
293  ip.set_j( 10 );
294 
296 
297  // Display in overlay horizontal red lines
298  for (unsigned i=0 ; i < I.getHeight() ; i+=20) {
299  ip1.set_i( i );
300  ip1.set_j( 0 );
301  ip2.set_i( i );
302  ip2.set_j( I.getWidth() );
303  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
304  }
305 
306  // Display a ligne in the diagonal
307  ip1.set_i( -10 );
308  ip1.set_j( -10 );
309  ip2.set_i( I.getHeight() + 10 );
310  ip2.set_j( I.getWidth() + 10 );
311 
312  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
313 
314  // Display in overlay vertical green dot lines
315  for (unsigned i=0 ; i < I.getWidth() ; i+=20) {
316  ip1.set_i( 0 );
317  ip1.set_j( i );
318  ip2.set_i( I.getWidth() );
319  ip2.set_j( i );
321  }
322 
323  // Display a rectangle
324  ip.set_i( I.getHeight() - 45 );
325  ip.set_j( -10 );
327 
328  // Display in overlay a blue arrow
329  ip1.set_i( 0 );
330  ip1.set_j( 0 );
331  ip2.set_i( 100 );
332  ip2.set_j( 100 );
333  vpDisplay::displayArrow(I, ip1, ip2, vpColor::blue) ;
334 
335  // Display in overlay some circles. The position of the center is 200, 200
336  // the radius is increased by 20 pixels for each circle
337 
338  for (unsigned int i=0 ; i < 100 ; i+=20) {
339  ip.set_i( 80 );
340  ip.set_j( 80 );
342  }
343 
344  ip.set_i( -10 );
345  ip.set_j( 300 );
347 
348  // Display in overlay a yellow string
349  ip.set_i( 85 );
350  ip.set_j( 100 );
351  //vpDisplay::setFont(I, "-*-courier 10 pitch-medium-r-normal-*-16-*-*-*-*-*-*-*");
353  "ViSP is a marvelous software",
354  vpColor::yellow) ;
355  //Flush the display
356  vpDisplay::flush(I);
357 
358  // Create a color image
359  vpImage<vpRGBa> Ioverlay ;
360  // Updates the color image with the original loaded image and the overlay
361  vpDisplay::getImage(I, Ioverlay) ;
362 
363  // Write the color image on the disk
364  filename = odirname + vpIoTools::path("/Klimt_grey.overlay.ppm");
365  vpImageIo::write(Ioverlay, filename) ;
366 
367  // If click is allowed, wait for a mouse click to close the display
368  if (opt_click_allowed) {
369  std::cout << "\nA click to close the windows..." << std::endl;
370  // Wait for a blocking mouse click
372  }
373 
374  // Close the display
375  vpDisplay::close(I);
376  }
377 
378  // Create a color image
379  vpImage<vpRGBa> Irgba ;
380 
381  // Load a grey image from the disk and convert it to a color image
382  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.pgm");
383  vpImageIo::read(Irgba, filename) ;
384 
385  // Create a new GTK display
386  vpDisplayGTK displayRGBa;
387 
388  if (opt_display) {
389  // For this color image, open a GTK display at position 100,100
390  // in the screen, and with title "GTK color display"
391  displayRGBa.init(Irgba, 100, 100, "GTK color display");
392 
393  // Display the color image
394  vpDisplay::display(Irgba) ;
395  vpDisplay::flush(Irgba) ;
396 
397  // If click is allowed, wait for a blocking mouse click to display a cross
398  // at the clicked pixel position
399  if (opt_click_allowed) {
400  std::cout << "\nA click to display a cross..." << std::endl;
401  // Blocking wait for a click. Get the position of the selected pixel
402  // (i correspond to the row and j to the column coordinates in the image)
403  vpDisplay::getClick(Irgba, ip);
404  // Display a red cross on the click pixel position
405  std::cout << "Cross position: " << ip << std::endl;
406  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
407  }
408  else {
409  ip.set_i( 10 );
410  ip.set_j( 20 );
411  // Display a red cross at position i, j (i correspond to the row
412  // and j to the column coordinates in the image)
413  std::cout << "Cross position: " << ip << std::endl;
414  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
415 
416  }
417  // Flush the display. Sometimes the display content is
418  // bufferized. Force to display the content that has been bufferized.
419  vpDisplay::flush(Irgba);
420 
421  // If click is allowed, wait for a blocking mouse click to exit.
422  if (opt_click_allowed) {
423  std::cout << "\nA click to exit the program..." << std::endl;
424  vpDisplay::getClick(Irgba) ;
425  std::cout << "Bye" << std::endl;
426  }
427  }
428  }
429  catch(vpException e) {
430  std::cout << "Catch an exception: " << e << std::endl;
431  return 1;
432  }
433 }
434 #else
435 int
436 main()
437 {
438  vpERROR_TRACE("You do not have GTK functionalities to display images...");
439 }
440 
441 #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: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
error that can be emited by ViSP classes.
Definition: vpException.h:76
static std::string path(const char *pathname)
Definition: vpIoTools.cpp:715
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: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
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: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
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