Visual Servoing Platform  version 3.1.0
testImgproc.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 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;
242  std::cout << "Read image: " << filename << std::endl;
243  vpImageIo::read(I_color, filename);
244  std::cout << "Image: " << I_color.getWidth() << "x" << I_color.getHeight() << std::endl;
245 
246  // Adjust
247  double alpha = 1.5, beta = -10.0;
248  vpImage<vpRGBa> I_color_adjust;
249  double t = vpTime::measureTimeMs();
250  vp::adjust(I_color, I_color_adjust, alpha, beta);
251  t = vpTime::measureTimeMs() - t;
252  std::cout << "Time to do color adjust: " << t << " ms" << std::endl;
253 
254  // Save adjust
255  filename = vpIoTools::createFilePath(opath, "Klimt_adjust.ppm");
256  vpImageIo::write(I_color_adjust, filename);
257 
258  // Equalize Histogram
259  vpImage<vpRGBa> I_color_equalize_histogram;
260  t = vpTime::measureTimeMs();
261  vp::equalizeHistogram(I_color, I_color_equalize_histogram);
262  t = vpTime::measureTimeMs() - t;
263  std::cout << "Time to do color histogram equalization: " << t << " ms" << std::endl;
264 
265  // Save equalizeHistogram
266  filename = vpIoTools::createFilePath(opath, "Klimt_equalize_histogram.ppm");
267  vpImageIo::write(I_color_equalize_histogram, filename);
268 
269  // Gamma correction
270  vpImage<vpRGBa> I_color_gamma_correction;
271  double gamma = 2.2;
272  t = vpTime::measureTimeMs();
273  vp::gammaCorrection(I_color, I_color_gamma_correction, gamma);
274  t = vpTime::measureTimeMs() - t;
275  std::cout << "Time to do color gamma correction: " << t << " ms" << std::endl;
276 
277  // Save gammaCorrection
278  filename = vpIoTools::createFilePath(opath, "Klimt_gamma_correction.ppm");
279  vpImageIo::write(I_color_gamma_correction, filename);
280 
281  // Retinex
282  vpImage<vpRGBa> I_color_retinex;
283  t = vpTime::measureTimeMs();
284  vp::retinex(I_color, I_color_retinex);
285  t = vpTime::measureTimeMs() - t;
286  std::cout << "Time to do color retinex: " << t << " ms" << std::endl;
287 
288  // Save retinex
289  filename = vpIoTools::createFilePath(opath, "Klimt_retinex.ppm");
290  vpImageIo::write(I_color_retinex, filename);
291 
292  // Stretch contrast
293  vpImage<vpRGBa> I_color_stretch_contrast;
294  t = vpTime::measureTimeMs();
295  vp::stretchContrast(I_color, I_color_stretch_contrast);
296  t = vpTime::measureTimeMs() - t;
297  std::cout << "Time to do color contrast stretching: " << t << " ms" << std::endl;
298 
299  // Save stretchContrast
300  filename = vpIoTools::createFilePath(opath, "Klimt_stretch_contrast.ppm");
301  vpImageIo::write(I_color_stretch_contrast, filename);
302 
303  // Stretch Contrast HSV
304  vpImage<vpRGBa> I_color_stretch_contrast_HSV;
305  t = vpTime::measureTimeMs();
306  vp::stretchContrastHSV(I_color, I_color_stretch_contrast_HSV);
307  t = vpTime::measureTimeMs() - t;
308  std::cout << "Time to do color HSV contrast stretching: " << t << " ms" << std::endl;
309 
310  // Save stretchContrastHSV
311  filename = vpIoTools::createFilePath(opath, "Klimt_stretch_contrast_HSV.ppm");
312  vpImageIo::write(I_color_stretch_contrast_HSV, filename);
313 
314  // Unsharp Mask
315  vpImage<vpRGBa> I_color_unsharp_mask;
316  t = vpTime::measureTimeMs();
317  vp::unsharpMask(I_color, I_color_unsharp_mask);
318  t = vpTime::measureTimeMs() - t;
319  std::cout << "Time to do color unsharp mask: " << t << " ms" << std::endl;
320 
321  // Save unsharpMask
322  filename = vpIoTools::createFilePath(opath, "Klimt_unsharp_mask.ppm");
323  vpImageIo::write(I_color_unsharp_mask, filename);
324 
325  // CLAHE
326  vpImage<vpRGBa> I_color_clahe;
327  t = vpTime::measureTimeMs();
328  vp::clahe(I_color, I_color_clahe);
329  t = vpTime::measureTimeMs() - t;
330  std::cout << "Time to do color CLAHE: " << t << " ms" << std::endl;
331 
332  // Save CLAHE
333  filename = vpIoTools::createFilePath(opath, "Klimt_CLAHE.ppm");
334  vpImageIo::write(I_color_clahe, filename);
335 
336  //
337  // Test grayscale function using image0000.pgm
338  //
339 
340  // Read image0000.pgm
341  filename = vpIoTools::createFilePath(ipath, "mbt/cube/image0000.pgm");
343  std::cout << "\nRead image: " << filename << std::endl;
344  vpImageIo::read(I, filename);
345  std::cout << "Image: " << I.getWidth() << "x" << I.getHeight() << std::endl;
346 
347  // Adjust
348  vpImage<unsigned char> I_adjust;
349  beta = -20.0;
350  t = vpTime::measureTimeMs();
351  vp::adjust(I, I_adjust, alpha, beta);
352  t = vpTime::measureTimeMs() - t;
353  std::cout << "Time to do grayscale adjust: " << t << " ms" << std::endl;
354 
355  // Save adjust
356  filename = vpIoTools::createFilePath(opath, "image0000_adjust.pgm");
357  vpImageIo::write(I_adjust, filename);
358 
359  // Equalize Histogram
360  vpImage<unsigned char> I_equalize_histogram;
361  t = vpTime::measureTimeMs();
362  vp::equalizeHistogram(I, I_equalize_histogram);
363  t = vpTime::measureTimeMs() - t;
364  std::cout << "Time to do grayscale histogram equalization: " << t << " ms" << std::endl;
365 
366  // Save equalizeHistogram
367  filename = vpIoTools::createFilePath(opath, "image0000_equalize_histogram.pgm");
368  vpImageIo::write(I_equalize_histogram, filename);
369 
370  // Gamma correction
371  vpImage<unsigned char> I_gamma_correction;
372  gamma = 1.8;
373  t = vpTime::measureTimeMs();
374  vp::gammaCorrection(I, I_gamma_correction, gamma);
375  t = vpTime::measureTimeMs() - t;
376  std::cout << "Time to do grayscale gamma correction: " << t << " ms" << std::endl;
377 
378  // Save gammaCorrection
379  filename = vpIoTools::createFilePath(opath, "image0000_gamma_correction.pgm");
380  vpImageIo::write(I_gamma_correction, filename);
381 
382  // Stretch contrast
383  vpImage<unsigned char> I_stretch_contrast;
384  t = vpTime::measureTimeMs();
385  vp::stretchContrast(I, I_stretch_contrast);
386  t = vpTime::measureTimeMs() - t;
387  std::cout << "Time to do grayscale contrast stretching: " << t << " ms" << std::endl;
388 
389  // Save stretchContrast
390  filename = vpIoTools::createFilePath(opath, "image0000_stretch_contrast.pgm");
391  vpImageIo::write(I_stretch_contrast, filename);
392 
393  // Unsharp Mask
394  vpImage<unsigned char> I_unsharp_mask;
395  t = vpTime::measureTimeMs();
396  vp::unsharpMask(I, I_unsharp_mask);
397  t = vpTime::measureTimeMs() - t;
398  std::cout << "Time to do grayscale unsharp mask: " << t << " ms" << std::endl;
399 
400  // Save unsharpMask
401  filename = vpIoTools::createFilePath(opath, "image0000_unsharp_mask.pgm");
402  vpImageIo::write(I_unsharp_mask, filename);
403 
404  // CLAHE
405  vpImage<unsigned char> I_clahe;
406  t = vpTime::measureTimeMs();
407  vp::clahe(I, I_clahe);
408  t = vpTime::measureTimeMs() - t;
409  std::cout << "Time to do grayscale CLAHE: " << t << " ms" << std::endl;
410 
411  // Save CLAHE
412  filename = vpIoTools::createFilePath(opath, "image0000_CLAHE.pgm");
413  vpImageIo::write(I_clahe, filename);
414 
415  return EXIT_SUCCESS;
416  } catch (const vpException &e) {
417  std::cerr << "Catch an exception: " << e.what() << std::endl;
418  return EXIT_FAILURE;
419  }
420 }
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:367
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1210
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:495
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:1435
static std::string getUserName()
Definition: vpIoTools.cpp:198
const char * what() const
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:224
unsigned int getHeight() const
Definition: vpImage.h:178
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 getWidth() const
Definition: vpImage.h:229
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