Visual Servoing Platform  version 3.6.1 under development (2024-05-09)
AROgre.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Implementation of a simple augmented reality application using the vpAROgre
33  * class.
34  *
35 *****************************************************************************/
36 
42 #include <iostream>
43 #include <visp3/core/vpConfig.h>
44 
45 //#if defined(VISP_HAVE_OGRE) && (defined(VISP_HAVE_OPENCV) ||
46 // defined(VISP_HAVE_GDI) || defined(VISP_HAVE_D3D9) || defined(VISP_HAVE_GTK)
47 //|| (defined(VISP_HAVE_X11) && ! defined(APPLE)))
48 #if defined(VISP_HAVE_OGRE) && \
49  (defined(VISP_HAVE_OPENCV) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_D3D9) || defined(VISP_HAVE_GTK) || \
50  (defined(VISP_HAVE_X11) && !(defined(__APPLE__) && defined(__MACH__))))
51 
52 //#if defined(VISP_HAVE_X11) && ! defined(APPLE)
53 #if defined(VISP_HAVE_X11) && !(defined(__APPLE__) && defined(__MACH__))
54 // produce an error on OSX: ‘typedef int Cursor’
55 // /usr/X11R6/include/X11/X.h:108: error: ‘Cursor’ has a previous
56 // declaration as ‘typedef XID Cursor’. That's why it should not be
57 // used on APPLE platforms
58 #include <visp3/gui/vpDisplayX.h>
59 #endif
60 #include <visp3/ar/vpAROgre.h>
61 #include <visp3/blob/vpDot2.h>
62 #include <visp3/core/vpDebug.h>
63 #include <visp3/core/vpImagePoint.h>
64 #include <visp3/core/vpIoTools.h>
65 #include <visp3/core/vpPixelMeterConversion.h>
66 #include <visp3/core/vpPoint.h>
67 #include <visp3/gui/vpDisplayD3D.h>
68 #include <visp3/gui/vpDisplayGDI.h>
69 #include <visp3/gui/vpDisplayGTK.h>
70 #include <visp3/gui/vpDisplayOpenCV.h>
71 #include <visp3/io/vpParseArgv.h>
72 #include <visp3/io/vpVideoReader.h>
73 #include <visp3/vision/vpPose.h>
74 
75 // List of allowed command line options
76 #define GETOPTARGS "ci:p:h"
77 
89 void usage(const char *name, const char *badparam, std::string ipath, std::string ppath)
90 {
91 #if VISP_HAVE_DATASET_VERSION >= 0x030600
92  std::string ext("png");
93 #else
94  std::string ext("pgm");
95 #endif
96 
97  fprintf(stdout, "\n\
98 Test augmented reality using the vpAROgre class.\n\
99 \n\
100 SYNOPSIS\n\
101  %s [-i <test image path>] [-p <personal image path>]\n\
102  [-c] [-h]\n", name);
103 
104  fprintf(stdout, "\n\
105 OPTIONS: Default\n\
106  -i <input image path> %s\n\
107  Set image input path.\n\
108  From this path read images \n\
109  \"mire-2/image.%%04d.%s\". These \n\
110  images come from visp-images-x.y.z.tar.gz available \n\
111  on the ViSP website.\n\
112  Setting the VISP_INPUT_IMAGE_PATH environment\n\
113  variable produces the same behaviour than using\n\
114  this option.\n\
115  \n\
116  -p <personal image path> %s\n\
117  Specify a personal sequence containing images \n\
118  to process.\n\
119  By image sequence, we mean one file per image.\n\
120  Example : \"/Temp/visp-images/cube/image.%%04d.%s\"\n\
121  %%04d is for the image numbering.\n\
122 \n\
123  -c\n\
124  Disable the mouse click. Useful to automate the \n\
125  execution of this program without human intervention.\n\
126 \n\
127  -h\n\
128  Print the help.\n",
129  ipath.c_str(), ext.c_str(), ppath.c_str(), ext.c_str());
130 
131  if (badparam)
132  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
133 }
147 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath, bool &click_allowed)
148 {
149  const char *optarg_;
150  int c;
151  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
152 
153  switch (c) {
154  case 'c':
155  click_allowed = false;
156  break;
157  case 'i':
158  ipath = optarg_;
159  break;
160  case 'p':
161  ppath = optarg_;
162  break;
163  case 'h':
164  usage(argv[0], nullptr, ipath, ppath);
165  return false;
166  break;
167 
168  default:
169  usage(argv[0], optarg_, ipath, ppath);
170  return false;
171  break;
172  }
173  }
174 
175  if ((c == 1) || (c == -1)) {
176  // standalone param or error
177  usage(argv[0], nullptr, ipath, ppath);
178  std::cerr << "ERROR: " << std::endl;
179  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
180  return false;
181  }
182 
183  return true;
184 }
185 
186 #ifndef DOXYGEN_SHOULD_SKIP_THIS
187 
188 class vpAROgreExample : public vpAROgre
189 {
190 public:
191  // The constructor doesn't change here
192  vpAROgreExample(const vpCameraParameters &cam = vpCameraParameters(), unsigned int width = 640,
193  unsigned int height = 480, const char *resourcePath = nullptr)
194  : vpAROgre(cam, width, height)
195  {
196  // Direction vectors
197  if (resourcePath)
198  mResourcePath = resourcePath;
199  std::cout << "mResourcePath: " << mResourcePath << std::endl;
200  vecDevant = Ogre::Vector3(0, -1, 0);
201  robot = nullptr;
202  mAnimationState = nullptr;
203  }
204 
205 protected:
206  // Attributes
207  // Vector to move
208  Ogre::Vector3 vecDevant;
209  // Animation attribute
210  Ogre::AnimationState *mAnimationState;
211  // The entity representing the robot
212  Ogre::Entity *robot;
213 
214  // Our scene will just be a plane
215  void createScene()
216  {
217  // Lumieres
218  mSceneMgr->setAmbientLight(Ogre::ColourValue((float)0.6, (float)0.6, (float)0.6)); // Default value of lightning
219  Ogre::Light *light = mSceneMgr->createLight();
220  light->setDiffuseColour(1.0, 1.0, 1.0); // scaled RGB values
221  light->setSpecularColour(1.0, 1.0, 1.0); // scaled RGB values
222  // Lumiere ponctuelle
223  light->setPosition(-5, -5, 10);
224  light->setType(Ogre::Light::LT_POINT);
225  light->setAttenuation((Ogre::Real)100, (Ogre::Real)1.0, (Ogre::Real)0.045, (Ogre::Real)0.0075);
226  // Ombres
227  light->setCastShadows(true);
228 
229  // Create the Entity
230  robot = mSceneMgr->createEntity("Robot", "robot.mesh");
231  // Attach robot to scene graph
232  Ogre::SceneNode *RobotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("Robot");
233  RobotNode->attachObject(robot);
234  RobotNode->scale((Ogre::Real)0.001, (Ogre::Real)0.001, (Ogre::Real)0.001);
235  RobotNode->pitch(Ogre::Degree(90));
236  RobotNode->yaw(Ogre::Degree(-90));
237  robot->setCastShadows(true);
238  mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_MODULATIVE);
239 
240  // Add an animation
241  // Set the good animation
242  mAnimationState = robot->getAnimationState("Idle");
243  // Start over when finished
244  mAnimationState->setLoop(true);
245  // Animation enabled
246  mAnimationState->setEnabled(true);
247 
248  // Add a ground
249  Ogre::Plane plan;
250  plan.d = 0;
251  plan.normal = Ogre::Vector3::UNIT_Z;
252  Ogre::MeshManager::getSingleton().createPlane("sol", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plan,
253  (Ogre::Real)0.22, (Ogre::Real)0.16, 10, 10, true, 1, 1, 1);
254  Ogre::Entity *ent = mSceneMgr->createEntity("Entitesol", "sol");
255  Ogre::SceneNode *PlaneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("Entitesol");
256  PlaneNode->attachObject(ent);
257  ent->setMaterialName("Examples/GrassFloor");
258  }
259 
260  bool customframeEnded(const Ogre::FrameEvent &evt)
261  {
262  // Update animation
263  // To move, we add it the time since last frame
264  mAnimationState->addTime(evt.timeSinceLastFrame);
265  return true;
266  }
267 
268 #ifdef VISP_HAVE_OIS
269  bool processInputEvent(const Ogre::FrameEvent & /*evt*/)
270  {
271  mKeyboard->capture();
272  Ogre::Matrix3 rotmy;
273  double angle = -M_PI / 8;
274  if (mKeyboard->isKeyDown(OIS::KC_ESCAPE))
275  return false;
276 
277  // Event telling that we will have to move, setting the animation to
278  // "walk", if false, annimation goes to "Idle"
279  bool event = false;
280  // Check entries
281  if (mKeyboard->isKeyDown(OIS::KC_Z) || mKeyboard->isKeyDown(OIS::KC_UP)) {
282  mSceneMgr->getSceneNode("Robot")->setPosition(mSceneMgr->getSceneNode("Robot")->getPosition() +
283  (Ogre::Real)0.003 * vecDevant);
284  event = true;
285  }
286  if (mKeyboard->isKeyDown(OIS::KC_S) || mKeyboard->isKeyDown(OIS::KC_DOWN)) {
287  mSceneMgr->getSceneNode("Robot")->setPosition(mSceneMgr->getSceneNode("Robot")->getPosition() -
288  (Ogre::Real)0.003 * vecDevant);
289  event = true;
290  }
291  if (mKeyboard->isKeyDown(OIS::KC_Q) || mKeyboard->isKeyDown(OIS::KC_LEFT)) {
292  rotmy = Ogre::Matrix3((Ogre::Real)cos(-angle), (Ogre::Real)sin(-angle), 0, (Ogre::Real)(-sin(-angle)),
293  (Ogre::Real)cos(-angle), 0, 0, 0, 1);
294  vecDevant = vecDevant * rotmy;
295  mSceneMgr->getSceneNode("Robot")->yaw(Ogre::Radian((Ogre::Real)(-angle)));
296  event = true;
297  }
298  if (mKeyboard->isKeyDown(OIS::KC_D) || mKeyboard->isKeyDown(OIS::KC_RIGHT)) {
299  rotmy = Ogre::Matrix3((Ogre::Real)cos(angle), (Ogre::Real)sin(angle), 0, (Ogre::Real)(-sin(angle)),
300  (Ogre::Real)cos(angle), 0, 0, 0, 1);
301  vecDevant = vecDevant * rotmy;
302  mSceneMgr->getSceneNode("Robot")->yaw(Ogre::Radian((Ogre::Real)angle));
303  event = true;
304  }
305 
306  // Play the right animation
307  if (event) {
308  mAnimationState = robot->getAnimationState("Walk");
309  }
310  else
311  mAnimationState = robot->getAnimationState("Idle");
312 
313  // Start over when finished
314  mAnimationState->setLoop(true);
315  // Animation enabled
316  mAnimationState->setEnabled(true);
317 
318  return true;
319  }
320 #endif
321 };
322 
329 void computeInitialPose(vpCameraParameters *mcam, vpImage<unsigned char> &I, vpPose *mPose, vpDot2 *md,
330  vpImagePoint *mcog, vpHomogeneousMatrix *cMo, vpPoint *mP, const bool &opt_click_allowed)
331 {
332  // ---------------------------------------------------
333  // Code inspired from ViSP example of camera pose
334  // ----------------------------------------------------
335  bool opt_display = true;
336 
337  //#if defined(VISP_HAVE_X11) && ! defined(APPLE)
338 #if defined(VISP_HAVE_X11) && !(defined(__APPLE__) && defined(__MACH__))
339  // produce an error on OSX: ‘typedef int Cursor’
340  // /usr/X11R6/include/X11/X.h:108: error: ‘Cursor’ has a previous
341  // declaration as ‘typedef XID Cursor’. That's why it should not be
342  // used on APPLE platforms
344 #elif defined(VISP_HAVE_GTK)
346 #elif defined(VISP_HAVE_GDI)
348 #elif defined(HAVE_OPENCV_HIGHGUI)
350 #elif defined(VISP_HAVE_D3D9)
352 #endif
353  for (unsigned int i = 0; i < 4; i++) {
354  if (opt_display) {
355  md[i].setGraphics(true);
356  }
357  else {
358  md[i].setGraphics(false);
359  }
360  }
361 
362  if (opt_display) {
363  try {
364  // Display size is automatically defined by the image (I) size
365  display.init(I, 100, 100, "Preliminary Pose Calculation");
366  // display the image
367  // The image class has a member that specify a pointer toward
368  // the display that has been initialized in the display declaration
369  // therefore is is no longer necessary to make a reference to the
370  // display variable.
372  // Flush the display
373  vpDisplay::flush(I);
374 
375  }
376  catch (...) {
377  vpERROR_TRACE("Error while displaying the image");
378  return;
379  }
380  }
381 
382  std::cout << "*************************************************************"
383  "***********************"
384  << std::endl;
385  std::cout << "*************************** Preliminary Pose Calculation "
386  "***************************"
387  << std::endl;
388  std::cout << "****************************** Click on the 4 dots "
389  "*******************************"
390  << std::endl;
391  std::cout << "********Dot1 : (-x,-y,0), Dot2 : (x,-y,0), Dot3 : (x,y,0), "
392  "Dot4 : (-x,y,0)**********"
393  << std::endl;
394  std::cout << "*************************************************************"
395  "***********************"
396  << std::endl;
397 
398  try {
399  vpImagePoint ip[4];
400  if (!opt_click_allowed) {
401  ip[0].set_i(265);
402  ip[0].set_j(93);
403  ip[1].set_i(248);
404  ip[1].set_j(242);
405  ip[2].set_i(166);
406  ip[2].set_j(215);
407  ip[3].set_i(178);
408  ip[3].set_j(85);
409  }
410  for (unsigned int i = 0; i < 4; i++) {
411  // by using setGraphics, we request to see the edges of the dot
412  // in red on the screen.
413  // It uses the overlay image plane.
414  // The default of this setting is that it is time consuming
415 
416  md[i].setGraphics(true);
417  md[i].setGrayLevelPrecision(0.7);
418  md[i].setSizePrecision(0.5);
419 
420  for (unsigned int j = 0; j < i; j++)
421  md[j].display(I);
422 
423  // flush the display buffer
424  vpDisplay::flush(I);
425  try {
426  if (opt_click_allowed)
427  md[i].initTracking(I);
428  else
429  md[i].initTracking(I, ip[i]);
430  }
431  catch (...) {
432  }
433 
434  mcog[i] = md[i].getCog();
435  // an exception is thrown by the track method if
436  // - dot is lost
437  // - the number of pixel is too small
438  // - too many pixels are detected (this is usual when a "big"
439  // specularity
440  // occurs. The threshold can be modified using the
441  // setNbMaxPoint(int) method
442  if (opt_display) {
443  md[i].display(I);
444  // flush the display buffer
445  vpDisplay::flush(I);
446  }
447  }
448  }
449  catch (const vpException &e) {
450  vpERROR_TRACE("Error while tracking dots");
451  vpCTRACE << e;
452  return;
453  }
454 
455  if (opt_display) {
456  // display a red cross (size 10) in the image at the dot center
457  // of gravity location
458  //
459  // WARNING
460  // in the vpDisplay class member's when pixel coordinates
461  // are considered the first element is the row index and the second
462  // is the column index:
463  // vpDisplay::displayCross(Image, row index, column index, size, color)
464  // therefore u and v are inverted wrt to the vpDot specification
465  // Alternatively, to avoid this problem another set of member have
466  // been defined in the vpDisplay class.
467  // If the method name is postfixe with _uv the specification is :
468  // vpDisplay::displayCross_uv(Image, column index, row index, size,
469  // color)
470 
471  for (unsigned int i = 0; i < 4; i++)
472  vpDisplay::displayCross(I, mcog[i], 10, vpColor::red);
473 
474  // flush the X11 buffer
475  vpDisplay::flush(I);
476  }
477 
478  // --------------------------------------------------------
479  // Now we will compute the pose
480  // --------------------------------------------------------
481 
482  // the list of point is cleared (if that's not done before)
483  mPose->clearPoint();
484 
485  // we set the 3D points coordinates (in meter !) in the object/world frame
486  double l = 0.06;
487  double L = 0.07;
488  mP[0].setWorldCoordinates(-L, -l, 0); // (X,Y,Z)
489  mP[1].setWorldCoordinates(L, -l, 0);
490  mP[2].setWorldCoordinates(L, l, 0);
491  mP[3].setWorldCoordinates(-L, l, 0);
492 
493  // pixel-> meter conversion
494  for (unsigned int i = 0; i < 4; i++) {
495  // u[i]. v[i] are expressed in pixel
496  // conversion in meter is achieved using
497  // x = (u-u0)/px
498  // y = (v-v0)/py
499  // where px, py, u0, v0 are the intrinsic camera parameters
500  double x = 0, y = 0;
501  vpPixelMeterConversion::convertPoint(*mcam, mcog[i], x, y);
502  mP[i].set_x(x);
503  mP[i].set_y(y);
504  }
505 
506  // The pose structure is build, we put in the point list the set of point
507  // here both 2D and 3D world coordinates are known
508  for (unsigned int i = 0; i < 4; i++) {
509  mPose->addPoint(mP[i]); // and added to the pose computation point list
510  }
511 
512  // compute the initial pose using Dementhon method followed by a non linear
513  // minimization method
514 
515  // Compute initial pose
517 
518  // Display briefly just to have a glimpse a the ViSP pose
519  if (opt_display) {
520  // Display the computed pose
521  mPose->display(I, *cMo, *mcam, 0.05, vpColor::red);
522  vpDisplay::flush(I);
523  vpTime::wait(800);
524  }
525 }
526 
527 #endif
528 
529 int main(int argc, const char **argv)
530 {
531 #if VISP_HAVE_DATASET_VERSION >= 0x030600
532  std::string ext("png");
533 #else
534  std::string ext("pgm");
535 #endif
536  try {
537  std::string env_ipath;
538  std::string opt_ipath;
539  std::string ipath;
540  std::string opt_ppath;
541  std::string dirname;
542  std::string filename;
543  bool opt_click_allowed = true;
544 
545  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
546  // environment variable value
547  env_ipath = vpIoTools::getViSPImagesDataPath();
548 
549  // Set the default input path
550  if (!env_ipath.empty())
551  ipath = env_ipath;
552 
553  // Read the command line options
554  if (getOptions(argc, argv, opt_ipath, opt_ppath, opt_click_allowed) == false) {
555  return EXIT_FAILURE;
556  }
557 
558  // Get the option values
559  if (!opt_ipath.empty())
560  ipath = opt_ipath;
561 
562  // Compare ipath and env_ipath. If they differ, we take into account
563  // the input path coming from the command line option
564  if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
565  if (ipath != env_ipath) {
566  std::cout << std::endl << "WARNING: " << std::endl;
567  std::cout << " Since -i <visp image path=" << ipath << "> "
568  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
569  << " we skip the environment variable." << std::endl;
570  }
571  }
572 
573  // Test if an input path is set
574  if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty()) {
575  usage(argv[0], nullptr, ipath, opt_ppath);
576  std::cerr << std::endl << "ERROR:" << std::endl;
577  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
578  << " environment variable to specify the location of the " << std::endl
579  << " image path where test images are located." << std::endl
580  << " Use -p <personal image path> option if you want to " << std::endl
581  << " use personal images." << std::endl
582  << std::endl;
583 
584  return EXIT_FAILURE;
585  }
586 
587  std::ostringstream s;
588 
589  if (opt_ppath.empty()) {
590  // Set the path location of the image sequence
591  dirname = vpIoTools::createFilePath(ipath, "mire-2");
592 
593  // Build the name of the image file
594 
595  s.setf(std::ios::right, std::ios::adjustfield);
596  s << "image.%04d.";
597  s << ext;
598  filename = vpIoTools::createFilePath(dirname, s.str());
599  }
600  else {
601  filename = opt_ppath;
602  }
603 
604  // We will read a sequence of images
605  vpVideoReader grabber;
606  grabber.setFirstFrameIndex(1);
607  grabber.setFileName(filename.c_str());
608  // Grey level image associated to a display in the initial pose
609  // computation
610  vpImage<unsigned char> Idisplay;
611  // Grey level image to track points
613  // RGBa image to get background
614  vpImage<vpRGBa> IC;
615  // Matrix representing camera parameters
617 
618  // Variables used for pose computation purposes
619  vpPose mPose;
620  vpDot2 md[4];
621  vpImagePoint mcog[4];
622  vpPoint mP[4];
623 
624  // CameraParameters we got from calibration
625  // Keep u0 and v0 as center of the screen
626  vpCameraParameters mcam;
627 
628  try {
629  vpCTRACE << "Load: " << filename << std::endl;
630  grabber.open(Idisplay);
631  grabber.acquire(Idisplay);
632  vpCameraParameters mcamTmp(592, 570, grabber.getWidth() / 2, grabber.getHeight() / 2);
633  // Compute the initial pose of the camera
634  computeInitialPose(&mcamTmp, Idisplay, &mPose, md, mcog, &cMo, mP, opt_click_allowed);
635  // Close the framegrabber
636  grabber.close();
637 
638  // Associate the grabber to the RGBa image
639  grabber.open(IC);
640  mcam.init(mcamTmp);
641  }
642  catch (...) {
643  std::cerr << std::endl << "ERROR:" << std::endl;
644  std::cerr << " Cannot read " << filename << std::endl;
645  std::cerr << " Check your -i " << ipath << " option " << std::endl
646  << " or VISP_INPUT_IMAGE_PATH environment variable." << std::endl;
647  return EXIT_FAILURE;
648  }
649 
650  // Create a vpRAOgre object with color background
651  vpAROgreExample ogre(mcam, (unsigned int)grabber.getWidth(), (unsigned int)grabber.getHeight());
652  // Initialize it
653  ogre.init(IC);
654 
655  double t0 = vpTime::measureTimeMs();
656 
657  // Rendering loop
658  while (ogre.continueRendering() && !grabber.end()) {
659  // Acquire a frame
660  grabber.acquire(IC);
661 
662  // Convert it to a grey level image for tracking purpose
664 
665  // kill the point list
666  mPose.clearPoint();
667 
668  // track the dot
669  for (int i = 0; i < 4; i++) {
670  // track the point
671  md[i].track(I, mcog[i]);
672  md[i].setGrayLevelPrecision(0.90);
673  // pixel->meter conversion
674  {
675  double x = 0, y = 0;
676  vpPixelMeterConversion::convertPoint(mcam, mcog[i], x, y);
677  mP[i].set_x(x);
678  mP[i].set_y(y);
679  }
680 
681  // and added to the pose computation point list
682  mPose.addPoint(mP[i]);
683  }
684  // the pose structure has been updated
685 
686  // the pose is now updated using the virtual visual servoing approach
687  // Dementhon or lagrange is no longer necessary, pose at the
688  // previous iteration is sufficient
689  mPose.computePose(vpPose::VIRTUAL_VS, cMo);
690 
691  // Display with ogre
692  ogre.display(IC, cMo);
693 
694  // Wait so that the video does not go too fast
695  double t1 = vpTime::measureTimeMs();
696  std::cout << "\r> " << 1000 / (t1 - t0) << " fps";
697  t0 = t1;
698  }
699  // Close the grabber
700  grabber.close();
701 
702  return EXIT_SUCCESS;
703  }
704  catch (const vpException &e) {
705  std::cout << "Catch a ViSP exception: " << e << std::endl;
706  return EXIT_FAILURE;
707  }
708  catch (Ogre::Exception &e) {
709  std::cout << "Catch an Ogre exception: " << e.getDescription() << std::endl;
710  return EXIT_FAILURE;
711  }
712  catch (...) {
713  std::cout << "Catch an exception " << std::endl;
714  return EXIT_FAILURE;
715  }
716 }
717 #else // VISP_HAVE_OGRE && VISP_HAVE_DISPLAY
718 int main()
719 {
720 #if (!(defined(VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI)))
721  std::cout << "You do not have X11, or GTK, or GDI (Graphical Device Interface) functionalities to display images..."
722  << std::endl;
723  std::cout << "Tip if you are on a unix-like system:" << std::endl;
724  std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
725  std::cout << "Tip if you are on a windows-like system:" << std::endl;
726  std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
727 #else
728  std::cout << "You do not have Ogre functionalities" << std::endl;
729  std::cout << "Tip:" << std::endl;
730  std::cout << "- Install Ogre3D, configure again ViSP using cmake and build again this example" << std::endl;
731 #endif
732  return EXIT_SUCCESS;
733 }
734 #endif
Implementation of an augmented reality viewer using Ogre3D 3rd party.
Definition: vpAROgre.h:96
virtual bool customframeEnded(const Ogre::FrameEvent &evt)
Definition: vpAROgre.cpp:564
virtual bool processInputEvent(const Ogre::FrameEvent &)
Definition: vpAROgre.h:315
virtual void createScene(void)
Definition: vpAROgre.h:299
Generic class defining intrinsic camera parameters.
void init()
Basic initialization with the default parameters.
static const vpColor red
Definition: vpColor.h:211
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:101
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:128
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:128
static void display(const vpImage< unsigned char > &I)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
This tracker is meant to track a blob (connex pixels with same gray level) on a vpImage.
Definition: vpDot2.h:124
void track(const vpImage< unsigned char > &I, bool canMakeTheWindowGrow=true)
Definition: vpDot2.cpp:435
void setGraphics(bool activate)
Definition: vpDot2.h:310
void display(const vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1) const
Definition: vpDot2.cpp:212
void setSizePrecision(const double &sizePrecision)
Definition: vpDot2.cpp:747
void setGrayLevelPrecision(const double &grayLevelPrecision)
Definition: vpDot2.cpp:717
vpImagePoint getCog() const
Definition: vpDot2.h:176
void initTracking(const vpImage< unsigned char > &I, unsigned int size=0)
Definition: vpDot2.cpp:254
error that can be emitted by ViSP classes.
Definition: vpException.h:59
unsigned int getWidth() const
Return the number of columns in the image.
unsigned int getHeight() const
Return the number of rows in the image.
Implementation of an homogeneous matrix and operations on such kind of matrices.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
void set_j(double jj)
Definition: vpImagePoint.h:304
void set_i(double ii)
Definition: vpImagePoint.h:293
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1832
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:2195
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:77
void set_x(double x)
Set the point x coordinate in the image plane.
Definition: vpPoint.cpp:504
void setWorldCoordinates(double oX, double oY, double oZ)
Definition: vpPoint.cpp:110
void set_y(double y)
Set the point y coordinate in the image plane.
Definition: vpPoint.cpp:506
Class used for pose computation from N points (pose from point only). Some of the algorithms implemen...
Definition: vpPose.h:78
void addPoint(const vpPoint &P)
Definition: vpPose.cpp:93
@ DEMENTHON_LAGRANGE_VIRTUAL_VS
Definition: vpPose.h:99
@ VIRTUAL_VS
Definition: vpPose.h:93
void clearPoint()
Definition: vpPose.cpp:86
static void display(vpImage< unsigned char > &I, vpHomogeneousMatrix &cMo, vpCameraParameters &cam, double size, vpColor col=vpColor::none)
Definition: vpPose.cpp:558
bool computePose(vpPoseMethodType method, vpHomogeneousMatrix &cMo, bool(*func)(const vpHomogeneousMatrix &)=nullptr)
Definition: vpPose.cpp:340
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 open(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
void setFirstFrameIndex(const long first_frame)
#define vpCTRACE
Definition: vpDebug.h:329
#define vpERROR_TRACE
Definition: vpDebug.h:382
void display(vpImage< unsigned char > &I, const std::string &title)
Display a gray-scale image.
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMs()