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>
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>
57#if defined(VISP_HAVE_YARP)
58#include <yarp/sig/ImageFile.h>
61#ifdef ENABLE_VISP_NAMESPACE
66#define GETOPTARGS "cdi:o:n:h"
79void usage(
const char *name,
const char *badparam,
const std::string &ipath,
const std::string &opath, std::string user,
83Test image conversions.\n\
86 %s [-i <input image path>] [-o <output image path>] [-n <nb benchmark iterations>]\n\
93 -i <input image path> %s\n\
94 Set image input path.\n\
95 From this path read \"Klimt/Klimt.pgm\"\n\
96 and \"Klimt/Klimt.ppm\" images.\n\
97 Setting the VISP_INPUT_IMAGE_PATH environment\n\
98 variable produces the same behaviour than using\n\
101 -o <output image path> %s\n\
102 Set image output path.\n\
103 From this directory, creates the \"%s\"\n\
104 subdirectory depending on the username, where \n\
105 Klimt_grey.pgm and Klimt_color.ppm output images\n\
108 -n <nb benchmark iterations> %d\n\
109 Set the number of benchmark iterations.\n\
112 Print the help.\n\n",
113 ipath.c_str(), opath.c_str(), user.c_str(), nbiter);
116 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
132bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath,
const std::string &user,
147 nbIterations = atoi(optarg_);
150 usage(argv[0],
nullptr, ipath, opath, user, nbIterations);
158 usage(argv[0], optarg_, ipath, opath, user, nbIterations);
163 if ((c == 1) || (c == -1)) {
165 usage(argv[0],
nullptr, ipath, opath, user, nbIterations);
166 std::cerr <<
"ERROR: " << std::endl;
167 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
174int main(
int argc,
const char **argv)
177 std::string env_ipath;
178 std::string opt_ipath;
179 std::string opt_opath;
183 std::string username;
184 int nbIterations = 1;
191 if (!env_ipath.empty())
196 opt_opath =
"C:/temp";
205 if (getOptions(argc, argv, opt_ipath, opt_opath, username, nbIterations) ==
false) {
210 if (!opt_ipath.empty())
212 if (!opt_opath.empty())
225 usage(argv[0],
nullptr, ipath, opt_opath, username, nbIterations);
226 std::cerr << std::endl <<
"ERROR:" << std::endl;
227 std::cerr <<
" Cannot create " << opath << std::endl;
228 std::cerr <<
" Check your -o " << opt_opath <<
" option " << std::endl;
235 if (opt_ipath.empty()) {
236 if (ipath != env_ipath) {
237 std::cout << std::endl <<
"WARNING: " << std::endl;
238 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
239 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
240 <<
" we skip the environment variable." << std::endl;
245 if (opt_ipath.empty() && env_ipath.empty()) {
246 usage(argv[0],
nullptr, ipath, opt_opath, username, nbIterations);
247 std::cerr << std::endl <<
"ERROR:" << std::endl;
248 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
249 <<
" environment variable to specify the location of the " << std::endl
250 <<
" image path where test images are located." << std::endl
263 std::cout <<
"** Convert a grey image (.pgm) to a color image (.ppm)" << std::endl;
266 std::cout <<
" Load " <<
filename << std::endl;
271 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
275 std::cout <<
"** Convert a color image (.ppm) to a grey image (.pgm)" << std::endl;
278 std::cout <<
" Load " <<
filename << std::endl;
283 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
287 std::cout <<
"** Convert YUV pixel value to a RGB value" << std::endl;
288 unsigned char y = 187,
u = 10,
v = 30;
289 unsigned char r, g, b;
293 std::cout <<
" y(" <<
static_cast<int>(
y) <<
") u(" <<
static_cast<int>(u) <<
") v(" <<
static_cast<int>(
v) <<
") = r(" <<
static_cast<int>(r) <<
") g(" <<
static_cast<int>(g)
294 <<
") b(" <<
static_cast<int>(b) <<
")" << std::endl;
302#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC)
307 std::cout <<
"** Convert a cv::Mat to a vpImage<vpRGBa>" << std::endl;
310 std::cout <<
" Reading the color image with c++ interface of opencv: " <<
filename << std::endl;
311#if VISP_HAVE_OPENCV_VERSION >= 0x030000
312 int flags = cv::IMREAD_COLOR;
314 int flags = CV_LOAD_IMAGE_COLOR;
316 imageMat = cv::imread(filename, flags);
317 if (imageMat.data ==
nullptr) {
318 std::cout <<
" Cannot read image: " <<
filename << std::endl;
323 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
329 std::cout <<
" Reading the grayscale image with opencv: " <<
filename << std::endl;
330#if VISP_HAVE_OPENCV_VERSION >= 0x030000
331 flags = cv::IMREAD_GRAYSCALE;
333 flags = CV_LOAD_IMAGE_GRAYSCALE;
335 imageMat = cv::imread(filename, flags);
336 if (imageMat.data ==
nullptr) {
337 std::cout <<
" Cannot read image: " <<
filename << std::endl;
342 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
348 std::cout <<
"** Convert a cv::Mat to a vpImage<nsigned char>" << std::endl;
353 std::cout <<
" Reading the color image with opencv: " <<
filename << std::endl;
354#if VISP_HAVE_OPENCV_VERSION >= 0x030000
355 flags = cv::IMREAD_COLOR;
357 flags = CV_LOAD_IMAGE_COLOR;
359 imageMat = cv::imread(filename, flags);
360 if (imageMat.data ==
nullptr) {
361 std::cout <<
" Cannot read image: " <<
filename << std::endl;
366 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
373 std::cout <<
" Reading the greyscale image with opencv: " <<
filename << std::endl;
374#if VISP_HAVE_OPENCV_VERSION >= 0x030000
375 flags = cv::IMREAD_GRAYSCALE;
377 flags = CV_LOAD_IMAGE_GRAYSCALE;
379 imageMat = cv::imread(filename, flags);
380 if (imageMat.data ==
nullptr) {
381 std::cout <<
" Cannot read image: " <<
filename << std::endl;
386 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
389 std::cout <<
" Convert result in " <<
filename << std::endl;
394 std::cout <<
"** Convert a vpImage<vpRGBa> to a cv::Mat" << std::endl;
400 std::cout <<
" Load " <<
filename << std::endl;
405 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
406 if (!cv::imwrite(filename, imageMat)) {
407 std::cout <<
" Cannot write image: " <<
filename << std::endl;
410 std::cout <<
" Convert result in " <<
filename << std::endl;
415 std::cout <<
"** Convert a vpImage<unsigned char> to a cv::Mat" << std::endl;
421 std::cout <<
" Load " <<
filename << std::endl;
427 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
428 if (!cv::imwrite(filename, imageMat)) {
429 std::cout <<
" Cannot write image: " <<
filename << std::endl;
432 std::cout <<
" Convert result in " <<
filename << std::endl;
434 std::cout <<
"== Conversion c++ interface : " << chrono.
getDurationMs() <<
" ms" << std::endl;
440 std::cout <<
"** Split a vpImage<vpRGBa> to vpImage<unsigned char>" << std::endl;
446 std::cout <<
" Load " <<
filename << std::endl;
451 for (
int iteration = 0; iteration < nbIterations; iteration++) {
456 std::cout <<
" Time for " << nbIterations <<
" split (ms): " << chrono.
getDurationMs() << std::endl;
460 std::cout <<
" Save Klimt R channel: " <<
filename << std::endl;
465 std::cout <<
" Save Klimt B channel: " <<
filename << std::endl;
471 std::cout <<
"** Merge 4 vpImage<unsigned char> (RGBa) to vpImage<vpRGBa>" << std::endl;
475 for (
int iteration = 0; iteration < nbIterations; iteration++) {
480 std::cout <<
" Time for 1000 merge (ms): " << chrono.
getDurationMs() << std::endl;
483 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
490 std::cout <<
"** Convert a vpImage<vpRGBa> in RGB color space to a vpImage<vpRGBa> in HSV color" << std::endl;
491 unsigned int size = Ic.
getSize();
494 std::vector<unsigned char> hue(size);
495 std::vector<unsigned char> saturation(size);
496 std::vector<unsigned char> value(size);
506 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
510 vpImageConvert::HSVToRGBa(&hue.front(), &saturation.front(), &value.front(),
reinterpret_cast<unsigned char *
>(Ic_from_hsv.bitmap), size);
511 for (
unsigned int i = 0;
i < Ic.
getHeight();
i++) {
512 for (
unsigned int j = 0;
j < Ic.
getWidth();
j++) {
513 double precision = 10.;
514 if ((!
vpMath::equal(
static_cast<double>(Ic[i][j].R),
static_cast<double>(Ic_from_hsv[i][j].R), precision))
515 || (!
vpMath::equal(
static_cast<double>(Ic[i][j].G),
static_cast<double>(Ic_from_hsv[i][j].G), precision))
516 || (!
vpMath::equal(
static_cast<double>(Ic[i][j].B),
static_cast<double>(Ic_from_hsv[i][j].B), precision))) {
517 std::cerr <<
"Ic[i][j].R=" <<
static_cast<unsigned int>(Ic[
i][
j].R)
518 <<
" ; Ic_from_hsv[i][j].R=" <<
static_cast<unsigned int>(Ic_from_hsv[i][j].R) <<
" precision: " << precision << std::endl;
519 std::cerr <<
"Ic[i][j].G=" <<
static_cast<unsigned int>(Ic[
i][
j].G)
520 <<
" ; Ic_from_hsv[i][j].G=" <<
static_cast<unsigned int>(Ic_from_hsv[i][j].G) <<
" precision: " << precision << std::endl;
521 std::cerr <<
"Ic[i][j].B=" <<
static_cast<unsigned int>(Ic[
i][
j].B)
522 <<
" ; Ic_from_hsv[i][j].B=" <<
static_cast<unsigned int>(Ic_from_hsv[i][j].B) <<
" precision: " << precision << std::endl;
528 std::vector<double> hue2(size);
529 std::vector<double> saturation2(size);
530 std::vector<double> value2(size);
533 std::vector<unsigned char> rgba(size * 4);
538 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
541 for (
unsigned int i = 0;
i < Ic.
getHeight();
i++) {
542 for (
unsigned int j = 0;
j < Ic.
getWidth();
j++) {
543 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) {
544 std::cerr <<
"Ic[i][j].R=" <<
static_cast<unsigned>(Ic[
i][
j].R)
545 <<
" ; I_HSV2RGBa[i][j].R=" <<
static_cast<unsigned>(I_HSV2RGBa[i][j].R) << std::endl;
546 std::cerr <<
"Ic[i][j].G=" <<
static_cast<unsigned>(Ic[
i][
j].G)
547 <<
" ; I_HSV2RGBa[i][j].G=" <<
static_cast<unsigned>(I_HSV2RGBa[i][j].G) << std::endl;
548 std::cerr <<
"Ic[i][j].B=" <<
static_cast<unsigned>(Ic[
i][
j].B)
549 <<
" ; I_HSV2RGBa[i][j].B=" <<
static_cast<unsigned>(I_HSV2RGBa[i][j].B) << std::endl;
558 std::cout <<
"** Construction of a vpImage from an array with copyData==true" << std::endl;
559 std::vector<unsigned char> rgba2(size * 4);
560 std::fill(rgba2.begin(), rgba2.end(), 127);
564 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
567 if (I_copyData.getSize() > 0) {
568 I_copyData[0][0].R = 10;
573 std::cout <<
"** Test color conversion" << std::endl;
580 std::vector<unsigned char> rgb_array(I_color.
getSize() * 3);
583#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC)
585 std::cout <<
"\n BGR cv::Mat to Grayscale" << std::endl;
587 cv::Mat colorMat = cv::imread(filename);
588 std::cout <<
" colorMat=" << colorMat.cols <<
"x" << colorMat.rows << std::endl;
591 std::cout <<
"\n RGB to Grayscale + Flip" << std::endl;
592 std::vector<unsigned char> rgb2gray_flip_array_sse(I_color.
getSize());
599 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
603 std::cout <<
"\n Conversion BGR to Grayscale + Flip" << std::endl;
604 std::vector<unsigned char> bgr2gray_flip_array_sse(I_color.
getSize());
610 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
614 std::cout <<
"\n RGB to Grayscale + Flip + Crop" << std::endl;
615 cv::Rect rect_roi(11, 17, 347, 449);
616 cv::Mat colorMat_crop = colorMat(rect_roi);
617 cv::Mat colorMat_crop_continuous = colorMat(rect_roi).clone();
618 std::cout <<
" colorMat_crop: " << colorMat_crop.cols <<
"x" << colorMat_crop.rows <<
" is continuous? "
619 << colorMat_crop.isContinuous() << std::endl;
620 std::cout <<
" colorMat_crop_continuous: " << colorMat_crop_continuous.cols <<
"x" << colorMat_crop_continuous.rows
621 <<
" is continuous? " << colorMat_crop_continuous.isContinuous() << std::endl;
623 vpImage<vpRGBa> I_color_crop(
static_cast<unsigned int>(rect_roi.height - rect_roi.y),
624 static_cast<unsigned int>(rect_roi.width - rect_roi.x));
625 for (
unsigned int i =
static_cast<unsigned int>(rect_roi.y); i <
static_cast<unsigned int>(rect_roi.height); i++) {
626 for (
unsigned int j =
static_cast<unsigned int>(rect_roi.x); j <
static_cast<unsigned int>(rect_roi.width); j++) {
627 I_color_crop[
static_cast<unsigned int>(
static_cast<int>(
i) - rect_roi.y)][
static_cast<unsigned int>(
static_cast<int>(j) - rect_roi.x)] = I_color[
i][
j];
631 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
634 std::vector<unsigned char> rgb_array_crop(I_color_crop.getSize() * 3);
637 std::vector<unsigned char> rgb2gray_flip_crop_array_sse(I_color_crop.getSize());
639 I_color_crop.getHeight(),
true);
640 vpImage<unsigned char> I_rgb2gray_flip_crop_sse(&rgb2gray_flip_crop_array_sse.front(), I_color_crop.getHeight(),
641 I_color_crop.getWidth());
644 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
648 std::cout <<
"\n BGR to Grayscale + Flip + Crop" << std::endl;
653 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
657 std::cout <<
"\n BGR to Grayscale + Flip + Crop + No continuous Mat" << std::endl;
658 vpImage<unsigned char> I_bgr2gray_flip_crop_no_continuous_sse(I_color_crop.getHeight(), I_color_crop.getWidth());
662 std::cout <<
" Resulting image saved in: " <<
filename << std::endl;
665 std::cout <<
" Test succeed" << std::endl;
668#if defined(VISP_HAVE_YARP)
672 std::cout <<
"** Test ViSP to Yarp image conversion by copy" << std::endl;
674 bool convert_by_copy =
true;
676 std::cout <<
" Reading the gray image with ViSP: " <<
filename << std::endl;
681 yarp::sig::ImageOf< yarp::sig::PixelMono > *Iyarp =
new yarp::sig::ImageOf<yarp::sig::PixelMono >();
686 std::cout <<
" Converted Yarp image saved in: " <<
filename << std::endl;
687 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PGM);
689 std::cout <<
" Reading the gray image with Yarp: " <<
filename << std::endl;
690 yarp::sig::ImageOf< yarp::sig::PixelMono > *IIyarp =
new yarp::sig::ImageOf<yarp::sig::PixelMono >();
691 yarp::sig::file::read(*IIyarp, filename, yarp::sig::file::FORMAT_PGM);
695 std::cout <<
" Converted image in ViSP saved in: " <<
filename << std::endl;
698 std::cout <<
" Yarp gray conversion test failed" << std::endl;
701 std::cout << std::endl;
704 bool convert_by_copy =
true;
706 std::cout <<
" Reading the color image with ViSP: " <<
filename << std::endl;
711 yarp::sig::ImageOf< yarp::sig::PixelRgba > *Iyarp =
new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
716 std::cout <<
" Converted image saved in: " <<
filename << std::endl;
717 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
719 std::cout <<
" Reading the color image with Yarp: " <<
filename << std::endl;
720 yarp::sig::ImageOf< yarp::sig::PixelRgba > *IIyarp =
new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
721 yarp::sig::file::read(*IIyarp, filename, yarp::sig::file::FORMAT_PPM);
725 std::cout <<
" Converted image in ViSP saved in: " <<
filename << std::endl;
728 std::cout <<
" Yarp color conversion test failed" << std::endl;
731 std::cout << std::endl;
734 std::cout <<
"** Test ViSP to Yarp image conversion without copy" << std::endl;
736 bool convert_by_copy =
false;
738 std::cout <<
" Reading the gray image with ViSP: " <<
filename << std::endl;
743 yarp::sig::ImageOf< yarp::sig::PixelMono > *Iyarp =
new yarp::sig::ImageOf<yarp::sig::PixelMono >();
748 std::cout <<
" Converted Yarp image saved in: " <<
filename << std::endl;
749 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PGM);
751 std::cout <<
" Reading the gray image with Yarp: " <<
filename << std::endl;
752 yarp::sig::ImageOf< yarp::sig::PixelMono > *IIyarp =
new yarp::sig::ImageOf<yarp::sig::PixelMono >();
753 yarp::sig::file::read(*IIyarp, filename, yarp::sig::file::FORMAT_PGM);
757 std::cout <<
" Converted image in ViSP saved in: " <<
filename << std::endl;
760 std::cout <<
" Yarp gray conversion test failed" << std::endl;
764 std::cout <<
" Yarp gray conversion test succeed" << std::endl;
766 std::cout << std::endl;
769 bool convert_by_copy =
false;
771 std::cout <<
" Reading the color image with ViSP: " <<
filename << std::endl;
776 yarp::sig::ImageOf< yarp::sig::PixelRgba > *Iyarp =
new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
781 std::cout <<
" Converted image saved in: " <<
filename << std::endl;
782 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
784 std::cout <<
" Reading the color image with Yarp: " <<
filename << std::endl;
785 yarp::sig::ImageOf< yarp::sig::PixelRgba > *IIyarp =
new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
786 yarp::sig::file::read(*IIyarp, filename, yarp::sig::file::FORMAT_PPM);
790 std::cout <<
" Converted image in ViSP saved in: " <<
filename << std::endl;
793 std::cout <<
" Yarp RGBa color conversion test failed" << std::endl;
797 std::cout <<
" Yarp RGBa color conversion test succeed" << std::endl;
800 yarp::sig::ImageOf< yarp::sig::PixelRgb > *IIIyarp =
new yarp::sig::ImageOf<yarp::sig::PixelRgb >();
805 std::cout <<
" Converted RGB image saved in: " <<
filename << std::endl;
806 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
808 std::cout <<
" Reading the RGB color image with Yarp: " <<
filename << std::endl;
809 yarp::sig::file::read(*IIIyarp, filename, yarp::sig::file::FORMAT_PPM);
813 std::cout <<
" Converted RGB image in ViSP saved in: " <<
filename << std::endl;
816 std::cout <<
" Yarp RGB color conversion test failed" << std::endl;
820 std::cout <<
" Yarp RGB color conversion test succeed" << std::endl;
823 std::cout << std::endl;
827 std::cout <<
"** All the tests succeed" << std::endl;
832 std::cout <<
"Catch an exception: " <<
e.getMessage() << std::endl;
void start(bool reset=true)
error that can be emitted by ViSP classes.
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)
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
static bool equal(double x, double y, double threshold=0.001)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)