Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
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_ = static_cast<int>(scale);
int radius_ = static_cast<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->setDownScalingFactor(scale);
d->init(I);
vpImageTools::crop(I, vpImagePoint(0, 245), static_cast<unsigned int>(roi.getHeight()), static_cast<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 = static_cast<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 = 1; 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" && i + 1 < argc) {
opt_ipath = std::string(argv[++i]);
}
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
#if defined(VISP_HAVE_OPENCV) && !defined(VISP_HAVE_OPENCV_HEADLESS)
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:198
static const vpColor cyan
Definition vpColor.h:207
static const vpColor blue
Definition vpColor.h:204
static const vpColor green
Definition vpColor.h:201
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition vpDisplayX.h:135
Class that defines generic functionalities for display.
Definition vpDisplay.h:171
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)
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)
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
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 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:755
static std::string getViSPImagesDataPath()
static std::string createFilePath(const std::string &parent, const std::string &child)
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