#include <iostream>
#include <visp3/core/vpConfig.h>
#if defined(VISP_HAVE_REALSENSE2) && defined(VISP_HAVE_OPENCV) && defined(VISP_HAVE_PUGIXML)
#include <visp3/core/vpDisplay.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
#include <visp3/mbt/vpMbGenericTracker.h>
#include <visp3/sensor/vpRealSense2.h>
#include <visp3/vision/vpKeyPoint.h>
int main(int argc, char *argv[])
{
#ifdef ENABLE_VISP_NAMESPACE
#endif
std::string config_color = "", config_depth = "";
std::string model_color = "", model_depth = "";
std::string init_file = "";
bool use_ogre = false;
bool use_scanline = false;
bool use_edges = true;
bool use_klt = true;
bool use_depth = true;
bool learn = false;
bool auto_init = false;
double proj_error_threshold = 25;
std::string learning_data = "learning/data-learned.bin";
bool display_projection_error = false;
for (int i = 1; i < argc; i++) {
if (std::string(argv[i]) == "--config_color" && i + 1 < argc) {
config_color = std::string(argv[i + 1]);
}
else if (std::string(argv[i]) == "--config_depth" && i + 1 < argc) {
config_depth = std::string(argv[i + 1]);
}
else if (std::string(argv[i]) == "--model_color" && i + 1 < argc) {
model_color = std::string(argv[i + 1]);
}
else if (std::string(argv[i]) == "--model_depth" && i + 1 < argc) {
model_depth = std::string(argv[i + 1]);
}
else if (std::string(argv[i]) == "--init_file" && i + 1 < argc) {
init_file = std::string(argv[i + 1]);
}
else if (std::string(argv[i]) == "--proj_error_threshold" && i + 1 < argc) {
proj_error_threshold = std::atof(argv[i + 1]);
}
else if (std::string(argv[i]) == "--use_ogre") {
use_ogre = true;
}
else if (std::string(argv[i]) == "--use_scanline") {
use_scanline = true;
}
else if (std::string(argv[i]) == "--use_edges" && i + 1 < argc) {
use_edges = (std::atoi(argv[i + 1]) == 0 ? false : true);
}
else if (std::string(argv[i]) == "--use_klt" && i + 1 < argc) {
use_klt = (std::atoi(argv[i + 1]) == 0 ? false : true);
}
else if (std::string(argv[i]) == "--use_depth" && i + 1 < argc) {
use_depth = (std::atoi(argv[i + 1]) == 0 ? false : true);
}
else if (std::string(argv[i]) == "--learn") {
learn = true;
}
else if (std::string(argv[i]) == "--learning_data" && i + 1 < argc) {
learning_data = argv[i + 1];
}
else if (std::string(argv[i]) == "--auto_init") {
auto_init = true;
}
else if (std::string(argv[i]) == "--display_proj_error") {
display_projection_error = true;
}
else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
std::cout << "Usage: \n"
<< argv[0]
<< " [--model_color <object.cao>] [--model_depth <object.cao>]"
" [--config_color <object.xml>] [--config_depth <object.xml>]"
" [--init_file <object.init>] [--use_ogre] [--use_scanline]"
" [--proj_error_threshold <threshold between 0 and 90> (default: "
<< proj_error_threshold
<< ")]"
" [--use_edges <0|1> (default: 1)] [--use_klt <0|1> (default: 1)] [--use_depth <0|1> (default: 1)]"
" [--learn] [--auto_init] [--learning_data <path to .bin> (default: learning/data-learned.bin)]"
" [--display_proj_error]"
<< std::endl;
std::cout << "\n** How to track a 4.2 cm width cube with manual initialization:\n"
<< argv[0] << " --model_color model/cube/cube.cao --use_edges 1 --use_klt 1 --use_depth 1" << std::endl;
std::cout << "\n** How to learn the cube and create a learning database:\n"
<< argv[0] << " --model_color model/cube/cube.cao --use_edges 1 --use_klt 1 --use_depth 1 --learn"
<< std::endl;
std::cout << "\n** How to track the cube with initialization from learning database:\n"
<< argv[0] << " --model_color model/cube/cube.cao --use_edges 1 --use_klt 1 --use_depth 1 --auto_init"
<< std::endl;
return EXIT_SUCCESS;
}
}
if (model_depth.empty()) {
model_depth = model_color;
}
if (config_color.empty()) {
config_color = (parentname.empty() ?
"" : (parentname +
"/")) +
vpIoTools::getNameWE(model_color) +
".xml";
}
if (config_depth.empty()) {
config_depth = (parentname.empty() ?
"" : (parentname +
"/")) +
vpIoTools::getNameWE(model_color) +
"_depth.xml";
}
if (init_file.empty()) {
init_file = (parentname.empty() ?
"" : (parentname +
"/")) +
vpIoTools::getNameWE(model_color) +
".init";
}
std::cout << "Tracked features: " << std::endl;
std::cout << " Use edges : " << use_edges << std::endl;
std::cout << " Use klt : " << use_klt << std::endl;
std::cout << " Use depth : " << use_depth << std::endl;
std::cout << "Tracker options: " << std::endl;
std::cout << " Use ogre : " << use_ogre << std::endl;
std::cout << " Use scanline: " << use_scanline << std::endl;
std::cout << " Proj. error : " << proj_error_threshold << std::endl;
std::cout << " Display proj. error: " << display_projection_error << std::endl;
std::cout << "Config files: " << std::endl;
std::cout << " Config color: "
<< "\"" << config_color << "\"" << std::endl;
std::cout << " Config depth: "
<< "\"" << config_depth << "\"" << std::endl;
std::cout << " Model color : "
<< "\"" << model_color << "\"" << std::endl;
std::cout << " Model depth : "
<< "\"" << model_depth << "\"" << std::endl;
std::cout << " Init file : "
<< "\"" << init_file << "\"" << std::endl;
std::cout << "Learning options : " << std::endl;
std::cout << " Learn : " << learn << std::endl;
std::cout << " Auto init : " << auto_init << std::endl;
std::cout << " Learning data: " << learning_data << std::endl;
if (!use_edges && !use_klt && !use_depth) {
std::cout << "You must choose at least one visual features between edge, KLT and depth." << std::endl;
return EXIT_FAILURE;
}
if (config_color.empty() || config_depth.empty() || model_color.empty() || model_depth.empty() || init_file.empty()) {
std::cout << "config_color.empty() || config_depth.empty() || model_color.empty() || model_depth.empty() || "
"init_file.empty()"
<< std::endl;
return EXIT_FAILURE;
}
int width = 640, height = 480;
int fps = 30;
rs2::config config;
config.enable_stream(RS2_STREAM_COLOR, width, height, RS2_FORMAT_RGBA8, fps);
config.enable_stream(RS2_STREAM_DEPTH, width, height, RS2_FORMAT_Z16, fps);
try {
}
std::cout <<
"Catch an exception: " << e.
what() << std::endl;
std::cout << "Check if the Realsense camera is connected..." << std::endl;
return EXIT_SUCCESS;
}
std::cout << "Sensor internal camera parameters for color camera: " << cam_color << std::endl;
std::cout << "Sensor internal camera parameters for depth camera: " << cam_depth << std::endl;
unsigned int _posx = 100, _posy = 50;
#ifdef VISP_HAVE_X11
vpDisplayX d1, d2;
#elif defined(VISP_HAVE_GDI)
#elif defined(HAVE_OPENCV_HIGHGUI)
#endif
if (use_edges || use_klt)
d1.
init(I_gray, _posx, _posy,
"Color stream");
if (use_depth)
d2.init(I_depth, _posx + I_gray.
getWidth() + 10, _posy,
"Depth stream");
while (true) {
realsense.
acquire((
unsigned char *)I_color.
bitmap, (
unsigned char *)I_depth_raw.
bitmap,
nullptr,
nullptr);
if (use_edges || use_klt) {
break;
}
}
if (use_depth) {
break;
}
}
}
std::vector<int> trackerTypes;
if (use_edges && use_klt)
else if (use_edges)
else if (use_klt)
trackerTypes.push_back(vpMbGenericTracker::KLT_TRACKER);
if (use_depth)
std::map<std::string, vpHomogeneousMatrix> mapOfCameraTransformations;
std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
std::map<std::string, std::string> mapOfInitFiles;
std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
std::map<std::string, vpHomogeneousMatrix> mapOfCameraPoses;
std::vector<vpColVector> pointcloud;
if ((use_edges || use_klt) && use_depth) {
std::cout << "Sensor internal depth_M_color: \n" << depth_M_color << std::endl;
mapOfCameraTransformations["Camera2"] = depth_M_color;
mapOfImages["Camera1"] = &I_gray;
mapOfImages["Camera2"] = &I_depth;
mapOfInitFiles["Camera1"] = init_file;
}
else if (use_edges || use_klt) {
}
else if (use_depth) {
}
#if (defined(VISP_HAVE_OPENCV_NONFREE) || defined(VISP_HAVE_OPENCV_XFEATURES2D)) || \
(VISP_HAVE_OPENCV_VERSION >= 0x030411 && CV_MAJOR_VERSION < 4) || (VISP_HAVE_OPENCV_VERSION >= 0x040400)
std::string detectorName = "SIFT";
std::string extractorName = "SIFT";
std::string matcherName = "BruteForce";
#else
std::string detectorName = "FAST";
std::string extractorName = "ORB";
std::string matcherName = "BruteForce-Hamming";
#endif
if (learn || auto_init) {
#if !(defined(VISP_HAVE_OPENCV_NONFREE) || defined(VISP_HAVE_OPENCV_XFEATURES2D))
#if (VISP_HAVE_OPENCV_VERSION < 0x030000)
keypoint.setDetectorParameter("ORB", "nLevels", 1);
#else
cv::Ptr<cv::ORB> orb_detector = keypoint.
getDetector(
"ORB").dynamicCast<cv::ORB>();
if (orb_detector) {
orb_detector->setNLevels(1);
}
#endif
#endif
}
if (auto_init) {
std::cout << "Cannot enable auto detection. Learning file \"" << learning_data << "\" doesn't exist" << std::endl;
return EXIT_FAILURE;
}
}
else {
if ((use_edges || use_klt) && use_depth)
tracker.initClick(mapOfImages, mapOfInitFiles, true);
else if (use_edges || use_klt)
tracker.initClick(I_gray, init_file, true);
else if (use_depth)
tracker.initClick(I_depth, init_file, true);
if (learn)
}
bool run_auto_init = false;
if (auto_init) {
run_auto_init = true;
}
std::vector<double> times_vec;
try {
int learn_id = 1;
bool quit = false;
bool learn_position = false;
double loop_t = 0;
while (!quit) {
bool tracking_failed = false;
realsense.
acquire((
unsigned char *)I_color.
bitmap, (
unsigned char *)I_depth_raw.
bitmap, &pointcloud,
nullptr,
nullptr);
if (use_edges || use_klt || run_auto_init) {
}
if (use_depth) {
}
if ((use_edges || use_klt) && use_depth) {
mapOfImages["Camera1"] = &I_gray;
mapOfPointclouds["Camera2"] = &pointcloud;
mapOfWidths["Camera2"] = width;
mapOfHeights["Camera2"] = height;
}
else if (use_edges || use_klt) {
mapOfImages["Camera"] = &I_gray;
}
else if (use_depth) {
mapOfPointclouds["Camera"] = &pointcloud;
mapOfWidths["Camera"] = width;
mapOfHeights["Camera"] = height;
}
if (run_auto_init) {
if (keypoint.
matchPoint(I_gray, cam_color, cMo)) {
std::cout << "Auto init succeed" << std::endl;
if ((use_edges || use_klt) && use_depth) {
mapOfCameraPoses["Camera1"] = cMo;
mapOfCameraPoses["Camera2"] = depth_M_color * cMo;
}
else if (use_edges || use_klt) {
}
else if (use_depth) {
}
}
else {
if (use_edges || use_klt) {
}
if (use_depth) {
}
continue;
}
}
try {
if (run_auto_init) {
run_auto_init = false;
}
if ((use_edges || use_klt) && use_depth) {
tracker.
track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
}
else if (use_edges || use_klt) {
}
else if (use_depth) {
tracker.
track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
}
}
tracking_failed = true;
if (auto_init) {
std::cout << "Tracker needs to restart (tracking exception)" << std::endl;
run_auto_init = true;
}
}
double proj_error = 0;
}
else {
}
if (auto_init && proj_error > proj_error_threshold) {
std::cout << "Tracker needs to restart (projection error detected: " << proj_error << ")" << std::endl;
run_auto_init = true;
tracking_failed = true;
}
if (!tracking_failed) {
if ((use_edges || use_klt) && use_depth) {
tracker.
display(I_gray, I_depth, cMo, depth_M_color * cMo, cam_color, cam_depth,
vpColor::red, 3);
}
else if (use_edges || use_klt) {
}
else if (use_depth) {
}
{
std::stringstream ss;
}
{
std::stringstream ss;
}
}
std::stringstream ss;
ss << "Loop time: " << loop_t << " ms";
if (use_edges || use_klt) {
if (learn)
else if (auto_init)
else
quit = true;
}
learn_position = true;
}
run_auto_init = true;
}
}
}
if (use_depth) {
quit = true;
}
}
if (learn_position) {
std::vector<cv::KeyPoint> trainKeyPoints;
keypoint.
detect(I_gray, trainKeyPoints);
std::vector<vpPolygon> polygons;
std::vector<std::vector<vpPoint> > roisPt;
std::pair<std::vector<vpPolygon>, std::vector<std::vector<vpPoint> > > pair = tracker.
getPolygonFaces();
polygons = pair.first;
roisPt = pair.second;
std::vector<cv::Point3f> points3f;
keypoint.
buildReference(I_gray, trainKeyPoints, points3f,
true, learn_id++);
for (std::vector<cv::KeyPoint>::const_iterator it = trainKeyPoints.begin(); it != trainKeyPoints.end(); ++it) {
}
learn_position = false;
std::cout << "Data learned" << std::endl;
}
times_vec.push_back(loop_t);
}
if (learn) {
std::cout << "Save learning file: " << learning_data << std::endl;
}
}
std::cout <<
"Catch an exception: " << e.
what() << std::endl;
}
if (!times_vec.empty()) {
<< std::endl;
}
return EXIT_SUCCESS;
}
#elif defined(VISP_HAVE_REALSENSE2)
int main()
{
std::cout << "Install OpenCV 3rd party, configure and build ViSP again to use this example" << std::endl;
return EXIT_SUCCESS;
}
#else
int main()
{
std::cout << "Install librealsense2 3rd party, configure and build ViSP again to use this example" << std::endl;
return EXIT_SUCCESS;
}
#endif
unsigned int size() const
Return the number of elements of the 2D array.
Generic class defining intrinsic camera parameters.
@ perspectiveProjWithoutDistortion
Perspective projection without distortion model.
static const vpColor none
static const vpColor yellow
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="") VP_OVERRIDE
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1, const vpImagePoint &offset=vpImagePoint(0, 0), const std::string &frameName="", const vpColor &textColor=vpColor::black, const vpImagePoint &textOffset=vpImagePoint(15, 15))
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)
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.
const std::string & getStringMessage() const
const char * what() const
Implementation of an homogeneous matrix and operations on such kind of matrices.
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
unsigned int getWidth() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
Class that allows keypoints detection (and descriptors extraction) and matching thanks to OpenCV libr...
unsigned int matchPoint(const vpImage< unsigned char > &I)
void setExtractor(const vpFeatureDescriptorType &extractorType)
void loadLearningData(const std::string &filename, bool binaryMode=false, bool append=false)
void detect(const vpImage< unsigned char > &I, std::vector< cv::KeyPoint > &keyPoints, const vpRect &rectangle=vpRect())
static void compute3DForPointsInPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, std::vector< cv::KeyPoint > &candidates, const std::vector< vpPolygon > &polygons, const std::vector< std::vector< vpPoint > > &roisPt, std::vector< cv::Point3f > &points, cv::Mat *descriptors=nullptr)
void setMatcher(const std::string &matcherName)
void saveLearningData(const std::string &filename, bool binaryMode=false, bool saveTrainingImages=true)
void setDetector(const vpFeatureDetectorType &detectorType)
unsigned int buildReference(const vpImage< unsigned char > &I)
cv::Ptr< cv::FeatureDetector > getDetector(const vpFeatureDetectorType &type) const
static double getMedian(const std::vector< double > &v)
static double getStdev(const std::vector< double > &v, bool useBesselCorrection=false)
static double getMean(const std::vector< double > &v)
Real-time 6D object pose tracking using its CAD model.
virtual void setCameraParameters(const vpCameraParameters &camera) VP_OVERRIDE
virtual int getTrackerType() const
virtual void setOgreVisibilityTest(const bool &v) VP_OVERRIDE
virtual std::pair< std::vector< vpPolygon >, std::vector< std::vector< vpPoint > > > getPolygonFaces(bool orderPolygons=true, bool useVisibility=true, bool clipPolygon=false) VP_OVERRIDE
virtual void setProjectionErrorComputation(const bool &flag) VP_OVERRIDE
virtual void setDisplayFeatures(bool displayF) VP_OVERRIDE
virtual vpColVector getError() const VP_OVERRIDE
virtual unsigned int getNbFeaturesEdge() const
virtual double computeCurrentProjectionError(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo, const vpCameraParameters &_cam) VP_OVERRIDE
virtual void initFromPose(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo) VP_OVERRIDE
virtual void getPose(vpHomogeneousMatrix &cMo) const VP_OVERRIDE
virtual unsigned int getNbFeaturesKlt() const
virtual void track(const vpImage< unsigned char > &I) VP_OVERRIDE
virtual unsigned int getNbFeaturesDepthDense() const
virtual void loadModel(const std::string &modelFile, bool verbose=false, const vpHomogeneousMatrix &T=vpHomogeneousMatrix()) VP_OVERRIDE
virtual void setScanLineVisibilityTest(const bool &v) VP_OVERRIDE
virtual void setCameraTransformationMatrix(const std::string &cameraName, const vpHomogeneousMatrix &cameraTransformationMatrix)
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false) VP_OVERRIDE
virtual void loadConfigFile(const std::string &configFile, bool verbose=true) VP_OVERRIDE
virtual void setProjectionErrorDisplay(bool display) VP_OVERRIDE
virtual double getProjectionError() const
vpCameraParameters getCameraParameters(const rs2_stream &stream, vpCameraParameters::vpCameraParametersProjType type=vpCameraParameters::perspectiveProjWithDistortion, int index=-1) const
void acquire(vpImage< unsigned char > &grey, double *ts=nullptr)
bool open(const rs2::config &cfg=rs2::config())
vpHomogeneousMatrix getTransformation(const rs2_stream &from, const rs2_stream &to, int from_index=-1) const
VISP_EXPORT double measureTimeMs()