Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
testImgproc.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 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 imgproc functions.
33  *
34  * Authors:
35  * Souriya Trinh
36  *
37  *****************************************************************************/
38 
39 #include <cstdio>
40 #include <cstdlib>
41 #include <visp3/core/vpImage.h>
42 #include <visp3/core/vpIoTools.h>
43 #include <visp3/core/vpMath.h>
44 #include <visp3/imgproc/vpImgproc.h>
45 #include <visp3/io/vpImageIo.h>
46 #include <visp3/io/vpParseArgv.h>
47 
54 // List of allowed command line options
55 #define GETOPTARGS "cdi:o:h"
56 
57 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user);
58 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user);
59 
60 /*
61  Print the program options.
62 
63  \param name : Program name.
64  \param badparam : Bad parameter name.
65  \param ipath: Input image path.
66  \param opath : Output image path.
67  \param user : Username.
68  */
69 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
70 {
71  fprintf(stdout, "\n\
72 Test imgproc functions.\n\
73 \n\
74 SYNOPSIS\n\
75  %s [-i <input image path>] [-o <output image path>]\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  -o <output image path> %s\n\
90  Set image output path.\n\
91  From this directory, creates the \"%s\"\n\
92  subdirectory depending on the username, where \n\
93  Klimt_grey.pgm output image is written.\n\
94 \n\
95  -h\n\
96  Print the help.\n\n", ipath.c_str(), opath.c_str(), user.c_str());
97 
98  if (badparam)
99  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
100 }
101 
112 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user)
113 {
114  const char *optarg_;
115  int c;
116  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
117 
118  switch (c) {
119  case 'i':
120  ipath = optarg_;
121  break;
122  case 'o':
123  opath = optarg_;
124  break;
125  case 'h':
126  usage(argv[0], NULL, ipath, opath, user);
127  return false;
128  break;
129 
130  case 'c':
131  case 'd':
132  break;
133 
134  default:
135  usage(argv[0], optarg_, ipath, opath, user);
136  return false;
137  break;
138  }
139  }
140 
141  if ((c == 1) || (c == -1)) {
142  // standalone param or error
143  usage(argv[0], NULL, ipath, opath, user);
144  std::cerr << "ERROR: " << std::endl;
145  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
146  return false;
147  }
148 
149  return true;
150 }
151 
152 int main(int argc, const char **argv)
153 {
154  try {
155  std::string env_ipath;
156  std::string opt_ipath;
157  std::string opt_opath;
158  std::string ipath;
159  std::string opath;
160  std::string filename;
161  std::string username;
162 
163  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
164  // environment variable value
165  env_ipath = vpIoTools::getViSPImagesDataPath();
166 
167  // Set the default input path
168  if (!env_ipath.empty())
169  ipath = env_ipath;
170 
171 // Set the default output path
172 #if defined(_WIN32)
173  opt_opath = "C:/temp";
174 #else
175  opt_opath = "/tmp";
176 #endif
177 
178  // Get the user login name
179  vpIoTools::getUserName(username);
180 
181  // Read the command line options
182  if (getOptions(argc, argv, opt_ipath, opt_opath, username) == false) {
183  return EXIT_FAILURE;
184  }
185 
186  // Get the option values
187  if (!opt_ipath.empty())
188  ipath = opt_ipath;
189  if (!opt_opath.empty())
190  opath = opt_opath;
191 
192  // Append to the output path string, the login name of the user
193  opath = vpIoTools::createFilePath(opath, username);
194 
195  // Test if the output path exist. If no try to create it
196  if (vpIoTools::checkDirectory(opath) == false) {
197  try {
198  // Create the dirname
200  } catch (...) {
201  usage(argv[0], NULL, ipath, opt_opath, username);
202  std::cerr << std::endl << "ERROR:" << std::endl;
203  std::cerr << " Cannot create " << opath << std::endl;
204  std::cerr << " Check your -o " << opt_opath << " option " << std::endl;
205  return EXIT_FAILURE;
206  }
207  }
208 
209  // Compare ipath and env_ipath. If they differ, we take into account
210  // the input path comming from the command line option
211  if (!opt_ipath.empty() && !env_ipath.empty()) {
212  if (ipath != env_ipath) {
213  std::cout << std::endl << "WARNING: " << std::endl;
214  std::cout << " Since -i <visp image path=" << ipath << "> "
215  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
216  << " we skip the environment variable." << std::endl;
217  }
218  }
219 
220  // Test if an input path is set
221  if (opt_ipath.empty() && env_ipath.empty()) {
222  usage(argv[0], NULL, ipath, opt_opath, username);
223  std::cerr << std::endl << "ERROR:" << std::endl;
224  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
225  << " environment variable to specify the location of the " << std::endl
226  << " image path where test images are located." << std::endl
227  << std::endl;
228  return EXIT_FAILURE;
229  }
230 
231  //
232  // Here starts really the test
233  //
234 
235  //
236  // Test color functions using Klimt.ppm
237  //
238 
239  // Read Klimt.ppm
240  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
241  vpImage<vpRGBa> I_color, Iinput_color;
242  std::cout << "Read image: " << filename << std::endl;
243  vpImageIo::read(Iinput_color, filename);
244  Iinput_color.halfSizeImage(I_color);
245  std::cout << "Image: " << I_color.getWidth() << "x" << I_color.getHeight() << std::endl;
246 
247  // Adjust
248  double alpha = 1.5, beta = -10.0;
249  vpImage<vpRGBa> I_color_adjust;
250  double t = vpTime::measureTimeMs();
251  vp::adjust(I_color, I_color_adjust, alpha, beta);
252  t = vpTime::measureTimeMs() - t;
253  std::cout << "Time to do color adjust: " << t << " ms" << std::endl;
254 
255  // Save adjust
256  filename = vpIoTools::createFilePath(opath, "Klimt_adjust.ppm");
257  vpImageIo::write(I_color_adjust, filename);
258 
259  // Equalize Histogram
260  vpImage<vpRGBa> I_color_equalize_histogram;
261  t = vpTime::measureTimeMs();
262  vp::equalizeHistogram(I_color, I_color_equalize_histogram);
263  t = vpTime::measureTimeMs() - t;
264  std::cout << "Time to do color histogram equalization: " << t << " ms" << std::endl;
265 
266  // Save equalizeHistogram
267  filename = vpIoTools::createFilePath(opath, "Klimt_equalize_histogram.ppm");
268  vpImageIo::write(I_color_equalize_histogram, filename);
269 
270  // Gamma correction
271  vpImage<vpRGBa> I_color_gamma_correction;
272  double gamma = 2.2;
273  t = vpTime::measureTimeMs();
274  vp::gammaCorrection(I_color, I_color_gamma_correction, gamma);
275  t = vpTime::measureTimeMs() - t;
276  std::cout << "Time to do color gamma correction: " << t << " ms" << std::endl;
277 
278  // Save gammaCorrection
279  filename = vpIoTools::createFilePath(opath, "Klimt_gamma_correction.ppm");
280  vpImageIo::write(I_color_gamma_correction, filename);
281 
282  // Retinex
283  vpImage<vpRGBa> I_color_retinex;
284  t = vpTime::measureTimeMs();
285  vp::retinex(I_color, I_color_retinex);
286  t = vpTime::measureTimeMs() - t;
287  std::cout << "Time to do color retinex: " << t << " ms" << std::endl;
288 
289  // Save retinex
290  filename = vpIoTools::createFilePath(opath, "Klimt_retinex.ppm");
291  vpImageIo::write(I_color_retinex, filename);
292 
293  // Stretch contrast
294  vpImage<vpRGBa> I_color_stretch_contrast;
295  t = vpTime::measureTimeMs();
296  vp::stretchContrast(I_color, I_color_stretch_contrast);
297  t = vpTime::measureTimeMs() - t;
298  std::cout << "Time to do color contrast stretching: " << t << " ms" << std::endl;
299 
300  // Save stretchContrast
301  filename = vpIoTools::createFilePath(opath, "Klimt_stretch_contrast.ppm");
302  vpImageIo::write(I_color_stretch_contrast, filename);
303 
304  // Stretch Contrast HSV
305  vpImage<vpRGBa> I_color_stretch_contrast_HSV;
306  t = vpTime::measureTimeMs();
307  vp::stretchContrastHSV(I_color, I_color_stretch_contrast_HSV);
308  t = vpTime::measureTimeMs() - t;
309  std::cout << "Time to do color HSV contrast stretching: " << t << " ms" << std::endl;
310 
311  // Save stretchContrastHSV
312  filename = vpIoTools::createFilePath(opath, "Klimt_stretch_contrast_HSV.ppm");
313  vpImageIo::write(I_color_stretch_contrast_HSV, filename);
314 
315  // Unsharp Mask
316  vpImage<vpRGBa> I_color_unsharp_mask;
317  t = vpTime::measureTimeMs();
318  vp::unsharpMask(I_color, I_color_unsharp_mask);
319  t = vpTime::measureTimeMs() - t;
320  std::cout << "Time to do color unsharp mask: " << t << " ms" << std::endl;
321 
322  // Save unsharpMask
323  filename = vpIoTools::createFilePath(opath, "Klimt_unsharp_mask.ppm");
324  vpImageIo::write(I_color_unsharp_mask, filename);
325 
326  // CLAHE
327  vpImage<vpRGBa> I_color_clahe;
328  t = vpTime::measureTimeMs();
329  vp::clahe(I_color, I_color_clahe, 50);
330  t = vpTime::measureTimeMs() - t;
331  std::cout << "Time to do color CLAHE: " << t << " ms" << std::endl;
332 
333  // Save CLAHE
334  filename = vpIoTools::createFilePath(opath, "Klimt_CLAHE.ppm");
335  vpImageIo::write(I_color_clahe, filename);
336 
337  //
338  // Test grayscale function using image0000.pgm
339  //
340 
341  // Read image0000.pgm
342  filename = vpIoTools::createFilePath(ipath, "mbt/cube/image0000.pgm");
343  vpImage<unsigned char> Iinput, I;
344  std::cout << "\nRead image: " << filename << std::endl;
345  vpImageIo::read(Iinput, filename);
346  Iinput.halfSizeImage(I);
347  std::cout << "Image: " << I.getWidth() << "x" << I.getHeight() << std::endl;
348 
349  // Adjust
350  vpImage<unsigned char> I_adjust;
351  beta = -20.0;
352  t = vpTime::measureTimeMs();
353  vp::adjust(I, I_adjust, alpha, beta);
354  t = vpTime::measureTimeMs() - t;
355  std::cout << "Time to do grayscale adjust: " << t << " ms" << std::endl;
356 
357  // Save adjust
358  filename = vpIoTools::createFilePath(opath, "image0000_adjust.pgm");
359  vpImageIo::write(I_adjust, filename);
360 
361  // Equalize Histogram
362  vpImage<unsigned char> I_equalize_histogram;
363  t = vpTime::measureTimeMs();
364  vp::equalizeHistogram(I, I_equalize_histogram);
365  t = vpTime::measureTimeMs() - t;
366  std::cout << "Time to do grayscale histogram equalization: " << t << " ms" << std::endl;
367 
368  // Save equalizeHistogram
369  filename = vpIoTools::createFilePath(opath, "image0000_equalize_histogram.pgm");
370  vpImageIo::write(I_equalize_histogram, filename);
371 
372  // Gamma correction
373  vpImage<unsigned char> I_gamma_correction;
374  gamma = 1.8;
375  t = vpTime::measureTimeMs();
376  vp::gammaCorrection(I, I_gamma_correction, gamma);
377  t = vpTime::measureTimeMs() - t;
378  std::cout << "Time to do grayscale gamma correction: " << t << " ms" << std::endl;
379 
380  // Save gammaCorrection
381  filename = vpIoTools::createFilePath(opath, "image0000_gamma_correction.pgm");
382  vpImageIo::write(I_gamma_correction, filename);
383 
384  // Stretch contrast
385  vpImage<unsigned char> I_stretch_contrast;
386  t = vpTime::measureTimeMs();
387  vp::stretchContrast(I, I_stretch_contrast);
388  t = vpTime::measureTimeMs() - t;
389  std::cout << "Time to do grayscale contrast stretching: " << t << " ms" << std::endl;
390 
391  // Save stretchContrast
392  filename = vpIoTools::createFilePath(opath, "image0000_stretch_contrast.pgm");
393  vpImageIo::write(I_stretch_contrast, filename);
394 
395  // Unsharp Mask
396  vpImage<unsigned char> I_unsharp_mask;
397  t = vpTime::measureTimeMs();
398  vp::unsharpMask(I, I_unsharp_mask);
399  t = vpTime::measureTimeMs() - t;
400  std::cout << "Time to do grayscale unsharp mask: " << t << " ms" << std::endl;
401 
402  // Save unsharpMask
403  filename = vpIoTools::createFilePath(opath, "image0000_unsharp_mask.pgm");
404  vpImageIo::write(I_unsharp_mask, filename);
405 
406  // CLAHE
407  vpImage<unsigned char> I_clahe;
408  t = vpTime::measureTimeMs();
409  vp::clahe(I, I_clahe, 50);
410  t = vpTime::measureTimeMs() - t;
411  std::cout << "Time to do grayscale CLAHE: " << t << " ms" << std::endl;
412 
413  // Save CLAHE
414  filename = vpIoTools::createFilePath(opath, "image0000_CLAHE.pgm");
415  vpImageIo::write(I_clahe, filename);
416 
417  return EXIT_SUCCESS;
418  } catch (const vpException &e) {
419  std::cerr << "Catch an exception: " << e.what() << std::endl;
420  return EXIT_FAILURE;
421  }
422 }
VISP_EXPORT void unsharpMask(vpImage< unsigned char > &I, const unsigned int size=7, const double weight=0.6)
Definition: vpImgproc.cpp:624
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:467
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1316
unsigned int getWidth() const
Definition: vpImage.h:239
VISP_EXPORT void adjust(vpImage< unsigned char > &I, const double alpha, const double beta)
Definition: vpImgproc.cpp:80
error that can be emited by ViSP classes.
Definition: vpException.h:71
VISP_EXPORT void gammaCorrection(vpImage< unsigned char > &I, const double gamma)
Definition: vpImgproc.cpp:334
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:88
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
VISP_EXPORT void stretchContrast(vpImage< unsigned char > &I)
Definition: vpImgproc.cpp:418
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:375
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:597
const char * what() const
VISP_EXPORT void stretchContrastHSV(vpImage< vpRGBa > &I)
Definition: vpImgproc.cpp:555
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1541
static std::string getUserName()
Definition: vpIoTools.cpp:298
VISP_EXPORT void clahe(const vpImage< unsigned char > &I1, vpImage< unsigned char > &I2, const int blockRadius=150, const int bins=256, const float slope=3.0f, const bool fast=true)
Definition: vpCLAHE.cpp:228
void halfSizeImage(vpImage< Type > &res) const
Definition: vpImage.h:1265
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:207
VISP_EXPORT void equalizeHistogram(vpImage< unsigned char > &I)
Definition: vpImgproc.cpp:164
unsigned int getHeight() const
Definition: vpImage.h:178
VISP_EXPORT void retinex(vpImage< vpRGBa > &I, const int scale=240, const int scaleDiv=3, const int level=RETINEX_UNIFORM, const double dynamic=1.2, const int kernelSize=-1)
Definition: vpRetinex.cpp:258