Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
displayX.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 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 https://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*****************************************************************************/
44#include <iostream>
45#include <stdlib.h>
46#include <visp3/core/vpConfig.h>
47
48#ifdef VISP_HAVE_X11
49
50#include <visp3/core/vpImage.h>
51#include <visp3/core/vpIoTools.h>
52#include <visp3/core/vpTime.h>
53#include <visp3/gui/vpDisplayX.h>
54#include <visp3/io/vpImageIo.h>
55#include <visp3/io/vpParseArgv.h>
56
66// List of allowed command line options
67#define GETOPTARGS "cdi:o:p:h"
68
80void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
81{
82 fprintf(stdout, "\n\
83Read an image on the disk, display it using X11, display some\n\
84features (line, circle, characters) in overlay and finally write \n\
85the image and the overlayed features in an image on the disk.\n\
86\n\
87SYNOPSIS\n\
88 %s [-i <input image path>] [-o <output image path>]\n\
89 [-c] [-d] [-h]\n \
90",
91name);
92
93 fprintf(stdout, "\n\
94OPTIONS: Default\n\
95 -i <input image path> %s\n\
96 Set image input path.\n\
97 From this path read \"Klimt/Klimt.pgm\"\n\
98 image.\n\
99 Setting the VISP_INPUT_IMAGE_PATH environment\n\
100 variable produces the same behaviour than using\n\
101 this option.\n\
102\n\
103 -o <output image path> %s\n\
104 Set image output path.\n\
105 From this directory, creates the \"%s\"\n\
106 subdirectory depending on the username, where \n\
107 Klimt_grey.overlay.ppm output image is written.\n\
108\n\
109 -c\n\
110 Disable the mouse click. Useful to automate the \n\
111 execution of this program without human intervention.\n\
112\n\
113 -d \n\
114 Disable the image display. This can be useful \n\
115 for automatic tests using crontab under Unix or \n\
116 using the task manager under Windows.\n\
117\n\
118 -h\n\
119 Print the help.\n\n",
120 ipath.c_str(), opath.c_str(), user.c_str());
121
122 if (badparam) {
123 fprintf(stderr, "ERROR: \n");
124 fprintf(stderr, "\nBad parameter [%s]\n", badparam);
125 }
126}
127
146bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, bool &click_allowed,
147 const std::string &user, bool &display)
148{
149 const char *optarg_;
150 int c;
151 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
152
153 switch (c) {
154 case 'c':
155 click_allowed = false;
156 break;
157 case 'd':
158 display = false;
159 break;
160 case 'i':
161 ipath = optarg_;
162 break;
163 case 'o':
164 opath = optarg_;
165 break;
166 case 'h':
167 usage(argv[0], NULL, ipath, opath, user);
168 return false;
169 break;
170
171 default:
172 usage(argv[0], optarg_, ipath, opath, user);
173 return false;
174 break;
175 }
176 }
177
178 if ((c == 1) || (c == -1)) {
179 // standalone param or error
180 usage(argv[0], NULL, ipath, opath, user);
181 std::cerr << "ERROR: " << std::endl;
182 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
183 return false;
184 }
185
186 return true;
187}
188
189int main(int argc, const char **argv)
190{
191 try {
192 std::string env_ipath;
193 std::string opt_ipath;
194 std::string opt_opath;
195 std::string ipath;
196 std::string opath;
197 std::string filename;
198 std::string username;
199 bool opt_click_allowed = true;
200 bool opt_display = true;
201
202 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
203 // environment variable value
205
206 // Set the default input path
207 if (!env_ipath.empty())
208 ipath = env_ipath;
209
210 // Set the default output path
211#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
212 opt_opath = "/tmp";
213#elif defined(_WIN32)
214 opt_opath = "C:\\temp";
215#endif
216
217 // Get the user login name
218 vpIoTools::getUserName(username);
219
220 // Read the command line options
221 if (getOptions(argc, argv, opt_ipath, opt_opath, opt_click_allowed, username, opt_display) == false) {
222 return EXIT_FAILURE;
223 }
224
225 // Get the option values
226 if (!opt_ipath.empty())
227 ipath = opt_ipath;
228 if (!opt_opath.empty())
229 opath = opt_opath;
230
231 // Append to the output path string, the login name of the user
232 std::string odirname = vpIoTools::createFilePath(opath, username);
233
234 // Test if the output path exist. If no try to create it
235 if (vpIoTools::checkDirectory(odirname) == false) {
236 try {
237 // Create the dirname
238 vpIoTools::makeDirectory(odirname);
239 }
240 catch (...) {
241 usage(argv[0], NULL, ipath, opath, username);
242 std::cerr << std::endl << "ERROR:" << std::endl;
243 std::cerr << " Cannot create " << odirname << std::endl;
244 std::cerr << " Check your -o " << opath << " option " << std::endl;
245 return EXIT_FAILURE;
246 }
247 }
248
249 // Compare ipath and env_ipath. If they differ, we take into account
250 // the input path comming from the command line option
251 if (!opt_ipath.empty() && !env_ipath.empty()) {
252 if (ipath != env_ipath) {
253 std::cout << std::endl << "WARNING: " << std::endl;
254 std::cout << " Since -i <visp image path=" << ipath << "> "
255 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
256 << " we skip the environment variable." << std::endl;
257 }
258 }
259
260 // Test if an input path is set
261 if (opt_ipath.empty() && env_ipath.empty()) {
262 usage(argv[0], NULL, ipath, opath, username);
263 std::cerr << std::endl << "ERROR:" << std::endl;
264 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
265 << " environment variable to specify the location of the " << std::endl
266 << " image path where test images are located." << std::endl
267 << std::endl;
268 return EXIT_FAILURE;
269 }
270
271 // Create a grey level image
273 vpImagePoint ip, ip1, ip2;
274
275 // Load a grey image from the disk
276 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
277 vpImageIo::read(I, filename);
278
279 // Create a display using X11
280 vpDisplayX display;
281
282 if (opt_display) {
283 // For this grey level image, open a X11 display at position 100,100
284 // in the screen, and with title "X11 display"
285 display.init(I, 100, 100, "X11 display");
286
287 // Display the image
289
290 // Display in overlay a red cross at position 10,10 in the
291 // image. The lines are 10 pixels long
292 ip.set_i(100);
293 ip.set_j(10);
294
296
297 // Display in overlay horizontal red lines
298 for (unsigned i = 0; i < I.getHeight(); i += 20) {
299 ip1.set_i(i);
300 ip1.set_j(0);
301 ip2.set_i(i);
302 ip2.set_j(I.getWidth());
304 }
305
306 // Display a ligne in the diagonal
307 ip1.set_i(-10);
308 ip1.set_j(-10);
309 ip2.set_i(I.getHeight() + 10);
310 ip2.set_j(I.getWidth() + 10);
311
313
314 // Display in overlay vertical green dot lines
315 for (unsigned i = 0; i < I.getWidth(); i += 20) {
316 ip1.set_i(0);
317 ip1.set_j(i);
318 ip2.set_i(I.getWidth());
319 ip2.set_j(i);
321 }
322
323 // Display a rectangle
324 ip.set_i(I.getHeight() - 45);
325 ip.set_j(-10);
327
328 // Display in overlay a blue arrow
329 ip1.set_i(0);
330 ip1.set_j(0);
331 ip2.set_i(100);
332 ip2.set_j(100);
334
335 // Display in overlay some circles. The position of the center is 200,
336 // 200 the radius is increased by 20 pixels for each circle
337
338 for (unsigned int i = 0; i < 100; i += 20) {
339 ip.set_i(80);
340 ip.set_j(80);
342 }
343
344 ip.set_i(-10);
345 ip.set_j(300);
347
348 // Display in overlay a yellow string
349 ip.set_i(85);
350 ip.set_j(100);
351 vpDisplay::displayText(I, ip, "ViSP is a marvelous software", vpColor::yellow);
352 // Flush the display
354
355 // Create a color image
356 vpImage<vpRGBa> Ioverlay;
357 // Updates the color image with the original loaded image and the
358 // overlay
359 vpDisplay::getImage(I, Ioverlay);
360
361 // Write the color image on the disk
362 filename = vpIoTools::createFilePath(odirname, "Klimt_grey.overlay.ppm");
363 vpImageIo::write(Ioverlay, filename);
364
365 // If click is allowed, wait for a mouse click to close the display
366 if (opt_click_allowed) {
367 std::cout << "\nA click to close the windows..." << std::endl;
368 // Wait for a blocking mouse click
370 }
371
372 // Close the display
374 }
375
376 // Create a color image
377 vpImage<vpRGBa> Irgba;
378
379 // Load a grey image from the disk and convert it to a color image
380 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
381 vpImageIo::read(Irgba, filename);
382
383 // Create a new display
384 vpDisplayX displayRGBa;
385
386 if (opt_display) {
387 // For this color image, open a X11 display at position 100,100
388 // in the screen, and with title "X11 color display"
389 displayRGBa.init(Irgba, 100, 100, "X11 color display");
390
391 // Display the color image
392 vpDisplay::display(Irgba);
393 vpDisplay::flush(Irgba);
394
395 // If click is allowed, wait for a blocking mouse click to display a
396 // cross at the clicked pixel position
397 if (opt_click_allowed) {
398 std::cout << "\nA click to display a cross..." << std::endl;
399 // Blocking wait for a click. Get the position of the selected pixel
400 // (i correspond to the row and j to the column coordinates in the
401 // image)
402 vpDisplay::getClick(Irgba, ip);
403 // Display a red cross on the click pixel position
404 std::cout << "Cross position: " << ip << std::endl;
406 }
407 else {
408 ip.set_i(10);
409 ip.set_j(20);
410 // Display a red cross at position i, j (i correspond to the row
411 // and j to the column coordinates in the image)
412 std::cout << "Cross position: " << ip << std::endl;
414 }
415 // Flush the display. Sometimes the display content is
416 // bufferized. Force to display the content that has been bufferized.
417 vpDisplay::flush(Irgba);
418
419 // Create a color image
420 vpImage<vpRGBa> Ioverlay;
421 // Updates the color image with the original loaded image and the
422 // overlay
423 vpDisplay::getImage(Irgba, Ioverlay);
424
425 // Write the color image on the disk
426 filename = vpIoTools::createFilePath(odirname, "Klimt_color.overlay.ppm");
427 vpImageIo::write(Ioverlay, filename);
428
429 // If click is allowed, wait for a blocking mouse click to exit.
430 if (opt_click_allowed) {
431 std::cout << "\nA click to exit the program..." << std::endl;
432 vpDisplay::getClick(Irgba);
433 std::cout << "Bye" << std::endl;
434 }
435 }
436 return EXIT_SUCCESS;
437 }
438 catch (const vpException &e) {
439 std::cout << "Catch an exception: " << e << std::endl;
440 return EXIT_FAILURE;
441 }
442}
443#else
444int main()
445{
446 std::cout << "You do not have X11 functionalities to display images..." << std::endl;
447 std::cout << "Tip if you are on a unix-like system:" << std::endl;
448 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
449 return EXIT_SUCCESS;
450}
451#endif
static const vpColor red
Definition vpColor.h:211
static const vpColor orange
Definition vpColor.h:221
static const vpColor blue
Definition vpColor.h:217
static const vpColor yellow
Definition vpColor.h:219
static const vpColor green
Definition vpColor.h:214
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition vpDisplayX.h:132
void init(vpImage< unsigned char > &I, int win_x=-1, int win_y=-1, const std::string &win_title="")
static void close(vpImage< unsigned char > &I)
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 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 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 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)
error that can be emitted by ViSP classes.
Definition vpException.h:59
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 ...
void set_j(double jj)
void set_i(double ii)
Definition of the vpImage class member functions.
Definition vpImage.h:135
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:184
static std::string getViSPImagesDataPath()
static bool checkDirectory(const std::string &dirname)
static std::string getUserName()
static std::string createFilePath(const std::string &parent, const std::string &child)
static void makeDirectory(const std::string &dirname)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)