Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
trackMeLine.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 * Tracking of a line.
33 *
34*****************************************************************************/
35
48#include <visp3/core/vpConfig.h>
49#include <visp3/core/vpDebug.h>
50
51#include <iomanip>
52#include <sstream>
53#include <stdio.h>
54#include <stdlib.h>
55
56#if defined(VISP_HAVE_MODULE_ME) && \
57 (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV))
58
59#include <visp3/core/vpColor.h>
60#include <visp3/core/vpImage.h>
61#include <visp3/core/vpImagePoint.h>
62#include <visp3/gui/vpDisplayGDI.h>
63#include <visp3/gui/vpDisplayGTK.h>
64#include <visp3/gui/vpDisplayOpenCV.h>
65#include <visp3/gui/vpDisplayX.h>
66#include <visp3/io/vpImageIo.h>
67
68#include <visp3/me/vpMeLine.h>
69
70#include <visp3/visual_features/vpFeatureBuilder.h>
71#include <visp3/visual_features/vpFeatureLine.h>
72
73#include <visp3/core/vpIoTools.h>
74#include <visp3/io/vpParseArgv.h>
75
76// List of allowed command line options
77#define GETOPTARGS "cdf:hi:l:p:s:"
78
92void usage(const char *name, const char *badparam, std::string ipath, std::string ppath, unsigned first,
93 unsigned last, unsigned step)
94{
95#if VISP_HAVE_DATASET_VERSION >= 0x030600
96 std::string ext("png");
97#else
98 std::string ext("pgm");
99#endif
100 fprintf(stdout, "\n\
101Tracking of a line.\n\
102\n\
103SYNOPSIS\n\
104 %s [-i <input image path>] [-p <personal image path>]\n\
105 [-f <first image>] [-l <last image>] [-s <step>]\n\
106 [-c] [-d] [-h]\n", name);
107
108 fprintf(stdout, "\n\
109OPTIONS: Default\n\
110 -i <input image path> %s\n\
111 Set image input path.\n\
112 From this path read \"line/image.%%04d.%s\"\n\
113 images. \n\
114 Setting the VISP_INPUT_IMAGE_PATH environment\n\
115 variable produces the same behaviour than using\n\
116 this option.\n\
117\n\
118 -p <personal image path> %s\n\
119 Specify a personal sequence containing images \n\
120 to process.\n\
121 By image sequence, we mean one file per image.\n\
122 Example : \"C:/Temp/visp-images/line/image.%%04d.%s\"\n\
123 %%04d is for the image numbering.\n\
124\n\
125 -f <first image> %u\n\
126 First image number of the sequence.\n\
127\n\
128 -l <last image> %u\n\
129 Last image number of the sequence.\n\
130\n\
131 -s <step> %u\n\
132 Step between two images.\n\
133\n\
134 -c\n\
135 Disable the mouse click. Useful to automate the \n\
136 execution of this program without human intervention.\n\
137\n\
138 -d \n\
139 Turn off the display.\n\
140\n\
141 -h\n\
142 Print the help.\n",
143 ipath.c_str(), ext.c_str(), ppath.c_str(), ext.c_str(), first, last, step);
144
145 if (badparam)
146 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
147}
148
166bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath, unsigned &first, unsigned &last,
167 unsigned &step, bool &click_allowed, bool &display)
168{
169 const char *optarg_;
170 int c;
171 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
172
173 switch (c) {
174 case 'c':
175 click_allowed = false;
176 break;
177 case 'd':
178 display = false;
179 break;
180 case 'i':
181 ipath = optarg_;
182 break;
183 case 'p':
184 ppath = optarg_;
185 break;
186 case 'f':
187 first = (unsigned)atoi(optarg_);
188 break;
189 case 'l':
190 last = (unsigned)atoi(optarg_);
191 break;
192 case 's':
193 step = (unsigned)atoi(optarg_);
194 break;
195 case 'h':
196 usage(argv[0], NULL, ipath, ppath, first, last, step);
197 return false;
198 break;
199
200 default:
201 usage(argv[0], optarg_, ipath, ppath, first, last, step);
202 return false;
203 break;
204 }
205 }
206
207 if ((c == 1) || (c == -1)) {
208 // standalone param or error
209 usage(argv[0], NULL, ipath, ppath, first, last, step);
210 std::cerr << "ERROR: " << std::endl;
211 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
212 return false;
213 }
214
215 return true;
216}
217
218int main(int argc, const char **argv)
219{
220#if defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV)
221 try {
222 std::string env_ipath;
223 std::string opt_ipath;
224 std::string ipath;
225 std::string opt_ppath;
226 std::string dirname;
227 std::string filename;
228 unsigned int opt_first = 1;
229 unsigned int opt_last = 30;
230 unsigned int opt_step = 1;
231 bool opt_click_allowed = true;
232 bool opt_display = true;
233
234#if VISP_HAVE_DATASET_VERSION >= 0x030600
235 std::string ext("png");
236#else
237 std::string ext("pgm");
238#endif
239
240 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
241 // environment variable value
243
244 // Set the default input path
245 if (!env_ipath.empty())
246 ipath = env_ipath;
247
248 // Read the command line options
249 if (getOptions(argc, argv, opt_ipath, opt_ppath, opt_first, opt_last, opt_step, opt_click_allowed,
250 opt_display) == false) {
251 return EXIT_FAILURE;
252 }
253
254 // Get the option values
255 if (!opt_ipath.empty())
256 ipath = opt_ipath;
257
258 // Compare ipath and env_ipath. If they differ, we take into account
259 // the input path comming from the command line option
260 if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
261 if (ipath != env_ipath) {
262 std::cout << std::endl << "WARNING: " << std::endl;
263 std::cout << " Since -i <visp image path=" << ipath << "> "
264 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
265 << " we skip the environment variable." << std::endl;
266 }
267 }
268
269 // Test if an input path is set
270 if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty()) {
271 usage(argv[0], NULL, ipath, opt_ppath, opt_first, opt_last, opt_step);
272 std::cerr << std::endl << "ERROR:" << std::endl;
273 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
274 << " environment variable to specify the location of the " << std::endl
275 << " image path where test images are located." << std::endl
276 << " Use -p <personal image path> option if you want to " << std::endl
277 << " use personal images." << std::endl
278 << std::endl;
279
280 return EXIT_FAILURE;
281 }
282
283 // Declare an image, this is a gray level image (unsigned char)
284 // it size is not defined yet, it will be defined when the image will
285 // read on the disk
287
288 unsigned iter = opt_first;
289 std::ostringstream s;
290 char cfilename[FILENAME_MAX];
291
292 if (opt_ppath.empty()) {
293
294 // Warning :
295 // The image sequence is not provided with the ViSP package
296 // therefore the program will return an error :
297 // !! couldn't read file visp-images/mire-2/image.0001.png
298 //
299 // ViSP dataset is available on the visp www site
300 // https://visp.inria.fr/download/.
301
302 // Set the path location of the image sequence
303 dirname = vpIoTools::createFilePath(ipath, "line");
304
305 // Build the name of the image file
306 s.setf(std::ios::right, std::ios::adjustfield);
307 s << "image." << std::setw(4) << std::setfill('0') << iter << "." << ext;
308 filename = vpIoTools::createFilePath(dirname, s.str());
309 }
310 else {
311 snprintf(cfilename, FILENAME_MAX, opt_ppath.c_str(), iter);
312 filename = cfilename;
313 }
314
315 // Read the image named "filename", and put the bitmap into the image structure I.
316 // I is initialized to the correct size
317 //
318 // vpImageIo::read() may throw various exception if, for example,
319 // the file does not exist, or if the memory cannot be allocated
320 try {
321 vpCTRACE << "Load: " << filename << std::endl;
322
323 vpImageIo::read(I, filename);
324 }
325 catch (...) {
326 // If an exception is thrown by vpImageIo::read() it will result in the end of the program.
327 std::cerr << std::endl << "ERROR:" << std::endl;
328 std::cerr << " Cannot read " << filename << std::endl;
329 if (opt_ppath.empty()) {
330 std::cerr << " Check your -i " << ipath << " option " << std::endl
331 << " or VISP_INPUT_IMAGE_PATH environment variable." << std::endl;
332 }
333 else {
334 std::cerr << " Check your -p " << opt_ppath << " option " << std::endl;
335 }
336 return EXIT_FAILURE;
337 }
338
339 // We open a window using either X11, GTK or GDI.
340#if defined(VISP_HAVE_X11)
341 vpDisplayX display;
342#elif defined(VISP_HAVE_GTK)
343 vpDisplayGTK display;
344#elif defined(VISP_HAVE_GDI)
345 vpDisplayGDI display;
346#elif defined(HAVE_OPENCV_HIGHGUI)
347 vpDisplayOpenCV display;
348#endif
349
350 if (opt_display) {
351 // Display size is automatically defined by the image (I) size
352 display.init(I, 100, 100, "Display...");
353 // Display the image
354 // The image class has a member that specify a pointer toward
355 // the display that has been initialized in the display declaration
356 // therefore is is no longer necessary to make a reference to the
357 // display variable.
360 }
361
362 vpMeLine L1;
363
364 vpMe me;
365 me.setRange(15);
366 me.setPointsToTrack(160);
368 me.setThreshold(20);
369
370 L1.setMe(&me);
372
373 if (opt_display && opt_click_allowed)
374 L1.initTracking(I);
375 else {
376 vpImagePoint ip1, ip2;
377 ip1.set_i(96);
378 ip1.set_j(191);
379 ip2.set_i(122);
380 ip2.set_j(211);
381 L1.initTracking(I, ip1, ip2);
382 }
383
384 if (opt_display)
385 L1.display(I, vpColor::green);
386
387 L1.track(I);
388 if (opt_display && opt_click_allowed) {
389 std::cout << "A click to continue..." << std::endl;
391 }
392 std::cout << "----------------------------------------------------------" << std::endl;
393
395
398 while (iter < opt_last) {
399 std::cout << "----------------------------------------------------------" << std::endl;
400 // set the new image name
401 s.str("");
402 s << "image." << std::setw(4) << std::setfill('0') << iter << "." << ext;
403 filename = vpIoTools::createFilePath(dirname, s.str());
404 // read the image
405 vpImageIo::read(I, filename);
406 if (opt_display) {
407 // Display the image
409 }
410
411 std::cout << "Tracking on image: " << filename << std::endl;
412 L1.track(I);
413
414 vpTRACE("L1 : %f %f", L1.getRho(), vpMath::deg(L1.getTheta()));
415 vpFeatureBuilder::create(l, cam, L1);
416 vpTRACE("L1 : %f %f", l.getRho(), vpMath::deg(l.getTheta()));
417
418 if (opt_display) {
419 L1.display(I, vpColor::green);
421 if (opt_click_allowed) {
422 std::cout << "A click to continue..." << std::endl;
424 }
425 }
426
427 iter += opt_step;
428 }
429 if (opt_display && opt_click_allowed) {
430 std::cout << "A click to exit..." << std::endl;
432 }
433 return EXIT_SUCCESS;
434 }
435 catch (const vpException &e) {
436 std::cout << "Catch an exception: " << e << std::endl;
437 return EXIT_FAILURE;
438 }
439#else
440 (void)argc;
441 (void)argv;
442 std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
443#endif
444}
445
446#else
447#include <iostream>
448
449int main()
450{
451 std::cout << "visp_me module or X11, GTK, GDI or OpenCV display "
452 "functionalities are required..."
453 << std::endl;
454 return EXIT_SUCCESS;
455}
456
457#endif
Generic class defining intrinsic camera parameters.
static const vpColor green
Definition vpColor.h:214
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:132
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
Definition vpException.h:59
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
Class that defines a 2D line visual feature which is composed by two parameters that are and ,...
double getTheta() const
double getRho() const
static void read(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
static std::string getViSPImagesDataPath()
static std::string createFilePath(const std::string &parent, const std::string &child)
static double deg(double rad)
Definition vpMath.h:106
Class that tracks in an image a line moving edges.
Definition vpMeLine.h:148
double getRho() const
Definition vpMeLine.cpp:825
void display(const vpImage< unsigned char > &I, const vpColor &color, unsigned int thickness=1)
Definition vpMeLine.cpp:181
double getTheta() const
Definition vpMeLine.cpp:827
void track(const vpImage< unsigned char > &I)
Definition vpMeLine.cpp:649
void initTracking(const vpImage< unsigned char > &I)
Definition vpMeLine.cpp:186
@ RANGE_RESULT
Definition vpMeSite.h:75
void setDisplay(vpMeSite::vpMeSiteDisplayType select)
void setMe(vpMe *p_me)
Definition vpMe.h:122
void setRange(const unsigned int &r)
Definition vpMe.h:383
void setLikelihoodThresholdType(const vpLikelihoodThresholdType likelihood_threshold_type)
Definition vpMe.h:445
void setPointsToTrack(const int &n)
Definition vpMe.h:376
@ NORMALIZED_THRESHOLD
Easy-to-use normalized likelihood threshold corresponding to the minimal luminance contrast to consid...
Definition vpMe.h:132
void setThreshold(const double &t)
Definition vpMe.h:435
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
#define vpCTRACE
Definition vpDebug.h:333
#define vpTRACE
Definition vpDebug.h:411