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