41#include <visp3/core/vpConfig.h>
43#if defined(VISP_HAVE_MODULE_ME) && defined(VISP_HAVE_DISPLAY)
45#include <visp3/core/vpColor.h>
46#include <visp3/core/vpImage.h>
47#include <visp3/core/vpImagePoint.h>
48#include <visp3/core/vpIoTools.h>
49#include <visp3/core/vpTime.h>
50#include <visp3/gui/vpDisplayFactory.h>
51#include <visp3/io/vpParseArgv.h>
52#include <visp3/io/vpVideoReader.h>
53#include <visp3/io/vpVideoWriter.h>
54#include <visp3/me/vpMeEllipse.h>
57#define GETOPTARGS "Aabcdf:hi:l:p:r:s:S:t:T:vw:y"
59#ifdef ENABLE_VISP_NAMESPACE
64void usage(
const char *name,
const char *badparam,
const std::string &video_in_ipath,
const std::string &video_in_ppath,
65 unsigned video_in_first,
int video_in_last,
int video_in_step,
int me_range,
int me_sample_step,
66 int me_threshold,
unsigned int &sleep_ms);
67bool getOptions(
int argc,
const char **argv, std::string &video_in_ipath, std::string &video_in_ppath,
68 int &video_in_first,
int &video_in_last,
int &video_in_step,
69 bool &click_allowed,
bool &display,
bool &display_scale_auto,
bool &track_circle,
bool &track_arc,
70 std::string &video_out_save,
int &me_range,
int &me_sample_step,
int &me_threshold,
bool &step_by_step,
71 unsigned int &sleep_ms,
bool &verbose);
88void usage(
const char *name,
const char *badparam,
const std::string &video_in_ipath,
const std::string &video_in_ppath,
89 unsigned video_in_first,
int video_in_last,
int video_in_step,
int me_range,
int me_sample_step,
90 int me_threshold,
unsigned int &sleep_ms)
92#if defined(VISP_HAVE_DATASET)
93#if VISP_HAVE_DATASET_VERSION >= 0x030600
94 std::string ext(
"png");
96 std::string ext(
"pgm");
100 std::string ext(
"png");
103Example of ellipse/circle or arc of ellipse/circle tracking using vpMeEllipse.\n\
106 %s [-i <visp dataset directory>] [-p <personal image path>]\n\
107 [-f <video first image>] [-l <video last image>] [-s <video step>]\n\
108 [-r <moving-edge range] [-t <moving-edge threshold] [-S <moving-edge sample step>]\n\
109 [-w <output images sequence name>] [-T <sleep ms>]\n\
110 [-c] [-d] [-a] [-A] [-b] [-y] [-v] [-h]\n", name);
114 -i <visp dataset directory> %s\n\
115 Set visp dataset directory location.\n\
116 From this directory read images \"ellipse-1/image.%%04d.%s\"\n\
118 Setting the VISP_INPUT_IMAGE_PATH environment variable\n\
119 produces the same behaviour than using this option.\n\
121 -p <personal image path> %s\n\
122 Specify a personal sequence containing images \n\
124 The format is selected by analyzing \n\
125 the filename extension.\n\
126 Example : \"C:/Temp/ViSP-images/ellipse-1/image.%%04d.%s\"\n\
127 %%04d is for the image numbering.\n\
129 -f <video first image> %d\n\
130 First image number to process.\n\
131 Set -1 to process the first image of the sequence.\n\
133 -l <video last image> %d\n\
134 Last image number to process. \n\
135 Set -1 to process images until the last image of the \n\
138 -s <video step> %d\n\
139 Step between two images.\n\
141 -r <moving-edge range> %d\n\
142 Moving-edge range.\n\
143 Increase value to consider large displacement. \n\
144 When set to -1, use default value. \n\
146 -S <moving-edge sample step> %d\n\
147 Moving-edge sample step.\n\
148 Distance between two moving-edges samples in degrees. \n\
149 When set to -1, use default value. \n\
151 -t <moving-edge threshold> %d\n\
152 Moving-edge threshold corresponding to the minimum \n\
153 contrast to consider. Value in range [0 ; 255] \n\
154 When set to -1, use default value. \n\
157 Disable the mouse click. Useful to automate the \n\
158 execution of this program without human intervention.\n\
161 Turn off the display.\n\
164 Enable step-by-step mode waiting for a mouse click to\n\
165 process next image.\n\
168 Enable arc of ellipse tracking.\n\
171 Enable circle tracking.\n\
174 Sleep time in ms before processing next image.\n\
175 Allows to slow down the image processing. \n\
177 -w <output images sequence name> \n\
178 Save images with tracking results in overlay.\n\
179 Example: \"result/I%%04d.png\" \n\
182 When display is activated using -d option, enable\n\
183 windows auto scaling to fit the screen size. \n\
190 video_in_ipath.c_str(), ext.c_str(), video_in_ppath.c_str(), ext.c_str(), video_in_first, video_in_last,
191 video_in_step, me_range, me_sample_step, me_threshold, sleep_ms);
194 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
223bool getOptions(
int argc,
const char **argv, std::string &video_in_ipath, std::string &video_in_ppath,
224 int &video_in_first,
int &video_in_last,
int &video_in_step,
225 bool &click_allowed,
bool &display,
bool &display_scale_auto,
bool &track_circle,
bool &track_arc,
226 std::string &video_out_save,
int &me_range,
int &me_sample_step,
int &me_threshold,
bool &step_by_step,
227 unsigned int &sleep_ms,
bool &verbose)
235 display_scale_auto =
true;
244 click_allowed =
false;
250 video_in_first = atoi(optarg_);
253 video_in_ipath = std::string(optarg_);
256 video_in_last = atoi(optarg_);
259 video_in_ppath = std::string(optarg_);
262 me_range = atoi(optarg_);
265 video_in_step = atoi(optarg_);
268 me_sample_step = atoi(optarg_);
271 me_threshold = atoi(optarg_);
274 sleep_ms = atoi(optarg_);
277 video_out_save = std::string(optarg_);
286 usage(argv[0],
nullptr, video_in_ipath, video_in_ppath, video_in_first, video_in_last, video_in_step, me_range, me_sample_step, me_threshold, sleep_ms);
290 usage(argv[0], optarg_, video_in_ipath, video_in_ppath, video_in_first, video_in_last, video_in_step, me_range, me_sample_step, me_threshold, sleep_ms);
295 if ((c == 1) || (c == -1)) {
297 usage(argv[0],
nullptr, video_in_ipath, video_in_ppath, video_in_first, video_in_last, video_in_step, me_range, me_sample_step, me_threshold, sleep_ms);
298 std::cerr <<
"ERROR: " << std::endl;
299 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
306int main(
int argc,
const char **argv)
308#if defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV)
309 std::string env_ipath;
310 std::string opt_ipath;
312 std::string opt_ppath;
313 std::string videoname;
317 int opt_me_range = 30;
318 int opt_me_sample_step = 5;
319 int opt_me_threshold = 20;
320 bool opt_click_allowed =
true;
321 bool opt_display =
true;
322 bool opt_display_scale_auto =
false;
323 bool opt_track_circle =
false;
324 bool opt_track_arc =
false;
325 bool opt_verbose =
false;
326 std::string opt_save;
327 bool opt_step_by_step =
false;
328 unsigned int opt_sleep_ms = 0;
338#if defined(VISP_HAVE_DATASET)
339#if VISP_HAVE_DATASET_VERSION >= 0x030600
340 std::string ext(
"png");
342 std::string ext(
"pgm");
346 std::string ext(
"png");
355 if (!env_ipath.empty())
359 if (getOptions(argc, argv, opt_ipath, opt_ppath, opt_first, opt_last, opt_step, opt_click_allowed,
360 opt_display, opt_display_scale_auto, opt_track_circle, opt_track_arc, opt_save,
361 opt_me_range, opt_me_sample_step, opt_me_threshold, opt_step_by_step, opt_sleep_ms, opt_verbose) ==
false) {
366 if (!opt_ipath.empty()) {
372 if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
373 if (ipath != env_ipath) {
374 std::cout << std::endl <<
"WARNING: " << std::endl;
375 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
376 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
377 <<
" we skip the environment variable." << std::endl;
382 if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty()) {
383 usage(argv[0],
nullptr, ipath, opt_ppath, opt_first, opt_last, opt_step, opt_me_range, opt_me_sample_step, opt_me_threshold, opt_sleep_ms);
384 std::cerr << std::endl <<
"ERROR:" << std::endl;
385 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
386 <<
" environment variable to specify the location of the " << std::endl
387 <<
" image path where test images are located." << std::endl
388 <<
" Use -p <personal image path> option if you want to " << std::endl
389 <<
" use personal images." << std::endl
396 if (!opt_save.empty()) {
398 if (!parent.empty()) {
399 std::cout <<
"Create output directory: " << parent << std::endl;
405 if (opt_ppath.empty()) {
426 if (opt_display_scale_auto) {
429 std::stringstream ss;
435 ss <<
"Init tracker image " << image_name;
438 display->init(I, 10, 10, ss.str());
450 if (!opt_save.empty()) {
458 if (opt_me_range > 0) {
461 if (opt_me_sample_step > 0) {
464 if (opt_me_threshold > 0) {
469 me_ellipse.
setMe(&me);
472 std::cout <<
"Video settings" << std::endl;
473 std::cout <<
" Name : " << g.
getFrameName() << std::endl;
476 std::cout <<
" Step : " << g.
getFrameStep() << std::endl;
477 std::cout <<
" Image size : " << I.getWidth() <<
" x " << I.getHeight() << std::endl;
479 std::cout <<
"Moving-edges settings" << std::endl;
481 std::cout <<
" Range : " << me_ellipse.
getMe()->
getRange() << std::endl;
482 std::cout <<
" Threshold type: " << (me_ellipse.
getMe()->getLikelihoodThresholdType() ==
vpMe::NORMALIZED_THRESHOLD ?
"normalized" :
"old threshold (to be avoided)") << std::endl;
485 if (!opt_save.empty()) {
486 std::cout <<
"Create video with tracking results" << std::endl;
487 std::cout <<
" Name : " << opt_save << std::endl;
490 if (opt_click_allowed) {
491 me_ellipse.
initTracking(I, opt_track_circle, opt_track_arc);
495 std::vector<vpImagePoint> ip;
502 me_ellipse.
initTracking(I, ip, opt_track_circle, opt_track_arc);
509 if (opt_display && opt_click_allowed) {
510 std::cout <<
"A click to continue..." << std::endl;
515 while (!g.
end() && !quit) {
518 std::stringstream ss;
524 ss <<
"Image " << image_name;
528 std::cout <<
"-- " << ss.str() << std::endl;
534 if (opt_click_allowed) {
535 vpDisplay::displayText(I, 20, I.getWidth() - 150, std::string(
"Mode: ") + (opt_step_by_step ? std::string(
"step-by-step") : std::string(
"continuous")),
vpColor::red);
539 if (opt_step_by_step) {
549 if (opt_click_allowed) {
556 if (opt_step_by_step) {
557 opt_step_by_step =
false;
560 opt_step_by_step =
true;
566 if (!opt_save.empty()) {
576 if (opt_display && opt_click_allowed && !quit) {
589 std::cout <<
"Catch an exception: " <<
e << std::endl;
590 if (opt_display && opt_click_allowed) {
598 std::cout <<
"Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
606 std::cout <<
"visp_me module or X11, GTK, GDI or OpenCV display "
607 "functionalities are required..."
static const vpColor green
Class that defines generic functionalities for display.
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
static void setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
static void flush(const vpImage< unsigned char > &I)
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.
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.
Class that tracks an ellipse or a circle using moving edges.
void display(const vpImage< unsigned char > &I, const vpColor &col, unsigned int thickness=1)
void initTracking(const vpImage< unsigned char > &I, bool trackCircle=false, bool trackArc=false)
void track(const vpImage< unsigned char > &I)
void setDisplay(vpMeSite::vpMeSiteDisplayType select)
void setRange(const unsigned int &range)
void setLikelihoodThresholdType(const vpLikelihoodThresholdType likelihood_threshold_type)
void setThreshold(const double &threshold)
void setSampleStep(const double &sample_step)
double getThreshold() const
double getSampleStep() const
unsigned int getRange() const
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...
bool isVideoFormat() const
void setLastFrameIndex(const long last_frame)
void open(vpImage< vpRGBa > &I) VP_OVERRIDE
void setFileName(const std::string &filename)
void setFirstFrameIndex(const long first_frame)
long getFirstFrameIndex()
void setFrameStep(const long frame_step)
long getFrameStep() const
std::string getFrameName() const
long getFrameIndex() const
void acquire(vpImage< vpRGBa > &I) VP_OVERRIDE
Class that enables to write easily a video file or a sequence of images.
void saveFrame(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
void open(vpImage< vpRGBa > &I)
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.
VISP_EXPORT void sleepMs(double t)