40#include <visp3/core/vpConfig.h>
42#if defined(VISP_HAVE_CATCH2)
44#include <visp3/core/vpIoTools.h>
45#include <visp3/core/vpImageConvert.h>
46#include <visp3/rbt/vpRBTracker.h>
48#include <visp3/rbt/vpRBSilhouetteMeTracker.h>
49#include <visp3/rbt/vpRBSilhouetteCCDTracker.h>
50#include <visp3/rbt/vpRBKltTracker.h>
51#include <visp3/rbt/vpRBDenseDepthTracker.h>
52#include <visp3/ar/vpPanda3DFrameworkManager.h>
54#include "test_utils.h"
56#if defined(VISP_HAVE_NLOHMANN_JSON)
57#include VISP_NLOHMANN_JSON(json.hpp)
60#define CATCH_CONFIG_RUNNER
61#include <catch_amalgamated.hpp>
63#ifdef ENABLE_VISP_NAMESPACE
67const std::string objCube =
69"v -0.050000 -0.050000 0.050000\n"
70"v -0.050000 0.050000 0.050000\n"
71"v -0.050000 -0.050000 -0.050000\n"
72"v -0.050000 0.050000 -0.050000\n"
73"v 0.050000 -0.050000 0.050000\n"
74"v 0.050000 0.050000 0.050000\n"
75"v 0.050000 -0.050000 -0.050000\n"
76"v 0.050000 0.050000 -0.050000\n"
77"vn -1.0000 -0.0000 -0.0000\n"
78"vn -0.0000 -0.0000 -1.0000\n"
79"vn 1.0000 -0.0000 -0.0000\n"
80"vn -0.0000 -0.0000 1.0000\n"
81"vn -0.0000 -1.0000 -0.0000\n"
82"vn -0.0000 1.0000 -0.0000\n"
83"vt 0.375000 0.000000\n"
84"vt 0.375000 1.000000\n"
85"vt 0.125000 0.750000\n"
86"vt 0.625000 0.000000\n"
87"vt 0.625000 1.000000\n"
88"vt 0.875000 0.750000\n"
89"vt 0.125000 0.500000\n"
90"vt 0.375000 0.250000\n"
91"vt 0.625000 0.250000\n"
92"vt 0.875000 0.500000\n"
93"vt 0.375000 0.750000\n"
94"vt 0.625000 0.750000\n"
95"vt 0.375000 0.500000\n"
96"vt 0.625000 0.500000\n"
98"f 2/4/1 3/8/1 1/1/1\n"
99"f 4/9/2 7/13/2 3/8/2\n"
100"f 8/14/3 5/11/3 7/13/3\n"
101"f 6/12/4 1/2/4 5/11/4\n"
102"f 7/13/5 1/3/5 3/7/5\n"
103"f 4/10/6 6/12/6 8/14/6\n"
104"f 2/4/1 4/9/1 3/8/1\n"
105"f 4/9/2 8/14/2 7/13/2\n"
106"f 8/14/3 6/12/3 5/11/3\n"
107"f 6/12/4 2/5/4 1/2/4\n"
108"f 7/13/5 5/11/5 1/3/5\n"
109"f 4/10/6 2/6/6 6/12/6\n";
111bool opt_no_display =
false;
113std::string createObjFile()
117 std::ofstream f(objFile);
125SCENARIO(
"Instantiating a silhouette me tracker",
"[rbt]")
127 GIVEN(
"A base me tracker")
130 WHEN(
"Changing mask parameters")
132 THEN(
"Enabling mask is seen")
134 bool useMaskDefault =
tracker.shouldUseMask();
135 tracker.setShouldUseMask(!useMaskDefault);
136 REQUIRE(useMaskDefault !=
tracker.shouldUseMask());
138 THEN(
"Changing mask min confidence with a correct value is Ok")
140 tracker.setMinimumMaskConfidence(0.0);
141 REQUIRE(
tracker.getMinimumMaskConfidence() == 0.0);
142 tracker.setMinimumMaskConfidence(1.0);
143 REQUIRE(
tracker.getMinimumMaskConfidence() == 1.0);
144 tracker.setMinimumMaskConfidence(0.5);
145 REQUIRE(
tracker.getMinimumMaskConfidence() == 0.5);
147 THEN(
"Setting incorrect mask confidence value fails")
149 REQUIRE_THROWS(
tracker.setMinimumMaskConfidence(-1.0));
152 WHEN(
"Changing robust threshold")
154 THEN(
"Setting correct value works")
156 tracker.setMinRobustThreshold(0.5);
157 REQUIRE(
tracker.getMinRobustThreshold() == 0.5);
159 THEN(
"Setting negative value throws")
161 REQUIRE_THROWS(
tracker.setMinRobustThreshold(-0.5));
164 WHEN(
"Changing number of candidates")
166 THEN(
"Setting correct value works")
169 REQUIRE(
tracker.getNumCandidates() == 3);
171 THEN(
"Setting incorrect value throws")
173 REQUIRE_THROWS(
tracker.setNumCandidates(0));
176 WHEN(
"Changing convergence settings")
178 THEN(
"Setting correct single point value works")
180 tracker.setSinglePointConvergenceThreshold(1.0);
181 REQUIRE(
tracker.getSinglePointConvergenceThreshold() == 1.0);
183 THEN(
"Setting incorrect single point value throws")
185 REQUIRE_THROWS(
tracker.setSinglePointConvergenceThreshold(-1.0));
187 THEN(
"Setting correct global value works")
189 tracker.setGlobalConvergenceMinimumRatio(0.0);
190 REQUIRE(
tracker.getGlobalConvergenceMinimumRatio() == 0.0);
191 tracker.setGlobalConvergenceMinimumRatio(1.0);
192 REQUIRE(
tracker.getGlobalConvergenceMinimumRatio() == 1.0);
193 tracker.setGlobalConvergenceMinimumRatio(0.5);
194 REQUIRE(
tracker.getGlobalConvergenceMinimumRatio() == 0.5);
197#if defined(VISP_HAVE_NLOHMANN_JSON)
198 WHEN(
"defining JSON parameters")
201 {
"type",
"silhouetteMe"},
202 {
"numCandidates", 1 },
204 {
"convergencePixelThreshold", 0.5 },
205 {
"convergenceRatio", 0.99},
207 {
"minMaskConfidence", 0.5},
211 {
"minSampleStep" , 4.0},
214 {
"ntotalSample" , 0},
215 {
"pointsToTrack" , 200},
217 {
"sampleStep" , 4.0},
219 {
"thresholdType" ,
"normalized"},
223 THEN(
"Loading correct settings works")
225 tracker.loadJsonConfiguration(j);
226 REQUIRE(
tracker.getNumCandidates() == 1);
227 REQUIRE(
tracker.shouldUseMask() ==
true);
228 REQUIRE(
tracker.getMinimumMaskConfidence() == 0.5);
229 REQUIRE(
tracker.getMe().getMaskNumber() == 90);
230 REQUIRE(
tracker.getMe().getThreshold() == 20.0);
232 THEN(
"Setting incorrect candidate number throws")
234 j[
"numCandidates"] = 0;
235 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
237 THEN(
"Setting incorrect mask confidence throws")
239 j[
"minMaskConfidence"] = 5.0;
240 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
242 THEN(
"Setting incorrect single point convergence vlaue confidence throws")
244 j[
"convergencePixelThreshold"] = -1.0;
245 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
247 THEN(
"Setting incorrect global convergence vlaue confidence throws")
249 j[
"convergenceRatio"] = 2.0;
250 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
257SCENARIO(
"Instantiating a silhouette CCD tracker",
"[rbt]")
259 GIVEN(
"A base ccd tracker")
262 WHEN(
"Setting smoothing factor")
264 THEN(
"Setting value above 0 works")
266 tracker.setTemporalSmoothingFactor(0.5);
267 REQUIRE(
tracker.getTemporalSmoothingFactor() == 0.5);
269 THEN(
"Setting value below 0 throws")
271 REQUIRE_THROWS(
tracker.setTemporalSmoothingFactor(-2.0));
274 WHEN(
"Updating CCD parameters")
280 THEN(
"Changes are propagated to tracker")
282 REQUIRE(
tracker.getCCDParameters().h == ccd.
h);
287#if defined(VISP_HAVE_NLOHMANN_JSON)
288 WHEN(
"Defining associated json")
291 {
"type",
"silhouetteCCD"},
293 {
"temporalSmoothing", 0.1},
294 {
"convergenceThreshold", 0.1},
298 {
"gamma", { 0.1, 0.2, 0.3, 0.4 } }
301 THEN(
"Loading correct json works")
303 tracker.loadJsonConfiguration(j);
304 REQUIRE(
tracker.getTemporalSmoothingFactor() == 0.1);
306 REQUIRE(ccd.
h == 64);
310 THEN(
"Loading invalid temporal smoothing factor throws")
312 j[
"temporalSmoothing"] = -3.14;
313 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
315 THEN(
"Loading invalid ccd gamma throws")
317 j[
"ccd"][
"gamma"] = -3.14;
318 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
325#if defined(VP_HAVE_RB_KLT_TRACKER)
326SCENARIO(
"Instantiating KLT tracker")
329 WHEN(
"Modifying basic settings")
331 tracker.setFilteringBorderSize(2);
332 tracker.setFilteringMaxReprojectionError(0.024);
333 tracker.setMinimumDistanceNewPoints(0.005);
334 tracker.setMinimumNumberOfPoints(20);
335 tracker.setShouldUseMask(
true);
336 tracker.setMinimumMaskConfidence(0.5);
337 THEN(
"Every change is visible")
339 REQUIRE(
tracker.getFilteringBorderSize() == 2);
340 REQUIRE(
tracker.getFilteringMaxReprojectionError() == 0.024);
341 REQUIRE(
tracker.getMinimumDistanceNewPoints() == 0.005);
342 REQUIRE(
tracker.getMinimumNumberOfPoints() == 20);
343 REQUIRE(
tracker.shouldUseMask());
344 REQUIRE(
tracker.getMinimumMaskConfidence() == 0.5);
346 THEN(
"Setting incorrect Mask confidence throws")
348 REQUIRE_THROWS(
tracker.setMinimumMaskConfidence(-1.0));
352#if defined(VISP_HAVE_NLOHMANN_JSON)
353 WHEN(
"Defining associated json")
358 {
"minimumNumPoints", 25},
359 {
"newPointsMinPixelDistance", 5},
360 {
"maxReprojectionErrorPixels", 0.01},
362 {
"minMaskConfidence", 0.1},
365 {
"maxFeatures", 500 }
367 THEN(
"Loading correct json works")
369 tracker.loadJsonConfiguration(j);
370 REQUIRE(
tracker.getMinimumNumberOfPoints() == 25);
371 REQUIRE(
tracker.getMinimumDistanceNewPoints() == 5);
372 REQUIRE(
tracker.getFilteringMaxReprojectionError() == 0.01);
373 REQUIRE(
tracker.shouldUseMask() ==
true);
374 REQUIRE(
tracker.getMinimumMaskConfidence() == 0.1f);
375 REQUIRE(
tracker.getKltTracker().getWindowSize() == 7);
376 REQUIRE(
tracker.getKltTracker().getQuality() == 0.01);
377 REQUIRE(
tracker.getKltTracker().getMaxFeatures() == 500);
379 THEN(
"Loading invalid mask confidence throws")
381 j[
"minMaskConfidence"] = -3.14;
382 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
389SCENARIO(
"Instantiating depth tracker",
"[rbt]")
392 WHEN(
"Setting steps")
394 THEN(
"Setting positive value works")
397 REQUIRE(
tracker.getStep() == 4);
399 THEN(
"Setting 0 step is invalid")
401 REQUIRE_THROWS(
tracker.setStep(0));
404 WHEN(
"Setting confidence")
406 THEN(
"Setting incorrect mask confidence value")
408 REQUIRE_THROWS(
tracker.setMinimumMaskConfidence(-1.0));
410 THEN(
"Setting correct mask confidence value")
412 tracker.setMinimumMaskConfidence(0.8);
413 REQUIRE(
tracker.getMinimumMaskConfidence() == 0.8f);
415 THEN(
"Toggling mask works")
417 tracker.setShouldUseMask(
true);
418 REQUIRE(
tracker.shouldUseMask());
421#if defined(VISP_HAVE_NLOHMANN_JSON)
422 WHEN(
"Defining associated json")
429 {
"minMaskConfidence", 0.1}
431 THEN(
"Loading correct json works")
433 tracker.loadJsonConfiguration(j);
434 REQUIRE(
tracker.getStep() == 16);
435 REQUIRE(
tracker.shouldUseMask());
436 REQUIRE(
tracker.getMinimumMaskConfidence() == 0.1f);
438 THEN(
"Loading invalid mask confidence throws")
440 j[
"minMaskConfidence"] = -3.14;
441 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
443 THEN(
"Loading invalid step throws")
446 REQUIRE_THROWS(
tracker.loadJsonConfiguration(j));
452SCENARIO(
"Instantiating a render-based tracker",
"[rbt]")
456 WHEN(
"Setting optimization parameters")
458 THEN(
"Max num iter cannot be zero")
460 REQUIRE_THROWS(
tracker.setMaxOptimizationIters(0));
462 THEN(
"Setting num iter is ok")
464 tracker.setMaxOptimizationIters(10);
465 REQUIRE(
tracker.getMaxOptimizationIters() == 10);
467 THEN(
"Gain cannot be negative")
469 REQUIRE_THROWS(
tracker.setOptimizationGain(-0.5));
471 THEN(
"Positive gain is ok")
473 tracker.setOptimizationGain(0.5);
474 REQUIRE(
tracker.getOptimizationGain() == 0.5);
476 THEN(
"Initial mu cannot be negative")
478 REQUIRE_THROWS(
tracker.setOptimizationInitialMu(-0.5));
480 THEN(
"Initial mu can be zero (gauss newton)")
482 tracker.setOptimizationInitialMu(0.0);
483 REQUIRE(
tracker.getOptimizationInitialMu() == 0.0);
485 THEN(
"Initial mu can be above zero")
487 tracker.setOptimizationInitialMu(0.1);
488 REQUIRE(
tracker.getOptimizationInitialMu() == 0.1);
491 THEN(
"Mu factor cannot be negative")
493 REQUIRE_THROWS(
tracker.setOptimizationMuIterFactor(-0.5));
495 THEN(
"Mu factor can be zero")
497 tracker.setOptimizationMuIterFactor(0.0);
498 REQUIRE(
tracker.getOptimizationMuIterFactor() == 0.0);
500 THEN(
"Mu factor can be positive")
502 tracker.setOptimizationMuIterFactor(0.1);
503 REQUIRE(
tracker.getOptimizationMuIterFactor() == 0.1);
507 WHEN(
"Setting camera parameters and resolution")
509 unsigned int h = 480,
w = 640;
511 THEN(
"Image height cannot be zero")
513 REQUIRE_THROWS(
tracker.setCameraParameters(cam, 0, w));
515 THEN(
"Image width cannot be zero")
517 REQUIRE_THROWS(
tracker.setCameraParameters(cam, h, 0));
519 THEN(
"Camera model cannot have distortion")
521 cam.initPersProjWithDistortion(600, 600, 320, 240, 0.01, 0.01);
522 REQUIRE_THROWS(
tracker.setCameraParameters(cam, h, w));
524 THEN(
"Loading with perspective model with no distortion and correct resolution is ok")
526 tracker.setCameraParameters(cam, h, w);
527 REQUIRE(
tracker.getCameraParameters() == cam);
528 REQUIRE(
tracker.getImageHeight() == h);
529 REQUIRE(
tracker.getImageWidth() == w);
533#if defined(VISP_HAVE_NLOHMANN_JSON)
534 WHEN(
"Loading JSON configuration")
536 const std::string jsonLiteral = R
"JSON({
539 "model": "perspectiveWithoutDistortion",
550 "maxIterations" : 10,
554 "model" : "path/to/model.obj",
555 "silhouetteExtractionSettings" : {
564 "reusePreviousPoints": true
569 "type": "silhouetteMe",
572 "convergencePixelThreshold" : 3,
573 "convergenceRatio" : 0.99,
577 "minSampleStep" : 4.0,
584 "pointsToTrack" : 200,
588 "thresholdType" : "normalized",
593 "type": "silhouetteColor",
595 "convergenceThreshold" : 0.1,
596 "temporalSmoothing" : 0.1,
607 const auto verifyBase = [&
tracker]() {
608 REQUIRE((
tracker.getImageHeight() == 240 &&
tracker.getImageWidth() == 320));
609 REQUIRE((
tracker.getOptimizationGain() == 1.0 &&
tracker.getMaxOptimizationIters() == 10));
615 REQUIRE((
tracker.getOptimizationGain() == 1.0 &&
tracker.getMaxOptimizationIters() == 10));
616 REQUIRE((
tracker.getOptimizationInitialMu() == 0.5 &&
tracker.getOptimizationMuIterFactor() == 0.1));
618 nlohmann::json
j = nlohmann::json::parse(jsonLiteral);
619 THEN(
"Loading configuration with trackers")
623 REQUIRE(
tracker.getModelPath() ==
"path/to/model.obj");
624 if (!opt_no_display) {
625 AND_THEN(
"Initializing tracking fails since object does not exist")
627 REQUIRE_THROWS(
tracker.startTracking());
631 THEN(
"Loading configuration without model also works")
636 REQUIRE(
tracker.getModelPath() ==
"");
637 if (!opt_no_display) {
638 AND_THEN(
"Initializing tracking fails since path is not specified")
640 REQUIRE_THROWS(
tracker.startTracking());
644 THEN(
"Loading configuration with real 3D model also works")
646 std::string objFile = createObjFile();
647 j[
"model"] = objFile;
650 REQUIRE(
tracker.getModelPath() == objFile);
651 if (!opt_no_display) {
652 AND_THEN(
"Initializing tracker works")
654 REQUIRE_NOTHROW(
tracker.startTracking());
660 WHEN(
"Adding trackers")
662 THEN(
"Adding nullptr is not allowed")
664 REQUIRE_THROWS(
tracker.addTracker(
nullptr));
666 THEN(
"Adding a tracker works")
668 auto ccdTracker = std::make_shared<vpRBSilhouetteCCDTracker>();
669 tracker.addTracker(ccdTracker);
675SCENARIO(
"Running tracker on static synthetic sequences",
"[rbt]")
677 if (opt_no_display) {
678 std::cout <<
"Display is disabled for tests, skipping..." << std::endl;
681 unsigned int h = 480,
w = 640;
685 std::string objFile = createObjFile();
687 renderer.addNodeToScene(renderer.loadObject(
"object", objFile));
690 const unsigned int n = 100;
692 std::vector<vpHomogeneousMatrix>
cTw;
693 std::vector<vpHomogeneousMatrix> oTw;
694 for (
unsigned int i = 0;
i < n; ++
i) {
696 cTw.push_back(
vpHomogeneousMatrix(0.0, 0.001 *
static_cast<double>(i), 0.3 + 0.001 *
static_cast<double>(i), 0.0, 0.0, 0.0));
699 TrajectoryData traj1 = generateTrajectory(renderParams, setupScene, cTw, oTw);
702 tracker.setCameraParameters(cam, h, w);
703 std::shared_ptr<vpRBSilhouetteCCDTracker> silTracker = std::make_shared<vpRBSilhouetteCCDTracker>();
704 silTracker->setTemporalSmoothingFactor(0.1);
707 silTracker->setCCDParameters(ccdParams);
709 tracker.addTracker(silTracker);
720 tracker.setSilhouetteExtractionParameters(silhouetteSettings);
721 tracker.setOptimizationGain(0.5);
722 tracker.setMaxOptimizationIters(10);
723 tracker.setOptimizationInitialMu(0.01);
730 for (
unsigned int i = 0;
i < traj1.
cTo.size(); ++
i) {
738 std::cout <<
"Translation error = " << errorT <<
" m" <<
", rotation error = " <<
vpMath::deg(errorR) <<
" deg" << std::endl;
739 REQUIRE((errorT < 0.005 && errorR <
vpMath::deg(2.1)));
744SCENARIO(
"Checking ADD convergence metric",
"[rbt]")
746 if (opt_no_display) {
747 std::cout <<
"Display is disabled for tests, skipping..." << std::endl;
751 GIVEN(
"A renderer and a convergence metric")
757 renderer.initFramework();
758 renderer.addObjectToScene(
"obj", createObjFile());
759 renderer.setFocusedObject(
"obj");
767 THEN(
"Trying to compute metric without sampling fails")
769 REQUIRE_THROWS(metric(cam, cTo1, cTo2NotConv));
772 THEN(
"Sampling and testing against various threshold works")
774 metric.sampleObject(renderer);
775 double metricValue = metric(cam, cTo1, cTo2NotConv);
776 REQUIRE(fabs(metricValue - 0.005) < 1e-4);
777 REQUIRE(!metric.hasConverged(cam, cTo1, cTo2NotConv));
778 REQUIRE(!metric.shouldUpdateRender(cam, cTo1, cTo2NotConv));
781 metricValue = metric(cam, cTo1, cTo2Conv);
782 REQUIRE(fabs(metricValue - 0.0001) < 1e-4);
783 REQUIRE(metric.hasConverged(cam, cTo1, cTo2Conv));
784 REQUIRE(!metric.shouldUpdateRender(cam, cTo1, cTo2Conv));
786 metricValue = metric(cam, cTo1, cTo2Render);
787 REQUIRE(fabs(metricValue - 0.02) < 1e-4);
788 REQUIRE(!metric.hasConverged(cam, cTo1, cTo2Render));
789 REQUIRE(metric.shouldUpdateRender(cam, cTo1, cTo2Render));
794SCENARIO(
"Testing point map",
"[rbt]")
797 map.setThresholdNormalVisibiltyCriterion(45.0);
798 REQUIRE(map.getNumMaxPoints() == 512);
799 REQUIRE(
vpMath::equal(map.getMinDistanceAddNewPoints(), 0.0, 1e-6));
800 REQUIRE(
vpMath::equal(map.getOutlierReprojectionErrorThreshold(), 2.0, 1e-6));
801 REQUIRE(
vpMath::equal(map.getMaxDepthErrorCandidate(), 0.02, 1e-6));
802 REQUIRE(
vpMath::equal(map.getThresholdNormalVisibiltyCriterion(), 45.0, 1e-6));
803 REQUIRE(map.getPoints().getRows() == 0);
805 unsigned int h = 480,
w = 640;
808 std::vector<int> removedIndices;
815 unsigned int N = 100;
827 for (
unsigned int i = 0;
i < N;
i++) {
831 baseUV[
i][0] = random.uniform(
static_cast<double>(w) / 5 * 2,
static_cast<double>(w) / 5 * 3);
832 baseUV[
i][1] = random.uniform(
static_cast<double>(h) / 5 * 2,
static_cast<double>(h) / 5 * 3);
833 unsigned uu =
static_cast<unsigned int>(baseUV[
i][0]), vu =
static_cast<unsigned int>(baseUV[i][1]);
834 if (depthImage[vu][uu] > 0.0) {
838 Z = 0.5 + random.uniform(-0.05, 0.05);
841 for (
int i = -1;
i < 2; ++
i) {
842 for (
int j = -1;
j < 2; ++
j) {
843 depthImage[vu +
i][uu +
j] = Z;
851 cX[
i][0] = baseXY[
i][0] * Z, cX[
i][1] = baseXY[
i][1] * Z, cX[
i][2] = Z;
852 cN[
i][0] = 0.0, cN[
i][1] = 0.0, cN[
i][2] = -1.0;
855 c[0] = cX[
i][0], c[1] = cX[
i][1], c[2] = cX[
i][2];
858 oX[
i][0] = ox[0] / ox[3], oX[
i][1] = ox[1] / ox[3], oX[
i][2] = ox[2] / ox[3];
859 const vpColVector on = cTo.inverse().getRotationMatrix() * cN.getRow(i).
t();
860 oN[
i][0] = on[0], oN[
i][1] = on[1], oN[
i][2] = on[2];
862 std::cout << oN << std::endl;
863 unsigned int numAddedPoints;
864 map.updatePoints(indicesToRemove, oX, oN, removedIndices, numAddedPoints);
865 REQUIRE(numAddedPoints == N);
867 vpMatrix reprojcX, reprojXY, reprojUV;
869 for (
unsigned int i = 0;
i < N; ++
i) {
872 map.project(cam, allPoints, cTo, reprojcX, reprojXY, reprojUV);
874 REQUIRE(((baseUV - reprojUV).frobeniusNorm() / (N * 2)) < 1e-3);
875 REQUIRE(((baseXY - reprojXY).frobeniusNorm() / (N * 2)) < 1e-3);
876 REQUIRE(((cX - reprojcX).frobeniusNorm() / (N * 3)) < 1e-3);
878 std::vector<int> visibleIndices;
879 map.getVisiblePoints(h, w, cam, cTo, depthImage, visibleIndices);
880 REQUIRE(visibleIndices.size() == N);
883 map.getVisiblePoints(h, w, cam, cTo *
vpHomogeneousMatrix(0.0, 0.0, map.getMaxDepthErrorVisibilityCriterion() + 0.01, 0.0, 0.0, 0.0), depthImage, visibleIndices);
884 REQUIRE(visibleIndices.size() == 0);
886 map.getVisiblePoints(h, w, cam,
vpHomogeneousMatrix(0.0, 0.0, map.getMaxDepthErrorVisibilityCriterion() * 0.9, 0.0, 0.0, 0.0) * cTo, depthImage, visibleIndices);
887 REQUIRE(visibleIndices.size() == N);
889 map.setMaxDepthErrorVisibilityCriterion(10);
891 map.getVisiblePoints(h, w, cam, cTo *
vpHomogeneousMatrix(0.0, 0.0, 0.0, 0.0,
vpMath::rad(map.getThresholdNormalVisibiltyCriterion() + 10), 0.0), depthImage, visibleIndices);
892 REQUIRE(visibleIndices.size() == 0);
893 std::cout << map.getThresholdNormalVisibiltyCriterion() << std::endl;
894 map.getVisiblePoints(h, w, cam, cTo *
vpHomogeneousMatrix(0.0, 0.0, 0.0, 0.0,
vpMath::rad(map.getThresholdNormalVisibiltyCriterion() - 10), 0.0), depthImage, visibleIndices);
895 REQUIRE(visibleIndices.size() == N);
897 map.setThresholdNormalVisibiltyCriterion(180);
898 map.getVisiblePoints(h, w, cam, cTo *
vpHomogeneousMatrix(0.0, 0.0, 0.0, 0.0,
vpMath::rad(map.getThresholdNormalVisibiltyCriterion() + 10), 0.0), depthImage, visibleIndices);
899 REQUIRE(visibleIndices.size() == N);
903int main(
int argc,
char *argv[])
905 Catch::Session session;
906 auto cli = session.cli()
907 | Catch::Clara::Opt(opt_no_display)[
"--no-display"](
"Disable display");
910 const int returnCode = session.applyCommandLine(argc, argv);
911 if (returnCode != 0) {
915 const int numFailed = session.run();
Implementation of a generic 2D array used as base class for matrices and vectors.
double gamma_2
Curve uncertainty computation hyperparameter. Recommended to leave fixed.
double gamma_3
Curve uncertainty computation hyperparameter. Recommended to leave fixed.
double gamma_1
Curve uncertainty computation hyperparameter. Recommended to leave fixed.
int delta_h
Sample step when computing statistics and errors. Increase this value to decrease computation time,...
int h
Size of the vicinity that is used to compute statistics and error. Length of the line along the norma...
double gamma_4
Curve uncertainty computation hyperparameter. Recommended to leave fixed.
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpThetaUVector getThetaUVector() const
vpTranslationVector getTranslationVector() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Definition of the vpImage class member functions.
static double rad(double deg)
static bool equal(double x, double y, double threshold=0.001)
static double deg(double rad)
Implementation of a matrix and operations on matrices.
Single object focused renderer.
Class representing an ambient light.
static vpPanda3DFrameworkManager & getInstance()
Rendering parameters for a panda3D simulation.
Class that renders multiple datatypes, in a single pass. A renderer set contains multiple subrenderer...
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
A tracker based on dense depth point-plane alignment.
Tracking based on the Contracting Curve Density algorithm.
Moving edge feature tracking from depth-extracted object contours.
Class implementing the Render-Based Tracker (RBT).
double frobeniusNorm() const
Class for generating random numbers with uniform probability density.
std::vector< vpHomogeneousMatrix > cTo
std::vector< vpImage< float > > depth
std::vector< vpImage< vpRGBa > > rgb