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