ViSP  3.0.0
testPerformanceLUT.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 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 performance between iteration and LUT.
32  *
33  * Authors:
34  * Souriya Trinh
35  *
36  *****************************************************************************/
37 
38 #include <visp3/core/vpImage.h>
39 #include <visp3/io/vpImageIo.h>
40 #include <visp3/io/vpParseArgv.h>
41 #include <visp3/core/vpIoTools.h>
42 #include <visp3/core/vpMath.h>
43 #include <stdlib.h>
44 #include <stdio.h>
45 
53 // List of allowed command line options
54 #define GETOPTARGS "cdi:o:h"
55 
56 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user);
57 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user);
58 
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  */
70 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
71 {
72  fprintf(stdout, "\n\
73 Test performance between methods to iterate over pixel image.\n\
74 \n\
75 SYNOPSIS\n\
76  %s [-i <input image path>] [-o <output image path>]\n\
77  [-h]\n \
78 ", name);
79 
80  fprintf(stdout, "\n\
81 OPTIONS: Default\n\
82  -i <input image path> %s\n\
83  Set image input path.\n\
84  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
85  image.\n\
86  Setting the VISP_INPUT_IMAGE_PATH environment\n\
87  variable produces the same behaviour than using\n\
88  this option.\n\
89 \n\
90  -o <output image path> %s\n\
91  Set image output path.\n\
92  From this directory, creates the \"%s\"\n\
93  subdirectory depending on the username, where \n\
94  Klimt_grey.pgm output image is written.\n\
95 \n\
96  -h\n\
97  Print the help.\n\n",
98  ipath.c_str(), opath.c_str(), user.c_str());
99 
100  if (badparam)
101  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
102 }
103 
116 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user)
117 {
118  const char *optarg_;
119  int c;
120  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
121 
122  switch (c) {
123  case 'i': ipath = optarg_; break;
124  case 'o': opath = optarg_; break;
125  case 'h': usage(argv[0], NULL, ipath, opath, user); return false; break;
126 
127  case 'c':
128  case 'd':
129  break;
130 
131  default:
132  usage(argv[0], optarg_, ipath, opath, user); return false; break;
133  }
134  }
135 
136  if ((c == 1) || (c == -1)) {
137  // standalone param or error
138  usage(argv[0], NULL, ipath, opath, user);
139  std::cerr << "ERROR: " << std::endl;
140  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
141  return false;
142  }
143 
144  return true;
145 }
146 
155 void iterate_method1(vpImage<vpRGBa> &I, const double alpha, const double beta) {
156  unsigned int size = I.getWidth() * I.getHeight();
157  unsigned char *ptrStart = (unsigned char*) I.bitmap;
158  unsigned char *ptrEnd = ptrStart + size*4;
159  unsigned char *ptrCurrent = ptrStart;
160 
161  while(ptrCurrent != ptrEnd) {
162  *ptrCurrent = vpMath::saturate<unsigned char>((*ptrCurrent) * alpha + beta);
163  ++ptrCurrent;
164  }
165 }
166 
175 void iterate_method2(vpImage<vpRGBa> &I, const double alpha, const double beta) {
176  for(unsigned int i = 0; i < I.getHeight(); i++) {
177  for(unsigned int j = 0; j < I.getWidth(); j++) {
178  I[i][j].R = vpMath::saturate<unsigned char>(I[i][j].R * alpha + beta);
179  I[i][j].G = vpMath::saturate<unsigned char>(I[i][j].G * alpha + beta);
180  I[i][j].B = vpMath::saturate<unsigned char>(I[i][j].B * alpha + beta);
181  I[i][j].A = vpMath::saturate<unsigned char>(I[i][j].A * alpha + beta);
182  }
183  }
184 }
185 
192 void lut_method(vpImage<vpRGBa> &I, const vpRGBa (&lut)[256]) {
193  I.performLut(lut);
194 }
195 
196 int
197 main(int argc, const char ** argv)
198 {
199  try {
200  std::string env_ipath;
201  std::string opt_ipath;
202  std::string opt_opath;
203  std::string ipath;
204  std::string opath;
205  std::string filename;
206  std::string username;
207 
208  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
209  env_ipath = vpIoTools::getViSPImagesDataPath();
210 
211  // Set the default input path
212  if (! env_ipath.empty())
213  ipath = env_ipath;
214 
215  // Set the default output path
216 #if defined(_WIN32)
217  opt_opath = "C:/temp";
218 #else
219  opt_opath = "/tmp";
220 #endif
221 
222  // Get the user login name
223  vpIoTools::getUserName(username);
224 
225  // Read the command line options
226  if (getOptions(argc, argv, opt_ipath, opt_opath, username) == false) {
227  exit (-1);
228  }
229 
230  // Get the option values
231  if (!opt_ipath.empty())
232  ipath = opt_ipath;
233  if (!opt_opath.empty())
234  opath = opt_opath;
235 
236  // Append to the output path string, the login name of the user
237  opath = vpIoTools::createFilePath(opath, username);
238 
239  // Test if the output path exist. If no try to create it
240  if (vpIoTools::checkDirectory(opath) == false) {
241  try {
242  // Create the dirname
244  }
245  catch (...) {
246  usage(argv[0], NULL, ipath, opt_opath, username);
247  std::cerr << std::endl
248  << "ERROR:" << std::endl;
249  std::cerr << " Cannot create " << opath << std::endl;
250  std::cerr << " Check your -o " << opt_opath << " option " << std::endl;
251  exit(-1);
252  }
253  }
254 
255  // Compare ipath and env_ipath. If they differ, we take into account
256  // the input path comming from the command line option
257  if (!opt_ipath.empty() && !env_ipath.empty()) {
258  if (ipath != env_ipath) {
259  std::cout << std::endl
260  << "WARNING: " << std::endl;
261  std::cout << " Since -i <visp image path=" << ipath << "> "
262  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
263  << " we skip the environment variable." << std::endl;
264  }
265  }
266 
267  // Test if an input path is set
268  if (opt_ipath.empty() && env_ipath.empty()){
269  usage(argv[0], NULL, ipath, opt_opath, username);
270  std::cerr << std::endl
271  << "ERROR:" << std::endl;
272  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
273  << std::endl
274  << " environment variable to specify the location of the " << std::endl
275  << " image path where test images are located." << std::endl << std::endl;
276  exit(-1);
277  }
278 
279 
280  //
281  // Here starts really the test
282  //
283 
284  // Create a grey level image
285  vpImage<vpRGBa> I_iterate1, I_iterate2, I_lut;
286 
287  // Load a grey image from the disk
288  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
289  std::cout << "Read image: " << filename << std::endl;
290  vpImageIo::read(I_iterate1, filename);
291  vpImageIo::read(I_iterate2, filename);
292  vpImageIo::read(I_lut, filename);
293 
294  std::cout << "I=" << I_iterate1.getWidth() << "x" << I_iterate1.getHeight() << std::endl;
295 
296  double alpha = 1.5, beta = -30.0;
297  unsigned int nbIterations = 10;
298 
299  //Iterate method 1
300  double t_iterate1 = vpTime::measureTimeMs();
301  for(unsigned int cpt = 0; cpt < nbIterations; cpt++) {
302  iterate_method1(I_iterate1, alpha, beta);
303  }
304  t_iterate1 = vpTime::measureTimeMs() - t_iterate1;
305  std::cout << "t_iterate1=" << t_iterate1 << " ms ; t_iterate1/" << nbIterations << "="
306  << (t_iterate1/nbIterations) << " ms" << std::endl;
307 
308  filename = vpIoTools::createFilePath(opath, "Klimt_performance_iterate1.ppm");
309  vpImageIo::write(I_iterate1, filename);
310 
311 
312  //Iterate method 2
313  double t_iterate2 = vpTime::measureTimeMs();
314  for(unsigned int cpt = 0; cpt < nbIterations; cpt++) {
315  iterate_method2(I_iterate2, alpha, beta);
316  }
317  t_iterate2 = vpTime::measureTimeMs() - t_iterate2;
318  std::cout << "t_iterate2=" << t_iterate2 << " ms ; t_iterate2/" << nbIterations << "="
319  << (t_iterate2/nbIterations) << " ms" << std::endl;
320 
321  filename = vpIoTools::createFilePath(opath, "Klimt_performance_iterate2.ppm");
322  vpImageIo::write(I_iterate2, filename);
323 
324 
325  //LUT method
326  double t_lut = vpTime::measureTimeMs();
327  for(unsigned int cpt = 0; cpt < nbIterations; cpt++) {
328  //Construct the LUT
329  vpRGBa lut[256];
330  for(unsigned int i = 0; i < 256; i++) {
331  lut[i].R = vpMath::saturate<unsigned char>(alpha * i + beta);
332  lut[i].G = vpMath::saturate<unsigned char>(alpha * i + beta);
333  lut[i].B = vpMath::saturate<unsigned char>(alpha * i + beta);
334  lut[i].A = vpMath::saturate<unsigned char>(alpha * i + beta);
335  }
336 
337  lut_method(I_lut, lut);
338  }
339  t_lut = vpTime::measureTimeMs() - t_lut;
340  std::cout << "t_lut=" << t_lut << " ms ; t_lut/" << nbIterations << "="
341  << (t_lut/nbIterations) << " ms" << std::endl;
342 
343  filename = vpIoTools::createFilePath(opath, "Klimt_performance_lut.ppm");
344  vpImageIo::write(I_lut, filename);
345  return 0;
346  }
347  catch(vpException &e) {
348  std::cerr << "Catch an exception: " << e.what() << std::endl;
349  return 1;
350  }
351 }
static void write(const vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:472
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:335
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1091
unsigned int getWidth() const
Definition: vpImage.h:161
unsigned char B
Blue component.
Definition: vpRGBa.h:144
Type * bitmap
points toward the bitmap
Definition: vpImage.h:116
error that can be emited by ViSP classes.
Definition: vpException.h:73
unsigned char G
Green component.
Definition: vpRGBa.h:143
void performLut(const Type(&lut)[256])
Definition: vpImage.h:1544
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
Class that defines a RGB 32 bits structure.
Definition: vpRGBa.h:64
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:404
const char * what() const
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1265
unsigned char A
Additionnal component.
Definition: vpRGBa.h:145
static std::string getUserName()
Definition: vpIoTools.cpp:161
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
unsigned char R
Red component.
Definition: vpRGBa.h:142
unsigned int getHeight() const
Definition: vpImage.h:152
static void read(vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:274