Visual Servoing Platform  version 3.4.0
testDisplayScaled.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Display testing.
33  *
34  * Authors:
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
39 #include <sstream>
40 
41 #include <visp3/core/vpImageTools.h>
42 #include <visp3/core/vpIoTools.h>
43 #include <visp3/gui/vpDisplayD3D.h>
44 #include <visp3/gui/vpDisplayGDI.h>
45 #include <visp3/gui/vpDisplayGTK.h>
46 #include <visp3/gui/vpDisplayOpenCV.h>
47 #include <visp3/gui/vpDisplayX.h>
48 #include <visp3/io/vpImageIo.h>
49 
50 template <typename Type> bool test(const std::string &display, vpImage<Type> &I, unsigned int scale, bool click)
51 {
52  bool success = true;
53  unsigned int radius(I.getHeight() / 4);
54  int scale_ = (int)scale;
55  int radius_ = (int)radius;
56  unsigned int thickness = 2;
57  vpImagePoint center(I.getHeight() / 2, I.getWidth() / 2);
58  vpImagePoint offset(30, 160);
59  vpImagePoint v_offset(radius, 0);
60  vpImagePoint h_offset(0, radius);
61  vpRect roi(center, radius_ + scale_, radius_);
62  std::string itype;
63 
64  // backup the input image
65  vpImage<Type> Ibackup(I);
66 
67  vpDisplay *d = NULL;
68  if (display == "GDI") {
69 #ifdef VISP_HAVE_GDI
70  d = new vpDisplayGDI;
71 #endif
72  } else if (display == "GTK") {
73 #ifdef VISP_HAVE_GTK
74  d = new vpDisplayGTK;
75 #endif
76  } else if (display == "X") {
77 #ifdef VISP_HAVE_X11
78  d = new vpDisplayX;
79 #endif
80  } else if (display == "OpenCV") {
81 #ifdef VISP_HAVE_OPENCV
82  d = new vpDisplayOpenCV;
83 #endif
84  } else if (display == "D3D9") {
85 #ifdef VISP_HAVE_D3D9
86  d = new vpDisplayD3D;
87 #endif
88  }
89  std::cout << "Start test for " << display << " renderer..." << std::endl;
90  std::cout << " Screen resolution: " << d->getScreenWidth() << " " << d->getScreenHeight() << std::endl;
91  d->setDownScalingFactor(scale);
92  d->init(I);
95 
96  vpImage<Type> crop;
97  vpImageTools::crop(I, vpImagePoint(0, 245), (unsigned int)roi.getHeight(), (unsigned int)roi.getWidth(), crop);
98  I.insert(crop, roi.getTopLeft());
99  vpDisplay::displayROI(I, roi);
100  vpDisplay::flush(I);
101 
102  // Compare input and rendered images
103  if (sizeof(Type) == 1) {
104  itype = "uchar";
105  vpImage<Type> Iinsert = I;
106  vpImage<vpRGBa> Isampled;
107  vpImage<vpRGBa> Icolor;
108  vpImageConvert::convert(Iinsert, Icolor);
109  Icolor.subsample(scale, scale, Isampled);
110 
111  vpImage<vpRGBa> Irendered;
112  vpDisplay::getImage(I, Irendered);
113 
114  if (Isampled != Irendered) {
115  success = false;
116  std::cout << " -- Test width scale= " << scale << " type= " << itype << ": failed" << std::endl;
117 
118  std::stringstream ss;
119  ss << "Isampled-" << itype << "-scale-" << scale;
120 #ifdef VISP_HAVE_OPENCV
121  ss << ".png";
122 #else
123  ss << ".ppm";
124 #endif
125 
126  vpImageIo::write(Isampled, ss.str());
127 
128  ss.str("");
129  ss.clear();
130  ss << "Irendered-" << itype << "-scale-" << scale;
131 #ifdef VISP_HAVE_OPENCV
132  ss << ".png";
133 #else
134  ss << ".ppm";
135 #endif
136 
137  vpImageIo::write(Irendered, ss.str());
138  vpImage<vpRGBa> Idiff;
139  vpImageTools::imageDifference(Isampled, Irendered, Idiff);
140 
141  ss.str("");
142  ss.clear();
143  ss << "Idiff-" << itype << "-scale-" << scale;
144 #ifdef VISP_HAVE_OPENCV
145  ss << ".png";
146 #else
147  ss << ".ppm";
148 #endif
149 
150  vpImageIo::write(Idiff, ss.str());
151  } else {
152  std::cout << " ++ Test width scale= " << scale << " type= " << itype << ": succeed" << std::endl;
153  }
154  } else {
155  itype = "rgba";
156  vpImage<Type> Iinsert = I;
157  vpImage<Type> Isampled; // vpRGBa necessary
158  Iinsert.subsample(scale, scale, Isampled);
159 
160  vpImage<vpRGBa> Irendered; // vpRGBa necessary
161  vpDisplay::getImage(I, Irendered);
162 
163  vpImage<vpRGBa> IsampledCopy; // vpRGBa necessary
164 
165  vpImageConvert::convert(Isampled, IsampledCopy);
166  if (IsampledCopy != Irendered) {
167  success = false;
168  std::cout << " -- Test width scale= " << scale << " type= " << itype << ": failed" << std::endl;
169 
170  std::stringstream ss;
171  ss << "Isampled-" << itype << "-scale-" << scale;
172 #ifdef VISP_HAVE_OPENCV
173  ss << ".png";
174 #else
175  ss << ".ppm";
176 #endif
177 
178  vpImageIo::write(Isampled, ss.str());
179 
180  ss.str("");
181  ss.clear();
182  ss << "Irendered-" << itype << "-scale-" << scale;
183 #ifdef VISP_HAVE_OPENCV
184  ss << ".png";
185 #else
186  ss << ".ppm";
187 #endif
188 
189  vpImageIo::write(Irendered, ss.str());
190  vpImage<vpRGBa> Idiff;
191  vpImageTools::imageDifference(IsampledCopy, Irendered, Idiff);
192  ss.str("");
193  ss.clear();
194  ss << "Idiff-" << itype << "-scale-" << scale;
195 #ifdef VISP_HAVE_OPENCV
196  ss << ".png";
197 #else
198  ss << ".ppm";
199 #endif
200 
201  vpImageIo::write(Idiff, ss.str());
202 
203  } else {
204  std::cout << " ++ Test width scale= " << scale << " type= " << itype << ": succeed" << std::endl;
205  }
206  }
207 
208  vpDisplay::displayRectangle(I, center - v_offset - h_offset, radius, radius, vpColor::blue, false, thickness);
209  vpDisplay::displayRectangle(I, center, center + v_offset + h_offset, vpColor::blue, false, thickness);
210  vpDisplay::displayRectangle(I, vpRect(center - v_offset - h_offset, center + v_offset + h_offset), vpColor::blue,
211  false, thickness);
212  vpDisplay::displayRectangle(I, center - v_offset * 3. / 2 + h_offset, radius / 2, radius / 2, vpColor::green, true);
213  vpDisplay::displayCircle(I, center, radius, vpColor::blue, false, thickness);
214  vpDisplay::displayArrow(I, center, center - v_offset / 4 - h_offset, vpColor::red, 10, 6, thickness);
215  vpDisplay::displayCross(I, center - radius / 2., radius, vpColor::green, thickness);
216  vpDisplay::displayDotLine(I, center - v_offset - h_offset, center, vpColor::cyan, thickness);
217  vpDisplay::displayLine(I, center + v_offset - h_offset, center - v_offset + h_offset, vpColor::cyan, thickness);
218  int nbpoints = (int)(radius * sqrt(2.) / 8 / scale);
219  for (int i = 0; i < nbpoints; i++) {
221  I, center - h_offset / 2. + vpImagePoint(-i * radius_ / (nbpoints * 2), i * radius_ / (nbpoints * 2)),
222  vpColor::cyan);
223  vpDisplay::displayPoint(I, center - h_offset + vpImagePoint(-i * radius_ / nbpoints, i * radius_ / nbpoints),
224  vpColor::cyan, thickness);
225  }
226 
227  if (click)
228  vpDisplay::displayText(I, 10 * scale_, 10 * scale_, "A click to continue", vpColor::red);
229  else
230  vpDisplay::displayText(I, 10 * scale_, 10 * scale_, "This is an image", vpColor::red);
231 
232  vpDisplay::flush(I);
233 
234  vpImage<vpRGBa> Irendered;
235  vpDisplay::getImage(I, Irendered);
236 
237  std::stringstream ss;
238  ss << "overlay-" << display << "-" << itype << "-scale-" << scale;
239 #ifdef VISP_HAVE_OPENCV
240  ss << ".png";
241 #else
242  ss << ".ppm";
243 #endif
244  std::cout << " Overlay saved in: " << ss.str() << std::endl;
245  vpImageIo::write(Irendered, ss.str());
246 
247  if (click)
249 
250  // Restore the input image
251  I = Ibackup;
252 
253  vpDisplay::close(I);
254 
255  if (d != NULL)
256  delete d;
257 
258  if (success)
259  return true;
260  else
261  return false;
262 }
263 
264 int main(int argc, const char *argv[])
265 {
266  bool opt_click = true;
267  bool opt_display = true;
268  std::string opt_ipath;
269  std::string env_ipath;
270  std::string ipath;
271 
272  for (int i = 0; i < argc; i++) {
273  if (std::string(argv[i]) == "-c")
274  opt_click = false;
275  else if (std::string(argv[i]) == "-d")
276  opt_display = false;
277  else if (std::string(argv[i]) == "-i")
278  opt_ipath = std::string(argv[i + 1]);
279  else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
280  std::cout << "\nUsage: " << argv[0] << " [-i <image path>] [-c] [-d] [--help]\n" << std::endl;
281  std::cout << "\nOptions: " << std::endl;
282  std::cout << " -i <input image path> : set image input path.\n"
283  << " From this path read \"Klimt/Klimt.pgm\" image.\n"
284  << " Setting the VISP_INPUT_IMAGE_PATH environment\n"
285  << " variable produces the same behaviour than using\n"
286  << " this option." << std::endl;
287  std::cout << " -c : disable mouse click" << std::endl;
288  std::cout << " -d : disable display" << std::endl;
289  std::cout << " -h, --help : print this help\n" << std::endl;
290  return 0;
291  }
292  }
293 
294  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
295  // environment variable value
296  env_ipath = vpIoTools::getViSPImagesDataPath();
297 
298  // Set the default input path
299  if (!env_ipath.empty())
300  ipath = env_ipath;
301 
302  // Get the option values
303  if (!opt_ipath.empty())
304  ipath = opt_ipath;
305 
306  std::string filename;
307 
308  std::vector<std::string> display;
309  if (opt_display) {
310 #ifdef VISP_HAVE_GDI
311  display.push_back("GDI");
312 #endif
313 #ifdef VISP_HAVE_GTK
314  display.push_back("GTK");
315 #endif
316 #ifdef VISP_HAVE_X11
317  display.push_back("X");
318 #endif
319 #ifdef VISP_HAVE_OPENCV
320  display.push_back("OpenCV");
321 #endif
322 #ifdef VISP_HAVE_D3D9
323  display.push_back("D3D9");
324 #endif
325 
326  if (display.size() == 0) {
327  std::cout << "No display available. We stop here." << std::endl;
328  return 0;
329  }
331  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
332  vpImageIo::read(I, filename);
333 
334  vpImage<vpRGBa> C;
335  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
336  vpImageIo::read(C, filename);
337 
338  int nbfailure = 0;
339 
340  for (unsigned int i = 0; i < display.size(); i++) {
341 
342  for (unsigned int scale = 1; scale < 4; scale++) {
343  if (!test(display[i], I, scale, opt_click))
344  nbfailure++;
345  if (!test(display[i], C, scale, opt_click))
346  nbfailure++;
347  }
348  }
349  if (nbfailure == 0)
350  std::cout << "Test succeed" << std::endl;
351  else
352  std::cout << "Test failed with " << nbfailure << " failures" << std::endl;
353  }
354 
355  return 0;
356 }
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:177
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1202
static void close(vpImage< unsigned char > &I)
unsigned int getWidth() const
Definition: vpImage.h:246
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
virtual void setDownScalingFactor(unsigned int scale)
Definition: vpDisplay.cpp:231
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:150
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
static void imageDifference(const vpImage< unsigned char > &I1, const vpImage< unsigned char > &I2, vpImage< unsigned char > &Idiff)
static const vpColor green
Definition: vpColor.h:220
static void flush(const vpImage< unsigned char > &I)
static const vpColor red
Definition: vpColor.h:217
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:445
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
Definition: vpDisplayD3D.h:106
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1446
static const vpColor cyan
Definition: vpColor.h:226
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 display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:134
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)
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
Definition: vpImage.h:1115
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
Definition: vpDisplay.cpp:144
void subsample(unsigned int v_scale, unsigned int h_scale, vpImage< Type > &sampled) const
Definition: vpImage.h:1220
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:244
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:305
unsigned int getHeight() const
Definition: vpImage.h:188
Defines a rectangle in the plane.
Definition: vpRect.h:79
static void displayROI(const vpImage< unsigned char > &I, const vpRect &roi)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:87
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
Definition of the vpImage class member functions.
Definition: vpImage.h:126
static void displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static const vpColor blue
Definition: vpColor.h:223