Visual Servoing Platform  version 3.6.1 under development (2024-10-18)
testDisplayScaled.cpp
/*
* ViSP, open source Visual Servoing Platform software.
* Copyright (C) 2005 - 2024 by Inria. All rights reserved.
*
* This software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See the file LICENSE.txt at the root directory of this source
* distribution for additional information about the GNU GPL.
*
* For using ViSP with software that can not be combined with the GNU
* GPL, please contact Inria about acquiring a ViSP Professional
* Edition License.
*
* See https://visp.inria.fr for more information.
*
* This software was developed at:
* Inria Rennes - Bretagne Atlantique
* Campus Universitaire de Beaulieu
* 35042 Rennes Cedex
* France
*
* If you have questions regarding the use of this file, please contact
* Inria at visp@inria.fr
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Description:
* Display testing.
*/
#include <sstream>
#include <visp3/core/vpConfig.h>
#include <visp3/core/vpImageTools.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/gui/vpDisplayD3D.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayGTK.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
#include <visp3/io/vpImageIo.h>
#ifdef ENABLE_VISP_NAMESPACE
using namespace VISP_NAMESPACE_NAME;
#endif
template <typename Type> bool test(const std::string &display, vpImage<Type> &I, unsigned int scale, bool click)
{
bool success = true;
unsigned int radius(I.getHeight() / 4);
int scale_ = (int)scale;
int radius_ = (int)radius;
unsigned int thickness = 2;
vpImagePoint center(I.getHeight() / 2, I.getWidth() / 2);
vpImagePoint offset(30, 160);
vpImagePoint v_offset(radius, 0);
vpImagePoint h_offset(0, radius);
vpRect roi(center, radius_ + scale_, radius_);
std::string itype;
// backup the input image
vpImage<Type> Ibackup(I);
vpDisplay *d = nullptr;
if (display == "GDI") {
#ifdef VISP_HAVE_GDI
d = new vpDisplayGDI;
#endif
}
else if (display == "GTK") {
#ifdef VISP_HAVE_GTK
d = new vpDisplayGTK;
#endif
}
else if (display == "X") {
#ifdef VISP_HAVE_X11
d = new vpDisplayX;
#endif
}
else if (display == "OpenCV") {
#ifdef HAVE_OPENCV_HIGHGUI
d = new vpDisplayOpenCV;
#endif
}
else if (display == "D3D9") {
#ifdef VISP_HAVE_D3D9
d = new vpDisplayD3D;
#endif
}
std::cout << "Start test for " << display << " renderer..." << std::endl;
std::cout << " Screen resolution: " << d->getScreenWidth() << " " << d->getScreenHeight() << std::endl;
d->init(I);
vpImageTools::crop(I, vpImagePoint(0, 245), (unsigned int)roi.getHeight(), (unsigned int)roi.getWidth(), crop);
I.insert(crop, roi.getTopLeft());
// Compare input and rendered images
if (sizeof(Type) == 1) {
itype = "uchar";
vpImage<Type> Iinsert = I;
vpImage<vpRGBa> Isampled;
vpImageConvert::convert(Iinsert, Icolor);
Icolor.subsample(scale, scale, Isampled);
vpImage<vpRGBa> Irendered;
vpDisplay::getImage(I, Irendered);
if (Isampled != Irendered) {
success = false;
std::cout << " -- Test width scale= " << scale << " type= " << itype << ": failed" << std::endl;
std::stringstream ss;
ss << "Isampled-" << itype << "-scale-" << scale;
#ifdef VISP_HAVE_OPENCV
ss << ".png";
#else
ss << ".ppm";
#endif
vpImageIo::write(Isampled, ss.str());
ss.str("");
ss.clear();
ss << "Irendered-" << itype << "-scale-" << scale;
#ifdef VISP_HAVE_OPENCV
ss << ".png";
#else
ss << ".ppm";
#endif
vpImageIo::write(Irendered, ss.str());
vpImageTools::imageDifference(Isampled, Irendered, Idiff);
ss.str("");
ss.clear();
ss << "Idiff-" << itype << "-scale-" << scale;
#ifdef VISP_HAVE_OPENCV
ss << ".png";
#else
ss << ".ppm";
#endif
vpImageIo::write(Idiff, ss.str());
}
else {
std::cout << " ++ Test width scale= " << scale << " type= " << itype << ": succeed" << std::endl;
}
}
else {
itype = "rgba";
vpImage<Type> Iinsert = I;
vpImage<Type> Isampled; // vpRGBa necessary
Iinsert.subsample(scale, scale, Isampled);
vpImage<vpRGBa> Irendered; // vpRGBa necessary
vpDisplay::getImage(I, Irendered);
vpImage<vpRGBa> IsampledCopy; // vpRGBa necessary
vpImageConvert::convert(Isampled, IsampledCopy);
if (IsampledCopy != Irendered) {
success = false;
std::cout << " -- Test width scale= " << scale << " type= " << itype << ": failed" << std::endl;
std::stringstream ss;
ss << "Isampled-" << itype << "-scale-" << scale;
#ifdef VISP_HAVE_OPENCV
ss << ".png";
#else
ss << ".ppm";
#endif
vpImageIo::write(Isampled, ss.str());
ss.str("");
ss.clear();
ss << "Irendered-" << itype << "-scale-" << scale;
#ifdef VISP_HAVE_OPENCV
ss << ".png";
#else
ss << ".ppm";
#endif
vpImageIo::write(Irendered, ss.str());
vpImageTools::imageDifference(IsampledCopy, Irendered, Idiff);
ss.str("");
ss.clear();
ss << "Idiff-" << itype << "-scale-" << scale;
#ifdef VISP_HAVE_OPENCV
ss << ".png";
#else
ss << ".ppm";
#endif
vpImageIo::write(Idiff, ss.str());
}
else {
std::cout << " ++ Test width scale= " << scale << " type= " << itype << ": succeed" << std::endl;
}
}
vpDisplay::displayRectangle(I, center - v_offset - h_offset, radius, radius, vpColor::blue, false, thickness);
vpDisplay::displayRectangle(I, center, center + v_offset + h_offset, vpColor::blue, false, thickness);
vpDisplay::displayRectangle(I, vpRect(center - v_offset - h_offset, center + v_offset + h_offset), vpColor::blue,
false, thickness);
vpDisplay::displayRectangle(I, center - v_offset * 3. / 2 + h_offset, radius / 2, radius / 2, vpColor::green, true);
vpDisplay::displayCircle(I, center, radius, vpColor::blue, false, thickness);
vpDisplay::displayArrow(I, center, center - v_offset / 4 - h_offset, vpColor::red, 10, 6, thickness);
vpDisplay::displayCross(I, center - radius / 2., radius, vpColor::green, thickness);
vpDisplay::displayDotLine(I, center - v_offset - h_offset, center, vpColor::cyan, thickness);
vpDisplay::displayLine(I, center + v_offset - h_offset, center - v_offset + h_offset, vpColor::cyan, thickness);
int nbpoints = (int)(radius * sqrt(2.) / 8 / scale);
for (int i = 0; i < nbpoints; i++) {
I, center - h_offset / 2. + vpImagePoint(-i * radius_ / (nbpoints * 2), i * radius_ / (nbpoints * 2)),
vpDisplay::displayPoint(I, center - h_offset + vpImagePoint(-i * radius_ / nbpoints, i * radius_ / nbpoints),
vpColor::cyan, thickness);
}
if (click)
vpDisplay::displayText(I, 10 * scale_, 10 * scale_, "A click to continue", vpColor::red);
else
vpDisplay::displayText(I, 10 * scale_, 10 * scale_, "This is an image", vpColor::red);
vpImage<vpRGBa> Irendered;
vpDisplay::getImage(I, Irendered);
std::stringstream ss;
ss << "overlay-" << display << "-" << itype << "-scale-" << scale;
#ifdef VISP_HAVE_OPENCV
ss << ".png";
#else
ss << ".ppm";
#endif
std::cout << " Overlay saved in: " << ss.str() << std::endl;
vpImageIo::write(Irendered, ss.str());
if (click)
// Restore the input image
I = Ibackup;
if (d != nullptr)
delete d;
if (success)
return true;
else
return false;
}
int main(int argc, const char *argv[])
{
bool opt_click = true;
bool opt_display = true;
std::string opt_ipath;
std::string env_ipath;
std::string ipath;
for (int i = 0; i < argc; i++) {
if (std::string(argv[i]) == "-c")
opt_click = false;
else if (std::string(argv[i]) == "-d")
opt_display = false;
else if (std::string(argv[i]) == "-i")
opt_ipath = std::string(argv[i + 1]);
else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
std::cout << "\nUsage: " << argv[0] << " [-i <image path>] [-c] [-d] [--help]\n" << std::endl;
std::cout << "\nOptions: " << std::endl;
std::cout << " -i <input image path> : set image input path.\n"
<< " From this path read \"Klimt/Klimt.pgm\" image.\n"
<< " Setting the VISP_INPUT_IMAGE_PATH environment\n"
<< " variable produces the same behaviour than using\n"
<< " this option." << std::endl;
std::cout << " -c : disable mouse click" << std::endl;
std::cout << " -d : disable display" << std::endl;
std::cout << " -h, --help : print this help\n" << std::endl;
return EXIT_SUCCESS;
}
}
// Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
// environment variable value
// Set the default input path
if (!env_ipath.empty())
ipath = env_ipath;
// Get the option values
if (!opt_ipath.empty())
ipath = opt_ipath;
std::string filename;
std::vector<std::string> display;
if (opt_display) {
#ifdef VISP_HAVE_GDI
display.push_back("GDI");
#endif
#ifdef VISP_HAVE_GTK
display.push_back("GTK");
#endif
#ifdef VISP_HAVE_X11
display.push_back("X");
#endif
#ifdef VISP_HAVE_OPENCV
display.push_back("OpenCV");
#endif
#ifdef VISP_HAVE_D3D9
display.push_back("D3D9");
#endif
if (display.size() == 0) {
std::cout << "No display available. We stop here." << std::endl;
return EXIT_FAILURE;
}
filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
vpImageIo::read(I, filename);
filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
vpImageIo::read(C, filename);
int nbfailure = 0;
for (unsigned int i = 0; i < display.size(); i++) {
for (unsigned int scale = 1; scale < 4; scale++) {
if (!test(display[i], I, scale, opt_click))
nbfailure++;
if (!test(display[i], C, scale, opt_click))
nbfailure++;
}
}
if (nbfailure == 0)
std::cout << "Test succeed" << std::endl;
else
std::cout << "Test failed with " << nbfailure << " failures" << std::endl;
}
return EXIT_SUCCESS;
}
static const vpColor red
Definition: vpColor.h:217
static const vpColor cyan
Definition: vpColor.h:226
static const vpColor blue
Definition: vpColor.h:223
static const vpColor green
Definition: vpColor.h:220
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:106
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:130
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:133
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="") VP_OVERRIDE
unsigned int getScreenWidth() VP_OVERRIDE
unsigned int getScreenHeight() VP_OVERRIDE
void setDownScalingFactor(unsigned int scale)
Class that defines generic functionalities for display.
Definition: vpDisplay.h:178
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void displayCircle(const vpImage< unsigned char > &I, const vpImageCircle &circle, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void displayROI(const vpImage< unsigned char > &I, const vpRect &roi)
static void display(const vpImage< unsigned char > &I)
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
Definition: vpDisplay.cpp:140
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void close(vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
static void displayArrow(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
static void displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
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
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
static void imageDifference(const vpImage< unsigned char > &I1, const vpImage< unsigned char > &I2, vpImage< unsigned char > &Idiff)
static void crop(const vpImage< Type > &I, double roi_top, double roi_left, unsigned int roi_height, unsigned int roi_width, vpImage< Type > &crop, unsigned int v_scale=1, unsigned int h_scale=1)
Definition: vpImageTools.h:315
Definition of the vpImage class member functions.
Definition: vpImage.h:131
void subsample(unsigned int v_scale, unsigned int h_scale, vpImage< Type > &sampled) const
Definition: vpImage.h:753
unsigned int getWidth() const
Definition: vpImage.h:242
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
Definition: vpImage.h:637
unsigned int getHeight() const
Definition: vpImage.h:181
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1053
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1427
Defines a rectangle in the plane.
Definition: vpRect.h:79
double getWidth() const
Definition: vpRect.h:227
vpImagePoint getTopLeft() const
Definition: vpRect.h:199
double getHeight() const
Definition: vpRect.h:166