1 #ifndef VP_RB_TRACKER_TUTORIAL_HELPER_H
2 #define VP_RB_TRACKER_TUTORIAL_HELPER_H
13 #include <visp3/core/vpImage.h>
14 #include <visp3/core/vpImageFilter.h>
15 #include <visp3/core/vpImageConvert.h>
16 #include <visp3/core/vpImageTools.h>
17 #include <visp3/core/vpIoTools.h>
18 #include <visp3/core/vpDisplay.h>
19 #include <visp3/core/vpTime.h>
20 #include <visp3/gui/vpDisplayFactory.h>
22 #include <visp3/io/vpImageIo.h>
23 #include <visp3/io/vpJsonArgumentParser.h>
24 #include <visp3/io/vpVideoWriter.h>
26 #include <visp3/gui/vpPlot.h>
28 #include <visp3/rbt/vpRBTracker.h>
29 #include <visp3/rbt/vpObjectMask.h>
30 #include <visp3/rbt/vpRBDriftDetector.h>
32 #include "pStatClient.h"
34 #ifndef DOXYGEN_SHOULD_SKIP_THIS
35 namespace vpRBTrackerTutorial
38 #ifdef ENABLE_VISP_NAMESPACE
44 BaseArguments() : trackerConfiguration(
""), maxDepthDisplay(1.f), display(true), debugDisplay(false), enableRenderProfiling(false) { }
49 .
addArgument(
"--tracker", trackerConfiguration,
false,
"Path to the JSON file containing the tracker")
50 .
addArgument(
"--object",
object,
false,
"Name of the object to track. Used to potentially fetch the init file")
51 .
addArgument(
"--init-file", initFile,
false,
"Path to the JSON file containing the 2D/3D correspondences for initialization by click")
52 .
addArgument(
"--pose", inlineInit,
false,
"Initial pose of the object in the camera frame.")
53 .
addArgument(
"--max-depth-display", maxDepthDisplay,
false,
"Maximum depth value, used to scale the depth display")
54 .
addFlag(
"--no-display", display,
"Disable display windows")
55 .
addFlag(
"--debug-display", debugDisplay,
"Enable additional displays from the renderer")
56 .
addFlag(
"--profile", enableRenderProfiling,
"Enable the use of Pstats to profile rendering times");
59 void postProcessArguments()
61 if (trackerConfiguration.empty()) {
66 object.erase(
object.end() - 5,
object.end());
68 if (initFile.empty()) {
72 if (!display && inlineInit.empty()) {
75 if (inlineInit.size() > 0) {
76 if (inlineInit.size() != 6) {
79 for (
unsigned int i = 0; i < 6; ++i) {
80 std::cout <<
"inline i = " << inlineInit[i] << std::endl;
82 cMoInit =
vpHomogeneousMatrix(inlineInit[0], inlineInit[1], inlineInit[2], inlineInit[3], inlineInit[4], inlineInit[5]);
88 return !inlineInit.empty();
91 std::string trackerConfiguration;
94 std::vector<double> inlineInit;
95 float maxDepthDisplay;
99 bool enableRenderProfiling;
102 class vpRBExperimentLogger
105 vpRBExperimentLogger() : enabled(false), videoEnabled(false), framerate(30)
111 .
addFlag(
"--save", enabled,
"Whether to save experiment data")
112 .
addArgument(
"--save-path", folder,
false,
"Where to save the experiment log. The folder should not exist.")
113 .
addFlag(
"--save-video", videoEnabled,
"Whether to save the video")
114 .
addArgument(
"--video-framerate", framerate,
false,
"Output video framerate");
121 if (folder.empty()) {
126 videoWriter.setFramerate(framerate);
127 videoWriter.setCodec(cv::VideoWriter::fourcc(
'P',
'I',
'M',
'1'));
142 #ifdef VISP_HAVE_OPENMP
143 #pragma omp parallel for
145 for (
unsigned int i = 0; i < IRGB.
getHeight(); ++i) {
146 memcpy(Iout[i], IgrayOverlay[i], IRGB.
getWidth() *
sizeof(
vpRGBa));
153 videoWriter.open(Iout);
156 videoWriter.saveFrame(Iout);
160 nlohmann::json iterLog;
163 iterLog[
"cMo"] = cMo;
165 log.push_back(iterLog);
174 f << log.dump(2) << std::endl;
189 unsigned int framerate;
195 class vpRBExperimentPlotter
199 vpRBExperimentPlotter() : enabled(false), plotPose(false), plotPose3d(false), plotDivergenceMetrics(false), plotCovariance(false) { }
204 .
addFlag(
"--plot-pose", plotPose,
"Plot the pose of the object in the camera frame")
205 .
addFlag(
"--plot-position", plotPose3d,
"Plot the position of the object in a 3d figure")
206 .
addFlag(
"--plot-divergence", plotDivergenceMetrics,
"Plot the metrics associated to the divergence threshold computation")
207 .
addFlag(
"--plot-cov", plotCovariance,
"Plot the pose covariance trace for each feature");
211 void postProcessArguments(
bool displayEnabled)
213 enabled = plotPose || plotDivergenceMetrics || plotPose3d || plotCovariance;
214 if (enabled && !displayEnabled) {
219 void init(std::vector<std::shared_ptr<vpDisplay>> &displays)
224 int ypos = 0, xpos = 0;
225 for (std::shared_ptr<vpDisplay> &display : displays) {
226 ypos = std::min(ypos, display->getWindowYPosition());
227 xpos = std::max(xpos, display->getWindowXPosition() +
static_cast<int>(display->getWidth()));
230 numPlots =
static_cast<int>(plotPose) +
static_cast<int>(plotDivergenceMetrics) +
static_cast<int>(plotPose3d) +
static_cast<int>(plotCovariance);
231 plotter.init(numPlots, 600, 800, xpos, ypos,
"Plot");
232 unsigned int plotIndex = 0;
234 plotter.initGraph(plotIndex, 6);
235 plotter.setTitle(plotIndex,
"cMo");
236 std::vector<std::string> legends = {
237 "tx",
"ty",
"tz",
"tux",
"tuy",
"tuz"
239 for (
unsigned int i = 0; i < 6; ++i) {
240 plotter.setLegend(plotIndex, i, legends[i]);
242 plotter.setGraphThickness(plotIndex, 2);
246 plotter.initGraph(plotIndex, 1);
247 plotter.setTitle(plotIndex,
"3D object position");
248 plotter.setGraphThickness(plotIndex, 2);
252 if (plotDivergenceMetrics) {
253 plotter.initGraph(plotIndex, 1);
254 plotter.initRange(plotIndex, 0.0, 1.0, 0.0, 1.0);
255 plotter.setTitle(plotIndex,
"Divergence");
258 if (plotCovariance) {
259 plotter.initGraph(plotIndex, 2);
260 plotter.setLegend(plotIndex, 0,
"Translation trace standard deviation (cm)");
261 plotter.setLegend(plotIndex, 1,
"Rotation trace standard deviation (deg)");
263 plotter.setTitle(plotIndex,
"Covariance");
273 unsigned int plotIndex = 0;
284 plotter.plot(plotIndex, 0, t[0], t[1], t[2]);
287 if (plotDivergenceMetrics) {
288 const std::shared_ptr<const vpRBDriftDetector> driftDetector = tracker.
getDriftDetector();
289 double metric = driftDetector ? driftDetector->getScore() : 0.0;
290 plotter.plot(plotIndex, 0, time, metric);
293 if (plotCovariance) {
295 double traceTranslation = 0.0, traceRotation = 0.0;
296 for (
unsigned int i = 0; i < 3; ++i) {
297 traceTranslation += cov[i][i];
298 traceRotation += cov[i + 3][i + 3];
300 traceTranslation = sqrt(traceTranslation) * 100;
303 plotter.plot(plotIndex, 0, time, traceTranslation);
304 plotter.plot(plotIndex, 1, time, traceRotation);
313 bool plotDivergenceMetrics;
319 std::vector<std::shared_ptr<vpDisplay>> createDisplays(
329 "Depth", depthDisplay,
330 "Proba mask", probaDisplay
334 std::vector<std::shared_ptr<vpDisplay>> createDisplays(
343 "Proba mask", probaDisplay
347 void enableRendererProfiling()
349 if (PStatClient::is_connected()) {
350 PStatClient::disconnect();
353 std::string host =
"";
355 if (!PStatClient::connect(host, port)) {
356 std::cout <<
"Could not connect to PStat server." << std::endl;
362 #ifdef VISP_HAVE_OPENMP
363 #pragma omp parallel for
365 for (
unsigned int i = 0; i < normalsImage.
getSize(); ++i) {
366 normalDisplayImage.
bitmap[i].
R =
static_cast<unsigned char>((normalsImage.
bitmap[i].
R + 1.0) * 127.5f);
367 normalDisplayImage.
bitmap[i].
G =
static_cast<unsigned char>((normalsImage.
bitmap[i].
G + 1.0) * 127.5f);
368 normalDisplayImage.
bitmap[i].
B =
static_cast<unsigned char>((normalsImage.
bitmap[i].
B + 1.0) * 127.5f);
378 #ifdef VISP_HAVE_OPENMP
379 #pragma omp parallel for
381 for (
unsigned int i = 0; i < cannyRawData.
getSize(); ++i) {
388 for (
unsigned int i = 0; i < canny.
getHeight(); i += 4) {
389 for (
unsigned int j = 0; j < canny.
getWidth(); j += 4) {
390 if (!valid[i][j])
continue;
391 float angle = cannyRawData[i][j].B;
392 unsigned x = j + 10 * cos(angle);
393 unsigned y = i + 10 * sin(angle);
static const vpColor green
static void display(const vpImage< unsigned char > &I)
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
static void flush(const vpImage< unsigned char > &I)
static void displayArrow(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
@ dimensionError
Bad dimension.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpTranslationVector getTranslationVector() const
unsigned int getWidth() const
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
Command line argument parsing with support for JSON files. If a JSON file is supplied,...
vpJsonArgumentParser & addArgument(const std::string &name, T ¶meter, const bool required=true, const std::string &help="No description")
Add an argument that can be provided by the user, either via command line or through the json file.
vpJsonArgumentParser & addFlag(const std::string &name, bool ¶meter, const std::string &help="No description")
Add an argument that acts as a flag when specified on the command line. When this flag is specified,...
static double deg(double rad)
Implementation of a matrix and operations on matrices.
This class enables real time drawing of 2D or 3D graphics. An instance of the class open a window whi...
Implementation of a pose vector and operations on poses.
void getPose(vpHomogeneousMatrix &cMo) const
vpMatrix getCovariance() const
std::shared_ptr< vpRBDriftDetector > getDriftDetector() const
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
Class that consider the case of a translation vector.
Class that enables to write easily a video file or a sequence of images.
std::vector< std::shared_ptr< vpDisplay > > makeDisplayGrid(unsigned int rows, unsigned int cols, unsigned int startX, unsigned int startY, unsigned int paddingX, unsigned int paddingY, Args &... args)
Create a grid of displays, given a set of images. All the displays will be initialized in the correct...