Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testImageResize.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Test image resize.
32  *
33  *****************************************************************************/
34 
35 #include <visp3/core/vpImage.h>
36 #include <visp3/core/vpDisplay.h>
37 #include <visp3/io/vpImageIo.h>
38 #include <visp3/core/vpImageTools.h>
39 #include <visp3/core/vpIoTools.h>
40 #include <visp3/io/vpParseArgv.h>
41 
42 #include <visp3/gui/vpDisplayOpenCV.h>
43 #include <visp3/gui/vpDisplayGTK.h>
44 #include <visp3/gui/vpDisplayX.h>
45 #include <visp3/gui/vpDisplayGDI.h>
46 #include <visp3/gui/vpDisplayD3D.h>
47 
53 // List of allowed command line options
54 #define GETOPTARGS "cdi:W:H:m:h"
55 
56 
57 namespace {
58  /*
59  Print the program options.
60 
61  \param name : Program name.
62  \param badparam : Bad parameter name.
63  \param ipath: Input image path.
64  \param w : Resize width.
65  \param h : Resize height.
66  \param m : Resize interpolation method.
67  */
68  void usage(const char *name, const char *badparam, std::string ipath, unsigned int &w, unsigned int &h, int &m)
69  {
70  fprintf(stdout, "\n\
71  Test image resize.\n\
72  \n\
73  SYNOPSIS\n\
74  %s [-i <input image path>] [-W <width>] [-H <height>] [-m <method>] [-c] [-d]\n\
75  [-h]\n \
76  ", name);
77 
78  fprintf(stdout, "\n\
79  OPTIONS: Default\n\
80  -i <input image path> %s\n\
81  Set image input path.\n\
82  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
83  image.\n\
84  Setting the VISP_INPUT_IMAGE_PATH environment\n\
85  variable produces the same behaviour than using\n\
86  this option.\n\
87  \n\
88  -W <width> %d\n\
89  Set the new image width.\n\
90  \n\
91  -H <height> %d\n\
92  Set the new image height.\n\
93  \n\
94  -m <method> %d\n\
95  Set resize interpolation method.\n\
96  \n\
97  -c \n\
98  Disable mouse click.\n\
99  \n\
100  -d \n\
101  Disable image display.\n\
102  \n\
103  -h\n\
104  Print the help.\n\n",
105  ipath.c_str(), w, h, m);
106 
107  if (badparam)
108  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
109  }
110 
124  bool getOptions(int argc, const char **argv, std::string &ipath, unsigned int &w, unsigned int &h, int &method,
125  bool &opt_display, bool &opt_click)
126  {
127  const char *optarg_;
128  int c;
129  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
130 
131  switch (c) {
132  case 'i': ipath = optarg_; break;
133  case 'W': w = (unsigned int) atoi(optarg_); break;
134  case 'H': h = (unsigned int) atoi(optarg_); break;
135  case 'm': method = atoi(optarg_); break;
136  case 'h': usage(argv[0], NULL, ipath, w, h, method); return false; break;
137 
138  case 'c': opt_click = false; break;
139  case 'd': opt_display = false; break;
140  break;
141 
142  default:
143  usage(argv[0], optarg_, ipath, w, h, method); return false; break;
144  }
145  }
146 
147  if ((c == 1) || (c == -1)) {
148  // standalone param or error
149  usage(argv[0], NULL, ipath, w, h, method);
150  std::cerr << "ERROR: " << std::endl;
151  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
152  return false;
153  }
154 
155  return true;
156  }
157 }
158 
159 int
160 main(int argc, const char ** argv)
161 {
162  try {
163  std::string env_ipath;
164  std::string opt_ipath;
165  std::string ipath;
166  std::string filename;
167  unsigned int width = 101;
168  unsigned int height = 207;
169  int method = 0;
170  bool opt_display = true;
171  bool opt_click = true;
172 
173  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
174  env_ipath = vpIoTools::getViSPImagesDataPath();
175 
176  // Set the default input path
177  if (! env_ipath.empty())
178  ipath = env_ipath;
179 
180  // Read the command line options
181  if (getOptions(argc, argv, opt_ipath, width, height, method, opt_display, opt_click) == false) {
182  exit (EXIT_FAILURE);
183  }
184 
185  // Get the option values
186  if (!opt_ipath.empty())
187  ipath = opt_ipath;
188 
189  // Compare ipath and env_ipath. If they differ, we take into account
190  // the input path comming from the command line option
191  if (opt_ipath.empty()) {
192  if (ipath != env_ipath) {
193  std::cout << std::endl
194  << "WARNING: " << std::endl;
195  std::cout << " Since -i <visp image path=" << ipath << "> "
196  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
197  << " we skip the environment variable." << std::endl;
198  }
199  }
200 
201  // Test if an input path is set
202  if (opt_ipath.empty() && env_ipath.empty()){
203  usage(argv[0], NULL, ipath, width, height, method);
204  std::cerr << std::endl
205  << "ERROR:" << std::endl;
206  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
207  << std::endl
208  << " environment variable to specify the location of the " << std::endl
209  << " image path where test images are located." << std::endl << std::endl;
210  exit(EXIT_FAILURE);
211  }
212 
213  //
214  // Here starts really the test
215  //
216  for (int m = 0; m < 3; m++) {
217  std::cout << "Interpolation method: " << m << std::endl;
218 
219  vpImage<unsigned char> Itest(3,4);
220  for (unsigned int cpt = 0; cpt < Itest.getSize(); cpt++) {
221  Itest.bitmap[cpt] = cpt;
222  }
223  vpImage<unsigned char> Itest_resize(Itest.getHeight()*2, Itest.getWidth()*2), Itest_resize2(Itest.getHeight(), Itest.getWidth());
225  vpImageTools::resize(Itest_resize, Itest_resize2, (vpImageTools::vpImageInterpolationType) m);
226  std::cout << "Itest:\n" << Itest << std::endl;
227  std::cout << "Itest_resize:\n" << Itest_resize << std::endl;
228  std::cout << "Itest_resize2:\n" << Itest_resize2 << std::endl;
229  std::cout << "(Itest ==Itest_resize2)? " << (Itest == Itest_resize2) << std::endl;
230 
231  Itest.resize(4,4);
232  for (unsigned int cpt = 0; cpt < Itest.getSize(); cpt++) {
233  Itest.bitmap[cpt] = cpt;
234  }
235  vpImageTools::resize(Itest, Itest_resize, Itest.getWidth()/2, Itest.getHeight()/2, (vpImageTools::vpImageInterpolationType) m);
236  vpImageTools::resize(Itest_resize, Itest_resize2, Itest.getWidth(), Itest.getHeight(), (vpImageTools::vpImageInterpolationType) m);
237  std::cout << "\nItest:\n" << Itest << std::endl;
238  std::cout << "Itest_resize:\n" << Itest_resize << std::endl;
239  std::cout << "Itest_resize2:\n" << Itest_resize2 << std::endl;
240  std::cout << "(Itest ==Itest_resize2)? " << (Itest == Itest_resize2) << std::endl << std::endl;
241  }
242 
243  //Grayscale image
244  vpImage<unsigned char> I; // Input image
245 
246  // Read the input grey image from the disk
247  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
248  std::cout << "Read image: " << filename << std::endl;
249  vpImageIo::read(I, filename);
250 
251  vpImage<unsigned char> I_resize;
252  double t = vpTime::measureTimeMs();
253  vpImageTools::resize(I, I_resize, width, height, (vpImageTools::vpImageInterpolationType) method);
254  t = vpTime::measureTimeMs() - t;
255  std::cout << "Time to resize from " << I.getWidth() << "x" << I.getHeight() << " to " << width << "x" << height << ": " << t << " ms" << std::endl;
256 
257 #if defined (VISP_HAVE_X11)
258  vpDisplayX *d1 = new vpDisplayX, *d2 = new vpDisplayX;
259 #elif defined (VISP_HAVE_OPENCV)
260  vpDisplayOpenCV *d1 = new vpDisplayOpenCV, *d2 = new vpDisplayOpenCV;
261 #elif defined (VISP_HAVE_GTK)
262  vpDisplayGTK *d1 = new vpDisplayGTK, *d2 = new vpDisplayGTK;
263 #elif defined (VISP_HAVE_GDI)
264  vpDisplayGDI *d1 = new vpDisplayGDI, *d2 = new vpDisplayGDI;
265 #elif defined (VISP_HAVE_D3D9)
266  vpDisplayD3D *d1 = new vpDisplayD3D, *d2 = new vpDisplayD3D;
267 #else
268  std::cerr << "No display available!" << std::endl;
269  opt_display = false;
270 #endif
271 
272  if (opt_display) {
273 #if defined (VISP_HAVE_X11) || defined (VISP_HAVE_OPENCV) || defined (VISP_HAVE_GTK) || defined (VISP_HAVE_GDI) || defined (VISP_HAVE_D3D9)
274  d1->init(I, 0, 0, "Grayscale image");
275  d2->init(I_resize, (int) I.getWidth()+80, 0, "Grayscale image resized");
276 #endif
277 
279  vpDisplay::display(I_resize);
280  vpDisplay::displayText(I_resize, 20, 20, "Click to continue.", vpColor::red);
281  vpDisplay::flush(I);
282  vpDisplay::flush(I_resize);
283 
284  if (opt_click) {
285  vpDisplay::getClick(I_resize);
286  }
287  }
288 
289 
290  //Color image
291  vpImage<vpRGBa> I_color; // Input image
292 
293  // Read the input grey image from the disk
294  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
295  std::cout << "\nRead image: " << filename << std::endl;
296  vpImageIo::read(I_color, filename);
297 
298  vpImage<vpRGBa> I_color_resize;
299  t = vpTime::measureTimeMs();
300  vpImageTools::resize(I_color, I_color_resize, width, height, (vpImageTools::vpImageInterpolationType) method);
301  t = vpTime::measureTimeMs() - t;
302  std::cout << "Time to resize from " << I_color.getWidth() << "x" << I_color.getHeight() << " to " << width << "x" << height << ": " << t << " ms" << std::endl;
303 
304 #if defined (VISP_HAVE_X11)
305  vpDisplayX *d3 = new vpDisplayX, *d4 = new vpDisplayX;
306 #elif defined (VISP_HAVE_OPENCV)
307  vpDisplayOpenCV *d3 = new vpDisplayOpenCV, *d4 = new vpDisplayOpenCV;
308 #elif defined (VISP_HAVE_GTK)
309  vpDisplayGTK *d3 = new vpDisplayGTK, *d4 = new vpDisplayGTK;
310 #elif defined (VISP_HAVE_GDI)
311  vpDisplayGDI *d3 = new vpDisplayGDI, *d4 = new vpDisplayGDI;
312 #elif defined (VISP_HAVE_D3D9)
313  vpDisplayD3D *d3 = new vpDisplayD3D, *d4 = new vpDisplayD3D;
314 #else
315  std::cerr << "No display available!" << std::endl;
316  opt_display = false;
317 #endif
318 
319  if (opt_display) {
320 #if defined (VISP_HAVE_X11) || defined (VISP_HAVE_OPENCV) || defined (VISP_HAVE_GTK) || defined (VISP_HAVE_GDI) || defined (VISP_HAVE_D3D9)
321  d3->init(I_color, 0, 0, "Color image");
322  d4->init(I_color_resize, (int) I_color.getWidth()+80, 0, "Color image resized");
323 #endif
324 
325  vpDisplay::display(I_color);
326  vpDisplay::display(I_color_resize);
327  vpDisplay::displayText(I_color_resize, 20, 20, "Click to quit.", vpColor::red);
328  vpDisplay::flush(I_color);
329  vpDisplay::flush(I_color_resize);
330  if (opt_click) {
331  vpDisplay::getClick(I_color_resize);
332  }
333  }
334 
335 
336 #if defined (VISP_HAVE_X11) || defined (VISP_HAVE_OPENCV) || defined (VISP_HAVE_GTK) || defined (VISP_HAVE_GDI) || defined (VISP_HAVE_D3D9)
337  delete d1;
338  delete d2;
339  delete d3;
340  delete d4;
341 #endif
342 
343 
344  vpImage<vpRGBa> I_color_double, I_color_double_half;
345  vpImageTools::resize(I_color, I_color_double, I_color.getWidth()*2, I_color.getHeight()*2, (vpImageTools::vpImageInterpolationType) method);
346  vpImageTools::resize(I_color_double, I_color_double_half, I_color.getWidth(), I_color.getHeight(), (vpImageTools::vpImageInterpolationType) method);
347  std::cout << "\n(I_color == I_color_double_half)? " << (I_color == I_color_double_half) << std::endl;
348 
349  double root_mean_square_error = 0.0;
350  for (unsigned int i = 0; i < I_color.getHeight(); i++) {
351  for (unsigned int j = 0; j < I_color.getWidth(); j++) {
352  vpColVector c_error = I_color[i][j] - I_color_double_half[i][j];
353  root_mean_square_error += c_error.sumSquare();
354  }
355  }
356  std::cout << "Root Mean Square Error: " << sqrt(root_mean_square_error / (I_color.getSize()*3)) << std::endl;
357 
358  vpImage<vpRGBa> I_color_half, I_color_half_double;
359  vpImageTools::resize(I_color, I_color_half, I_color.getWidth()/2, I_color.getHeight()/2, (vpImageTools::vpImageInterpolationType) method);
360  vpImageTools::resize(I_color_half, I_color_half_double, I_color.getWidth(), I_color.getHeight(), (vpImageTools::vpImageInterpolationType) method);
361  std::cout << "\n(I_color == I_color_half_double)? " << (I_color == I_color_half_double) << std::endl;
362 
363  root_mean_square_error = 0.0;
364  for (unsigned int i = 0; i < I_color.getHeight(); i++) {
365  for (unsigned int j = 0; j < I_color.getWidth(); j++) {
366  vpColVector c_error = I_color[i][j] - I_color_half_double[i][j];
367  root_mean_square_error += c_error.sumSquare();
368  }
369  }
370  std::cout << "Root Mean Square Error: " << sqrt(root_mean_square_error / (I_color.getSize()*3)) << std::endl;
371 
372 
373  return EXIT_SUCCESS;
374  }
375  catch(const vpException &e) {
376  std::cerr << "Catch an exception: " << e << std::endl;
377  return EXIT_FAILURE;
378  }
379 }
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1157
unsigned int getWidth() const
Definition: vpImage.h:226
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:153
error that can be emited by ViSP classes.
Definition: vpException.h:73
static void flush(const vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
static const vpColor red
Definition: vpColor.h:163
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
Definition: vpDisplayD3D.h:107
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1366
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:138
double sumSquare() const
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:205
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
unsigned int getHeight() const
Definition: vpImage.h:175
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
static void resize(const vpImage< Type > &I, vpImage< Type > &Ires, const unsigned int width, const unsigned int height, const vpImageInterpolationType &method=INTERPOLATION_NEAREST)
Definition: vpImageTools.h:994