4 #include <visp3/core/vpConfig.h>
6 #if defined(VISP_HAVE_REALSENSE2) && defined(VISP_HAVE_OPENCV) && defined(VISP_HAVE_NLOHMANN_JSON)
7 #include <visp3/core/vpDisplay.h>
8 #include <visp3/core/vpIoTools.h>
9 #include <visp3/gui/vpDisplayFactory.h>
10 #include <visp3/mbt/vpMbGenericTracker.h>
11 #include <visp3/sensor/vpRealSense2.h>
13 #include VISP_NLOHMANN_JSON(json.hpp)
14 using json = nlohmann::json;
17 int main(
int argc,
char *argv[])
19 #ifdef ENABLE_VISP_NAMESPACE
23 std::string config_file =
"";
24 std::string model =
"";
25 std::string init_file =
"";
27 double proj_error_threshold = 25;
29 for (
int i = 1; i < argc; i++) {
30 if (std::string(argv[i]) ==
"--config" && i + 1 < argc) {
31 config_file = std::string(argv[i + 1]);
33 else if (std::string(argv[i]) ==
"--model" && i + 1 < argc) {
34 model = std::string(argv[i + 1]);
36 else if (std::string(argv[i]) ==
"--init_file" && i + 1 < argc) {
37 init_file = std::string(argv[i + 1]);
39 else if (std::string(argv[i]) ==
"--proj_error_threshold" && i + 1 < argc) {
40 proj_error_threshold = std::atof(argv[i + 1]);
42 else if (std::string(argv[i]) ==
"--help" || std::string(argv[i]) ==
"-h") {
43 std::cout <<
"Usage: \n"
45 <<
"--config <settings.json>"
46 <<
" --model <object.cao>"
47 " --init_file <object.init>"
48 " [--proj_error_threshold <threshold between 0 and 90> (default: "
49 << proj_error_threshold
53 std::cout <<
"\n** How to track a 4.2 cm width cube with manual initialization:\n"
54 << argv[0] <<
"--config model/cube/rgbd-tracker.json --model model/cube/cube.cao" << std::endl;
59 std::cout <<
"Config files: " << std::endl;
60 std::cout <<
" JSON config: "
61 <<
"\"" << config_file <<
"\"" << std::endl;
62 std::cout <<
" Model: "
63 <<
"\"" << model <<
"\"" << std::endl;
64 std::cout <<
" Init file: "
65 <<
"\"" << init_file <<
"\"" << std::endl;
67 if (config_file.empty()) {
68 std::cout <<
"No JSON configuration was provided!" << std::endl;
73 int width = 640, height = 480;
76 config.enable_stream(RS2_STREAM_COLOR, width, height, RS2_FORMAT_RGBA8, fps);
77 config.enable_stream(RS2_STREAM_DEPTH, width, height, RS2_FORMAT_Z16, fps);
80 realsense.
open(config);
83 std::cout <<
"Catch an exception: " << e.
what() << std::endl;
84 std::cout <<
"Check if the Realsense camera is connected..." << std::endl;
93 std::cout <<
"Sensor internal camera parameters for color camera: " << cam_color << std::endl;
94 std::cout <<
"Sensor internal camera parameters for depth camera: " << cam_depth << std::endl;
100 std::vector<vpColVector> pointcloud;
104 std::map<std::string, vpHomogeneousMatrix> mapOfCameraTransformations;
105 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
106 std::map<std::string, std::string> mapOfInitFiles;
107 std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
108 std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
109 std::map<std::string, vpCameraParameters> mapOfCameraIntrinsics;
115 if (model.empty() && init_file.empty()) {
116 std::ifstream config(config_file);
117 const json j = json::parse(config);
119 if (j.contains(
"model")) {
123 std::cerr <<
"No model was provided in either JSON file or arguments" << std::endl;
127 if (init_file.empty()) {
129 init_file = (parentname.empty() ?
"" : (parentname +
"/")) +
vpIoTools::getNameWE(model) +
".init";
133 std::string color_key =
"", depth_key =
"";
135 std::cout <<
"tracker key == " << tracker_type.first << std::endl;
138 color_key = tracker_type.first;
139 mapOfImages[color_key] = &I_gray;
140 mapOfInitFiles[color_key] = init_file;
141 mapOfWidths[color_key] = width;
142 mapOfHeights[color_key] = height;
143 mapOfCameraIntrinsics[color_key] = cam_color;
147 depth_key = tracker_type.first;
148 mapOfImages[depth_key] = &I_depth;
149 mapOfWidths[depth_key] = width;
150 mapOfHeights[depth_key] = height;
151 mapOfCameraIntrinsics[depth_key] = cam_depth;
152 mapOfCameraTransformations[depth_key] = depth_M_color;
153 mapOfPointclouds[depth_key] = &pointcloud;
156 const bool use_depth = !depth_key.empty();
157 const bool use_color = !color_key.empty();
166 std::cout <<
"Updating configuration with parameters provided by RealSense SDK..." << std::endl;
168 if (use_color && use_depth) {
172 unsigned int _posx = 100, _posy = 50;
174 #if defined(VISP_HAVE_DISPLAY)
175 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
183 display1->init(I_gray, _posx, _posy,
"Color stream");
185 display2->init(I_depth, _posx + I_gray.getWidth() + 10, _posy,
"Depth stream");
189 realsense.
acquire((
unsigned char *)I_color.bitmap, (
unsigned char *)I_depth_raw.bitmap,
nullptr,
nullptr);
216 tracker.initClick(mapOfImages, mapOfInitFiles,
true);
219 std::vector<double> times_vec;
227 bool tracking_failed =
false;
230 realsense.
acquire((
unsigned char *)I_color.bitmap, (
unsigned char *)I_depth_raw.bitmap, &pointcloud,
nullptr,
nullptr);
241 if (use_color && use_depth) {
242 mapOfImages[color_key] = &I_gray;
243 mapOfPointclouds[depth_key] = &pointcloud;
244 mapOfWidths[depth_key] = width;
245 mapOfHeights[depth_key] = height;
247 else if (use_color) {
248 mapOfImages[color_key] = &I_gray;
250 else if (use_depth) {
251 mapOfPointclouds[depth_key] = &pointcloud;
256 if (use_color && use_depth) {
257 tracker.
track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
259 else if (use_color) {
260 tracker.
track(I_gray);
262 else if (use_depth) {
263 tracker.
track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
268 tracking_failed =
true;
275 double proj_error = 0;
284 if (proj_error > proj_error_threshold) {
285 std::cout <<
"Tracker needs to restart (projection error detected: " << proj_error <<
")" << std::endl;
289 if (!tracking_failed) {
293 if (use_color && use_depth) {
294 tracker.
display(I_gray, I_depth, cMo, depth_M_color * cMo, cam_color, cam_depth,
vpColor::red, 3);
298 else if (use_color) {
302 else if (use_depth) {
308 std::stringstream ss;
313 std::stringstream ss;
320 std::stringstream ss;
322 times_vec.push_back(loop_t);
323 ss <<
"Loop time: " << loop_t <<
" ms";
351 std::cout <<
"Caught an exception: " << e.
what() << std::endl;
354 if (!times_vec.empty()) {
361 #if defined(VISP_HAVE_DISPLAY) && (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
362 if (display !=
nullptr) {
368 #elif defined(VISP_HAVE_REALSENSE2) && defined(VISP_HAVE_OPENCV)
371 std::cout <<
"Install the JSON 3rd party library (Nlohmann JSON), reconfigure VISP and build again" << std::endl;
374 #elif defined(VISP_HAVE_REALSENSE2) && defined(VISP_HAVE_NLOHMANN_JSON)
377 std::cout <<
"Install OpenCV, reconfigure VISP and build again" << std::endl;
383 std::cout <<
"Install librealsense2 3rd party, configure and build ViSP again to use this example" << std::endl;
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
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 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 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)
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 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 getPose(vpHomogeneousMatrix &cMo) const VP_OVERRIDE
virtual std::map< std::string, int > getCameraTrackerTypes() const
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 unsigned int getNbFeaturesDepthNormal() const
virtual unsigned int getNbPolygon() const 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 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
std::shared_ptr< vpDisplay > createDisplay()
Return a smart pointer vpDisplay specialization if a GUI library is available or nullptr otherwise.
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.
VISP_EXPORT double measureTimeMs()