Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
testConversion.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 https://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 
40 #include <iomanip>
41 #include <stdlib.h>
42 
43 #include <visp3/core/vpConfig.h>
44 #include <visp3/core/vpDebug.h>
45 #include <visp3/core/vpImage.h>
46 #include <visp3/core/vpImageConvert.h>
47 #include <visp3/core/vpIoTools.h>
48 #include <visp3/core/vpTime.h>
49 #include <visp3/io/vpImageIo.h>
50 #include <visp3/io/vpParseArgv.h>
51 
52 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_IMGPROC)
53 #include <opencv2/imgcodecs.hpp>
54 #include <opencv2/imgproc/imgproc.hpp>
55 #endif
56 
57 #if defined(VISP_HAVE_YARP)
58 #include <yarp/sig/ImageFile.h>
59 #endif
60 
61 #ifdef ENABLE_VISP_NAMESPACE
62 using namespace VISP_NAMESPACE_NAME;
63 #endif
64 
65 // List of allowed command line options
66 #define GETOPTARGS "cdi:o:n:h"
67 
68 /*
69  Print the program options.
70 
71  \param name : Program name.
72  \param badparam : Bad parameter name.
73  \param ipath: Input image path.
74  \param opath : Output image path.
75  \param user : Username.
76  \param nbiter : Iteration number.
77 
78  */
79 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user, int nbiter)
80 {
81  fprintf(stdout, "\n\
82 Test image conversions.\n\
83 \n\
84 SYNOPSIS\n\
85  %s [-i <input image path>] [-o <output image path>] [-n <nb benchmark iterations>]\n\
86  [-h]\n\
87 ",
88 name);
89 
90  fprintf(stdout, "\n\
91 OPTIONS: Default\n\
92  -i <input image path> %s\n\
93  Set image input path.\n\
94  From this path read \"Klimt/Klimt.pgm\"\n\
95  and \"Klimt/Klimt.ppm\" images.\n\
96  Setting the VISP_INPUT_IMAGE_PATH environment\n\
97  variable produces the same behaviour than using\n\
98  this option.\n\
99 \n\
100  -o <output image path> %s\n\
101  Set image output path.\n\
102  From this directory, creates the \"%s\"\n\
103  subdirectory depending on the username, where \n\
104  Klimt_grey.pgm and Klimt_color.ppm output images\n\
105  are written.\n\
106 \n\
107  -n <nb benchmark iterations> %d\n\
108  Set the number of benchmark iterations.\n\
109 \n\
110  -h\n\
111  Print the help.\n\n",
112  ipath.c_str(), opath.c_str(), user.c_str(), nbiter);
113 
114  if (badparam)
115  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
116 }
117 
131 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, const std::string &user,
132  int &nbIterations)
133 {
134  const char *optarg_;
135  int c;
136  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
137 
138  switch (c) {
139  case 'i':
140  ipath = optarg_;
141  break;
142  case 'o':
143  opath = optarg_;
144  break;
145  case 'n':
146  nbIterations = atoi(optarg_);
147  break;
148  case 'h':
149  usage(argv[0], nullptr, ipath, opath, user, nbIterations);
150  return false;
151 
152  case 'c':
153  case 'd':
154  break;
155 
156  default:
157  usage(argv[0], optarg_, ipath, opath, user, nbIterations);
158  return false;
159  }
160  }
161 
162  if ((c == 1) || (c == -1)) {
163  // standalone param or error
164  usage(argv[0], nullptr, ipath, opath, user, nbIterations);
165  std::cerr << "ERROR: " << std::endl;
166  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
167  return false;
168  }
169 
170  return true;
171 }
172 
173 int main(int argc, const char **argv)
174 {
175  try {
176  std::string env_ipath;
177  std::string opt_ipath;
178  std::string opt_opath;
179  std::string ipath;
180  std::string opath;
181  std::string filename;
182  std::string username;
183  int nbIterations = 1;
184 
185  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
186  // environment variable value
187  env_ipath = vpIoTools::getViSPImagesDataPath();
188 
189  // Set the default input path
190  if (!env_ipath.empty())
191  ipath = env_ipath;
192 
193 // Set the default output path
194 #if defined(_WIN32)
195  opt_opath = "C:/temp";
196 #else
197  opt_opath = "/tmp";
198 #endif
199 
200  // Get the user login name
201  vpIoTools::getUserName(username);
202 
203  // Read the command line options
204  if (getOptions(argc, argv, opt_ipath, opt_opath, username, nbIterations) == false) {
205  return EXIT_FAILURE;
206  }
207 
208  // Get the option values
209  if (!opt_ipath.empty())
210  ipath = opt_ipath;
211  if (!opt_opath.empty())
212  opath = opt_opath;
213 
214  // Append to the output path string, the login name of the user
215  opath = vpIoTools::createFilePath(opath, username);
216 
217  // Test if the output path exist. If no try to create it
218  if (vpIoTools::checkDirectory(opath) == false) {
219  try {
220  // Create the dirname
222  }
223  catch (...) {
224  usage(argv[0], nullptr, ipath, opt_opath, username, nbIterations);
225  std::cerr << std::endl << "ERROR:" << std::endl;
226  std::cerr << " Cannot create " << opath << std::endl;
227  std::cerr << " Check your -o " << opt_opath << " option " << std::endl;
228  return EXIT_FAILURE;
229  }
230  }
231 
232  // Compare ipath and env_ipath. If they differ, we take into account
233  // the input path coming from the command line option
234  if (opt_ipath.empty()) {
235  if (ipath != env_ipath) {
236  std::cout << std::endl << "WARNING: " << std::endl;
237  std::cout << " Since -i <visp image path=" << ipath << "> "
238  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
239  << " we skip the environment variable." << std::endl;
240  }
241  }
242 
243  // Test if an input path is set
244  if (opt_ipath.empty() && env_ipath.empty()) {
245  usage(argv[0], nullptr, ipath, opt_opath, username, nbIterations);
246  std::cerr << std::endl << "ERROR:" << std::endl;
247  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
248  << " environment variable to specify the location of the " << std::endl
249  << " image path where test images are located." << std::endl
250  << std::endl;
251  return EXIT_FAILURE;
252  }
253 
254  //
255  // Here starts really the test
256  //
257 
258  vpImage<unsigned char> Ig; // Grey image
259  vpImage<vpRGBa> Ic; // Color image
260 
261  //-------------------- .pgm -> .ppm
262  std::cout << "** Convert a grey image (.pgm) to a color image (.ppm)" << std::endl;
263  // Load a grey image from the disk
264  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
265  std::cout << " Load " << filename << std::endl;
266  vpImageIo::read(Ig, filename);
267  // Create a color image from the grey
268  vpImageConvert::convert(Ig, Ic);
269  filename = vpIoTools::createFilePath(opath, "Klimt_color.ppm");
270  std::cout << " Resulting image saved in: " << filename << std::endl;
271  vpImageIo::write(Ic, filename);
272 
273  //-------------------- .ppm -> .pgm
274  std::cout << "** Convert a color image (.ppm) to a grey image (.pgm)" << std::endl;
275  // Load a color image from the disk
276  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
277  std::cout << " Load " << filename << std::endl;
278  vpImageIo::read(Ic, filename);
279  // Create a grey image from the color
280  vpImageConvert::convert(Ic, Ig);
281  filename = vpIoTools::createFilePath(opath, "Klimt_grey.pgm");
282  std::cout << " Resulting image saved in: " << filename << std::endl;
283  vpImageIo::write(Ig, filename);
284 
285  //-------------------- YUV -> RGB
286  std::cout << "** Convert YUV pixel value to a RGB value" << std::endl;
287  unsigned char y = 187, u = 10, v = 30;
288  unsigned char r, g, b;
289 
290  // Convert a YUV pixel value to a RGB value
291  vpImageConvert::YUVToRGB(y, u, v, r, g, b);
292  std::cout << " y(" << (int)y << ") u(" << (int)u << ") v(" << (int)v << ") = r(" << (int)r << ") g(" << (int)g
293  << ") b(" << (int)b << ")" << std::endl;
294 
295  vpChrono chrono;
296 
297  /* ------------------------------------------------------------------------ */
298  /* conversion for the new c++ interface */
299  /* ------------------------------------------------------------------------ */
300 
301 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC)
302  chrono.start();
304  // Convert a cv::Mat to a vpImage<vpRGBa>
306  std::cout << "** Convert a cv::Mat to a vpImage<vpRGBa>" << std::endl;
307  cv::Mat imageMat;
308  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
309  std::cout << " Reading the color image with c++ interface of opencv: " << filename << std::endl;
310 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
311  int flags = cv::IMREAD_COLOR;
312 #else
313  int flags = CV_LOAD_IMAGE_COLOR;
314 #endif
315  imageMat = cv::imread(filename, flags); // Force to a three channel BGR color image.
316  if (imageMat.data == nullptr) {
317  std::cout << " Cannot read image: " << filename << std::endl;
318  return EXIT_FAILURE;
319  }
320  vpImageConvert::convert(imageMat, Ic);
321  filename = vpIoTools::createFilePath(opath, "Klimt_color_cvMat.ppm");
322  std::cout << " Resulting image saved in: " << filename << std::endl;
323  vpImageIo::write(Ic, filename);
324 
325  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
326  /* Read the pgm image */
327 
328  std::cout << " Reading the grayscale image with opencv: " << filename << std::endl;
329 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
330  flags = cv::IMREAD_GRAYSCALE;
331 #else
332  flags = CV_LOAD_IMAGE_GRAYSCALE;
333 #endif
334  imageMat = cv::imread(filename, flags); // Forced to grayscale.
335  if (imageMat.data == nullptr) {
336  std::cout << " Cannot read image: " << filename << std::endl;
337  return EXIT_FAILURE;
338  }
339  vpImageConvert::convert(imageMat, Ic);
340  filename = vpIoTools::createFilePath(opath, "Klimt_grey_cvMat.ppm");
341  std::cout << " Resulting image saved in: " << filename << std::endl;
342  vpImageIo::write(Ic, filename);
343 
345  // Convert a cv::Mat to a vpImage<unsigned char>
347  std::cout << "** Convert a cv::Mat to a vpImage<nsigned char>" << std::endl;
348  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
349 
350  /* Read the color image */
351 
352  std::cout << " Reading the color image with opencv: " << filename << std::endl;
353 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
354  flags = cv::IMREAD_COLOR;
355 #else
356  flags = CV_LOAD_IMAGE_COLOR;
357 #endif
358  imageMat = cv::imread(filename, flags); // Force to a three channel BGR color image.
359  if (imageMat.data == nullptr) {
360  std::cout << " Cannot read image: " << filename << std::endl;
361  return EXIT_FAILURE;
362  }
363  vpImageConvert::convert(imageMat, Ig);
364  filename = vpIoTools::createFilePath(opath, "Klimt_color_cvMat.pgm");
365  std::cout << " Resulting image saved in: " << filename << std::endl;
366  vpImageIo::write(Ig, filename);
367 
368  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
369 
370  /* Read the pgm image */
371 
372  std::cout << " Reading the greyscale image with opencv: " << filename << std::endl;
373 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
374  flags = cv::IMREAD_GRAYSCALE;
375 #else
376  flags = CV_LOAD_IMAGE_GRAYSCALE;
377 #endif
378  imageMat = cv::imread(filename, flags);
379  if (imageMat.data == nullptr) {
380  std::cout << " Cannot read image: " << filename << std::endl;
381  return EXIT_FAILURE;
382  }
383  vpImageConvert::convert(imageMat, Ig);
384  filename = vpIoTools::createFilePath(opath, "Klimt_grey_cvMat.pgm");
385  std::cout << " Resulting image saved in: " << filename << std::endl;
386  vpImageIo::write(Ig, filename);
387 
388  std::cout << " Convert result in " << filename << std::endl;
389 
391  // Convert a vpImage<vpRGBa> to a cv::Mat
393  std::cout << "** Convert a vpImage<vpRGBa> to a cv::Mat" << std::endl;
394  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
395 
396  /* Read the color image */
397 
398  // Load a color image from the disk
399  std::cout << " Load " << filename << std::endl;
400  vpImageIo::read(Ic, filename);
401  vpImageConvert::convert(Ic, imageMat);
402  filename = vpIoTools::createFilePath(opath, "Klimt_ipl_color_cvMat.ppm");
403  /* Save the the current image */
404  std::cout << " Resulting image saved in: " << filename << std::endl;
405  if (!cv::imwrite(filename, imageMat)) {
406  std::cout << " Cannot write image: " << filename << std::endl;
407  return EXIT_FAILURE;
408  }
409  std::cout << " Convert result in " << filename << std::endl;
410 
412  // Convert a vpImage<unsigned char> to a cv::Mat
414  std::cout << "** Convert a vpImage<unsigned char> to a cv::Mat" << std::endl;
415  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
416 
417  /* Read the grey image */
418 
419  // Load a color image from the disk
420  std::cout << " Load " << filename << std::endl;
421  vpImageIo::read(Ig, filename);
422  vpImageConvert::convert(Ig, imageMat);
423  filename = vpIoTools::createFilePath(opath, "Klimt_ipl_grey_cvMat.pgm");
424  /* Save the the current image */
425 
426  std::cout << " Resulting image saved in: " << filename << std::endl;
427  if (!cv::imwrite(filename, imageMat)) {
428  std::cout << " Cannot write image: " << filename << std::endl;
429  return EXIT_FAILURE;
430  }
431  std::cout << " Convert result in " << filename << std::endl;
432  chrono.stop();
433  std::cout << "== Conversion c++ interface : " << chrono.getDurationMs() << " ms" << std::endl;
434 #endif
435 
437  // Split a vpImage<vpRGBa> to vpImage<unsigned char>
439  std::cout << "** Split a vpImage<vpRGBa> to vpImage<unsigned char>" << std::endl;
440  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
441 
442  /* Read the color image */
443 
444  // Load a color image from the disk
445  std::cout << " Load " << filename << std::endl;
446  vpImageIo::read(Ic, filename);
447  vpImage<unsigned char> R, G, B, a;
448  vpImageConvert::split(Ic, &R, nullptr, &B);
449  chrono.start();
450  for (int iteration = 0; iteration < nbIterations; iteration++) {
451  vpImageConvert::split(Ic, &R, nullptr, &B);
452  }
453  chrono.stop();
454 
455  std::cout << " Time for " << nbIterations << " split (ms): " << chrono.getDurationMs() << std::endl;
456 
457  filename = vpIoTools::createFilePath(opath, "Klimt_RChannel.pgm");
458  /* Save the the current image */
459  std::cout << " Save Klimt R channel: " << filename << std::endl;
460  vpImageIo::write(R, filename);
461 
462  filename = vpIoTools::createFilePath(opath, "Klimt_BChannel.pgm");
463  /* Save the the current image */
464  std::cout << " Save Klimt B channel: " << filename << std::endl;
465  vpImageIo::write(B, filename);
466 
468  // Merge 4 vpImage<unsigned char> (RGBa) to vpImage<vpRGBa>
470  std::cout << "** Merge 4 vpImage<unsigned char> (RGBa) to vpImage<vpRGBa>" << std::endl;
471  vpImageConvert::split(Ic, &R, &G, &B, &a);
472  chrono.start();
473  vpImage<vpRGBa> I_merge;
474  for (int iteration = 0; iteration < nbIterations; iteration++) {
475  vpImageConvert::merge(&R, &G, &B, &a, I_merge);
476  }
477  chrono.stop();
478 
479  std::cout << " Time for 1000 merge (ms): " << chrono.getDurationMs() << std::endl;
480 
481  filename = vpIoTools::createFilePath(opath, "Klimt_merge.ppm");
482  std::cout << " Resulting image saved in: " << filename << std::endl;
483  vpImageIo::write(I_merge, filename);
484 
486  // Convert a vpImage<vpRGBa> in RGB color space to a vpImage<vpRGBa> in
487  // HSV color
489  std::cout << "** Convert a vpImage<vpRGBa> in RGB color space to a vpImage<vpRGBa> in HSV color" << std::endl;
490  unsigned int size = Ic.getSize();
491  unsigned int w = Ic.getWidth(), h = Ic.getHeight();
492  // Check the conversion RGBa <==> HSV(unsigned char)
493  std::vector<unsigned char> hue(size);
494  std::vector<unsigned char> saturation(size);
495  std::vector<unsigned char> value(size);
496 
497  vpImageConvert::RGBaToHSV((unsigned char *)Ic.bitmap, &hue.front(), &saturation.front(), &value.front(), size);
498  vpImage<unsigned char> I_hue(&hue.front(), h, w);
499  vpImage<unsigned char> I_saturation(&saturation.front(), h, w);
500  vpImage<unsigned char> I_value(&value.front(), h, w);
501  vpImage<vpRGBa> I_HSV;
502  vpImageConvert::merge(&I_hue, &I_saturation, &I_value, nullptr, I_HSV);
503 
504  filename = vpIoTools::createFilePath(opath, "Klimt_HSV.ppm");
505  std::cout << " Resulting image saved in: " << filename << std::endl;
506  vpImageIo::write(I_HSV, filename);
507 
508  vpImage<vpRGBa> Ic_from_hsv(Ic.getHeight(), Ic.getWidth());
509  vpImageConvert::HSVToRGBa(&hue.front(), &saturation.front(), &value.front(), reinterpret_cast<unsigned char *>(Ic_from_hsv.bitmap), size);
510  for (unsigned int i = 0; i < Ic.getHeight(); i++) {
511  for (unsigned int j = 0; j < Ic.getWidth(); j++) {
512  double precision = 10.; // Due to cast to unsigned char
513  if ((!vpMath::equal(static_cast<double>(Ic[i][j].R), static_cast<double>(Ic_from_hsv[i][j].R), precision))
514  || (!vpMath::equal(static_cast<double>(Ic[i][j].G), static_cast<double>(Ic_from_hsv[i][j].G), precision))
515  || (!vpMath::equal(static_cast<double>(Ic[i][j].B), static_cast<double>(Ic_from_hsv[i][j].B), precision))) {
516  std::cerr << "Ic[i][j].R=" << static_cast<unsigned int>(Ic[i][j].R)
517  << " ; Ic_from_hsv[i][j].R=" << static_cast<unsigned int>(Ic_from_hsv[i][j].R) << " precision: " << precision << std::endl;
518  std::cerr << "Ic[i][j].G=" << static_cast<unsigned int>(Ic[i][j].G)
519  << " ; Ic_from_hsv[i][j].G=" << static_cast<unsigned int>(Ic_from_hsv[i][j].G) << " precision: " << precision << std::endl;
520  std::cerr << "Ic[i][j].B=" << static_cast<unsigned int>(Ic[i][j].B)
521  << " ; Ic_from_hsv[i][j].B=" << static_cast<unsigned int>(Ic_from_hsv[i][j].B) << " precision: " << precision << std::endl;
522  throw vpException(vpException::fatalError, "Problem with conversion between RGB <==> HSV(unsigned char)");
523  }
524  }
525  }
526  // Check the conversion RGBa <==> HSV(double)
527  std::vector<double> hue2(size);
528  std::vector<double> saturation2(size);
529  std::vector<double> value2(size);
530  vpImageConvert::RGBaToHSV((unsigned char *)Ic.bitmap, &hue2.front(), &saturation2.front(), &value2.front(), size);
531 
532  std::vector<unsigned char> rgba(size * 4);
533  vpImageConvert::HSVToRGBa(&hue2.front(), &saturation2.front(), &value2.front(), &rgba.front(), size);
534 
535  vpImage<vpRGBa> I_HSV2RGBa(reinterpret_cast<vpRGBa *>(&rgba.front()), h, w);
536  filename = vpIoTools::createFilePath(opath, "Klimt_HSV2RGBa.ppm");
537  std::cout << " Resulting image saved in: " << filename << std::endl;
538  vpImageIo::write(I_HSV2RGBa, filename);
539 
540  for (unsigned int i = 0; i < Ic.getHeight(); i++) {
541  for (unsigned int j = 0; j < Ic.getWidth(); j++) {
542  if (Ic[i][j].R != I_HSV2RGBa[i][j].R || Ic[i][j].G != I_HSV2RGBa[i][j].G || Ic[i][j].B != I_HSV2RGBa[i][j].B) {
543  std::cerr << "Ic[i][j].R=" << static_cast<unsigned>(Ic[i][j].R)
544  << " ; I_HSV2RGBa[i][j].R=" << static_cast<unsigned>(I_HSV2RGBa[i][j].R) << std::endl;
545  std::cerr << "Ic[i][j].G=" << static_cast<unsigned>(Ic[i][j].G)
546  << " ; I_HSV2RGBa[i][j].G=" << static_cast<unsigned>(I_HSV2RGBa[i][j].G) << std::endl;
547  std::cerr << "Ic[i][j].B=" << static_cast<unsigned>(Ic[i][j].B)
548  << " ; I_HSV2RGBa[i][j].B=" << static_cast<unsigned>(I_HSV2RGBa[i][j].B) << std::endl;
549  throw vpException(vpException::fatalError, "Problem with conversion between RGB <==> HSV(double)");
550  }
551  }
552  }
553 
555  // Test construction of a vpImage from an array with copyData==true
557  std::cout << "** Construction of a vpImage from an array with copyData==true" << std::endl;
558  std::vector<unsigned char> rgba2(size * 4);
559  std::fill(rgba2.begin(), rgba2.end(), 127);
560  vpImage<vpRGBa> I_copyData(reinterpret_cast<vpRGBa *>(&rgba2.front()), h, w, true);
561 
562  filename = vpIoTools::createFilePath(opath, "I_copyData.ppm");
563  std::cout << " Resulting image saved in: " << filename << std::endl;
564  vpImageIo::write(I_copyData, filename);
565 
566  if (I_copyData.getSize() > 0) {
567  I_copyData[0][0].R = 10;
568  }
569 
570  // Test color conversion
571  {
572  std::cout << "** Test color conversion" << std::endl;
573  // RGBa to Grayscale
574  vpImage<vpRGBa> I_color;
575  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
576  vpImageIo::read(I_color, filename);
577 
578  // RGB to Grayscale conversion
579  std::vector<unsigned char> rgb_array(I_color.getSize() * 3);
580  vpImageConvert::RGBaToRGB((unsigned char *)I_color.bitmap, &rgb_array.front(), I_color.getSize());
581 
582 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC)
583  // BGR cv::Mat to Grayscale
584  std::cout << "\n BGR cv::Mat to Grayscale" << std::endl;
585  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
586  cv::Mat colorMat = cv::imread(filename);
587  std::cout << " colorMat=" << colorMat.cols << "x" << colorMat.rows << std::endl;
588 
589  // Test RGB to Grayscale + Flip
590  std::cout << "\n RGB to Grayscale + Flip" << std::endl;
591  std::vector<unsigned char> rgb2gray_flip_array_sse(I_color.getSize());
592  vpImageConvert::RGBToGrey(&rgb_array.front(), &rgb2gray_flip_array_sse.front(), I_color.getWidth(),
593  I_color.getHeight(), true);
594  vpImage<unsigned char> I_rgb2gray_flip_sse(&rgb2gray_flip_array_sse.front(), I_color.getHeight(),
595  I_color.getWidth());
596 
597  filename = vpIoTools::createFilePath(opath, "I_rgb2gray_flip_sse.pgm");
598  std::cout << " Resulting image saved in: " << filename << std::endl;
599  vpImageIo::write(I_rgb2gray_flip_sse, filename);
600 
601  // Test BGR to Grayscale + Flip
602  std::cout << "\n Conversion BGR to Grayscale + Flip" << std::endl;
603  std::vector<unsigned char> bgr2gray_flip_array_sse(I_color.getSize());
604  vpImage<unsigned char> I_bgr2gray_flip_sse(&bgr2gray_flip_array_sse.front(), I_color.getHeight(),
605  I_color.getWidth());
606  vpImageConvert::convert(colorMat, I_bgr2gray_flip_sse, true);
607 
608  filename = vpIoTools::createFilePath(opath, "I_bgr2gray_flip_sse.pgm");
609  std::cout << " Resulting image saved in: " << filename << std::endl;
610  vpImageIo::write(I_bgr2gray_flip_sse, filename);
611 
612  // Test RGB to Grayscale + Flip + Crop
613  std::cout << "\n RGB to Grayscale + Flip + Crop" << std::endl;
614  cv::Rect rect_roi(11, 17, 347, 449);
615  cv::Mat colorMat_crop = colorMat(rect_roi);
616  cv::Mat colorMat_crop_continuous = colorMat(rect_roi).clone();
617  std::cout << " colorMat_crop: " << colorMat_crop.cols << "x" << colorMat_crop.rows << " is continuous? "
618  << colorMat_crop.isContinuous() << std::endl;
619  std::cout << " colorMat_crop_continuous: " << colorMat_crop_continuous.cols << "x" << colorMat_crop_continuous.rows
620  << " is continuous? " << colorMat_crop_continuous.isContinuous() << std::endl;
621 
622  vpImage<vpRGBa> I_color_crop((unsigned int)(rect_roi.height - rect_roi.y),
623  (unsigned int)(rect_roi.width - rect_roi.x));
624  for (unsigned int i = (unsigned int)rect_roi.y; i < (unsigned int)rect_roi.height; i++) {
625  for (unsigned int j = (unsigned int)rect_roi.x; j < (unsigned int)rect_roi.width; j++) {
626  I_color_crop[(unsigned int)((int)i - rect_roi.y)][(unsigned int)((int)j - rect_roi.x)] = I_color[i][j];
627  }
628  }
629  filename = vpIoTools::createFilePath(opath, "I_color_crop.ppm");
630  std::cout << " Resulting image saved in: " << filename << std::endl;
631  vpImageIo::write(I_color_crop, filename);
632 
633  std::vector<unsigned char> rgb_array_crop(I_color_crop.getSize() * 3);
634  vpImageConvert::RGBaToRGB((unsigned char *)I_color_crop.bitmap, &rgb_array_crop.front(), I_color_crop.getSize());
635 
636  std::vector<unsigned char> rgb2gray_flip_crop_array_sse(I_color_crop.getSize());
637  vpImageConvert::RGBToGrey(&rgb_array_crop.front(), &rgb2gray_flip_crop_array_sse.front(), I_color_crop.getWidth(),
638  I_color_crop.getHeight(), true);
639  vpImage<unsigned char> I_rgb2gray_flip_crop_sse(&rgb2gray_flip_crop_array_sse.front(), I_color_crop.getHeight(),
640  I_color_crop.getWidth());
641 
642  filename = vpIoTools::createFilePath(opath, "I_rgb2gray_flip_crop_sse.pgm");
643  std::cout << " Resulting image saved in: " << filename << std::endl;
644  vpImageIo::write(I_rgb2gray_flip_crop_sse, filename);
645 
646  // Test BGR to Grayscale + Flip + Crop
647  std::cout << "\n BGR to Grayscale + Flip + Crop" << std::endl;
648  vpImage<unsigned char> I_bgr2gray_flip_crop_sse(I_color_crop.getHeight(), I_color_crop.getWidth());
649  vpImageConvert::convert(colorMat_crop_continuous, I_bgr2gray_flip_crop_sse, true);
650 
651  filename = vpIoTools::createFilePath(opath, "I_bgr2gray_flip_crop_sse.pgm");
652  std::cout << " Resulting image saved in: " << filename << std::endl;
653  vpImageIo::write(I_bgr2gray_flip_crop_sse, filename);
654 
655  // Test BGR to Grayscale + Flip + Crop + No continuous Mat
656  std::cout << "\n BGR to Grayscale + Flip + Crop + No continuous Mat" << std::endl;
657  vpImage<unsigned char> I_bgr2gray_flip_crop_no_continuous_sse(I_color_crop.getHeight(), I_color_crop.getWidth());
658  vpImageConvert::convert(colorMat_crop, I_bgr2gray_flip_crop_no_continuous_sse, true);
659 
660  filename = vpIoTools::createFilePath(opath, "I_bgr2gray_flip_crop_no_continuous_sse.pgm");
661  std::cout << " Resulting image saved in: " << filename << std::endl;
662  vpImageIo::write(I_bgr2gray_flip_crop_no_continuous_sse, filename);
663 #endif
664  std::cout << " Test succeed" << std::endl;
665  }
666 
667 #if defined(VISP_HAVE_YARP)
669  // Convert a ViSP to Yarp uchar image
671  std::cout << "** Test ViSP to Yarp image conversion by copy" << std::endl;
672  {
673  bool convert_by_copy = true;
674  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
675  std::cout << " Reading the gray image with ViSP: " << filename << std::endl;
677  // Read an image on a disk
678  vpImageIo::read(I, filename);
679 
680  yarp::sig::ImageOf< yarp::sig::PixelMono > *Iyarp = new yarp::sig::ImageOf<yarp::sig::PixelMono >();
681  // Convert the vpImage<unsigned char> to a yarp::sig::ImageOf<yarp::sig::PixelMono>
682  vpImageConvert::convert(I, Iyarp, convert_by_copy);
683  // Write the image
684  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_copy.pgm");
685  std::cout << " Converted Yarp image saved in: " << filename << std::endl;
686  yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PGM);
687 
688  std::cout << " Reading the gray image with Yarp: " << filename << std::endl;
689  yarp::sig::ImageOf< yarp::sig::PixelMono > *IIyarp = new yarp::sig::ImageOf<yarp::sig::PixelMono >();
690  yarp::sig::file::read(*IIyarp, filename, yarp::sig::file::FORMAT_PGM);
692  vpImageConvert::convert(IIyarp, II, convert_by_copy);
693  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_copy_visp.pgm");
694  std::cout << " Converted image in ViSP saved in: " << filename << std::endl;
695  vpImageIo::write(II, filename);
696  if (I != II) {
697  std::cout << " Yarp gray conversion test failed" << std::endl;
698  return EXIT_FAILURE;
699  }
700  std::cout << std::endl;
701  }
702  {
703  bool convert_by_copy = true;
704  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
705  std::cout << " Reading the color image with ViSP: " << filename << std::endl;
706  vpImage<vpRGBa> I;
707  // Read an image on a disk
708  vpImageIo::read(I, filename);
709 
710  yarp::sig::ImageOf< yarp::sig::PixelRgba > *Iyarp = new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
711  // Convert the vpImage<vpRGBa> to a yarp::sig::ImageOf<yarp::sig::PixelRgba>
712  vpImageConvert::convert(I, Iyarp, convert_by_copy);
713  // Write the image
714  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_copy.ppm");
715  std::cout << " Converted image saved in: " << filename << std::endl;
716  yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
717 
718  std::cout << " Reading the color image with Yarp: " << filename << std::endl;
719  yarp::sig::ImageOf< yarp::sig::PixelRgba > *IIyarp = new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
720  yarp::sig::file::read(*IIyarp, filename, yarp::sig::file::FORMAT_PPM);
721  vpImage<vpRGBa> II;
722  vpImageConvert::convert(IIyarp, II, convert_by_copy);
723  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_copy_visp.ppm");
724  std::cout << " Converted image in ViSP saved in: " << filename << std::endl;
725  vpImageIo::write(II, filename);
726  if (I != II) {
727  std::cout << " Yarp color conversion test failed" << std::endl;
728  return EXIT_FAILURE;
729  }
730  std::cout << std::endl;
731  }
732 
733  std::cout << "** Test ViSP to Yarp image conversion without copy" << std::endl;
734  {
735  bool convert_by_copy = false;
736  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
737  std::cout << " Reading the gray image with ViSP: " << filename << std::endl;
739  // Read an image on a disk
740  vpImageIo::read(I, filename);
741 
742  yarp::sig::ImageOf< yarp::sig::PixelMono > *Iyarp = new yarp::sig::ImageOf<yarp::sig::PixelMono >();
743  // Convert the vpImage<unsigned char> to a yarp::sig::ImageOf<yarp::sig::PixelMono>
744  vpImageConvert::convert(I, Iyarp, convert_by_copy);
745  // Write the image
746  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_without_copy.pgm");
747  std::cout << " Converted Yarp image saved in: " << filename << std::endl;
748  yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PGM);
749 
750  std::cout << " Reading the gray image with Yarp: " << filename << std::endl;
751  yarp::sig::ImageOf< yarp::sig::PixelMono > *IIyarp = new yarp::sig::ImageOf<yarp::sig::PixelMono >();
752  yarp::sig::file::read(*IIyarp, filename, yarp::sig::file::FORMAT_PGM);
754  vpImageConvert::convert(IIyarp, II, convert_by_copy);
755  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_without_copy_visp.pgm");
756  std::cout << " Converted image in ViSP saved in: " << filename << std::endl;
757  vpImageIo::write(II, filename);
758  if (I != II) {
759  std::cout << " Yarp gray conversion test failed" << std::endl;
760  return EXIT_FAILURE;
761  }
762  else {
763  std::cout << " Yarp gray conversion test succeed" << std::endl;
764  }
765  std::cout << std::endl;
766  }
767  {
768  bool convert_by_copy = false;
769  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
770  std::cout << " Reading the color image with ViSP: " << filename << std::endl;
771  vpImage<vpRGBa> I;
772  // Read an image on a disk
773  vpImageIo::read(I, filename);
774 
775  yarp::sig::ImageOf< yarp::sig::PixelRgba > *Iyarp = new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
776  // Convert the vpImage<vpRGBa> to a yarp::sig::ImageOf<yarp::sig::PixelRgba>
777  vpImageConvert::convert(I, Iyarp, convert_by_copy);
778  // Write the image
779  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_without_copy.ppm");
780  std::cout << " Converted image saved in: " << filename << std::endl;
781  yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
782 
783  std::cout << " Reading the color image with Yarp: " << filename << std::endl;
784  yarp::sig::ImageOf< yarp::sig::PixelRgba > *IIyarp = new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
785  yarp::sig::file::read(*IIyarp, filename, yarp::sig::file::FORMAT_PPM);
786  vpImage<vpRGBa> II;
787  vpImageConvert::convert(IIyarp, II, convert_by_copy);
788  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_without_copy_visp.ppm");
789  std::cout << " Converted image in ViSP saved in: " << filename << std::endl;
790  vpImageIo::write(II, filename);
791  if (I != II) {
792  std::cout << " Yarp RGBa color conversion test failed" << std::endl;
793  return EXIT_FAILURE;
794  }
795  else {
796  std::cout << " Yarp RGBa color conversion test succeed" << std::endl;
797  }
798 
799  yarp::sig::ImageOf< yarp::sig::PixelRgb > *IIIyarp = new yarp::sig::ImageOf<yarp::sig::PixelRgb >();
800  // Convert the vpImage<vpRGBa> to a yarp::sig::ImageOf<yarp::sig::PixelRgb>
801  vpImageConvert::convert(I, IIIyarp);
802  // Write the image
803  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_without_copy_rgb.ppm");
804  std::cout << " Converted RGB image saved in: " << filename << std::endl;
805  yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
806 
807  std::cout << " Reading the RGB color image with Yarp: " << filename << std::endl;
808  yarp::sig::file::read(*IIIyarp, filename, yarp::sig::file::FORMAT_PPM);
809  vpImage<vpRGBa> III;
810  vpImageConvert::convert(IIIyarp, III);
811  filename = vpIoTools::createFilePath(opath, "Klimt_yarp_without_copy_visp_rgb.ppm");
812  std::cout << " Converted RGB image in ViSP saved in: " << filename << std::endl;
813  vpImageIo::write(II, filename);
814  if (I != III) {
815  std::cout << " Yarp RGB color conversion test failed" << std::endl;
816  return EXIT_FAILURE;
817  }
818  else {
819  std::cout << " Yarp RGB color conversion test succeed" << std::endl;
820  }
821 
822  std::cout << std::endl;
823  }
824 #endif
825 
826  std::cout << "** All the tests succeed" << std::endl;
827 
828  return EXIT_SUCCESS;
829  }
830  catch (const vpException &e) {
831  std::cout << "Catch an exception: " << e.getMessage() << std::endl;
832  return EXIT_FAILURE;
833  }
834 }
void start(bool reset=true)
Definition: vpTime.cpp:401
void stop()
Definition: vpTime.cpp:416
double getDurationMs()
Definition: vpTime.cpp:390
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ fatalError
Fatal error.
Definition: vpException.h:72
const char * getMessage() const
Definition: vpException.cpp:65
static void HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba, unsigned int size)
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 YUVToRGB(unsigned char y, unsigned char u, unsigned char v, unsigned char &r, unsigned char &g, unsigned char &b)
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=nullptr)
static void RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, unsigned int size)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
static void RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:147
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:291
unsigned int getWidth() const
Definition: vpImage.h:242
unsigned int getSize() const
Definition: vpImage.h:221
Type * bitmap
points toward the bitmap
Definition: vpImage.h:135
unsigned int getHeight() const
Definition: vpImage.h:181
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1053
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:396
static std::string getUserName()
Definition: vpIoTools.cpp:285
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1427
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:550
static bool equal(double x, double y, double threshold=0.001)
Definition: vpMath.h:458
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:70
Definition: vpRGBa.h:65