Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
trackMeNurbs.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Tracking of a nurbs.
32 */
33
39
45
46#include <visp3/core/vpConfig.h>
47#include <visp3/core/vpDebug.h>
48
49#include <iomanip>
50#include <sstream>
51#include <stdio.h>
52#include <stdlib.h>
53
54#if defined(VISP_HAVE_MODULE_ME) && \
55 (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV))
56
57#include <visp3/core/vpColor.h>
58#include <visp3/core/vpImage.h>
59#include <visp3/core/vpImagePoint.h>
60#include <visp3/gui/vpDisplayGDI.h>
61#include <visp3/gui/vpDisplayGTK.h>
62#include <visp3/gui/vpDisplayOpenCV.h>
63#include <visp3/gui/vpDisplayX.h>
64#include <visp3/io/vpImageIo.h>
65
66#include <visp3/core/vpIoTools.h>
67#include <visp3/io/vpParseArgv.h>
68#include <visp3/io/vpVideoReader.h>
69#include <visp3/me/vpMeNurbs.h>
70
71// List of allowed command line options
72#define GETOPTARGS "cdi:h"
73
74#ifdef ENABLE_VISP_NAMESPACE
75using namespace VISP_NAMESPACE_NAME;
76#endif
77
78void usage(const char *name, const char *badparam, std::string ipath);
79bool getOptions(int argc, const char **argv, std::string &ipath, bool &click_allowed, bool &display);
80
90void usage(const char *name, const char *badparam, std::string ipath)
91{
92#if defined(VISP_HAVE_DATASET)
93#if VISP_HAVE_DATASET_VERSION >= 0x030600
94 std::string ext("png");
95#else
96 std::string ext("pgm");
97#endif
98#else
99 // We suppose that the user will download a recent dataset
100 std::string ext("png");
101#endif
102 fprintf(stdout, "\n\
103Tracking of a nurbs using vpMe.\n\
104\n\
105SYNOPSIS\n\
106 %s [-i <input image path>] [-c] [-d] [-h]\n",
107 name);
108
109 fprintf(stdout, "\n\
110OPTIONS: Default\n\
111 -i <input image path> %s\n\
112 Set image input path.\n\
113 From this path read images \n\
114 \"ellipse-1/image.%%04d.%s\"\n\
115 Setting the VISP_INPUT_IMAGE_PATH environment\n\
116 variable produces the same behaviour than using\n\
117 this option.\n\
118\n\
119 -c\n\
120 Disable the mouse click. Useful to automate the \n\
121 execution of this program without human intervention.\n\
122\n\
123 -d \n\
124 Turn off the display.\n\
125\n\
126 -h\n\
127 Print the help.\n",
128 ipath.c_str(), ext.c_str());
129
130 if (badparam)
131 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
132}
146bool getOptions(int argc, const char **argv, std::string &ipath, bool &click_allowed, bool &display)
147{
148 const char *optarg_;
149 int c;
150 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
151
152 switch (c) {
153 case 'c':
154 click_allowed = false;
155 break;
156 case 'd':
157 display = false;
158 break;
159 case 'i':
160 ipath = optarg_;
161 break;
162 case 'h':
163 usage(argv[0], nullptr, ipath);
164 return false;
165
166 default:
167 usage(argv[0], optarg_, ipath);
168 return false;
169 }
170 }
171
172 if ((c == 1) || (c == -1)) {
173 // standalone param or error
174 usage(argv[0], nullptr, ipath);
175 std::cerr << "ERROR: " << std::endl;
176 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
177 return false;
178 }
179
180 return true;
181}
182
183int main(int argc, const char **argv)
184{
185 try {
186 std::string env_ipath;
187 std::string opt_ipath;
188 std::string ipath;
189 std::string filename;
190 bool opt_click_allowed = true;
191 bool opt_display = true;
192
193#if defined(VISP_HAVE_DATASET)
194#if VISP_HAVE_DATASET_VERSION >= 0x030600
195 std::string ext("png");
196#else
197 std::string ext("pgm");
198#endif
199#else
200 // We suppose that the user will download a recent dataset
201 std::string ext("png");
202#endif
203
204 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
205 // environment variable value
207
208 // Set the default input path
209 if (!env_ipath.empty())
210 ipath = env_ipath;
211
212 // Read the command line options
213 if (getOptions(argc, argv, opt_ipath, opt_click_allowed, opt_display) == false) {
214 return EXIT_FAILURE;
215 }
216
217 // Get the option values
218 if (!opt_ipath.empty())
219 ipath = opt_ipath;
220
221 // Compare ipath and env_ipath. If they differ, we take into account
222 // the input path coming from the command line option
223 if (!opt_ipath.empty() && !env_ipath.empty()) {
224 if (ipath != env_ipath) {
225 std::cout << std::endl << "WARNING: " << std::endl;
226 std::cout << " Since -i <visp image path=" << ipath << "> "
227 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
228 << " we skip the environment variable." << std::endl;
229 }
230 }
231
232 // Test if an input path is set
233 if (opt_ipath.empty() && env_ipath.empty()) {
234 usage(argv[0], nullptr, ipath);
235 std::cerr << std::endl << "ERROR:" << std::endl;
236 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
237 << " environment variable to specify the location of the " << std::endl
238 << " image path where test images are located." << std::endl
239 << std::endl;
240 return EXIT_FAILURE;
241 }
242
243 // Declare an image, this is a gray level image (unsigned char)
244 // it size is not defined yet, it will be defined when the image is
245 // read on the disk
247
248 // Set the path location of the image sequence
249 filename = vpIoTools::createFilePath(ipath, "ellipse-1/image.%04d." + ext);
250
251 // Build the name of the image file
252 vpVideoReader reader;
253 // Initialize the reader and get the first frame.
254 reader.setFileName(filename.c_str());
255 reader.setFirstFrameIndex(1);
256 reader.open(I);
257
258 // We open a window using either X11, GTK or GDI.
259#if defined(VISP_HAVE_X11)
260 vpDisplayX display;
261#elif defined(VISP_HAVE_GTK)
262 vpDisplayGTK display;
263#elif defined(VISP_HAVE_GDI)
264 vpDisplayGDI display;
265#elif defined(HAVE_OPENCV_HIGHGUI)
266 vpDisplayOpenCV display;
267#endif
268
269 if (opt_display) {
270 // Display size is automatically defined by the image (I) size
271 display.init(I, 100, 100, "Display...");
272 // Display the image
273 // The image class has a member that specify a pointer toward
274 // the display that has been initialized in the display declaration
275 // therefore is is no longer necessary to make a reference to the
276 // display variable.
279 }
280
281 vpMeNurbs nurbs;
282
283 vpMe me;
284 me.setRange(30);
285 me.setSampleStep(5);
286 me.setPointsToTrack(60);
288 me.setThreshold(20);
289
290 nurbs.setMe(&me);
292 nurbs.setNbControlPoints(14);
293
294 if (opt_click_allowed) {
295 std::cout << "Click on points along the edge with the left button." << std::endl;
296 std::cout << "Then click on the right button to continue." << std::endl;
297 nurbs.initTracking(I);
298 }
299 else {
300 // Create a list of points to automate the test
301 std::list<vpImagePoint> list;
302 list.push_back(vpImagePoint(178, 357));
303 list.push_back(vpImagePoint(212, 287));
304 list.push_back(vpImagePoint(236, 210));
305 list.push_back(vpImagePoint(240, 118));
306 list.push_back(vpImagePoint(210, 40));
307
308 nurbs.initTracking(I, list);
309 }
310 if (opt_display) {
311 nurbs.display(I, vpColor::green);
312 }
313
314 nurbs.track(I);
315 if (opt_display && opt_click_allowed) {
316 std::cout << "A click to continue..." << std::endl;
318 }
319 std::cout << "------------------------------------------------------------" << std::endl;
320
321 for (int iter = 1; iter < 40; iter++) {
322 // read the image
323 reader.getFrame(I, iter);
324 if (opt_display) {
325 // Display the image
327 }
328
329 // Track the nurbs
330 nurbs.track(I);
331
332 if (opt_display) {
333 nurbs.display(I, vpColor::green);
335 vpTime::wait(100);
336 }
337 }
338 if (opt_display && opt_click_allowed) {
339 std::cout << "A click to exit..." << std::endl;
341 }
342 return EXIT_SUCCESS;
343 }
344 catch (vpException &e) {
345 std::cout << "Catch an exception: " << e.getMessage() << std::endl;
346 return EXIT_SUCCESS;
347 }
348}
349#else
350#include <iostream>
351
352int main()
353{
354 std::cout << "visp_me module or X11, GTK, GDI or OpenCV display "
355 "functionalities are required..."
356 << std::endl;
357}
358
359#endif
static const vpColor green
Definition vpColor.h:201
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:135
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:60
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
Definition vpImage.h:131
static std::string getViSPImagesDataPath()
static std::string createFilePath(const std::string &parent, const std::string &child)
Class that tracks in an image a edge defined by a Nurbs.
Definition vpMeNurbs.h:140
void track(const vpImage< unsigned char > &I)
void initTracking(const vpImage< unsigned char > &I)
void setNbControlPoints(unsigned int nb_point)
Definition vpMeNurbs.h:184
void display(const vpImage< unsigned char > &I, const vpColor &color, unsigned int thickness=1)
@ RANGE_RESULT
Definition vpMeSite.h:85
void setDisplay(vpMeSite::vpMeSiteDisplayType select)
void setMe(vpMe *me)
Definition vpMe.h:143
void setPointsToTrack(const int &points_to_track)
Definition vpMe.h:431
void setRange(const unsigned int &range)
Definition vpMe.h:438
void setLikelihoodThresholdType(const vpLikelihoodThresholdType likelihood_threshold_type)
Definition vpMe.h:531
void setThreshold(const double &threshold)
Definition vpMe.h:489
void setSampleStep(const double &sample_step)
Definition vpMe.h:445
@ NORMALIZED_THRESHOLD
Definition vpMe.h:154
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void open(vpImage< vpRGBa > &I) VP_OVERRIDE
void setFileName(const std::string &filename)
void setFirstFrameIndex(const long first_frame)
bool getFrame(vpImage< vpRGBa > &I, long frame)
VISP_EXPORT int wait(double t0, double t)