Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testConversion.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 for image conversions.
32  *
33  * Authors:
34  * Fabien Spindler
35  *
36  *****************************************************************************/
37 
38 #include <stdlib.h>
39 #include <iomanip>
40 
41 #include <visp3/core/vpConfig.h>
42 #include <visp3/core/vpImage.h>
43 #include <visp3/io/vpImageIo.h>
44 #include <visp3/core/vpImageConvert.h>
45 #include <visp3/io/vpParseArgv.h>
46 #include <visp3/core/vpIoTools.h>
47 #include <visp3/core/vpDebug.h>
48 #include <visp3/core/vpTime.h>
49 
50 
57 // List of allowed command line options
58 #define GETOPTARGS "cdi:o:n:h"
59 
60 
61 /*
62  Print the program options.
63 
64  \param name : Program name.
65  \param badparam : Bad parameter name.
66  \param ipath: Input image path.
67  \param opath : Output image path.
68  \param user : Username.
69  \param nbiter : Iteration number.
70 
71  */
72 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user, int nbiter)
73 {
74  fprintf(stdout, "\n\
75 Test image conversions.\n\
76 \n\
77 SYNOPSIS\n\
78  %s [-i <input image path>] [-o <output image path>] [-n <nb benchmark iterations>]\n\
79  [-h]\n \
80 ", name);
81 
82  fprintf(stdout, "\n\
83 OPTIONS: Default\n\
84  -i <input image path> %s\n\
85  Set image input path.\n\
86  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
87  and \"ViSP-images/Klimt/Klimt.ppm\" images.\n\
88  Setting the VISP_INPUT_IMAGE_PATH environment\n\
89  variable produces the same behaviour than using\n\
90  this option.\n\
91 \n\
92  -o <output image path> %s\n\
93  Set image output path.\n\
94  From this directory, creates the \"%s\"\n\
95  subdirectory depending on the username, where \n\
96  Klimt_grey.pgm and Klimt_color.ppm output images\n\
97  are written.\n\
98 \n\
99  -n <nb benchmark iterations> %d\n\
100  Set the number of benchmark iterations.\n\
101 \n\
102  -h\n\
103  Print the help.\n\n",
104  ipath.c_str(), opath.c_str(), user.c_str(), nbiter);
105 
106  if (badparam)
107  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
108 }
109 
123 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, std::string user,
124  int &nbIterations)
125 {
126  const char *optarg_;
127  int c;
128  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
129 
130  switch (c) {
131  case 'i': ipath = optarg_; break;
132  case 'o': opath = optarg_; break;
133  case 'n': nbIterations = atoi(optarg_); break;
134  case 'h': usage(argv[0], NULL, ipath, opath, user, nbIterations); return false; break;
135 
136  case 'c':
137  case 'd':
138  break;
139 
140  default:
141  usage(argv[0], optarg_, ipath, opath, user, nbIterations); return false; break;
142  }
143  }
144 
145  if ((c == 1) || (c == -1)) {
146  // standalone param or error
147  usage(argv[0], NULL, ipath, opath, user, nbIterations);
148  std::cerr << "ERROR: " << std::endl;
149  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
150  return false;
151  }
152 
153  return true;
154 }
155 
156 void computeRegularRGBaToGrayscale(const unsigned char* rgba, unsigned char* grey, unsigned int size) {
157  const unsigned char *pt_input = rgba;
158  const unsigned char *pt_end = rgba + size*4;
159  unsigned char *pt_output = grey;
160 
161  while(pt_input != pt_end) {
162  *pt_output = (unsigned char) (0.2126 * (*pt_input)
163  + 0.7152 * (*(pt_input + 1))
164  + 0.0722 * (*(pt_input + 2)) );
165  pt_input += 4;
166  pt_output ++;
167  }
168 }
169 
170 void computeRegularRGBToGrayscale(const unsigned char* rgb, unsigned char* grey, unsigned int size) {
171  const unsigned char *pt_input = rgb;
172  const unsigned char* pt_end = rgb + size*3;
173  unsigned char *pt_output = grey;
174 
175  while(pt_input != pt_end) {
176  *pt_output = (unsigned char) (0.2126 * (*pt_input)
177  + 0.7152 * (*(pt_input + 1))
178  + 0.0722 * (*(pt_input + 2)) );
179  pt_input += 3;
180  pt_output ++;
181  }
182 }
183 
184 void computeRegularBGRToGrayscale(unsigned char * bgr, unsigned char * grey,
185  unsigned int width, unsigned int height, bool flip) {
186  //if we have to flip the image, we start from the end last scanline so the
187  //step is negative
188  int lineStep = (flip) ? -(int)(width*3) : (int)(width*3);
189 
190  //starting source address = last line if we need to flip the image
191  unsigned char * src = (flip) ? bgr+(width*height*3)+lineStep : bgr;
192 
193  unsigned int j=0;
194  unsigned int i=0;
195 
196  for(i=0 ; i < height ; i++)
197  {
198  unsigned char *line = src;
199  for( j=0 ; j < width ; j++)
200  {
201  *grey++ = (unsigned char)( 0.2126 * *(line+2)
202  + 0.7152 * *(line+1)
203  + 0.0722 * *(line+0)) ;
204  line+=3;
205  }
206 
207  //go to the next line
208  src+=lineStep;
209  }
210 }
211 
212 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
213 void computeRegularBGRToGrayscale(const cv::Mat& src, vpImage<unsigned char>& dest)
214 {
215  if(src.type() == CV_8UC3) {
216  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
217 
218  if(src.isContinuous()) {
219  computeRegularBGRToGrayscale((unsigned char*)src.data, (unsigned char*)dest.bitmap, (unsigned int)src.cols, (unsigned int)src.rows, false);
220  }
221  }
222 }
223 #endif
224 
225 int
226 main(int argc, const char ** argv)
227 {
228  try {
229  std::string env_ipath;
230  std::string opt_ipath;
231  std::string opt_opath;
232  std::string ipath;
233  std::string opath;
234  std::string filename;
235  std::string username;
236  int nbIterations = 100;
237 
238  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
239  env_ipath = vpIoTools::getViSPImagesDataPath();
240 
241  // Set the default input path
242  if (! env_ipath.empty())
243  ipath = env_ipath;
244 
245  // Set the default output path
246 #if defined(_WIN32)
247  opt_opath = "C:/temp";
248 #else
249  opt_opath = "/tmp";
250 #endif
251 
252  // Get the user login name
253  vpIoTools::getUserName(username);
254 
255  // Read the command line options
256  if (getOptions(argc, argv, opt_ipath, opt_opath, username, nbIterations) == false) {
257  exit (-1);
258  }
259 
260  // Get the option values
261  if (!opt_ipath.empty())
262  ipath = opt_ipath;
263  if (!opt_opath.empty())
264  opath = opt_opath;
265 
266  // Append to the output path string, the login name of the user
267  opath = vpIoTools::createFilePath(opath, username);
268 
269  // Test if the output path exist. If no try to create it
270  if (vpIoTools::checkDirectory(opath) == false) {
271  try {
272  // Create the dirname
274  }
275  catch (...) {
276  usage(argv[0], NULL, ipath, opt_opath, username, nbIterations);
277  std::cerr << std::endl
278  << "ERROR:" << std::endl;
279  std::cerr << " Cannot create " << opath << std::endl;
280  std::cerr << " Check your -o " << opt_opath << " option " << std::endl;
281  exit(-1);
282  }
283  }
284 
285  // Compare ipath and env_ipath. If they differ, we take into account
286  // the input path comming from the command line option
287  if (opt_ipath.empty()) {
288  if (ipath != env_ipath) {
289  std::cout << std::endl
290  << "WARNING: " << std::endl;
291  std::cout << " Since -i <visp image path=" << ipath << "> "
292  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
293  << " we skip the environment variable." << std::endl;
294  }
295  }
296 
297  // Test if an input path is set
298  if (opt_ipath.empty() && env_ipath.empty()){
299  usage(argv[0], NULL, ipath, opt_opath, username, nbIterations);
300  std::cerr << std::endl
301  << "ERROR:" << std::endl;
302  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
303  << std::endl
304  << " environment variable to specify the location of the " << std::endl
305  << " image path where test images are located." << std::endl << std::endl;
306  exit(-1);
307  }
308 
309  //
310  // Here starts really the test
311  //
312 
313  vpImage<unsigned char> Ig ; // Grey image
314  vpImage<vpRGBa> Ic ; // Color image
315 
316  //-------------------- .pgm -> .ppm
317  std::cout << "** Convert a grey image (.pgm) to a color image (.ppm)" << std::endl;
318  // Load a grey image from the disk
319  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
320  std::cout << " Load " << filename << std::endl;
321  vpImageIo::read(Ig, filename) ;
322  // Create a color image from the grey
323  vpImageConvert::convert(Ig, Ic);
324  filename = vpIoTools::createFilePath(opath, "Klimt_color.ppm");
325  std::cout << " Resulting image saved in: " << filename << std::endl;
326  vpImageIo::write(Ic, filename) ;
327 
328  //-------------------- .ppm -> .pgm
329  std::cout << "** Convert a color image (.ppm) to a grey image (.pgm)" << std::endl;
330  // Load a color image from the disk
331  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
332  std::cout << " Load " << filename << std::endl;
333  vpImageIo::read(Ic, filename) ;
334  // Create a grey image from the color
335  vpImageConvert::convert(Ic, Ig);
336  filename = vpIoTools::createFilePath(opath, "Klimt_grey.pgm");
337  std::cout << " Resulting image saved in: " << filename << std::endl;
338  vpImageIo::write(Ig, filename) ;
339 
340  //-------------------- YUV -> RGB
341  std::cout << "** Convert YUV pixel value to a RGB value" << std::endl;
342  unsigned char y=187, u=10, v=30;
343  unsigned char r, g, b;
344 
345  // Convert a YUV pixel value to a RGB value
346  vpImageConvert::YUVToRGB(y, u, v, r, g, b);
347  std::cout << " y(" << (int)y << ") u("<< (int)u << ") v(" << (int)v << ") = r(" << (int)r << ") g(" << (int)g << ") b(" << (int)b << ")" << std::endl;
348 
349 #ifdef VISP_HAVE_OPENCV
350 #if VISP_HAVE_OPENCV_VERSION < 0x020408
351  double t0 = vpTime::measureTimeMs();
353  // Convert a IplImage to a vpImage<vpRGBa>
355  std::cout << "** Convert an IplImage to a vpImage<vpRGBa>" << std::endl;
356  IplImage* image = NULL;
357  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
358 
359  /* Read the color image */
360 
361  std::cout << " Reading the color image with opencv: "<< filename << std::endl;
362  if((image = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR)) == NULL) {
363  std::cout << " Cannot read image: "<< filename << std::endl;
364  return (-1);
365  }
366  vpImageConvert::convert(image, Ic);
367  filename = vpIoTools::createFilePath(opath, "Klimt_color_cv.ppm");
368  std::cout << " Resulting image saved in: " << filename << std::endl;
369  vpImageIo::write(Ic, filename) ;
370 
371  std::cout << " Convert result in " << filename << std::endl;
372 
373  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
374 
375  /* Read the pgm image */
376  std::cout << " Reading the greyscale image with opencv: " << filename << std::endl;
377  if(image!=NULL) cvReleaseImage( &image );
378  if((image = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE)) == NULL) {
379  std::cout << " Cannot read image: " << filename << std::endl;
380  return (-1);
381  }
382  vpImageConvert::convert(image, Ic);
383  filename = vpIoTools::createFilePath(opath, "Klimt_grey_cv.ppm");
384  std::cout << " Resulting image saved in: " << filename << std::endl;
385  vpImageIo::write(Ic, filename) ;
386 
387  std::cout << " Convert result in " << filename << std::endl;
388 
390  // Convert a IplImage to a vpImage<unsigned char>
392  std::cout << "** Convert an IplImage to a vpImage<unsigned char>" << std::endl;
393  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
394 
395  /* Read the color image */
396 
397  std::cout << " Reading the color image with opencv: "<< filename << std::endl;
398  if(image!=NULL) cvReleaseImage( &image );
399  if((image = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR)) == NULL) {
400  std::cout << " Cannot read image: "<< filename << std::endl;
401  return (-1);
402  }
403  vpImageConvert::convert(image, Ig);
404  filename = vpIoTools::createFilePath(opath, "Klimt_color_cv.pgm");
405  std::cout << " Resulting image saved in: " << filename << std::endl;
406  vpImageIo::write(Ig, filename) ;
407 
408  std::cout << " Convert result in " << filename << std::endl;
409 
410  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
411 
412  /* Read the pgm image */
413 
414  std::cout << " Reading the greyscale image with opencv: " << filename << std::endl;
415  if(image!=NULL) cvReleaseImage( &image );
416  if((image = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE)) == NULL) {
417  std::cout << " Cannot read image: "<< filename << std::endl;
418  return (-1);
419  }
420  vpImageConvert::convert(image, Ig);
421  filename = vpIoTools::createFilePath(opath, "Klimt_grey_cv.pgm");
422  std::cout << " Resulting image saved in: " << filename << std::endl;
423  vpImageIo::write(Ig, filename) ;
424 
425  std::cout << " Convert result in " << filename << std::endl;
426 
428  // Convert a vpImage<vpRGBa> to a IplImage
430  std::cout << "** Convert a vpImage<vpRGBa> to an IplImage" << std::endl;
431  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
432 
433  /* Read the color image */
434 
435  // Load a color image from the disk
436  std::cout << " Load " << filename << std::endl;
437  vpImageIo::read(Ic, filename) ;
438  vpImageConvert::convert(Ic, image);
439  filename = vpIoTools::createFilePath(opath, "Klimt_ipl_color_cv.ppm");
440  /* Save the the current image */
441  std::cout << " Write " << filename << std::endl;
442  if((cvSaveImage(filename.c_str(), image)) == 0) {
443  std::cout << " Cannot write image: " << filename << std::endl;
444  if(image!=NULL) cvReleaseImage( &image );
445  return (-1);
446  }
447  std::cout << " Convert result in " << filename << std::endl;
448 
450  // Convert a vpImage<unsigned char> to an IplImage
452  std::cout << "** Convert a vpImage<unsigned char> to an IplImage" << std::endl;
453  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
454 
455  /* Read the grey image */
456 
457  // Load a color image from the disk
458  std::cout << " Load " << filename << std::endl;
459  vpImageIo::read(Ig, filename) ;
460  vpImageConvert::convert(Ig, image);
461  filename = vpIoTools::createFilePath(opath, "Klimt_ipl_grey_cv.pgm");
462  /* Save the the current image */
463 
464  std::cout << " Write " << filename << std::endl;
465  if((cvSaveImage(filename.c_str(), image)) == 0) {
466  std::cout << " Cannot write image: "<< std::endl << filename << std::endl;
467  if(image!=NULL) cvReleaseImage( &image );
468  return (-1);
469  }
470  std::cout << " Convert result in " << filename << std::endl;
471 
472  if(image!=NULL) cvReleaseImage( &image );
473  double t1 = vpTime::measureTimeMs();
474  std::cout << "== Conversion c interface : " << t1 - t0 << " ms" << std::endl;
475 #endif
476 
477  /* ------------------------------------------------------------------------ */
478  /* conversion for the new c++ interface */
479  /* ------------------------------------------------------------------------ */
480 
481 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
482  double t2 = vpTime::measureTimeMs();
484  // Convert a cv::Mat to a vpImage<vpRGBa>
486  std::cout << "** Convert a cv::Mat to a vpImage<vpRGBa>" << std::endl;
487  cv::Mat imageMat;
488  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
489  std::cout << " Reading the color image with c++ interface of opencv: " << filename << std::endl;
490  imageMat = cv::imread(filename, 1);// force to a three channel color image.
491  if(imageMat.data == NULL){
492  std::cout << " Cannot read image: "<< filename << std::endl;
493  return -1;
494  }
495  vpImageConvert::convert(imageMat, Ic);
496  filename = vpIoTools::createFilePath(opath, "Klimt_color_cvMat.ppm");
497  std::cout << " Resulting image saved in: " << filename << std::endl;
498  vpImageIo::write(Ic, filename) ;
499 
500  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
501  /* Read the pgm image */
502 
503  std::cout << " Reading the greyscale image with opencv: " << filename << std::endl;
504  imageMat = cv::imread(filename, 0);// forced to grayscale.
505  if(imageMat.data == NULL) {
506  std::cout << " Cannot read image: "<< filename << std::endl;
507  return (-1);
508  }
509  vpImageConvert::convert(imageMat, Ic);
510  filename = vpIoTools::createFilePath(opath, "Klimt_grey_cvMat.ppm");
511  std::cout << " Resulting image saved in: " << filename << std::endl;
512  vpImageIo::write(Ic, filename) ;
513 
515  // Convert a cv::Mat to a vpImage<unsigned char>
517  std::cout << "** Convert a cv::Mat to a vpImage<nsigned char>" << std::endl;
518  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
519 
520  /* Read the color image */
521 
522  std::cout << " Reading the color image with opencv: " << filename << std::endl;
523  imageMat = cv::imread(filename, 1);// force to a three channel color image.
524  if(imageMat.data == NULL){
525  std::cout << " Cannot read image: " << filename << std::endl;
526  return -1;
527  }
528  vpImageConvert::convert(imageMat, Ig);
529  filename = vpIoTools::createFilePath(opath, "Klimt_color_cvMat.pgm");
530  std::cout << " Resulting image saved in: " << filename << std::endl;
531  vpImageIo::write(Ig, filename) ;
532 
533  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
534 
535  /* Read the pgm image */
536 
537  std::cout << " Reading the greyscale image with opencv: " << filename << std::endl;
538  imageMat = cv::imread(filename, 0);
539  if(imageMat.data == NULL){
540  std::cout << " Cannot read image: "<< filename << std::endl;
541  return (-1);
542  }
543  vpImageConvert::convert(imageMat, Ig);
544  filename = vpIoTools::createFilePath(opath, "Klimt_grey_cvMat.pgm");
545  std::cout << " Resulting image saved in: " << filename << std::endl;
546  vpImageIo::write(Ig, filename) ;
547 
548  std::cout << " Convert result in " << filename << std::endl;
549 
551  // Convert a vpImage<vpRGBa> to a cv::Mat
553  std::cout << "** Convert a vpImage<vpRGBa> to a cv::Mat" << std::endl;
554  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
555 
556  /* Read the color image */
557 
558  // Load a color image from the disk
559  std::cout << " Load " << filename << std::endl;
560  vpImageIo::read(Ic, filename) ;
561  vpImageConvert::convert(Ic, imageMat);
562  filename = vpIoTools::createFilePath(opath, "Klimt_ipl_color_cvMat.ppm");
563  /* Save the the current image */
564  std::cout << " Resulting image saved in: " << filename << std::endl;
565  if(!cv::imwrite(filename, imageMat)){
566  std::cout << " Cannot write image: " << filename << std::endl;
567  return (-1);
568  }
569  std::cout << " Convert result in " << filename << std::endl;
570 
572  // Convert a vpImage<unsigned char> to a cv::Mat
574  std::cout << "** Convert a vpImage<unsigned char> to a cv::Mat" << std::endl;
575  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
576 
577  /* Read the grey image */
578 
579  // Load a color image from the disk
580  std::cout << " Load " << filename << std::endl;
581  vpImageIo::read(Ig, filename);
582  vpImageConvert::convert(Ig, imageMat);
583  filename = vpIoTools::createFilePath(opath, "Klimt_ipl_grey_cvMat.pgm");
584  /* Save the the current image */
585 
586  std::cout << " Resulting image saved in: " << filename << std::endl;
587  if(!cv::imwrite(filename, imageMat)){
588  std::cout << " Cannot write image: "<< filename << std::endl;
589  return (-1);
590  }
591  std::cout << " Convert result in " << filename << std::endl;
592  double t3 = vpTime::measureTimeMs();
593  std::cout << "== Conversion c++ interface : " << t3 - t2 << " ms" << std::endl;
594 #endif
595 #endif
596 
598  // Split a vpImage<vpRGBa> to vpImage<unsigned char>
600  std::cout << "** Split a vpImage<vpRGBa> to vpImage<unsigned char>" << std::endl;
601  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
602 
603  /* Read the color image */
604 
605  // Load a color image from the disk
606  std::cout << " Load " << filename << std::endl;
607  vpImageIo::read(Ic, filename) ;
608  vpImage<unsigned char> R,G,B,a;
609  vpImageConvert::split(Ic, &R,NULL,&B);
610  double begintime = vpTime::measureTimeMs();
611  for(int i=0; i<1000;i++){
612  vpImageConvert::split(Ic, &R,NULL,&B);
613  }
614  double endtime = vpTime::measureTimeMs();
615 
616  std::cout << " Time for 1000 split (ms): " << endtime - begintime <<std::endl;
617 
618  filename = vpIoTools::createFilePath(opath, "Klimt_RChannel.pgm");
619  /* Save the the current image */
620  std::cout << " Save Klimt R channel: " << filename << std::endl;
621  vpImageIo::write(R, filename) ;
622 
623  filename = vpIoTools::createFilePath(opath, "Klimt_BChannel.pgm");
624  /* Save the the current image */
625  std::cout << " Save Klimt B channel: " << filename << std::endl;
626  vpImageIo::write(B, filename) ;
627 
629  // Merge 4 vpImage<unsigned char> (RGBa) to vpImage<vpRGBa>
631  std::cout << "** Merge 4 vpImage<unsigned char> (RGBa) to vpImage<vpRGBa>" << std::endl;
632  vpImageConvert::split(Ic, &R, &G, &B, &a);
633  begintime = vpTime::measureTimeMs();
634  vpImage<vpRGBa> I_merge;
635  for(int i=0; i<1000; i++){
636  vpImageConvert::merge(&R, &G, &B, &a, I_merge);
637  }
638  endtime = vpTime::measureTimeMs();
639 
640  std::cout << " Time for 1000 merge (ms): "<< endtime - begintime <<std::endl;
641 
642  filename = vpIoTools::createFilePath(opath, "Klimt_merge.ppm");
643  std::cout << " Resulting image saved in: " << filename << std::endl;
644  vpImageIo::write(I_merge, filename) ;
645 
647  // Convert a vpImage<vpRGBa> in RGB color space to a vpImage<vpRGBa> in HSV color
649  std::cout << "** Convert a vpImage<vpRGBa> in RGB color space to a vpImage<vpRGBa> in HSV color" << std::endl;
650  unsigned int size = Ic.getSize();
651  unsigned int w = Ic.getWidth(), h = Ic.getHeight();
652  unsigned char *hue = new unsigned char[size];
653  unsigned char *saturation = new unsigned char[size];
654  unsigned char *value = new unsigned char[size];
655 
656  vpImageConvert::RGBaToHSV((unsigned char *) Ic.bitmap, hue, saturation, value, size);
657  vpImage<unsigned char> I_hue(hue, h, w);
658  vpImage<unsigned char> I_saturation(saturation, h, w);
659  vpImage<unsigned char> I_value(value, h, w);
660  vpImage<vpRGBa> I_HSV;
661  vpImageConvert::merge(&I_hue, &I_saturation, &I_value, NULL, I_HSV);
662 
663  filename = vpIoTools::createFilePath(opath, "Klimt_HSV.ppm");
664  std::cout << " Resulting image saved in: " << filename << std::endl;
665  vpImageIo::write(I_HSV, filename);
666 
667  //Check the conversion RGBa <==> HSV
668  double *hue2 = new double[size];
669  double *saturation2 = new double[size];
670  double *value2 = new double[size];
671  vpImageConvert::RGBaToHSV((unsigned char *) Ic.bitmap, hue2, saturation2, value2, size);
672 
673  unsigned char *rgba = new unsigned char[size*4];
674  vpImageConvert::HSVToRGBa(hue2, saturation2, value2, rgba, size);
675 
676  if(hue2 != NULL) {
677  delete[] hue2;
678  hue2 = NULL;
679  }
680 
681  if(saturation2 != NULL) {
682  delete[] saturation2;
683  saturation2 = NULL;
684  }
685 
686  if(value2 != NULL) {
687  delete[] value2;
688  value2 = NULL;
689  }
690 
691  vpImage<vpRGBa> I_HSV2RGBa((vpRGBa *) rgba, h, w);
692  filename = vpIoTools::createFilePath(opath, "Klimt_HSV2RGBa.ppm");
693  std::cout << " Resulting image saved in: " << filename << std::endl;
694  vpImageIo::write(I_HSV2RGBa, filename);
695 
696  for(unsigned int i = 0; i < Ic.getHeight(); i++) {
697  for(unsigned int j = 0; j < Ic.getWidth(); j++) {
698  if(Ic[i][j].R != I_HSV2RGBa[i][j].R ||
699  Ic[i][j].G != I_HSV2RGBa[i][j].G ||
700  Ic[i][j].B != I_HSV2RGBa[i][j].B) {
701  std::cerr << "Ic[i][j].R=" << static_cast<unsigned>(Ic[i][j].R)
702  << " ; I_HSV2RGBa[i][j].R=" << static_cast<unsigned>(I_HSV2RGBa[i][j].R) << std::endl;
703  std::cerr << "Ic[i][j].G=" << static_cast<unsigned>(Ic[i][j].G)
704  << " ; I_HSV2RGBa[i][j].G=" << static_cast<unsigned>(I_HSV2RGBa[i][j].G) << std::endl;
705  std::cerr << "Ic[i][j].B=" << static_cast<unsigned>(Ic[i][j].B)
706  << " ; I_HSV2RGBa[i][j].B=" << static_cast<unsigned>(I_HSV2RGBa[i][j].B) << std::endl;
707  throw vpException(vpException::fatalError, "Problem with conversion between RGB <==> HSV");
708  }
709  }
710  }
711 
713  // Test construction of a vpImage from an array with copyData==true
715  std::cout << "** Construction of a vpImage from an array with copyData==true" << std::endl;
716  unsigned char *rgba2 = new unsigned char[size*4];
717  memset(rgba2, 127, size*4);
718  vpImage<vpRGBa> I_copyData((vpRGBa *) rgba2, h, w, true);
719 
720  // Delete the array
721  delete[] rgba2;
722 
723  filename = vpIoTools::createFilePath(opath, "I_copyData.ppm");
724  std::cout << " Resulting image saved in: " << filename << std::endl;
725  vpImageIo::write(I_copyData, filename);
726 
727  if(I_copyData.getSize() > 0) {
728  I_copyData[0][0].R = 10;
729  }
730 
731 
732  //Benchmark and test RGBa / RGB / cv::Mat to Grayscale conversion
733  {
734  std::cout << "** Benchmark and test RGBa / RGB / cv::Mat to Grayscale conversion" << std::endl;
735  //RGBa to Grayscale
736  vpImage<vpRGBa> I_color;
737  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
738  vpImageIo::read(I_color, filename);
739 
740  vpImage<unsigned char> I_gray_sse(I_color.getHeight(), I_color.getWidth());
741  vpImage<unsigned char> I_gray_regular(I_color.getHeight(), I_color.getWidth());
742  unsigned char value_sse = 0, value_regular = 0;
743 
744  double t_sse = vpTime::measureTimeMs();
745  for(int iteration = 0; iteration < nbIterations; iteration++) {
746  vpImageConvert::convert(I_color, I_gray_sse);
747  value_sse += I_gray_sse[0][0];
748  }
749  t_sse = vpTime::measureTimeMs() - t_sse;
750 
751  double t_regular = vpTime::measureTimeMs();
752  for(int iteration = 0; iteration < nbIterations; iteration++) {
753  computeRegularRGBaToGrayscale((unsigned char *) I_color.bitmap, I_gray_regular.bitmap, I_color.getSize());
754  value_regular += I_gray_regular[0][0];
755  }
756  t_regular = vpTime::measureTimeMs() - t_regular;
757 
758  //Compute the error between the SSE and regular version
759  double rmse_error = 0.0;
760  for(unsigned int i = 0; i < I_color.getHeight(); i++) {
761  for(unsigned int j = 0; j < I_color.getWidth(); j++) {
762  rmse_error += (I_gray_sse[i][j] - I_gray_regular[i][j]) * (I_gray_sse[i][j] - I_gray_regular[i][j]);
763  }
764  }
765 
766  std::cout << "\n RGBa to Grayscale" << std::endl;
767  std::cout << " t_regular (" << nbIterations << " iterations)=" << t_regular << " ms"
768  << " ; t_sse (" << nbIterations << " iterations)=" << t_sse << " ms" << std::endl;
769  std::cout << " Speed-up=" << (t_regular/t_sse) << "X" << std::endl;
770  std::cout << " RMSE error between SSE and regular version: " << (std::sqrt(rmse_error/I_color.getSize())) << std::endl;
771 
772  //To prevent the iteration loop to not be optimized?
773  std::cout << " value_sse=" << static_cast<unsigned>(value_sse)
774  << " ; value_regular=" << static_cast<unsigned>(value_regular) << std::endl;
775 
776  filename = vpIoTools::createFilePath(opath, "I_rgba2gray_sse.pgm");
777  std::cout << " Resulting image saved in: " << filename << std::endl;
778  vpImageIo::write(I_gray_sse, filename);
779 
780  filename = vpIoTools::createFilePath(opath, "I_rgba2gray_regular.pgm");
781  std::cout << " Resulting image saved in: " << filename << std::endl;
782  vpImageIo::write(I_gray_regular, filename);
783 
784  //RGB to Grayscale conversion
785  unsigned char *rgb_array = new unsigned char[I_color.getSize() * 3];
786  vpImageConvert::RGBaToRGB((unsigned char *) I_color.bitmap, rgb_array, I_color.getSize());
787 
788  value_sse = 0;
789  value_regular = 0;
790 
791  unsigned char *rgb2gray_array_sse = new unsigned char[I_color.getSize()];
792  t_sse = vpTime::measureTimeMs();
793  for(int iteration = 0; iteration < nbIterations; iteration++) {
794  vpImageConvert::RGBToGrey(rgb_array, rgb2gray_array_sse, I_color.getWidth(), I_color.getHeight(), false);
795  value_sse += rgb2gray_array_sse[0];
796  }
797  t_sse = vpTime::measureTimeMs() - t_sse;
798 
799  unsigned char *rgb2gray_array_regular = new unsigned char[I_color.getSize()];
800  t_regular = vpTime::measureTimeMs();
801  for(int iteration = 0; iteration < nbIterations; iteration++) {
802  computeRegularRGBToGrayscale(rgb_array, rgb2gray_array_regular, I_color.getSize());
803  value_regular += rgb2gray_array_regular[0];
804  }
805  t_regular = vpTime::measureTimeMs() - t_regular;
806 
807  vpImage<unsigned char> I_gray2rgba_sse(rgb2gray_array_sse, I_color.getHeight(), I_color.getWidth(), false);
808  vpImage<unsigned char> I_gray2rgba_regular(rgb2gray_array_regular, I_color.getHeight(), I_color.getWidth(), false);
809 
810  //Compute the error between the SSE and regular version
811  rmse_error = 0.0;
812  for(unsigned int i = 0; i < I_color.getHeight(); i++) {
813  for(unsigned int j = 0; j < I_color.getWidth(); j++) {
814  rmse_error += (I_gray2rgba_sse[i][j] - I_gray2rgba_regular[i][j]) * (I_gray2rgba_sse[i][j] - I_gray2rgba_regular[i][j]);
815  }
816  }
817 
818  std::cout << "\n RGB to Grayscale" << std::endl;
819  std::cout << " t_regular (" << nbIterations << " iterations)=" << t_regular << " ms"
820  << " ; t_sse (" << nbIterations << " iterations)=" << t_sse << " ms" << std::endl;
821  std::cout << " Speed-up=" << (t_regular/t_sse) << "X" << std::endl;
822  std::cout << " RMSE error between SSE and regular version: " << (std::sqrt(rmse_error/I_color.getSize())) << std::endl;
823 
824  //To prevent the iteration loop to not be optimized?
825  std::cout << " value_sse=" << static_cast<unsigned>(value_sse)
826  << " ; value_regular=" << static_cast<unsigned>(value_regular) << std::endl;
827 
828  filename = vpIoTools::createFilePath(opath, "I_rgb2gray_sse.pgm");
829  std::cout << " Resulting image saved in: " << filename << std::endl;
830  vpImageIo::write(I_gray2rgba_sse, filename);
831 
832  filename = vpIoTools::createFilePath(opath, "I_rgb2gray_regular.pgm");
833  std::cout << " Resulting image saved in: " << filename << std::endl;
834  vpImageIo::write(I_gray2rgba_regular, filename);
835 
836 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
837  //BGR cv::Mat to Grayscale
838  std::cout << "\n BGR cv::Mat to Grayscale" << std::endl;
839  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
840  cv::Mat colorMat = cv::imread(filename);
841  std::cout << " colorMat=" << colorMat.cols << "x" << colorMat.rows << std::endl;
842 
843  vpImage<unsigned char> I_mat2gray_sse, I_mat2gray_regular;
844  value_sse = 0;
845  value_regular = 0;
846 
847  t_sse = vpTime::measureTimeMs();
848  for(int iteration = 0; iteration < nbIterations; iteration++) {
849  vpImageConvert::convert(colorMat, I_mat2gray_sse, false);
850  value_sse += I_mat2gray_sse[0][0];
851  }
852  t_sse = vpTime::measureTimeMs() - t_sse;
853 
854  t_regular = vpTime::measureTimeMs();
855  for(int iteration = 0; iteration < nbIterations; iteration++) {
856  computeRegularBGRToGrayscale(colorMat, I_mat2gray_regular);
857  value_regular += I_mat2gray_sse[0][0];
858  }
859  t_regular = vpTime::measureTimeMs() - t_regular;
860 
861  //Compute the error between the SSE and regular version
862  rmse_error = 0.0;
863  for(unsigned int i = 0; i < I_color.getHeight(); i++) {
864  for(unsigned int j = 0; j < I_color.getWidth(); j++) {
865  rmse_error += (I_mat2gray_sse[i][j] - I_mat2gray_regular[i][j]) * (I_mat2gray_sse[i][j] - I_mat2gray_regular[i][j]);
866  }
867  }
868 
869  std::cout << " t_regular (" << nbIterations << " iterations)=" << t_regular << " ms"
870  << " ; t_sse (" << nbIterations << " iterations)=" << t_sse << " ms" << std::endl;
871  std::cout << " Speed-up=" << (t_regular/t_sse) << "X" << std::endl;
872  std::cout << " RMSE error between SSE and regular version: " << (std::sqrt(rmse_error/I_color.getSize())) << std::endl;
873 
874  //To prevent the iteration loop to not be optimized?
875  std::cout << " value_sse=" << static_cast<unsigned>(value_sse)
876  << " ; value_regular=" << static_cast<unsigned>(value_regular) << std::endl;
877 
878  filename = vpIoTools::createFilePath(opath, "I_mat2gray_sse.pgm");
879  std::cout << " Resulting image saved in: " << filename << std::endl;
880  vpImageIo::write(I_mat2gray_sse, filename);
881 
882  filename = vpIoTools::createFilePath(opath, "I_mat2gray_regular.pgm");
883  std::cout << " Resulting image saved in: " << filename << std::endl;
884  vpImageIo::write(I_mat2gray_regular, filename);
885 
886 
887  //BGR cv::Mat to Grayscale cv::Mat
888  std::cout << "\n BGR Mat to Grayscale Mat" << std::endl;
889  cv::Mat grayscaleMat(colorMat.size(), CV_8U);
890  unsigned char value_mat = 0;
891 
892  double t_opencv = vpTime::measureTimeMs();
893  for(int iteration = 0; iteration < nbIterations; iteration++) {
894  cv::cvtColor(colorMat, grayscaleMat, cv::COLOR_BGR2GRAY);
895  value_mat += grayscaleMat.ptr<uchar>(0)[0];
896  }
897  t_opencv = vpTime::measureTimeMs() - t_opencv;
898 
899  std::cout << " t_opencv (" << nbIterations << " iterations)=" << t_opencv << " ms"
900  << " ; t_sse (" << nbIterations << " iterations)=" << t_sse << " ms" << std::endl;
901  std::cout << " Speed-up=" << (t_opencv/t_sse) << "X" << std::endl;
902  std::cout << " value_mat=" << static_cast<unsigned>(value_mat) << std::endl;
903 
904  vpImage<unsigned char> I_grayscale_mat;
905  vpImageConvert::convert(grayscaleMat, I_grayscale_mat);
906  filename = vpIoTools::createFilePath(opath, "grayscaleMat.pgm");
907  std::cout << " Resulting image saved in: " << filename << std::endl;
908  vpImageIo::write(I_grayscale_mat, filename);
909 
910 
911  //Test RGB to Grayscale + Flip
912  std::cout << "\n RGB to Grayscale + Flip" << std::endl;
913  unsigned char *rgb2gray_flip_array_sse = new unsigned char[I_color.getSize()];
914  vpImageConvert::RGBToGrey(rgb_array, rgb2gray_flip_array_sse, I_color.getWidth(), I_color.getHeight(), true);
915  vpImage<unsigned char> I_rgb2gray_flip_sse(rgb2gray_flip_array_sse, I_color.getHeight(), I_color.getWidth());
916 
917  filename = vpIoTools::createFilePath(opath, "I_rgb2gray_flip_sse.pgm");
918  std::cout << " Resulting image saved in: " << filename << std::endl;
919  vpImageIo::write(I_rgb2gray_flip_sse, filename);
920 
921 
922  //Test BGR to Grayscale + Flip
923  std::cout << "\n Conversion BGR to Grayscale + Flip" << std::endl;
924  unsigned char *bgr2gray_flip_array_sse = new unsigned char[I_color.getSize()];
925  vpImage<unsigned char> I_bgr2gray_flip_sse(bgr2gray_flip_array_sse, I_color.getHeight(), I_color.getWidth());
926  vpImageConvert::convert(colorMat, I_bgr2gray_flip_sse, true);
927 
928  filename = vpIoTools::createFilePath(opath, "I_bgr2gray_flip_sse.pgm");
929  std::cout << " Resulting image saved in: " << filename << std::endl;
930  vpImageIo::write(I_bgr2gray_flip_sse, filename);
931 
932 
933  //Test RGB to Grayscale + Flip + Crop
934  std::cout << "\n RGB to Grayscale + Flip + Crop" << std::endl;
935  cv::Rect rect_roi(11, 17, 347, 449);
936  cv::Mat colorMat_crop = colorMat(rect_roi);
937  cv::Mat colorMat_crop_continous = colorMat(rect_roi).clone();
938  std::cout << " colorMat_crop: " << colorMat_crop.cols << "x" << colorMat_crop.rows <<
939  " is continuous? " << colorMat_crop.isContinuous() << std::endl;
940  std::cout << " colorMat_crop_continous: " << colorMat_crop_continous.cols
941  << "x" << colorMat_crop_continous.rows << " is continuous? "
942  << colorMat_crop_continous.isContinuous() << std::endl;
943 
944  vpImage<vpRGBa> I_color_crop( (unsigned int) (rect_roi.height-rect_roi.y), (unsigned int) (rect_roi.width-rect_roi.x) );
945  for(unsigned int i = (unsigned int) rect_roi.y; i < (unsigned int) rect_roi.height; i++) {
946  for(unsigned int j = (unsigned int) rect_roi.x; j < (unsigned int) rect_roi.width; j++) {
947  I_color_crop[(unsigned int) ((int)i-rect_roi.y)][(unsigned int) ((int)j-rect_roi.x)] = I_color[i][j];
948  }
949  }
950  filename = vpIoTools::createFilePath(opath, "I_color_crop.ppm");
951  std::cout << " Resulting image saved in: " << filename << std::endl;
952  vpImageIo::write(I_color_crop, filename);
953 
954  unsigned char *rgb_array_crop = new unsigned char[I_color_crop.getSize()*3];
955  vpImageConvert::RGBaToRGB((unsigned char *) I_color_crop.bitmap, rgb_array_crop, I_color_crop.getSize());
956 
957  unsigned char *rgb2gray_flip_crop_array_sse = new unsigned char[I_color_crop.getSize()];
958  vpImageConvert::RGBToGrey(rgb_array_crop, rgb2gray_flip_crop_array_sse, I_color_crop.getWidth(),
959  I_color_crop.getHeight(), true);
960  vpImage<unsigned char> I_rgb2gray_flip_crop_sse(rgb2gray_flip_crop_array_sse, I_color_crop.getHeight(),
961  I_color_crop.getWidth());
962 
963  filename = vpIoTools::createFilePath(opath, "I_rgb2gray_flip_crop_sse.pgm");
964  std::cout << " Resulting image saved in: " << filename << std::endl;
965  vpImageIo::write(I_rgb2gray_flip_crop_sse, filename);
966 
967 
968  //Test BGR to Grayscale + Flip + Crop
969  std::cout << "\n BGR to Grayscale + Flip + Crop" << std::endl;
970  vpImage<unsigned char> I_bgr2gray_flip_crop_sse(I_color_crop.getHeight(), I_color_crop.getWidth());
971  vpImageConvert::convert(colorMat_crop_continous, I_bgr2gray_flip_crop_sse, true);
972 
973  filename = vpIoTools::createFilePath(opath, "I_bgr2gray_flip_crop_sse.pgm");
974  std::cout << " Resulting image saved in: " << filename << std::endl;
975  vpImageIo::write(I_bgr2gray_flip_crop_sse, filename);
976 
977 
978  //Test BGR to Grayscale + Flip + Crop + No continuous Mat
979  std::cout << "\n BGR to Grayscale + Flip + Crop + No continuous Mat" << std::endl;
980  vpImage<unsigned char> I_bgr2gray_flip_crop_no_continuous_sse(I_color_crop.getHeight(),
981  I_color_crop.getWidth());
982  vpImageConvert::convert(colorMat_crop, I_bgr2gray_flip_crop_no_continuous_sse, true);
983 
984  filename = vpIoTools::createFilePath(opath, "I_bgr2gray_flip_crop_no_continuous_sse.pgm");
985  std::cout << " Resulting image saved in: " << filename << std::endl;
986  vpImageIo::write(I_bgr2gray_flip_crop_no_continuous_sse, filename);
987 #endif
988  delete [] rgb_array;
989  std::cout << "Test succeed" << std::endl;
990  }
991 
992  return 0;
993  }
994  catch(const vpException &e) {
995  std::cout << "Catch an exception: " << e.getMessage() << std::endl;
996  return 1;
997  }
998 }
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:358
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1157
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
unsigned int getWidth() const
Definition: vpImage.h:226
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Type * bitmap
points toward the bitmap
Definition: vpImage.h:134
File and directories basic tools.
Definition: vpIoTools.h:151
error that can be emited by ViSP classes.
Definition: vpException.h:73
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=NULL)
static void YUVToRGB(unsigned char y, unsigned char u, unsigned char v, unsigned char &r, unsigned char &g, unsigned char &b)
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
Definition: vpRGBa.h:66
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:368
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:427
unsigned int getSize() const
Definition: vpImage.h:212
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1366
static std::string getUserName()
Definition: vpIoTools.cpp:177
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:903
Read/write images with various image format.
Definition: vpImageIo.h:116
const char * getMessage(void) const
Definition: vpException.cpp:97
static void merge(const vpImage< unsigned char > *R, const vpImage< unsigned char > *G, const vpImage< unsigned char > *B, const vpImage< unsigned char > *a, vpImage< vpRGBa > &RGBa)
static void RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, const unsigned int size)
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:205
static void HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba, const unsigned int size)
unsigned int getHeight() const
Definition: vpImage.h:175
static void RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)