53 #include <visp/vpConfig.h>
54 #include <visp/vpDebug.h>
56 #if ((defined (VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI)) && (VISP_HAVE_OPENCV_VERSION >= 0x020000) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
60 #include <visp/vpPlanarObjectDetector.h>
61 #include <visp/vpParseArgv.h>
62 #include <visp/vpConfig.h>
63 #include <visp/vpImage.h>
64 #include <visp/vpDisplayX.h>
65 #include <visp/vpDisplayGTK.h>
66 #include <visp/vpDisplayGDI.h>
67 #include <visp/vpHomography.h>
68 #include <visp/vpImageIo.h>
69 #include <visp/vpIoTools.h>
70 #include <visp/vpTime.h>
72 #include <visp/vpV4l2Grabber.h>
73 #include <visp/vp1394TwoGrabber.h>
75 #define GETOPTARGS "hlcdb:i:p"
77 void usage(
const char *name,
const char *badparam);
78 bool getOptions(
int argc,
const char **argv,
bool &isLearning, std::string& dataFile,
bool& click_allowed,
79 bool& display,
bool& displayPoints, std::string& ipath);
89 void usage(
const char *name,
const char *badparam)
92 Test of detection of planar surface using a Fern classifier. The object needs \
93 first to be learned (-l option). This learning process will create a file used\
94 to detect the object.\n\
97 %s [-l] [-h] [-b] [-c] [-d] [-p] [-i] [-s]\n", name);
104 -i <input image path> \n\
105 Set image input path.\n\
106 From this path read \"ViSP-images/line/image.%%04d.pgm\"\n\
108 Setting the VISP_INPUT_IMAGE_PATH environment\n\
109 variable produces the same behaviour than using\n\
113 database filename to use (default is ./dataPlanar).\n\
116 Disable the mouse click. Useful to automaze the \n\
117 execution of this program without humain intervention.\n\
120 Turn off the display.\n\
123 Turn off the use of the sequence and use a webcam.\n\
126 display points of interest.\n\
129 Print this help.\n");
132 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
152 bool getOptions(
int argc,
const char **argv,
bool &isLearning, std::string& dataFile,
bool& click_allowed,
153 bool& display,
bool& displayPoints, std::string& ipath)
160 case 'c': click_allowed =
false;
break;
161 case 'd': display =
false;
break;
162 case 'l': isLearning =
true;
break;
163 case 'h': usage(argv[0], NULL);
return false;
break;
164 case 'b': dataFile = optarg_;
break;
165 case 'p': displayPoints =
true;
break;
166 case 'i': ipath = optarg_;
break;
168 usage(argv[0], optarg_);
173 if ((c == 1) || (c == -1)) {
175 usage(argv[0], NULL);
176 std::cerr <<
"ERROR: " << std::endl;
177 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
187 main(
int argc,
const char** argv)
190 bool isLearning =
false;
191 std::string dataFile(
"./dataPlanar");
192 bool opt_click_allowed =
true;
193 bool opt_display =
true;
194 std::string objectName(
"object");
195 bool displayPoints =
false;
196 std::string opt_ipath;
198 std::string env_ipath;
200 std::string filename;
206 if (! env_ipath.empty()){
211 if (getOptions(argc, argv,
212 isLearning, dataFile, opt_click_allowed, opt_display, displayPoints, opt_ipath) ==
false) {
217 if (!opt_ipath.empty()){
223 if (!opt_ipath.empty() && !env_ipath.empty()) {
224 if (ipath != env_ipath) {
225 std::cout << std::endl
226 <<
"WARNING: " << std::endl;
227 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
228 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
229 <<
" we skip the environment variable." << std::endl;
234 if (opt_ipath.empty() && env_ipath.empty()){
235 usage(argv[0], NULL);
236 std::cerr << std::endl
237 <<
"ERROR:" << std::endl;
238 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
240 <<
" environment variable to specify the location of the " << std::endl
241 <<
" image path where test images are located." << std::endl << std::endl;
254 std::ostringstream s;
255 s.setf(std::ios::right, std::ios::adjustfield);
256 s <<
"image." << std::setw(4) << std::setfill(
'0') << iter <<
".pgm";
266 std::cout <<
"Load: " << filename << std::endl;
276 std::cerr << std::endl
277 <<
"ERROR:" << std::endl;
278 std::cerr <<
" Cannot read " << filename << std::endl;
279 std::cerr <<
" Check your -i " << ipath <<
" option " << std::endl
280 <<
" or VISP_INPUT_IMAGE_PATH environment variable."
285 #if defined VISP_HAVE_X11
287 #elif defined VISP_HAVE_GTK
289 #elif defined VISP_HAVE_GDI
293 #if defined VISP_HAVE_X11
295 #elif defined VISP_HAVE_GTK
297 #elif defined VISP_HAVE_GDI
307 displayRef.
init(Iref, 100, 100,
"Reference image") ;
311 if (opt_display && opt_click_allowed){
312 std::cout <<
"Click on the top left and the bottom right corners to define the reference plane" << std::endl;
313 for (
int i=0 ; i < 2 ; i++){
315 std::cout << corners[i] << std::endl;
329 if (opt_click_allowed){
330 std::cout <<
"Click on the image to continue" << std::endl;
334 vpRect roi(corners[0], corners[1]);
336 std::cout <<
"> train the classifier on the selected plane (may take up to several minutes)." << std::endl;
350 vpERROR_TRACE(
"cannot load the database with the specified name. Has the object been learned with the -l option? ");
355 planar.
load(dataFile, objectName);
358 vpERROR_TRACE(
"cannot load the database with the specified name. Has the object been learned with the -l option? ");
364 display.
init(I, 110 + (
int)Iref.
getWidth(), 100,
"Current image") ;
369 if (opt_display && opt_click_allowed){
370 std::cout <<
"Click on the reference image to continue" << std::endl;
372 "Click on the reference image to continue",
vpColor::red);
384 s <<
"image." << std::setw(4) << std::setfill(
'0') << iter <<
".pgm";
401 std::cout <<
" > computed homography:" << std::endl << H << std::endl;
406 planar.
display(Iref, I, displayPoints);
409 planar.
display(I, displayPoints);
414 std::cout <<
" > reference is not detected in the image" << std::endl;
427 std::cout <<
"Catch an exception: " << e << std::endl;
436 #if ( ! (defined (VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI)) )
437 vpERROR_TRACE(
"You do not have X11, GTK or GDI display functionalities...");
439 vpERROR_TRACE(
"You do not have OpenCV-2.0.0 or a more recent release...");
unsigned int getWidth() const
void getHomography(vpHomography &_H) const
Display for windows using GDI (available on any windows 32 platform).
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Define the X11 console to display images.
void load(const std::string &dataFilename, const std::string &objName)
Load the Fern classifier.
error that can be emited by ViSP classes.
static double measureTimeMs()
static const vpColor green
static void flush(const vpImage< unsigned char > &I)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
bool matchPoint(const vpImage< unsigned char > &I)
This class aims to compute the homography wrt.two images.
void display(vpImage< unsigned char > &I, bool displayKpts=false)
static void display(const vpImage< unsigned char > &I)
The vpDisplayGTK allows to display image using the GTK+ library version 1.2.
virtual void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)=0
unsigned int buildReference(const vpImage< unsigned char > &I)
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
void recordDetector(const std::string &objectName, const std::string &dataFile)
Record the Ferns classifier in the text file.
unsigned int getHeight() const
Defines a rectangle in the plane.
virtual bool getClick(bool blocking=true)=0
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Class used to detect a planar surface.
static void read(vpImage< unsigned char > &I, const char *filename)
void set_ij(const double ii, const double jj)