#include <visp3/core/vpConfig.h>
#include <visp3/core/vpDebug.h>
#include <iomanip>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#if defined(VISP_HAVE_MODULE_ME) && \
(defined(VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV))
#include <visp3/core/vpColor.h>
#include <visp3/core/vpImage.h>
#include <visp3/core/vpImagePoint.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayGTK.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.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:vw:"
#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)
{
#if VISP_HAVE_DATASET_VERSION >= 0x030600
std::string ext("png");
#else
std::string ext("pgm");
#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>] \n\
[-c] [-d] [-a] [-A] [-b] [-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 \n\
\"ellipse-1/image.%%04d.%s\"\n\
Setting the VISP_INPUT_IMAGE_PATH environment\n\
variable produces the same behaviour than using\n\
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\n\
of the 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\
-a \n\
Enable arc of ellipse tracking.\n\
\n\
-b \n\
Enable circle tracking.\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);
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 &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 'w':
video_out_save = std::string(optarg_);
break;
case 'v':
verbose = 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);
return false;
break;
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);
return false;
break;
}
}
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);
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;
unsigned int thickness = 1;
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_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);
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;
}
thickness += 1;
}
if (opt_ppath.empty()) {
#if VISP_HAVE_DATASET_VERSION >= 0x030600
#else
#endif
}
else {
}
if (opt_first > 0) {
}
if (opt_last > 0) {
}
if (opt_display) {
#if defined(VISP_HAVE_X11)
display = new vpDisplayX;
#elif defined(VISP_HAVE_GTK)
#elif defined(VISP_HAVE_GDI)
#elif defined(HAVE_OPENCV_HIGHGUI)
#endif
if (opt_display_scale_auto) {
}
display->init(I, 10, 10, "Current image");
}
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;
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;
if (opt_verbose) {
std::cout << "-- " << ss.str() << std::endl;
}
if (opt_display) {
if (opt_click_allowed) {
}
}
if (opt_display) {
}
if (!opt_save.empty()) {
}
if (opt_display && opt_click_allowed) {
quit = true;
}
}
}
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
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...
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 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 ...
unsigned int getWidth() const
unsigned int getHeight() const
Class that tracks an ellipse 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)
vpLikelihoodThresholdType getLikelihoodThresholdType() const
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...
void acquire(vpImage< vpRGBa > &I)
void setLastFrameIndex(const long last_frame)
void open(vpImage< vpRGBa > &I)
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
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)