ViSP
displayOpenCV.cpp
1 /****************************************************************************
2  *
3  * $Id: displayOpenCV.cpp 5005 2014-11-24 08:25:51Z 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 OpenCV.
36  *
37  * Authors:
38  * Nicolas Melchior
39  *
40  *****************************************************************************/
50 #include <visp/vpDebug.h>
51 #include <visp/vpConfig.h>
52 #include <stdlib.h>
53 
54 #if defined(VISP_HAVE_OPENCV)
55 
56 #include <visp/vpImage.h>
57 #include <visp/vpImageIo.h>
58 #include <visp/vpDisplayOpenCV.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,
78  bool &click_allowed, 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 OpenCV, 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,
158  bool &click_allowed, 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-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
202  env_ipath = vpIoTools::getViSPImagesDataPath();
203 
204  // Set the default input path
205  if (! env_ipath.empty())
206  ipath = env_ipath;
207 
208  // Set the default output path
209 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
210  opt_opath = "/tmp";
211 #elif defined(_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 = vpIoTools::createFilePath(opath, 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 = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
279  vpImageIo::read(I, filename) ;
280 
281  // Create a display using X11
282  vpDisplayOpenCV display;
283 
284  if (opt_display) {
285  // For this grey level image, open a X11 display at position 100,100
286  // in the screen, and with title "X11 display"
287  display.init(I, 100, 100, "X11 display") ;
288 
289  // Display the image
290  vpDisplay::display(I) ;
291 
292  // Display in overlay a red cross at position 10,10 in the
293  // image. The lines are 10 pixels long
294  ip.set_i( 100 );
295  ip.set_j( 10 );
296 
298 
299  // Display in overlay horizontal red lines
300  for (unsigned i=0 ; i < I.getHeight() ; i+=20) {
301  ip1.set_i( i );
302  ip1.set_j( 0 );
303  ip2.set_i( i );
304  ip2.set_j( I.getWidth() );
305  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
306  }
307 
308  // Display a ligne in the diagonal
309  ip1.set_i( -10 );
310  ip1.set_j( -10 );
311  ip2.set_i( I.getHeight() + 10 );
312  ip2.set_j( I.getWidth() + 10 );
313 
314  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
315 
316  // Display in overlay vertical green dot lines
317  for (unsigned i=0 ; i < I.getWidth() ; i+=20) {
318  ip1.set_i( 0 );
319  ip1.set_j( i );
320  ip2.set_i( I.getWidth() );
321  ip2.set_j( i );
323  }
324 
325  // Display a rectangle
326  ip.set_i( I.getHeight() - 45 );
327  ip.set_j( -10 );
329 
330  // Display in overlay a blue arrow
331  ip1.set_i( 0 );
332  ip1.set_j( 0 );
333  ip2.set_i( 100 );
334  ip2.set_j( 100 );
335  vpDisplay::displayArrow(I, ip1, ip2, vpColor::blue) ;
336 
337  // Display in overlay some circles. The position of the center is 200, 200
338  // the radius is increased by 20 pixels for each circle
339 
340  for (unsigned int i=0 ; i < 100 ; i+=20) {
341  ip.set_i( 80 );
342  ip.set_j( 80 );
344  }
345 
346  ip.set_i( -10 );
347  ip.set_j( 300 );
349 
350  // Display in overlay a yellow string
351  ip.set_i( 85 );
352  ip.set_j( 100 );
354  "ViSP is a marvelous software",
355  vpColor::yellow) ;
356  //Flush the display
357  vpDisplay::flush(I);
358 
359  // Create a color image
360  vpImage<vpRGBa> Ioverlay ;
361  // Updates the color image with the original loaded image and the overlay
362  vpDisplay::getImage(I, Ioverlay) ;
363 
364  // Write the color image on the disk
365  filename = vpIoTools::createFilePath(odirname, "Klimt_grey.overlay.ppm");
366  vpImageIo::write(Ioverlay, filename) ;
367 
368  // If click is allowed, wait for a mouse click to close the display
369  if (opt_click_allowed) {
370  std::cout << "\nA click to close the windows..." << std::endl;
371  // Wait for a blocking mouse click
373  }
374 
375  // Close the display
376  vpDisplay::close(I);
377  }
378 
379  // Create a color image
380  vpImage<vpRGBa> Irgba ;
381 
382  // Load a grey image from the disk and convert it to a color image
383  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
384  vpImageIo::read(Irgba, filename) ;
385 
386  // Create a new display
387  vpDisplayOpenCV displayRGBa;
388 
389  if (opt_display) {
390  // For this color image, open a X11 display at position 100,100
391  // in the screen, and with title "X11 color display"
392  displayRGBa.init(Irgba, 100, 100, "X11 color display");
393 
394  // Display the color image
395  vpDisplay::display(Irgba) ;
396  vpDisplay::flush(Irgba) ;
397 
398  // If click is allowed, wait for a blocking mouse click to display a cross
399  // at the clicked pixel position
400  if (opt_click_allowed) {
401  std::cout << "\nA click to display a cross..." << std::endl;
402  // Blocking wait for a click. Get the position of the selected pixel
403  // (i correspond to the row and j to the column coordinates in the image)
404  vpDisplay::getClick(Irgba, ip);
405  // Display a red cross on the click pixel position
406  std::cout << "Cross position: " << ip << std::endl;
407  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
408  }
409  else {
410  ip.set_i( 10 );
411  ip.set_j( 20 );
412  // Display a red cross at position i, j (i correspond to the row
413  // and j to the column coordinates in the image)
414  std::cout << "Cross position: " << ip << std::endl;
415  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
416 
417  }
418  // Flush the display. Sometimes the display content is
419  // bufferized. Force to display the content that has been bufferized.
420  vpDisplay::flush(Irgba);
421 
422  // Create a color image
423  vpImage<vpRGBa> Ioverlay ;
424  // Updates the color image with the original loaded image and the overlay
425  vpDisplay::getImage(Irgba, Ioverlay) ;
426 
427  // Write the color image on the disk
428  filename = vpIoTools::createFilePath(odirname, "Klimt_color.overlay.ppm");
429  vpImageIo::write(Ioverlay, filename) ;
430 
431  // If click is allowed, wait for a blocking mouse click to exit.
432  if (opt_click_allowed) {
433  std::cout << "\nA click to exit the program..." << std::endl;
434  vpDisplay::getClick(Irgba) ;
435  std::cout << "Bye" << std::endl;
436  }
437  }
438  return 0;
439  }
440  catch(vpException e) {
441  std::cout << "Catch an exception: " << e << std::endl;
442  return 1;
443  }
444 }
445 #else
446 int
447 main()
448 {
449  vpERROR_TRACE("You do not have OpenCV functionalities to display images...");
450 }
451 
452 #endif
453 
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
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
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
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
The vpDisplayOpenCV allows to display image using the opencv library.
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
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