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)
14using json = nlohmann::json;
17int 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;
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;
113 tracker.loadConfigFile(config_file);
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")) {
122 else if (
j.at(
"trackers").begin()->contains(
"model")) {
123 model = (*
j[
"trackers"].begin())[
"model"];
126 std::cerr <<
"No model was provided in either JSON file or arguments" << std::endl;
130 if (init_file.empty()) {
132 init_file = (parentname.empty() ?
"" : (parentname +
"/")) +
vpIoTools::getNameWE(model) +
".init";
136 std::string color_key =
"", depth_key =
"";
137 for (
const auto &tracker_type :
tracker.getCameraTrackerTypes()) {
138 std::cout <<
"tracker key == " << tracker_type.first << std::endl;
141 color_key = tracker_type.first;
142 mapOfImages[color_key] = &I_gray;
143 mapOfInitFiles[color_key] = init_file;
144 mapOfWidths[color_key] =
width;
145 mapOfHeights[color_key] =
height;
146 mapOfCameraIntrinsics[color_key] =
cam_color;
150 depth_key = tracker_type.first;
151 mapOfImages[depth_key] = &
I_depth;
152 mapOfWidths[depth_key] =
width;
153 mapOfHeights[depth_key] =
height;
154 mapOfCameraIntrinsics[depth_key] =
cam_depth;
156 mapOfPointclouds[depth_key] = &pointcloud;
159 const bool use_depth = !depth_key.empty();
160 const bool use_color = !color_key.empty();
163 if (
tracker.getNbPolygon() == 0) {
169 std::cout <<
"Updating configuration with parameters provided by RealSense SDK..." << std::endl;
170 tracker.setCameraParameters(mapOfCameraIntrinsics);
171 if (use_color && use_depth) {
172 tracker.setCameraTransformationMatrix(mapOfCameraTransformations);
175 unsigned int _posx = 100, _posy = 50;
177#if defined(VISP_HAVE_DISPLAY)
178#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
186 display1->init(I_gray, _posx, _posy,
"Color stream");
188 display2->init(I_depth, _posx + I_gray.getWidth() + 10, _posy,
"Depth stream");
192 realsense.
acquire((
unsigned char *)I_color.bitmap, (
unsigned char *)I_depth_raw.bitmap,
nullptr,
nullptr);
217 tracker.setProjectionErrorComputation(
true);
219 tracker.initClick(mapOfImages, mapOfInitFiles,
true);
222 std::vector<double> times_vec;
230 bool tracking_failed =
false;
233 realsense.
acquire((
unsigned char *)I_color.bitmap, (
unsigned char *)I_depth_raw.bitmap, &pointcloud,
nullptr,
nullptr);
244 if (use_color && use_depth) {
245 mapOfImages[color_key] = &I_gray;
246 mapOfPointclouds[depth_key] = &pointcloud;
247 mapOfWidths[depth_key] =
width;
248 mapOfHeights[depth_key] =
height;
250 else if (use_color) {
251 mapOfImages[color_key] = &I_gray;
253 else if (use_depth) {
254 mapOfPointclouds[depth_key] = &pointcloud;
259 if (use_color && use_depth) {
260 tracker.track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
262 else if (use_color) {
265 else if (use_depth) {
266 tracker.track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
270 std::cout <<
"Tracker exception: " <<
e.getStringMessage() << std::endl;
271 tracking_failed =
true;
278 double proj_error = 0;
281 proj_error =
tracker.getProjectionError();
284 proj_error =
tracker.computeCurrentProjectionError(I_gray, cMo, cam_color);
287 if (proj_error > proj_error_threshold) {
288 std::cout <<
"Tracker needs to restart (projection error detected: " << proj_error <<
")" << std::endl;
292 if (!tracking_failed) {
294 tracker.setDisplayFeatures(
true);
296 if (use_color && use_depth) {
297 tracker.display(I_gray, I_depth, cMo, depth_M_color * cMo, cam_color, cam_depth,
vpColor::red, 3);
301 else if (use_color) {
305 else if (use_depth) {
311 std::stringstream ss;
312 ss <<
"Nb features: " <<
tracker.getError().size();
316 std::stringstream ss;
317 ss <<
"Features: edges " <<
tracker.getNbFeaturesEdge() <<
", klt " <<
tracker.getNbFeaturesKlt()
318 <<
", depth dense " <<
tracker.getNbFeaturesDepthDense() <<
", depth normal" <<
tracker.getNbFeaturesDepthNormal();
323 std::stringstream ss;
325 times_vec.push_back(loop_t);
326 ss <<
"Loop time: " << loop_t <<
" ms";
354 std::cout <<
"Caught an exception: " <<
e.what() << std::endl;
357 if (!times_vec.empty()) {
364#if defined(VISP_HAVE_DISPLAY) && (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
365 if (display !=
nullptr) {
371#elif defined(VISP_HAVE_REALSENSE2) && defined(VISP_HAVE_OPENCV)
374 std::cout <<
"Install the JSON 3rd party library (Nlohmann JSON), reconfigure VISP and build again" << std::endl;
377#elif defined(VISP_HAVE_REALSENSE2) && defined(VISP_HAVE_NLOHMANN_JSON)
380 std::cout <<
"Install OpenCV, reconfigure VISP and build again" << std::endl;
386 std::cout <<
"Install librealsense2 3rd party, configure and build ViSP again to use this example" << std::endl;
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.
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)
Definition of the vpImage class member functions.
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.
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()