Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
testDisplayScaled.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 * Display testing.
32 */
33
37#include <sstream>
38
39#include <visp3/core/vpConfig.h>
40#include <visp3/core/vpImageTools.h>
41#include <visp3/core/vpIoTools.h>
42#include <visp3/gui/vpDisplayD3D.h>
43#include <visp3/gui/vpDisplayGDI.h>
44#include <visp3/gui/vpDisplayGTK.h>
45#include <visp3/gui/vpDisplayOpenCV.h>
46#include <visp3/gui/vpDisplayX.h>
47#include <visp3/io/vpImageIo.h>
48
49#ifdef ENABLE_VISP_NAMESPACE
50using namespace VISP_NAMESPACE_NAME;
51#endif
52
53template <typename Type> bool test(const std::string &display, vpImage<Type> &I, unsigned int scale, bool click)
54{
55 bool success = true;
56 unsigned int radius(I.getHeight() / 4);
57 int scale_ = static_cast<int>(scale);
58 int radius_ = static_cast<int>(radius);
59 unsigned int thickness = 2;
60 vpImagePoint center(I.getHeight() / 2, I.getWidth() / 2);
61 vpImagePoint offset(30, 160);
62 vpImagePoint v_offset(radius, 0);
63 vpImagePoint h_offset(0, radius);
64 vpRect roi(center, radius_ + scale_, radius_);
65 std::string itype;
66
67 // backup the input image
68 vpImage<Type> Ibackup(I);
69
70 vpDisplay *d = nullptr;
71 if (display == "GDI") {
72#ifdef VISP_HAVE_GDI
73 d = new vpDisplayGDI;
74#endif
75 }
76 else if (display == "GTK") {
77#ifdef VISP_HAVE_GTK
78 d = new vpDisplayGTK;
79#endif
80 }
81 else if (display == "X") {
82#ifdef VISP_HAVE_X11
83 d = new vpDisplayX;
84#endif
85 }
86 else if (display == "OpenCV") {
87#ifdef HAVE_OPENCV_HIGHGUI
88 d = new vpDisplayOpenCV;
89#endif
90 }
91 else if (display == "D3D9") {
92#ifdef VISP_HAVE_D3D9
93 d = new vpDisplayD3D;
94#endif
95 }
96 std::cout << "Start test for " << display << " renderer..." << std::endl;
97 std::cout << " Screen resolution: " << d->getScreenWidth() << " " << d->getScreenHeight() << std::endl;
98 d->setDownScalingFactor(scale);
99 d->init(I);
102
103 vpImage<Type> crop;
104 vpImageTools::crop(I, vpImagePoint(0, 245), static_cast<unsigned int>(roi.getHeight()), static_cast<unsigned int>(roi.getWidth()), crop);
105 I.insert(crop, roi.getTopLeft());
106 vpDisplay::displayROI(I, roi);
108
109 // Compare input and rendered images
110 if (sizeof(Type) == 1) {
111 itype = "uchar";
112 vpImage<Type> Iinsert = I;
113 vpImage<vpRGBa> Isampled;
114 vpImage<vpRGBa> Icolor;
115 vpImageConvert::convert(Iinsert, Icolor);
116 Icolor.subsample(scale, scale, Isampled);
117
118 vpImage<vpRGBa> Irendered;
119 vpDisplay::getImage(I, Irendered);
120
121 if (Isampled != Irendered) {
122 success = false;
123 std::cout << " -- Test width scale= " << scale << " type= " << itype << ": failed" << std::endl;
124
125 std::stringstream ss;
126 ss << "Isampled-" << itype << "-scale-" << scale;
127#ifdef VISP_HAVE_OPENCV
128 ss << ".png";
129#else
130 ss << ".ppm";
131#endif
132
133 vpImageIo::write(Isampled, ss.str());
134
135 ss.str("");
136 ss.clear();
137 ss << "Irendered-" << itype << "-scale-" << scale;
138#ifdef VISP_HAVE_OPENCV
139 ss << ".png";
140#else
141 ss << ".ppm";
142#endif
143
144 vpImageIo::write(Irendered, ss.str());
145 vpImage<vpRGBa> Idiff;
146 vpImageTools::imageDifference(Isampled, Irendered, Idiff);
147
148 ss.str("");
149 ss.clear();
150 ss << "Idiff-" << itype << "-scale-" << scale;
151#ifdef VISP_HAVE_OPENCV
152 ss << ".png";
153#else
154 ss << ".ppm";
155#endif
156
157 vpImageIo::write(Idiff, ss.str());
158 }
159 else {
160 std::cout << " ++ Test width scale= " << scale << " type= " << itype << ": succeed" << std::endl;
161 }
162 }
163 else {
164 itype = "rgba";
165 vpImage<Type> Iinsert = I;
166 vpImage<Type> Isampled; // vpRGBa necessary
167 Iinsert.subsample(scale, scale, Isampled);
168
169 vpImage<vpRGBa> Irendered; // vpRGBa necessary
170 vpDisplay::getImage(I, Irendered);
171
172 vpImage<vpRGBa> IsampledCopy; // vpRGBa necessary
173
174 vpImageConvert::convert(Isampled, IsampledCopy);
175 if (IsampledCopy != Irendered) {
176 success = false;
177 std::cout << " -- Test width scale= " << scale << " type= " << itype << ": failed" << std::endl;
178
179 std::stringstream ss;
180 ss << "Isampled-" << itype << "-scale-" << scale;
181#ifdef VISP_HAVE_OPENCV
182 ss << ".png";
183#else
184 ss << ".ppm";
185#endif
186
187 vpImageIo::write(Isampled, ss.str());
188
189 ss.str("");
190 ss.clear();
191 ss << "Irendered-" << itype << "-scale-" << scale;
192#ifdef VISP_HAVE_OPENCV
193 ss << ".png";
194#else
195 ss << ".ppm";
196#endif
197
198 vpImageIo::write(Irendered, ss.str());
199 vpImage<vpRGBa> Idiff;
200 vpImageTools::imageDifference(IsampledCopy, Irendered, Idiff);
201 ss.str("");
202 ss.clear();
203 ss << "Idiff-" << itype << "-scale-" << scale;
204#ifdef VISP_HAVE_OPENCV
205 ss << ".png";
206#else
207 ss << ".ppm";
208#endif
209
210 vpImageIo::write(Idiff, ss.str());
211
212 }
213 else {
214 std::cout << " ++ Test width scale= " << scale << " type= " << itype << ": succeed" << std::endl;
215 }
216 }
217
218 vpDisplay::displayRectangle(I, center - v_offset - h_offset, radius, radius, vpColor::blue, false, thickness);
219 vpDisplay::displayRectangle(I, center, center + v_offset + h_offset, vpColor::blue, false, thickness);
220 vpDisplay::displayRectangle(I, vpRect(center - v_offset - h_offset, center + v_offset + h_offset), vpColor::blue,
221 false, thickness);
222 vpDisplay::displayRectangle(I, center - v_offset * 3. / 2 + h_offset, radius / 2, radius / 2, vpColor::green, true);
223 vpDisplay::displayCircle(I, center, radius, vpColor::blue, false, thickness);
224 vpDisplay::displayArrow(I, center, center - v_offset / 4 - h_offset, vpColor::red, 10, 6, thickness);
225 vpDisplay::displayCross(I, center - radius / 2., radius, vpColor::green, thickness);
226 vpDisplay::displayDotLine(I, center - v_offset - h_offset, center, vpColor::cyan, thickness);
227 vpDisplay::displayLine(I, center + v_offset - h_offset, center - v_offset + h_offset, vpColor::cyan, thickness);
228 int nbpoints = static_cast<int>(radius * sqrt(2.) / 8 / scale);
229 for (int i = 0; i < nbpoints; i++) {
231 I, center - h_offset / 2. + vpImagePoint(-i * radius_ / (nbpoints * 2), i * radius_ / (nbpoints * 2)),
233 vpDisplay::displayPoint(I, center - h_offset + vpImagePoint(-i * radius_ / nbpoints, i * radius_ / nbpoints),
234 vpColor::cyan, thickness);
235 }
236
237 if (click)
238 vpDisplay::displayText(I, 10 * scale_, 10 * scale_, "A click to continue", vpColor::red);
239 else
240 vpDisplay::displayText(I, 10 * scale_, 10 * scale_, "This is an image", vpColor::red);
241
243
244 vpImage<vpRGBa> Irendered;
245 vpDisplay::getImage(I, Irendered);
246
247 std::stringstream ss;
248 ss << "overlay-" << display << "-" << itype << "-scale-" << scale;
249#ifdef VISP_HAVE_OPENCV
250 ss << ".png";
251#else
252 ss << ".ppm";
253#endif
254 std::cout << " Overlay saved in: " << ss.str() << std::endl;
255 vpImageIo::write(Irendered, ss.str());
256
257 if (click)
259
260 // Restore the input image
261 I = Ibackup;
262
264
265 if (d != nullptr)
266 delete d;
267
268 if (success)
269 return true;
270 else
271 return false;
272}
273
274int main(int argc, const char *argv[])
275{
276 bool opt_click = true;
277 bool opt_display = true;
278 std::string opt_ipath;
279 std::string env_ipath;
280 std::string ipath;
281
282 for (int i = 1; i < argc; i++) {
283 if (std::string(argv[i]) == "-c") {
284 opt_click = false;
285 }
286 else if (std::string(argv[i]) == "-d") {
287 opt_display = false;
288 }
289 else if (std::string(argv[i]) == "-i" && i + 1 < argc) {
290 opt_ipath = std::string(argv[++i]);
291 }
292 else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
293 std::cout << "\nUsage: " << argv[0] << " [-i <image path>] [-c] [-d] [--help]\n" << std::endl;
294 std::cout << "\nOptions: " << std::endl;
295 std::cout << " -i <input image path> : set image input path.\n"
296 << " From this path read \"Klimt/Klimt.pgm\" image.\n"
297 << " Setting the VISP_INPUT_IMAGE_PATH environment\n"
298 << " variable produces the same behaviour than using\n"
299 << " this option." << std::endl;
300 std::cout << " -c : disable mouse click" << std::endl;
301 std::cout << " -d : disable display" << std::endl;
302 std::cout << " -h, --help : print this help\n" << std::endl;
303 return EXIT_SUCCESS;
304 }
305 }
306
307 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
308 // environment variable value
310
311 // Set the default input path
312 if (!env_ipath.empty())
313 ipath = env_ipath;
314
315 // Get the option values
316 if (!opt_ipath.empty())
317 ipath = opt_ipath;
318
319 std::string filename;
320
321 std::vector<std::string> display;
322 if (opt_display) {
323#ifdef VISP_HAVE_GDI
324 display.push_back("GDI");
325#endif
326#ifdef VISP_HAVE_GTK
327 display.push_back("GTK");
328#endif
329#ifdef VISP_HAVE_X11
330 display.push_back("X");
331#endif
332#if defined(VISP_HAVE_OPENCV) && !defined(VISP_HAVE_OPENCV_HEADLESS)
333 display.push_back("OpenCV");
334#endif
335#ifdef VISP_HAVE_D3D9
336 display.push_back("D3D9");
337#endif
338
339 if (display.size() == 0) {
340 std::cout << "No display available. We stop here." << std::endl;
341 return EXIT_FAILURE;
342 }
344 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
345 vpImageIo::read(I, filename);
346
348 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
349 vpImageIo::read(C, filename);
350
351 int nbfailure = 0;
352
353 for (unsigned int i = 0; i < display.size(); i++) {
354
355 for (unsigned int scale = 1; scale < 4; scale++) {
356 if (!test(display[i], I, scale, opt_click))
357 nbfailure++;
358 if (!test(display[i], C, scale, opt_click))
359 nbfailure++;
360 }
361 }
362 if (nbfailure == 0)
363 std::cout << "Test succeed" << std::endl;
364 else
365 std::cout << "Test failed with " << nbfailure << " failures" << std::endl;
366 }
367
368 return EXIT_SUCCESS;
369}
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