Visual Servoing Platform version 3.5.0
displayXMulti.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 * Read an image on the disk and display it using X11.
33 *
34 * Authors:
35 * Eric Marchand
36 * Fabien Spindler
37 *
38 *****************************************************************************/
48#include <visp3/core/vpConfig.h>
49#include <visp3/core/vpDebug.h>
50
51#ifdef VISP_HAVE_X11
52
53#include <stdio.h>
54#include <stdlib.h>
55#include <string.h>
56#include <visp3/core/vpImage.h>
57#include <visp3/gui/vpDisplayX.h>
58#include <visp3/io/vpImageIo.h>
59
60#include <visp3/core/vpIoTools.h>
61#include <visp3/io/vpParseArgv.h>
62
73// List of allowed command line options
74#define GETOPTARGS "cdi:o:h"
75
87void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
88{
89 fprintf(stdout, "\n\
90Read an image on the disk, display it using X11, display some\n\
91features (line, circle, caracters) in overlay and finaly write \n\
92the image and the overlayed features in an image on the disk.\n\
93\n\
94SYNOPSIS\n\
95 %s [-i <input image path>] [-o <output image path>]\n\
96 [-c] [-d] [-h]\n \
97", name);
98
99 fprintf(stdout, "\n\
100OPTIONS: Default\n\
101 -i <input image path> %s\n\
102 Set image input path.\n\
103 From this path read \"Klimt/Klimt.pgm\"\n\
104 and \"Klimt/Klimt.ppm\" images.\n\
105 Setting the VISP_INPUT_IMAGE_PATH environment\n\
106 variable produces the same behaviour than using\n\
107 this option.\n\
108\n\
109 -o <output image path> %s\n\
110 Set image output path.\n\
111 From this directory, creates the \"%s\"\n\
112 subdirectory depending on the username, where \n\
113 Klimt_grey.overlay.ppm output image is written.\n\
114\n\
115 -c\n\
116 Disable the mouse click. Useful to automate the \n\
117 execution of this program without humain intervention.\n\
118\n\
119 -d \n\
120 Disable the image display. This can be useful \n\
121 for automatic tests using crontab under Unix or \n\
122 using the task manager under Windows.\n\
123\n\
124 -h\n\
125 Print the help.\n\n", ipath.c_str(), opath.c_str(), user.c_str());
126
127 if (badparam) {
128 fprintf(stderr, "ERROR: \n");
129 fprintf(stderr, "\nBad parameter [%s]\n", badparam);
130 }
131}
132
150bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, bool &click_allowed,
151 const std::string &user, bool &display)
152{
153 const char *optarg_;
154 int c;
155 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
156
157 switch (c) {
158 case 'c':
159 click_allowed = false;
160 break;
161 case 'd':
162 display = false;
163 break;
164 case 'i':
165 ipath = optarg_;
166 break;
167 case 'o':
168 opath = optarg_;
169 break;
170 case 'h':
171 usage(argv[0], NULL, ipath, opath, user);
172 return false;
173 break;
174
175 default:
176 usage(argv[0], optarg_, ipath, opath, user);
177 return false;
178 break;
179 }
180 }
181
182 if ((c == 1) || (c == -1)) {
183 // standalone param or error
184 usage(argv[0], NULL, ipath, opath, user);
185 std::cerr << "ERROR: " << std::endl;
186 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
187 return false;
188 }
189
190 return true;
191}
192
193int main(int argc, const char **argv)
194{
195 try {
196 std::string env_ipath;
197 std::string opt_ipath;
198 std::string opt_opath;
199 std::string ipath;
200 std::string opath;
201 std::string filename;
202 std::string username;
203 bool opt_click_allowed = true;
204 bool opt_display = true;
205
206 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
207 // environment variable value
209
210 // Set the default input path
211 if (!env_ipath.empty())
212 ipath = env_ipath;
213
214// Set the default output path
215#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
216 opt_opath = "/tmp";
217#elif defined(_WIN32)
218 opt_opath = "C:\\temp";
219#endif
220
221 // Get the user login name
222 vpIoTools::getUserName(username);
223
224 // Read the command line options
225 if (getOptions(argc, argv, opt_ipath, opt_opath, opt_click_allowed, username, opt_display) == false) {
226 exit(-1);
227 }
228
229 // Get the option values
230 if (!opt_ipath.empty())
231 ipath = opt_ipath;
232 if (!opt_opath.empty())
233 opath = opt_opath;
234
235 // Append to the output path string, the login name of the user
236 std::string odirname = vpIoTools::createFilePath(opath, username);
237
238 // Test if the output path exist. If no try to create it
239 if (vpIoTools::checkDirectory(odirname) == false) {
240 try {
241 // Create the dirname
242 vpIoTools::makeDirectory(odirname);
243 } catch (...) {
244 usage(argv[0], NULL, ipath, opath, username);
245 std::cerr << std::endl << "ERROR:" << std::endl;
246 std::cerr << " Cannot create " << odirname << std::endl;
247 std::cerr << " Check your -o " << opath << " option " << std::endl;
248 exit(-1);
249 }
250 }
251
252 // Compare ipath and env_ipath. If they differ, we take into account
253 // the input path comming from the command line option
254 if (!opt_ipath.empty() && !env_ipath.empty()) {
255 if (ipath != env_ipath) {
256 std::cout << std::endl << "WARNING: " << std::endl;
257 std::cout << " Since -i <visp image path=" << ipath << "> "
258 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
259 << " we skip the environment variable." << std::endl;
260 }
261 }
262
263 // Test if an input path is set
264 if (opt_ipath.empty() && env_ipath.empty()) {
265 usage(argv[0], NULL, ipath, opath, username);
266 std::cerr << std::endl << "ERROR:" << std::endl;
267 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
268 << " environment variable to specify the location of the " << std::endl
269 << " image path where test images are located." << std::endl
270 << std::endl;
271 exit(-1);
272 }
273
274 // Create two color images
275 vpImage<vpRGBa> I1, I2;
276 vpImagePoint ip, ip1, ip2;
277
278 try {
279 // Load a grey image from the disk
280 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
281 vpImageIo::read(I1, filename);
282 } catch (...) {
283 std::cerr << std::endl << "ERROR:" << std::endl;
284 std::cerr << " Cannot read " << filename << std::endl;
285 std::cerr << " Check your -i " << ipath << " option " << std::endl
286 << " or VISP_INPUT_IMAGE_PATH environment variable." << std::endl;
287 exit(-1);
288 }
289 try {
290 // Load a color image from the disk
291 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
292 vpImageIo::read(I2, filename);
293 } catch (...) {
294 std::cerr << std::endl << "ERROR:" << std::endl;
295 std::cerr << " Cannot read " << filename << std::endl;
296 std::cerr << " Check your -i " << ipath << " option " << std::endl
297 << " or VISP_INPUT_IMAGE_PATH environment variable." << std::endl;
298 exit(-1);
299 }
300
301 // For each image, open a X11 display
302 vpDisplayX display1;
303 vpDisplayX display2;
304
305 if (opt_display) {
306 // Attach image 1 to display 1
307 display1.init(I1, 0, 0, "X11 Display 1...");
308 // Attach image 2 to display 2
309 display2.init(I2, 200, 200, "X11 Display 2...");
310 // Display the images
313
314 // In the first display, display in overlay horizontal red lines
315 for (unsigned int i = 0; i < I1.getHeight(); i += 20) {
316 ip1.set_i(i);
317 ip1.set_j(0);
318 ip2.set_i(i);
319 ip2.set_j(I1.getWidth());
321 }
322
323 // In the first display, display in overlay vertical green dot lines
324 for (unsigned int i = 0; i < I1.getWidth(); i += 20) {
325 ip1.set_i(0);
326 ip1.set_j(i);
327 ip2.set_i(I1.getWidth());
328 ip2.set_j(i);
330 }
331
332 // In the first display, display in overlay a blue arrow
333 ip1.set_i(0);
334 ip1.set_j(0);
335 ip2.set_i(100);
336 ip2.set_j(100);
338
339 // In the first display, display in overlay some circles. The
340 // position of the center is 200, 200 the radius is increased by 20
341 // pixels for each circle
342 for (unsigned int i = 0; i < 100; i += 20) {
343 ip.set_i(200);
344 ip.set_j(200);
346 }
347
348 // In the first display, display in overlay a yellow string
349 ip.set_i(100);
350 ip.set_j(100);
351 vpDisplay::displayText(I1, ip, "ViSP is a marvelous software", vpColor::blue);
352
353 // Flush displays. The displays must be flushed to show the overlay.
354 // without this line, nothing will be displayed.
357
358 // If click is allowed, wait for a blocking mouse click in the first
359 // display, to display a cross at the clicked pixel position
360 if (opt_click_allowed) {
361 std::cout << "\nA click in the first display to draw a cross..." << std::endl;
362 // Blocking wait for a click. Get the position of the selected pixel
363 // (i correspond to the row and j to the column coordinates in the
364 // image)
365 vpDisplay::getClick(I1, ip);
366 // Display a red cross on the click pixel position
367 std::cout << "Cross position: " << ip << std::endl;
370 } else {
371 ip.set_i(50);
372 ip.set_j(50);
373 // Display a red cross at position ip in the first display
374 std::cout << "Cross position: " << ip << std::endl;
377 }
378
379 // Create a color image
380 vpImage<vpRGBa> Ioverlay;
381 // Updates the color image with the original loaded image 1 and the
382 // overlay
383 vpDisplay::getImage(I1, Ioverlay);
384
385 // Write the color image on the disk
386 filename = vpIoTools::createFilePath(odirname, "Klimt_grey.overlay.ppm");
387 vpImageIo::write(Ioverlay, filename);
388
389 // If click is allowed, wait for a mouse click to close the display
390 if (opt_click_allowed) {
391 std::cout << "\nA click in the second display to close the windows "
392 "and exit..."
393 << std::endl;
394 // Wait for a blocking mouse click
396 }
397 }
398 return EXIT_SUCCESS;
399 } catch (const vpException &e) {
400 std::cout << "Catch an exception: " << e << std::endl;
401 return EXIT_FAILURE;
402 }
403}
404#else
405int main() {
406 std::cout << "You do not have X11 functionalities to display images..." << std::endl;
407 std::cout << "Tip if you are on a unix-like system:" << std::endl;
408 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
409 return EXIT_SUCCESS;
410}
411#endif
static const vpColor red
Definition: vpColor.h:217
static const vpColor blue
Definition: vpColor.h:223
static const vpColor yellow
Definition: vpColor.h:225
static const vpColor green
Definition: vpColor.h:220
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:135
void init(vpImage< unsigned char > &I, int win_x=-1, int win_y=-1, const std::string &win_title="")
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
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:144
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
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 displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
error that can be emited by ViSP classes.
Definition: vpException.h:72
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:149
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:293
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void set_j(double jj)
Definition: vpImagePoint.h:177
void set_i(double ii)
Definition: vpImagePoint.h:166
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:188
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:420
static std::string getUserName()
Definition: vpIoTools.cpp:316
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1670
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:570
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69