#include <visp3/core/vpConfig.h>
#if defined(VISP_HAVE_MODULE_ME) && defined(VISP_HAVE_DISPLAY)
#include <visp3/core/vpColor.h>
#include <visp3/core/vpImage.h>
#include <visp3/core/vpImagePoint.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/core/vpTime.h>
#include <visp3/gui/vpDisplayFactory.h>
#include <visp3/io/vpParseArgv.h>
#include <visp3/io/vpVideoReader.h>
#include <visp3/io/vpVideoWriter.h>
#include <visp3/me/vpMeEllipse.h>
#define GETOPTARGS "Aabcdf:hi:l:p:r:s:S:t:T:vw:y"
#ifdef ENABLE_VISP_NAMESPACE
#endif
void usage(const char *name, const char *badparam, const std::string &video_in_ipath, const std::string &video_in_ppath,
unsigned video_in_first, int video_in_last, int video_in_step, int me_range, int me_sample_step,
int me_threshold, unsigned int &sleep_ms);
bool getOptions(int argc, const char **argv, std::string &video_in_ipath, std::string &video_in_ppath,
int &video_in_first, int &video_in_last, int &video_in_step,
bool &click_allowed, bool &display, bool &display_scale_auto, bool &track_circle, bool &track_arc,
std::string &video_out_save, int &me_range, int &me_sample_step, int &me_threshold, bool &step_by_step,
unsigned int &sleep_ms, bool &verbose);
void usage(const char *name, const char *badparam, const std::string &video_in_ipath, const std::string &video_in_ppath,
unsigned video_in_first, int video_in_last, int video_in_step, int me_range, int me_sample_step,
int me_threshold, unsigned int &sleep_ms)
{
#if defined(VISP_HAVE_DATASET)
#if VISP_HAVE_DATASET_VERSION >= 0x030600
std::string ext("png");
#else
std::string ext("pgm");
#endif
#else
std::string ext("png");
#endif
fprintf(stdout, "\n\
Example of ellipse/circle or arc of ellipse/circle tracking using vpMeEllipse.\n\
\n\
SYNOPSIS\n\
%s [-i <visp dataset directory>] [-p <personal image path>]\n\
[-f <video first image>] [-l <video last image>] [-s <video step>]\n\
[-r <moving-edge range] [-t <moving-edge threshold] [-S <moving-edge sample step>]\n\
[-w <output images sequence name>] [-T <sleep ms>]\n\
[-c] [-d] [-a] [-A] [-b] [-y] [-v] [-h]\n", name);
fprintf(stdout, "\n\
OPTIONS: Default\n\
-i <visp dataset directory> %s\n\
Set visp dataset directory location.\n\
From this directory read images \"ellipse-1/image.%%04d.%s\"\n\
images.\n\
Setting the VISP_INPUT_IMAGE_PATH environment variable\n\
produces the same behaviour than using this option.\n\
\n\
-p <personal image path> %s\n\
Specify a personal sequence containing images \n\
to process.\n\
The format is selected by analyzing \n\
the filename extension.\n\
Example : \"C:/Temp/ViSP-images/ellipse-1/image.%%04d.%s\"\n\
%%04d is for the image numbering.\n\
\n\
-f <video first image> %d\n\
First image number to process.\n\
Set -1 to process the first image of the sequence.\n\
\n\
-l <video last image> %d\n\
Last image number to process. \n\
Set -1 to process images until the last image of the \n\
sequence.\n\
\n\
-s <video step> %d\n\
Step between two images.\n\
\n\
-r <moving-edge range> %d\n\
Moving-edge range.\n\
Increase value to consider large displacement. \n\
When set to -1, use default value. \n\
\n\
-S <moving-edge sample step> %d\n\
Moving-edge sample step.\n\
Distance between two moving-edges samples in degrees. \n\
When set to -1, use default value. \n\
\n\
-t <moving-edge threshold> %d\n\
Moving-edge threshold corresponding to the minimum \n\
contrast to consider. Value in range [0 ; 255] \n\
When set to -1, use default value. \n\
\n\
-c\n\
Disable the mouse click. Useful to automate the \n\
execution of this program without human intervention.\n\
\n\
-d \n\
Turn off the display.\n\
\n\
-y \n\
Enable step-by-step mode waiting for a mouse click to\n\
process next image.\n\
\n\
-a \n\
Enable arc of ellipse tracking.\n\
\n\
-b \n\
Enable circle tracking.\n\
\n\
-T %d \n\
Sleep time in ms before processing next image.\n\
Allows to slow down the image processing. \n\
\n\
-w <output images sequence name> \n\
Save images with tracking results in overlay.\n\
Example: \"result/I%%04d.png\" \n\
\n\
-A \n\
When display is activated using -d option, enable\n\
windows auto scaling to fit the screen size. \n\
\n\
-v\n\
Enable verbosity.\n\
\n\
-h\n\
Print the help.\n",
video_in_ipath.c_str(), ext.c_str(), video_in_ppath.c_str(), ext.c_str(), video_in_first, video_in_last,
video_in_step, me_range, me_sample_step, me_threshold, sleep_ms);
if (badparam) {
fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
}
}
bool getOptions(int argc, const char **argv, std::string &video_in_ipath, std::string &video_in_ppath,
int &video_in_first, int &video_in_last, int &video_in_step,
bool &click_allowed, bool &display, bool &display_scale_auto, bool &track_circle, bool &track_arc,
std::string &video_out_save, int &me_range, int &me_sample_step, int &me_threshold, bool &step_by_step,
unsigned int &sleep_ms, bool &verbose)
{
const char *optarg_;
int c;
switch (c) {
case 'A':
display_scale_auto = true;
break;
case 'a':
track_arc = true;
break;
case 'b':
track_circle = true;
break;
case 'c':
click_allowed = false;
break;
case 'd':
display = false;
break;
case 'f':
video_in_first = atoi(optarg_);
break;
case 'i':
video_in_ipath = std::string(optarg_);
break;
case 'l':
video_in_last = atoi(optarg_);
break;
case 'p':
video_in_ppath = std::string(optarg_);
break;
case 'r':
me_range = atoi(optarg_);
break;
case 's':
video_in_step = atoi(optarg_);
break;
case 'S':
me_sample_step = atoi(optarg_);
break;
case 't':
me_threshold = atoi(optarg_);
break;
case 'T':
sleep_ms = atoi(optarg_);
break;
case 'w':
video_out_save = std::string(optarg_);
break;
case 'v':
verbose = true;
break;
case 'y':
step_by_step = true;
break;
case 'h':
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);
return false;
default:
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);
return false;
}
}
if ((c == 1) || (c == -1)) {
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);
std::cerr << "ERROR: " << std::endl;
std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
return false;
}
return true;
}
int main(int argc, const char **argv)
{
#if defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV)
std::string env_ipath;
std::string opt_ipath;
std::string ipath;
std::string opt_ppath;
std::string videoname;
int opt_first = -1;
int opt_last = -1;
int opt_step = 1;
int opt_me_range = 30;
int opt_me_sample_step = 5;
int opt_me_threshold = 20;
bool opt_click_allowed = true;
bool opt_display = true;
bool opt_display_scale_auto = false;
bool opt_track_circle = false;
bool opt_track_arc = false;
bool opt_verbose = false;
std::string opt_save;
bool opt_step_by_step = false;
unsigned int opt_sleep_ms = 0;
#if defined(VISP_HAVE_DATASET)
#if VISP_HAVE_DATASET_VERSION >= 0x030600
std::string ext("png");
#else
std::string ext("pgm");
#endif
#else
std::string ext("png");
#endif
try {
if (!env_ipath.empty())
ipath = env_ipath;
if (getOptions(argc, argv, opt_ipath, opt_ppath, opt_first, opt_last, opt_step, opt_click_allowed,
opt_display, opt_display_scale_auto, opt_track_circle, opt_track_arc, opt_save,
opt_me_range, opt_me_sample_step, opt_me_threshold, opt_step_by_step, opt_sleep_ms, opt_verbose) == false) {
return EXIT_FAILURE;
}
if (!opt_ipath.empty()) {
ipath = opt_ipath;
}
if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
if (ipath != env_ipath) {
std::cout << std::endl << "WARNING: " << std::endl;
std::cout << " Since -i <visp image path=" << ipath << "> "
<< " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
<< " we skip the environment variable." << std::endl;
}
}
if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty()) {
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);
std::cerr << std::endl << "ERROR:" << std::endl;
std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
<< " environment variable to specify the location of the " << std::endl
<< " image path where test images are located." << std::endl
<< " Use -p <personal image path> option if you want to " << std::endl
<< " use personal images." << std::endl
<< std::endl;
return EXIT_FAILURE;
}
if (!opt_save.empty()) {
if (!parent.empty()) {
std::cout << "Create output directory: " << parent << std::endl;
}
}
if (opt_ppath.empty()) {
}
else {
}
if (opt_first > 0) {
}
if (opt_last > 0) {
}
if (opt_display) {
if (opt_display_scale_auto) {
}
std::stringstream ss;
}
else {
ss << "Init tracker image " << image_name;
}
display->init(I, 10, 10, ss.str());
}
if (!opt_save.empty()) {
}
if (opt_me_range > 0) {
}
if (opt_me_sample_step > 0) {
}
if (opt_me_threshold > 0) {
}
std::cout << "Video settings" << std::endl;
std::cout << " Image size : " << I.getWidth() << " x " << I.getHeight() << std::endl;
std::cout << "Moving-edges settings" << std::endl;
std::cout <<
" Range : " << me_ellipse.
getMe()->
getRange() << std::endl;
std::cout <<
" Threshold type: " << (me_ellipse.
getMe()->getLikelihoodThresholdType() ==
vpMe::NORMALIZED_THRESHOLD ?
"normalized" :
"old threshold (to be avoided)") << std::endl;
if (!opt_save.empty()) {
std::cout << "Create video with tracking results" << std::endl;
std::cout << " Name : " << opt_save << std::endl;
}
if (opt_click_allowed) {
me_ellipse.
initTracking(I, opt_track_circle, opt_track_arc);
}
else {
std::vector<vpImagePoint> ip;
me_ellipse.
initTracking(I, ip, opt_track_circle, opt_track_arc);
}
if (opt_display) {
}
if (opt_display && opt_click_allowed) {
std::cout << "A click to continue..." << std::endl;
}
bool quit = false;
while (!g.
end() && !quit) {
std::stringstream ss;
}
else {
ss << "Image " << image_name;
}
if (opt_verbose) {
std::cout << "-- " << ss.str() << std::endl;
}
if (opt_display) {
if (opt_click_allowed) {
if (opt_step_by_step) {
}
}
}
if (opt_display) {
if (opt_click_allowed) {
quit = true;
}
if (opt_step_by_step) {
opt_step_by_step = false;
}
else {
opt_step_by_step = true;
}
}
}
}
}
if (!opt_save.empty()) {
}
if (opt_sleep_ms) {
}
}
if (opt_display && opt_click_allowed && !quit) {
}
if (writer) {
delete writer;
}
if (display) {
delete display;
}
return EXIT_SUCCESS;
}
std::cout <<
"Catch an exception: " <<
e << std::endl;
if (opt_display && opt_click_allowed) {
}
return EXIT_FAILURE;
}
#else
(void)argc;
(void)argv;
std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
#endif
}
#else
#include <iostream>
int main()
{
std::cout << "visp_me module or X11, GTK, GDI or OpenCV display "
"functionalities are required..."
<< std::endl;
return EXIT_SUCCESS;
}
#endif
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)