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"
79 void usage(
const char *name,
const char *badparam, std::string ipath, std::string opath, std::string user,
int nbiter)
82 Test image conversions.\n\
85 %s [-i <input image path>] [-o <output image path>] [-n <nb benchmark iterations>]\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\
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\
107 -n <nb benchmark iterations> %d\n\
108 Set the number of benchmark iterations.\n\
111 Print the help.\n\n",
112 ipath.c_str(), opath.c_str(), user.c_str(), nbiter);
115 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
131 bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &opath,
const std::string &user,
146 nbIterations = atoi(optarg_);
149 usage(argv[0],
nullptr, ipath, opath, user, nbIterations);
157 usage(argv[0], optarg_, ipath, opath, user, nbIterations);
162 if ((c == 1) || (c == -1)) {
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;
173 int main(
int argc,
const char **argv)
176 std::string env_ipath;
177 std::string opt_ipath;
178 std::string opt_opath;
181 std::string filename;
182 std::string username;
183 int nbIterations = 1;
190 if (!env_ipath.empty())
195 opt_opath =
"C:/temp";
204 if (getOptions(argc, argv, opt_ipath, opt_opath, username, nbIterations) ==
false) {
209 if (!opt_ipath.empty())
211 if (!opt_opath.empty())
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;
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;
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
262 std::cout <<
"** Convert a grey image (.pgm) to a color image (.ppm)" << std::endl;
265 std::cout <<
" Load " << filename << std::endl;
270 std::cout <<
" Resulting image saved in: " << filename << std::endl;
274 std::cout <<
"** Convert a color image (.ppm) to a grey image (.pgm)" << std::endl;
277 std::cout <<
" Load " << filename << std::endl;
282 std::cout <<
" Resulting image saved in: " << filename << std::endl;
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;
292 std::cout <<
" y(" << (int)y <<
") u(" << (
int)u <<
") v(" << (int)v <<
") = r(" << (
int)r <<
") g(" << (int)g
293 <<
") b(" << (
int)b <<
")" << std::endl;
301 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC)
306 std::cout <<
"** Convert a cv::Mat to a vpImage<vpRGBa>" << std::endl;
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;
313 int flags = CV_LOAD_IMAGE_COLOR;
315 imageMat = cv::imread(filename, flags);
316 if (imageMat.data ==
nullptr) {
317 std::cout <<
" Cannot read image: " << filename << std::endl;
322 std::cout <<
" Resulting image saved in: " << filename << std::endl;
328 std::cout <<
" Reading the grayscale image with opencv: " << filename << std::endl;
329 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
330 flags = cv::IMREAD_GRAYSCALE;
332 flags = CV_LOAD_IMAGE_GRAYSCALE;
334 imageMat = cv::imread(filename, flags);
335 if (imageMat.data ==
nullptr) {
336 std::cout <<
" Cannot read image: " << filename << std::endl;
341 std::cout <<
" Resulting image saved in: " << filename << std::endl;
347 std::cout <<
"** Convert a cv::Mat to a vpImage<nsigned char>" << std::endl;
352 std::cout <<
" Reading the color image with opencv: " << filename << std::endl;
353 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
354 flags = cv::IMREAD_COLOR;
356 flags = CV_LOAD_IMAGE_COLOR;
358 imageMat = cv::imread(filename, flags);
359 if (imageMat.data ==
nullptr) {
360 std::cout <<
" Cannot read image: " << filename << std::endl;
365 std::cout <<
" Resulting image saved in: " << filename << std::endl;
372 std::cout <<
" Reading the greyscale image with opencv: " << filename << std::endl;
373 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
374 flags = cv::IMREAD_GRAYSCALE;
376 flags = CV_LOAD_IMAGE_GRAYSCALE;
378 imageMat = cv::imread(filename, flags);
379 if (imageMat.data ==
nullptr) {
380 std::cout <<
" Cannot read image: " << filename << std::endl;
385 std::cout <<
" Resulting image saved in: " << filename << std::endl;
388 std::cout <<
" Convert result in " << filename << std::endl;
393 std::cout <<
"** Convert a vpImage<vpRGBa> to a cv::Mat" << std::endl;
399 std::cout <<
" Load " << filename << std::endl;
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;
409 std::cout <<
" Convert result in " << filename << std::endl;
414 std::cout <<
"** Convert a vpImage<unsigned char> to a cv::Mat" << std::endl;
420 std::cout <<
" Load " << filename << std::endl;
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;
431 std::cout <<
" Convert result in " << filename << std::endl;
433 std::cout <<
"== Conversion c++ interface : " << chrono.
getDurationMs() <<
" ms" << std::endl;
439 std::cout <<
"** Split a vpImage<vpRGBa> to vpImage<unsigned char>" << std::endl;
445 std::cout <<
" Load " << filename << std::endl;
450 for (
int iteration = 0; iteration < nbIterations; iteration++) {
455 std::cout <<
" Time for " << nbIterations <<
" split (ms): " << chrono.
getDurationMs() << std::endl;
459 std::cout <<
" Save Klimt R channel: " << filename << std::endl;
464 std::cout <<
" Save Klimt B channel: " << filename << std::endl;
470 std::cout <<
"** Merge 4 vpImage<unsigned char> (RGBa) to vpImage<vpRGBa>" << std::endl;
474 for (
int iteration = 0; iteration < nbIterations; iteration++) {
479 std::cout <<
" Time for 1000 merge (ms): " << chrono.
getDurationMs() << std::endl;
482 std::cout <<
" Resulting image saved in: " << filename << std::endl;
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();
493 std::vector<unsigned char> hue(size);
494 std::vector<unsigned char> saturation(size);
495 std::vector<unsigned char> value(size);
505 std::cout <<
" Resulting image saved in: " << filename << std::endl;
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.;
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;
527 std::vector<double> hue2(size);
528 std::vector<double> saturation2(size);
529 std::vector<double> value2(size);
532 std::vector<unsigned char> rgba(size * 4);
537 std::cout <<
" Resulting image saved in: " << filename << std::endl;
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;
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);
563 std::cout <<
" Resulting image saved in: " << filename << std::endl;
566 if (I_copyData.getSize() > 0) {
567 I_copyData[0][0].R = 10;
572 std::cout <<
"** Test color conversion" << std::endl;
579 std::vector<unsigned char> rgb_array(I_color.
getSize() * 3);
582 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC)
584 std::cout <<
"\n BGR cv::Mat to Grayscale" << std::endl;
586 cv::Mat colorMat = cv::imread(filename);
587 std::cout <<
" colorMat=" << colorMat.cols <<
"x" << colorMat.rows << std::endl;
590 std::cout <<
"\n RGB to Grayscale + Flip" << std::endl;
591 std::vector<unsigned char> rgb2gray_flip_array_sse(I_color.
getSize());
598 std::cout <<
" Resulting image saved in: " << filename << std::endl;
602 std::cout <<
"\n Conversion BGR to Grayscale + Flip" << std::endl;
603 std::vector<unsigned char> bgr2gray_flip_array_sse(I_color.
getSize());
609 std::cout <<
" Resulting image saved in: " << filename << std::endl;
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;
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];
630 std::cout <<
" Resulting image saved in: " << filename << std::endl;
633 std::vector<unsigned char> rgb_array_crop(I_color_crop.getSize() * 3);
636 std::vector<unsigned char> rgb2gray_flip_crop_array_sse(I_color_crop.getSize());
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());
643 std::cout <<
" Resulting image saved in: " << filename << std::endl;
647 std::cout <<
"\n BGR to Grayscale + Flip + Crop" << std::endl;
652 std::cout <<
" Resulting image saved in: " << filename << std::endl;
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());
661 std::cout <<
" Resulting image saved in: " << filename << std::endl;
664 std::cout <<
" Test succeed" << std::endl;
667 #if defined(VISP_HAVE_YARP)
671 std::cout <<
"** Test ViSP to Yarp image conversion by copy" << std::endl;
673 bool convert_by_copy =
true;
675 std::cout <<
" Reading the gray image with ViSP: " << filename << std::endl;
680 yarp::sig::ImageOf< yarp::sig::PixelMono > *Iyarp =
new yarp::sig::ImageOf<yarp::sig::PixelMono >();
685 std::cout <<
" Converted Yarp image saved in: " << filename << std::endl;
686 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PGM);
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);
694 std::cout <<
" Converted image in ViSP saved in: " << filename << std::endl;
697 std::cout <<
" Yarp gray conversion test failed" << std::endl;
700 std::cout << std::endl;
703 bool convert_by_copy =
true;
705 std::cout <<
" Reading the color image with ViSP: " << filename << std::endl;
710 yarp::sig::ImageOf< yarp::sig::PixelRgba > *Iyarp =
new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
715 std::cout <<
" Converted image saved in: " << filename << std::endl;
716 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
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);
724 std::cout <<
" Converted image in ViSP saved in: " << filename << std::endl;
727 std::cout <<
" Yarp color conversion test failed" << std::endl;
730 std::cout << std::endl;
733 std::cout <<
"** Test ViSP to Yarp image conversion without copy" << std::endl;
735 bool convert_by_copy =
false;
737 std::cout <<
" Reading the gray image with ViSP: " << filename << std::endl;
742 yarp::sig::ImageOf< yarp::sig::PixelMono > *Iyarp =
new yarp::sig::ImageOf<yarp::sig::PixelMono >();
747 std::cout <<
" Converted Yarp image saved in: " << filename << std::endl;
748 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PGM);
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);
756 std::cout <<
" Converted image in ViSP saved in: " << filename << std::endl;
759 std::cout <<
" Yarp gray conversion test failed" << std::endl;
763 std::cout <<
" Yarp gray conversion test succeed" << std::endl;
765 std::cout << std::endl;
768 bool convert_by_copy =
false;
770 std::cout <<
" Reading the color image with ViSP: " << filename << std::endl;
775 yarp::sig::ImageOf< yarp::sig::PixelRgba > *Iyarp =
new yarp::sig::ImageOf<yarp::sig::PixelRgba >();
780 std::cout <<
" Converted image saved in: " << filename << std::endl;
781 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
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);
789 std::cout <<
" Converted image in ViSP saved in: " << filename << std::endl;
792 std::cout <<
" Yarp RGBa color conversion test failed" << std::endl;
796 std::cout <<
" Yarp RGBa color conversion test succeed" << std::endl;
799 yarp::sig::ImageOf< yarp::sig::PixelRgb > *IIIyarp =
new yarp::sig::ImageOf<yarp::sig::PixelRgb >();
804 std::cout <<
" Converted RGB image saved in: " << filename << std::endl;
805 yarp::sig::file::write(*Iyarp, filename, yarp::sig::file::FORMAT_PPM);
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);
812 std::cout <<
" Converted RGB image in ViSP saved in: " << filename << std::endl;
815 std::cout <<
" Yarp RGB color conversion test failed" << std::endl;
819 std::cout <<
" Yarp RGB color conversion test succeed" << std::endl;
822 std::cout << std::endl;
826 std::cout <<
"** All the tests succeed" << std::endl;
831 std::cout <<
"Catch an exception: " << e.
getMessage() << std::endl;
void start(bool reset=true)
error that can be emitted by ViSP classes.
const char * getMessage() const
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)
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)