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