mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-11 04:19:50 +08:00
Exposed all AprilTag parameters. Sharing Marker/Dictionary between opencv and apriltag implementation. Added new Marker/Lengths parameter.
This commit is contained in:
+1
-1
@@ -22,7 +22,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
|||||||
#######################
|
#######################
|
||||||
SET(RTABMAP_MAJOR_VERSION 0)
|
SET(RTABMAP_MAJOR_VERSION 0)
|
||||||
SET(RTABMAP_MINOR_VERSION 23)
|
SET(RTABMAP_MINOR_VERSION 23)
|
||||||
SET(RTABMAP_PATCH_VERSION 6)
|
SET(RTABMAP_PATCH_VERSION 7)
|
||||||
SET(RTABMAP_VERSION
|
SET(RTABMAP_VERSION
|
||||||
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
Strategy strategy_;
|
Strategy strategy_;
|
||||||
float markerLength_;
|
float markerLength_;
|
||||||
|
std::map<int, float> markerLengths_;
|
||||||
float maxDepthError_;
|
float maxDepthError_;
|
||||||
float maxRange_;
|
float maxRange_;
|
||||||
float minRange_;
|
float minRange_;
|
||||||
|
|||||||
@@ -918,19 +918,28 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(GridGlobal, FloodFillDepth, unsigned int, 0, "Flood fill filter (0=disabled), used to remove empty cells outside the map. The flood fill is done at the specified depth (between 1 and 16) of the OctoMap.");
|
RTABMAP_PARAM(GridGlobal, FloodFillDepth, unsigned int, 0, "Flood fill filter (0=disabled), used to remove empty cells outside the map. The flood fill is done at the specified depth (between 1 and 16) of the OctoMap.");
|
||||||
|
|
||||||
RTABMAP_PARAM(Marker, Strategy, int, 0, "Marker detection implementation: 0=OpenCV, 1=AprilTag");
|
RTABMAP_PARAM(Marker, Strategy, int, 0, "Marker detection implementation: 0=OpenCV, 1=AprilTag");
|
||||||
RTABMAP_PARAM(Marker, Dictionary, int, 0, "Dictionary to use: DICT_ARUCO_4X4_50=0, DICT_ARUCO_4X4_100=1, DICT_ARUCO_4X4_250=2, DICT_ARUCO_4X4_1000=3, DICT_ARUCO_5X5_50=4, DICT_ARUCO_5X5_100=5, DICT_ARUCO_5X5_250=6, DICT_ARUCO_5X5_1000=7, DICT_ARUCO_6X6_50=8, DICT_ARUCO_6X6_100=9, DICT_ARUCO_6X6_250=10, DICT_ARUCO_6X6_1000=11, DICT_ARUCO_7X7_50=12, DICT_ARUCO_7X7_100=13, DICT_ARUCO_7X7_250=14, DICT_ARUCO_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16, DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20");
|
RTABMAP_PARAM(Marker, Dictionary, int, 0, "Dictionary to use: DICT_ARUCO_4X4_50=0, DICT_ARUCO_4X4_100=1, DICT_ARUCO_4X4_250=2, DICT_ARUCO_4X4_1000=3, DICT_ARUCO_5X5_50=4, DICT_ARUCO_5X5_100=5, DICT_ARUCO_5X5_250=6, DICT_ARUCO_5X5_1000=7, DICT_ARUCO_6X6_50=8, DICT_ARUCO_6X6_100=9, DICT_ARUCO_6X6_250=10, DICT_ARUCO_6X6_1000=11, DICT_ARUCO_7X7_50=12, DICT_ARUCO_7X7_100=13, DICT_ARUCO_7X7_250=14, DICT_ARUCO_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16, DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36H12=21");
|
||||||
RTABMAP_PARAM(Marker, Length, float, 0, "The length (m) of the markers' side. Value <=0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization). If 0, the length is estimated only on the first marker detected, then re-used for all next detections (i.e., this assumes that markers have all the same length). With <0, the length is estimated once for each unique marker, then re-used for next detections with the same marker ID.");
|
RTABMAP_PARAM(Marker, Length, float, 0, "The length (m) of the markers' side. Value <=0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization). If 0, the length is estimated only on the first marker detected, then re-used for all next detections (i.e., this assumes that markers have all the same length). With <0, the length is estimated once for each unique marker, then re-used for next detections with the same marker ID.");
|
||||||
|
RTABMAP_PARAM_STR(Marker, Lengths, "", uFormat("List of markers to detect. Format is the marker's ID followed by its length (in meters), markers are separated by a vertical line (\"id1 length|id2 length\"). If empty, all markers of the chosen dictionary can be detected and their length is set/estimated based on %s. For example, to detect only markers 12 and 14 with lengths of 8 and 15 cm respectively, set \"12 0.08|14 0.15\".", kMarkerDictionary().c_str()).c_str());
|
||||||
RTABMAP_PARAM(Marker, MaxDepthError, float, 0.01, uFormat("Maximum depth error between all corners of a marker when estimating the marker length (when %s is 0). The smaller it is, the more perpendicular the camera should be toward the marker to initialize the length.", kMarkerLength().c_str()));
|
RTABMAP_PARAM(Marker, MaxDepthError, float, 0.01, uFormat("Maximum depth error between all corners of a marker when estimating the marker length (when %s is 0). The smaller it is, the more perpendicular the camera should be toward the marker to initialize the length.", kMarkerLength().c_str()));
|
||||||
RTABMAP_PARAM(Marker, VarianceLinear, float, 0.001, uFormat("Linear variance to set on marker detections. If %s is enabled and %s=2 (GTSAM): it is the variance of the range factor, with 9999 to disable range factor and to do only bearing.", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str()));
|
RTABMAP_PARAM(Marker, VarianceLinear, float, 0.001, uFormat("Linear variance to set on marker detections. If %s is enabled and %s=2 (GTSAM): it is the variance of the range factor, with 9999 to disable range factor and to do only bearing.", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str()));
|
||||||
RTABMAP_PARAM(Marker, VarianceAngular, float, 0.01, uFormat("Angular variance to set on marker detections. If %s is enabled, it is ignored with %s=1 (g2o) and it corresponds to bearing variance with %s=2 (GTSAM).", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str(), kOptimizerStrategy().c_str()));
|
RTABMAP_PARAM(Marker, VarianceAngular, float, 0.01, uFormat("Angular variance to set on marker detections. If %s is enabled, it is ignored with %s=1 (g2o) and it corresponds to bearing variance with %s=2 (GTSAM).", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str(), kOptimizerStrategy().c_str()));
|
||||||
RTABMAP_PARAM(Marker, VarianceOrientationIgnored, bool, false, uFormat("When this setting is false, the landmark's orientation is optimized during graph optimization. When this setting is true, only the position of the landmark is optimized. This can be useful when the landmark's orientation estimation is not reliable. Note that for %s=1 (g2o), only %s needs be set if we ignore orientation. For %s=2 (GTSAM), instead of optimizing the landmark's position directly, a bearing/range factor is used, with %s as the variance of the range factor (with 9999 to optimize the position with only a bearing factor) and %s as the variance of the bearing factor (pitch/yaw).", kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kMarkerVarianceAngular().c_str()));
|
RTABMAP_PARAM(Marker, VarianceOrientationIgnored, bool, false, uFormat("When this setting is false, the landmark's orientation is optimized during graph optimization. When this setting is true, only the position of the landmark is optimized. This can be useful when the landmark's orientation estimation is not reliable. Note that for %s=1 (g2o), only %s needs be set if we ignore orientation. For %s=2 (GTSAM), instead of optimizing the landmark's position directly, a bearing/range factor is used, with %s as the variance of the range factor (with 9999 to optimize the position with only a bearing factor) and %s as the variance of the bearing factor (pitch/yaw).", kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kMarkerVarianceAngular().c_str()));
|
||||||
RTABMAP_PARAM(Marker, CornerRefinementMethod, int, 0, "Corner refinement method (0: None, 1: Subpixel, 2:contour, 3: AprilTag2). For OpenCV <3.3.0, this is \"doCornerRefinement\" parameter: set 0 for false and 1 for true.");
|
|
||||||
RTABMAP_PARAM(Marker, MaxRange, float, 0.0, "Maximum range in which markers will be detected. <=0 for unlimited range.");
|
RTABMAP_PARAM(Marker, MaxRange, float, 0.0, "Maximum range in which markers will be detected. <=0 for unlimited range.");
|
||||||
RTABMAP_PARAM(Marker, MinRange, float, 0.0, "Miniminum range in which markers will be detected. <=0 for unlimited range.");
|
RTABMAP_PARAM(Marker, MinRange, float, 0.0, "Miniminum range in which markers will be detected. <=0 for unlimited range.");
|
||||||
RTABMAP_PARAM_STR(Marker, Priors, "", "World prior locations of the markers. The map will be transformed in marker's world frame when a tag is detected. Format is the marker's ID followed by its position (angles in rad), markers are separated by vertical line (\"id1 x y z roll pitch yaw|id2 x y z roll pitch yaw\"). Example: \"1 0 0 1 0 0 0|2 1 0 1 0 0 1.57\" (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).");
|
RTABMAP_PARAM_STR(Marker, Priors, "", "World prior locations of the markers. The map will be transformed in marker's world frame when a tag is detected. Format is the marker's ID followed by its position (angles in rad), markers are separated by vertical line (\"id1 x y z roll pitch yaw|id2 x y z roll pitch yaw\"). Example: \"1 0 0 1 0 0 0|2 1 0 1 0 0 1.57\" (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).");
|
||||||
RTABMAP_PARAM(Marker, PriorsVarianceLinear, float, 0.001, "Linear variance to set on marker priors.");
|
RTABMAP_PARAM(Marker, PriorsVarianceLinear, float, 0.001, "Linear variance to set on marker priors.");
|
||||||
RTABMAP_PARAM(Marker, PriorsVarianceAngular, float, 0.001, "Angular variance to set on marker priors.");
|
RTABMAP_PARAM(Marker, PriorsVarianceAngular, float, 0.001, "Angular variance to set on marker priors.");
|
||||||
|
|
||||||
|
RTABMAP_PARAM(MarkerAprilTag, NThreads, int, 1, "How many threads should be used?");
|
||||||
|
RTABMAP_PARAM(MarkerAprilTag, QuadDecimate, float, 2.0, "Detection of quads can be done on a lower-resolution image, improving speed at a cost of pose accuracy and a slight decrease in detection rate. Decoding the binary payload is still done at full resolution.");
|
||||||
|
RTABMAP_PARAM(MarkerAprilTag, QuadSigma, float, 0.0, "What Gaussian blur should be applied to the segmented image (used for quad detection?) Parameter is the standard deviation in pixels. Very noisy images benefit from non-zero values (e.g. 0.8).");
|
||||||
|
RTABMAP_PARAM(MarkerAprilTag, RefineEdges, bool, true, uFormat("When true, the edges of the each quad are adjusted to \"snap to\" strong gradients nearby. This is useful when decimation is employed, as it can increase the quality of the initial quad estimate substantially. Generally recommended to be on (true). Very computationally inexpensive. Option is ignored if %s = 1.", kMarkerAprilTagQuadDecimate().c_str()));
|
||||||
|
RTABMAP_PARAM(MarkerAprilTag, DecodeSharpening, double, 0.25, "How much sharpening should be done to decoded images? This can help decode small tags but may or may not help in odd lighting conditions or low light conditions.");
|
||||||
|
RTABMAP_PARAM(MarkerAprilTag, Debug, bool, false, uFormat("When true, write a variety of debugging images to the working directory where the app started (not %s) at various stages through the detection process. (Somewhat slow).", kRtabmapWorkingDirectory().c_str()));
|
||||||
|
|
||||||
|
RTABMAP_PARAM(MarkerOpenCV, CornerRefinementMethod, int, 0, "Corner refinement method for OpenCV strategy (0: None, 1: Subpixel, 2:contour, 3: AprilTag2). For OpenCV <3.3.0, this is \"doCornerRefinement\" parameter: set 0 for false and 1 for true.");
|
||||||
|
|
||||||
RTABMAP_PARAM(ImuFilter, MadgwickGain, double, 0.1, "Gain of the filter. Higher values lead to faster convergence but more noise. Lower values lead to slower convergence but smoother signal, belongs in [0, 1].");
|
RTABMAP_PARAM(ImuFilter, MadgwickGain, double, 0.1, "Gain of the filter. Higher values lead to faster convergence but more noise. Lower values lead to slower convergence but smoother signal, belongs in [0, 1].");
|
||||||
RTABMAP_PARAM(ImuFilter, MadgwickZeta, double, 0.0, "Gyro drift gain (approx. rad/s), belongs in [-1, 1].");
|
RTABMAP_PARAM(ImuFilter, MadgwickZeta, double, 0.0, "Gyro drift gain (approx. rad/s), belongs in [-1, 1].");
|
||||||
|
|
||||||
|
|||||||
@@ -534,8 +534,8 @@ IF(FastCV_FOUND)
|
|||||||
ENDIF(FastCV_FOUND)
|
ENDIF(FastCV_FOUND)
|
||||||
|
|
||||||
IF(apriltag_FOUND)
|
IF(apriltag_FOUND)
|
||||||
SET(LIBRARIES
|
SET(PUBLIC_LIBRARIES
|
||||||
${LIBRARIES}
|
${PUBLIC_LIBRARIES}
|
||||||
apriltag::apriltag
|
apriltag::apriltag
|
||||||
)
|
)
|
||||||
ENDIF(apriltag_FOUND)
|
ENDIF(apriltag_FOUND)
|
||||||
|
|||||||
+281
-30
@@ -28,17 +28,163 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/core/MarkerDetector.h>
|
#include <rtabmap/core/MarkerDetector.h>
|
||||||
#include <rtabmap/core/util2d.h>
|
#include <rtabmap/core/util2d.h>
|
||||||
#include <rtabmap/utilite/ULogger.h>
|
#include <rtabmap/utilite/ULogger.h>
|
||||||
|
#include <rtabmap/utilite/UStl.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENCV_ARUCO
|
||||||
|
#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <8)
|
||||||
|
namespace cv{
|
||||||
|
namespace aruco {
|
||||||
|
static const int DICT_ARUCO_MIP_36h12 = 21;
|
||||||
|
#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <7)
|
||||||
|
typedef PREDEFINED_DICTIONARY_NAME PredefinedDictionaryType;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RTABMAP_APRILTAG
|
#ifdef RTABMAP_APRILTAG
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "apriltag/apriltag.h"
|
#include "apriltag/apriltag.h"
|
||||||
#include "apriltag/apriltag_pose.h"
|
#include "apriltag/apriltag_pose.h"
|
||||||
|
#include "apriltag/aruco/tagAruco4x4_50.h"
|
||||||
|
#include "apriltag/aruco/tagAruco4x4_100.h"
|
||||||
|
#include "apriltag/aruco/tagAruco4x4_250.h"
|
||||||
|
#include "apriltag/aruco/tagAruco4x4_1000.h"
|
||||||
|
#include "apriltag/aruco/tagAruco5x5_50.h"
|
||||||
|
#include "apriltag/aruco/tagAruco5x5_100.h"
|
||||||
|
#include "apriltag/aruco/tagAruco5x5_250.h"
|
||||||
|
#include "apriltag/aruco/tagAruco5x5_1000.h"
|
||||||
|
#include "apriltag/aruco/tagAruco6x6_50.h"
|
||||||
|
#include "apriltag/aruco/tagAruco6x6_100.h"
|
||||||
|
#include "apriltag/aruco/tagAruco6x6_250.h"
|
||||||
|
#include "apriltag/aruco/tagAruco6x6_1000.h"
|
||||||
|
#include "apriltag/aruco/tagAruco7x7_50.h"
|
||||||
|
#include "apriltag/aruco/tagAruco7x7_100.h"
|
||||||
|
#include "apriltag/aruco/tagAruco7x7_250.h"
|
||||||
|
#include "apriltag/aruco/tagAruco7x7_1000.h"
|
||||||
|
#include "apriltag/tag16h5.h"
|
||||||
|
#include "apriltag/tag25h9.h"
|
||||||
|
#include "apriltag/tag36h10.h"
|
||||||
#include "apriltag/tag36h11.h"
|
#include "apriltag/tag36h11.h"
|
||||||
|
#include "apriltag/aruco/tagArucoMIP36h12.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_OPENCV_ARUCO
|
||||||
|
// To match opencv::aruco module, add opencv::aruco dictionary enum
|
||||||
|
namespace cv{
|
||||||
|
namespace aruco {
|
||||||
|
enum PredefinedDictionaryType {
|
||||||
|
DICT_4X4_50 = 0,
|
||||||
|
DICT_4X4_100,
|
||||||
|
DICT_4X4_250,
|
||||||
|
DICT_4X4_1000,
|
||||||
|
DICT_5X5_50,
|
||||||
|
DICT_5X5_100,
|
||||||
|
DICT_5X5_250,
|
||||||
|
DICT_5X5_1000,
|
||||||
|
DICT_6X6_50,
|
||||||
|
DICT_6X6_100,
|
||||||
|
DICT_6X6_250,
|
||||||
|
DICT_6X6_1000,
|
||||||
|
DICT_7X7_50,
|
||||||
|
DICT_7X7_100,
|
||||||
|
DICT_7X7_250,
|
||||||
|
DICT_7X7_1000,
|
||||||
|
DICT_ARUCO_ORIGINAL,
|
||||||
|
DICT_APRILTAG_16h5,
|
||||||
|
DICT_APRILTAG_25h9,
|
||||||
|
DICT_APRILTAG_36h10,
|
||||||
|
DICT_APRILTAG_36h11,
|
||||||
|
DICT_ARUCO_MIP_36h12
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
|
#ifdef RTABMAP_APRILTAG
|
||||||
|
|
||||||
|
#define ARUCO_CASE(N, TOTAL) \
|
||||||
|
case cv::aruco::DICT_##N##X##N##_##TOTAL: \
|
||||||
|
af = tagAruco##N##x##N##_##TOTAL##_create(); \
|
||||||
|
break;
|
||||||
|
#define APRILTAG_CASE(N1, N2) \
|
||||||
|
case cv::aruco::DICT_APRILTAG_##N1##h##N2: \
|
||||||
|
af = tag##N1##h##N2##_create(); \
|
||||||
|
break;
|
||||||
|
|
||||||
|
apriltag_family_t * createAprilTagPredefinedDictionary(int opencvArucoDictionary)
|
||||||
|
{
|
||||||
|
apriltag_family_t * af = NULL;
|
||||||
|
switch(opencvArucoDictionary)
|
||||||
|
{
|
||||||
|
ARUCO_CASE(4, 50)
|
||||||
|
ARUCO_CASE(4, 100)
|
||||||
|
ARUCO_CASE(4, 250)
|
||||||
|
ARUCO_CASE(4, 1000)
|
||||||
|
ARUCO_CASE(5, 50)
|
||||||
|
ARUCO_CASE(5, 100)
|
||||||
|
ARUCO_CASE(5, 250)
|
||||||
|
ARUCO_CASE(5, 1000)
|
||||||
|
ARUCO_CASE(6, 50)
|
||||||
|
ARUCO_CASE(6, 100)
|
||||||
|
ARUCO_CASE(6, 250)
|
||||||
|
ARUCO_CASE(6, 1000)
|
||||||
|
ARUCO_CASE(7, 50)
|
||||||
|
ARUCO_CASE(7, 100)
|
||||||
|
ARUCO_CASE(7, 250)
|
||||||
|
ARUCO_CASE(7, 1000)
|
||||||
|
APRILTAG_CASE(16, 5)
|
||||||
|
APRILTAG_CASE(25, 9)
|
||||||
|
APRILTAG_CASE(36, 10)
|
||||||
|
APRILTAG_CASE(36, 11)
|
||||||
|
case cv::aruco::DICT_ARUCO_MIP_36h12:
|
||||||
|
af = tagArucoMIP36h12_create();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return af;
|
||||||
|
}
|
||||||
|
void destroyAprilTagDictionary(apriltag_family_t * dictionary)
|
||||||
|
{
|
||||||
|
if(dictionary == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const char* name = dictionary->name;
|
||||||
|
if(strcmp(name, "tagAruco4x4_50") == 0) tagAruco4x4_50_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco4x4_100") == 0) tagAruco4x4_100_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco4x4_250") == 0) tagAruco4x4_250_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco4x4_1000") == 0) tagAruco4x4_1000_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco5x5_50") == 0) tagAruco5x5_50_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco5x5_100") == 0) tagAruco5x5_100_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco5x5_250") == 0) tagAruco5x5_250_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco5x5_1000") == 0) tagAruco5x5_1000_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco6x6_50") == 0) tagAruco6x6_50_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco6x6_100") == 0) tagAruco6x6_100_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco6x6_250") == 0) tagAruco6x6_250_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco6x6_1000") == 0) tagAruco6x6_1000_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco7x7_50") == 0) tagAruco7x7_50_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco7x7_100") == 0) tagAruco7x7_100_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco7x7_250") == 0) tagAruco7x7_250_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagAruco7x7_1000") == 0) tagAruco7x7_1000_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tag16h5") == 0) tag16h5_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tag25h9") == 0) tag25h9_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tag36h10") == 0) tag36h10_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tag36h11") == 0) tag36h11_destroy(dictionary);
|
||||||
|
else if(strcmp(name, "tagArucoMIP_36h12") == 0) tagArucoMIP36h12_destroy(dictionary);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UFATAL("AprilTag: Didn't find the right desctructor for dictionary \"%s\"", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MarkerDetector::MarkerDetector(const ParametersMap & parameters) :
|
MarkerDetector::MarkerDetector(const ParametersMap & parameters) :
|
||||||
strategy_((Strategy)Parameters::defaultMarkerStrategy()),
|
strategy_((Strategy)Parameters::defaultMarkerStrategy()),
|
||||||
markerLength_(Parameters::defaultMarkerLength()),
|
markerLength_(Parameters::defaultMarkerLength()),
|
||||||
@@ -58,11 +204,11 @@ MarkerDetector::MarkerDetector(const ParametersMap & parameters) :
|
|||||||
detectorParams_.reset(new cv::aruco::DetectorParameters());
|
detectorParams_.reset(new cv::aruco::DetectorParameters());
|
||||||
#endif
|
#endif
|
||||||
#if CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION >= 7)
|
#if CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION >= 7)
|
||||||
detectorParams_->cornerRefinementMethod = (cv::aruco::CornerRefineMethod) Parameters::defaultMarkerCornerRefinementMethod();
|
detectorParams_->cornerRefinementMethod = (cv::aruco::CornerRefineMethod) Parameters::defaultMarkerOpenCVCornerRefinementMethod();
|
||||||
#elif CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION == 3 && CV_MINOR_VERSION >=3)
|
#elif CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION == 3 && CV_MINOR_VERSION >=3)
|
||||||
detectorParams_->cornerRefinementMethod = Parameters::defaultMarkerCornerRefinementMethod();
|
detectorParams_->cornerRefinementMethod = Parameters::defaultMarkerOpenCVCornerRefinementMethod();
|
||||||
#else
|
#else
|
||||||
detectorParams_->doCornerRefinement = Parameters::defaultMarkerCornerRefinementMethod()!=0;
|
detectorParams_->doCornerRefinement = Parameters::defaultMarkerOpenCVCornerRefinementMethod()!=0;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -77,7 +223,7 @@ MarkerDetector::~MarkerDetector() {
|
|||||||
}
|
}
|
||||||
if(apriltagLibFamily_)
|
if(apriltagLibFamily_)
|
||||||
{
|
{
|
||||||
tag36h11_destroy((apriltag_family_t*)apriltagLibFamily_);
|
destroyAprilTagDictionary((apriltag_family_t*)apriltagLibFamily_);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -92,6 +238,36 @@ void MarkerDetector::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::parse(parameters, Parameters::kMarkerMaxRange(), maxRange_);
|
Parameters::parse(parameters, Parameters::kMarkerMaxRange(), maxRange_);
|
||||||
Parameters::parse(parameters, Parameters::kMarkerMinRange(), minRange_);
|
Parameters::parse(parameters, Parameters::kMarkerMinRange(), minRange_);
|
||||||
Parameters::parse(parameters, Parameters::kMarkerDictionary(), dictionaryId_);
|
Parameters::parse(parameters, Parameters::kMarkerDictionary(), dictionaryId_);
|
||||||
|
|
||||||
|
if(parameters.find(Parameters::kMarkerLengths()) != parameters.end())
|
||||||
|
{
|
||||||
|
markerLengths_.clear();
|
||||||
|
std::string strLengths;
|
||||||
|
Parameters::parse(parameters, Parameters::kMarkerLengths(), strLengths);
|
||||||
|
std::list<std::string> strList = uSplit(strLengths, '|');
|
||||||
|
for(std::list<std::string>::iterator iter=strList.begin(); iter!=strList.end(); ++iter)
|
||||||
|
{
|
||||||
|
std::list<std::string> items = uSplit(*iter, ' ');
|
||||||
|
if(items.size() != 2)
|
||||||
|
{
|
||||||
|
UERROR("Invalid string format \"%s\" for parameter %s, make "
|
||||||
|
"sure the values are separated by single space and/or '|'. See "
|
||||||
|
"description of the parameter for example. That parameter "
|
||||||
|
"will be ignored.",
|
||||||
|
strLengths.c_str(),
|
||||||
|
Parameters::kMarkerLengths().c_str());
|
||||||
|
markerLengths_.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int id = uStr2Int(items.front());
|
||||||
|
float length = uStr2Float(items.back());
|
||||||
|
UDEBUG("Adding marker %d with length %f", id, length);
|
||||||
|
markerLengths_.insert(std::make_pair(id, length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_OPENCV_ARUCO
|
#ifdef HAVE_OPENCV_ARUCO
|
||||||
detectorParams_->adaptiveThreshWinSizeMin = 3;
|
detectorParams_->adaptiveThreshWinSizeMin = 3;
|
||||||
@@ -106,13 +282,13 @@ void MarkerDetector::parseParameters(const ParametersMap & parameters)
|
|||||||
detectorParams_->minMarkerDistanceRate = 0.05;
|
detectorParams_->minMarkerDistanceRate = 0.05;
|
||||||
#if CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION >= 7)
|
#if CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION >= 7)
|
||||||
int cornerRefinementMethod;
|
int cornerRefinementMethod;
|
||||||
Parameters::parse(parameters, Parameters::kMarkerCornerRefinementMethod(), cornerRefinementMethod);
|
Parameters::parse(parameters, Parameters::kMarkerOpenCVCornerRefinementMethod(), cornerRefinementMethod);
|
||||||
detectorParams_->cornerRefinementMethod = (cv::aruco::CornerRefineMethod)cornerRefinementMethod;
|
detectorParams_->cornerRefinementMethod = (cv::aruco::CornerRefineMethod)cornerRefinementMethod;
|
||||||
#elif CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION == 3 && CV_MINOR_VERSION >=3)
|
#elif CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION == 3 && CV_MINOR_VERSION >=3)
|
||||||
Parameters::parse(parameters, Parameters::kMarkerCornerRefinementMethod(), detectorParams_->cornerRefinementMethod);
|
Parameters::parse(parameters, Parameters::kMarkerOpenCVCornerRefinementMethod(), detectorParams_->cornerRefinementMethod);
|
||||||
#else
|
#else
|
||||||
int doCornerRefinement = detectorParams_->doCornerRefinement?1:0;
|
int doCornerRefinement = detectorParams_->doCornerRefinement?1:0;
|
||||||
Parameters::parse(parameters, Parameters::kMarkerCornerRefinementMethod(), doCornerRefinement);
|
Parameters::parse(parameters, Parameters::kMarkerOpenCVCornerRefinementMethod(), doCornerRefinement);
|
||||||
detectorParams_->doCornerRefinement = doCornerRefinement!=0;
|
detectorParams_->doCornerRefinement = doCornerRefinement!=0;
|
||||||
#endif
|
#endif
|
||||||
detectorParams_->cornerRefinementWinSize = 5;
|
detectorParams_->cornerRefinementWinSize = 5;
|
||||||
@@ -127,7 +303,7 @@ void MarkerDetector::parseParameters(const ParametersMap & parameters)
|
|||||||
|
|
||||||
|
|
||||||
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION <4 || (CV_MINOR_VERSION ==4 && CV_SUBMINOR_VERSION<2)))
|
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION <4 || (CV_MINOR_VERSION ==4 && CV_SUBMINOR_VERSION<2)))
|
||||||
if(dictionaryId_ >= 17 && strategy_ == 0)
|
if(dictionaryId_ = 17 && strategy_ == 0)
|
||||||
{
|
{
|
||||||
UERROR("Cannot set AprilTag dictionary. OpenCV version should be at least 3.4.2, "
|
UERROR("Cannot set AprilTag dictionary. OpenCV version should be at least 3.4.2, "
|
||||||
"current version is %s. Setting %s to default (%d)",
|
"current version is %s. Setting %s to default (%d)",
|
||||||
@@ -136,37 +312,67 @@ void MarkerDetector::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::defaultMarkerDictionary());
|
Parameters::defaultMarkerDictionary());
|
||||||
dictionaryId_ = Parameters::defaultMarkerDictionary();
|
dictionaryId_ = Parameters::defaultMarkerDictionary();
|
||||||
}
|
}
|
||||||
|
#elif CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <8)
|
||||||
|
if(dictionaryId_ == 21 && strategy_ == 0)
|
||||||
|
{
|
||||||
|
UERROR("Cannot set ARUCO_MIP_36h12 dictionary. OpenCV version should be at least 4.8.0, "
|
||||||
|
"current version is %s. Setting %s to default (%d)",
|
||||||
|
CV_VERSION,
|
||||||
|
Parameters::kMarkerDictionary().c_str(),
|
||||||
|
Parameters::defaultMarkerDictionary());
|
||||||
|
dictionaryId_ = Parameters::defaultMarkerDictionary();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION >= 7)
|
#if CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION >= 7)
|
||||||
dictionary_.reset(new cv::aruco::Dictionary());
|
dictionary_.reset(new cv::aruco::Dictionary());
|
||||||
*dictionary_ = cv::aruco::getPredefinedDictionary(cv::aruco::PredefinedDictionaryType(dictionaryId_));
|
*dictionary_ = cv::aruco::getPredefinedDictionary(cv::aruco::PredefinedDictionaryType(dictionaryId_));
|
||||||
#elif CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION == 3 && CV_MINOR_VERSION >=2)
|
#elif CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION == 3 && CV_MINOR_VERSION >=2)
|
||||||
dictionary_ = cv::aruco::getPredefinedDictionary(cv::aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId_));
|
dictionary_ = cv::aruco::getPredefinedDictionary(cv::aruco::PredefinedDictionaryType(dictionaryId_));
|
||||||
#else
|
#else
|
||||||
dictionary_.reset(new cv::aruco::Dictionary());
|
dictionary_.reset(new cv::aruco::Dictionary());
|
||||||
*dictionary_ = cv::aruco::getPredefinedDictionary(cv::aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId_));
|
*dictionary_ = cv::aruco::getPredefinedDictionary(cv::aruco::PredefinedDictionaryType(dictionaryId_));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RTABMAP_APRILTAG
|
#ifdef RTABMAP_APRILTAG
|
||||||
if(apriltagLibDetector_)
|
if(apriltagLibDetector_ && apriltagLibFamily_) {
|
||||||
{
|
apriltag_detector_remove_family(((apriltag_detector_t*)apriltagLibDetector_), (apriltag_family_t*)apriltagLibFamily_);
|
||||||
apriltag_detector_destroy(((apriltag_detector_t*)apriltagLibDetector_));
|
|
||||||
apriltagLibDetector_ = NULL;
|
|
||||||
}
|
}
|
||||||
if(apriltagLibFamily_)
|
if(apriltagLibFamily_)
|
||||||
{
|
{
|
||||||
tag36h11_destroy((apriltag_family_t*)apriltagLibFamily_);
|
destroyAprilTagDictionary((apriltag_family_t*)apriltagLibFamily_);
|
||||||
apriltagLibFamily_ = NULL;
|
apriltagLibFamily_ = NULL;
|
||||||
}
|
}
|
||||||
apriltagLibDetector_ = apriltag_detector_create();
|
if(strategy_ == 1)
|
||||||
((apriltag_detector_t*)apriltagLibDetector_)->nthreads = 2;
|
{
|
||||||
((apriltag_detector_t*)apriltagLibDetector_)->quad_decimate = 1;
|
if(apriltagLibDetector_ == NULL)
|
||||||
apriltagLibFamily_ = tag36h11_create();
|
{
|
||||||
apriltag_detector_add_family(((apriltag_detector_t*)apriltagLibDetector_), (apriltag_family_t*)apriltagLibFamily_);
|
apriltagLibDetector_ = apriltag_detector_create();
|
||||||
|
}
|
||||||
|
Parameters::parse(parameters, Parameters::kMarkerAprilTagNThreads(), ((apriltag_detector_t*)apriltagLibDetector_)->nthreads);
|
||||||
|
Parameters::parse(parameters, Parameters::kMarkerAprilTagQuadDecimate(), ((apriltag_detector_t*)apriltagLibDetector_)->quad_decimate);
|
||||||
|
Parameters::parse(parameters, Parameters::kMarkerAprilTagQuadSigma(), ((apriltag_detector_t*)apriltagLibDetector_)->quad_sigma);
|
||||||
|
Parameters::parse(parameters, Parameters::kMarkerAprilTagRefineEdges(), ((apriltag_detector_t*)apriltagLibDetector_)->refine_edges);
|
||||||
|
Parameters::parse(parameters, Parameters::kMarkerAprilTagDecodeSharpening(), ((apriltag_detector_t*)apriltagLibDetector_)->decode_sharpening);
|
||||||
|
Parameters::parse(parameters, Parameters::kMarkerAprilTagDebug(), ((apriltag_detector_t*)apriltagLibDetector_)->debug);
|
||||||
|
|
||||||
if (errno == ENOMEM) {
|
cv::aruco::PredefinedDictionaryType dictFamily = cv::aruco::PredefinedDictionaryType(dictionaryId_);
|
||||||
UFATAL("Unable to add family to detector due to insufficient memory to allocate the tag-family decoder with the default maximum hamming value of 2. Try choosing an alternative tag family.");
|
if(dictFamily == cv::aruco::DICT_ARUCO_ORIGINAL)
|
||||||
|
{
|
||||||
|
UERROR("Cannot set ARUCO_ORIGINAL dictionary with AprilTag library implementation. "
|
||||||
|
"Use opencv-aruco implementation instead. Setting %s to default (%d)",
|
||||||
|
Parameters::kMarkerDictionary().c_str(),
|
||||||
|
Parameters::defaultMarkerDictionary());
|
||||||
|
dictionaryId_ = Parameters::defaultMarkerDictionary();
|
||||||
|
dictFamily = cv::aruco::PredefinedDictionaryType(dictionaryId_);
|
||||||
|
}
|
||||||
|
apriltagLibFamily_ = createAprilTagPredefinedDictionary(dictFamily);
|
||||||
|
UASSERT_MSG(apriltagLibFamily_ != NULL, uFormat("AprilTag library cannot be used with dictionary type %d", (int)dictionaryId_).c_str());
|
||||||
|
apriltag_detector_add_family(((apriltag_detector_t*)apriltagLibDetector_), (apriltag_family_t*)apriltagLibFamily_);
|
||||||
|
|
||||||
|
if (errno == ENOMEM) {
|
||||||
|
UFATAL("Unable to add family to detector due to insufficient memory to allocate the tag-family decoder with the default maximum hamming value of 2. Try choosing an alternative tag family.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -193,7 +399,7 @@ std::map<int, Transform> MarkerDetector::detect(const cv::Mat & image, const Cam
|
|||||||
std::map<int, MarkerInfo> MarkerDetector::detect(const cv::Mat & image,
|
std::map<int, MarkerInfo> MarkerDetector::detect(const cv::Mat & image,
|
||||||
const std::vector<CameraModel> & models,
|
const std::vector<CameraModel> & models,
|
||||||
const cv::Mat & depth,
|
const cv::Mat & depth,
|
||||||
const std::map<int, float> & markerLengths,
|
const std::map<int, float> & extraMarkerLengths,
|
||||||
cv::Mat * imageWithDetections)
|
cv::Mat * imageWithDetections)
|
||||||
{
|
{
|
||||||
UASSERT(!models.empty() && !image.empty());
|
UASSERT(!models.empty() && !image.empty());
|
||||||
@@ -226,8 +432,12 @@ std::map<int, MarkerInfo> MarkerDetector::detect(const cv::Mat & image,
|
|||||||
if(strategy_ == kStrategyApriltag)
|
if(strategy_ == kStrategyApriltag)
|
||||||
{
|
{
|
||||||
#ifdef RTABMAP_APRILTAG
|
#ifdef RTABMAP_APRILTAG
|
||||||
UASSERT(image.type() == CV_8UC1);
|
cv::Mat grayImage = image;
|
||||||
image_u8_t im = {image.cols, image.rows, (int)image.step, image.data};
|
if(image.channels() > 1)
|
||||||
|
{
|
||||||
|
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
|
||||||
|
}
|
||||||
|
image_u8_t im = {grayImage.cols, grayImage.rows, (int)grayImage.step, grayImage.data};
|
||||||
|
|
||||||
zarray_t *apriltagDetections = apriltag_detector_detect(((apriltag_detector_t*)apriltagLibDetector_), &im);
|
zarray_t *apriltagDetections = apriltag_detector_detect(((apriltag_detector_t*)apriltagLibDetector_), &im);
|
||||||
|
|
||||||
@@ -250,6 +460,15 @@ std::map<int, MarkerInfo> MarkerDetector::detect(const cv::Mat & image,
|
|||||||
int cameraIndex = int(det->c[0]) / subRGBWidth;
|
int cameraIndex = int(det->c[0]) / subRGBWidth;
|
||||||
UASSERT(cameraIndex>=0 && cameraIndex<(int)models.size());
|
UASSERT(cameraIndex>=0 && cameraIndex<(int)models.size());
|
||||||
|
|
||||||
|
if(!markerLengths_.empty() &&
|
||||||
|
markerLengths_.find(det->id) == markerLengths_.end() &&
|
||||||
|
extraMarkerLengths.find(det->id) == extraMarkerLengths.end())
|
||||||
|
{
|
||||||
|
UDEBUG("Ignoring marker %d because it is not in the list of expected markers (see %s)",
|
||||||
|
det->id,
|
||||||
|
Parameters::kMarkerLengths().c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(idsAdded.find(det->id)!=idsAdded.end())
|
if(idsAdded.find(det->id)!=idsAdded.end())
|
||||||
{
|
{
|
||||||
UWARN("Marker %d already added by another camera, ignoring detection from camera %d", det->id, cameraIndex);
|
UWARN("Marker %d already added by another camera, ignoring detection from camera %d", det->id, cameraIndex);
|
||||||
@@ -337,6 +556,15 @@ std::map<int, MarkerInfo> MarkerDetector::detect(const cv::Mat & image,
|
|||||||
int cameraIndex = int(cvCorners[i][0].x) / subRGBWidth;
|
int cameraIndex = int(cvCorners[i][0].x) / subRGBWidth;
|
||||||
UASSERT(cameraIndex>=0 && cameraIndex<(int)models.size());
|
UASSERT(cameraIndex>=0 && cameraIndex<(int)models.size());
|
||||||
|
|
||||||
|
if(!markerLengths_.empty() &&
|
||||||
|
markerLengths_.find(id) == markerLengths_.end() &&
|
||||||
|
extraMarkerLengths.find(id) == extraMarkerLengths.end())
|
||||||
|
{
|
||||||
|
UDEBUG("Ignoring marker %d because it is not in the list of expected markers (see %s)",
|
||||||
|
id,
|
||||||
|
Parameters::kMarkerLengths().c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(idsAdded.find(id) != idsAdded.end())
|
if(idsAdded.find(id) != idsAdded.end())
|
||||||
{
|
{
|
||||||
UWARN("Marker %d already added by another camera, ignoring detection from camera %d", id, cameraIndex);
|
UWARN("Marker %d already added by another camera, ignoring detection from camera %d", id, cameraIndex);
|
||||||
@@ -390,8 +618,8 @@ std::map<int, MarkerInfo> MarkerDetector::detect(const cv::Mat & image,
|
|||||||
for(size_t i=0; i<ids.size(); ++i)
|
for(size_t i=0; i<ids.size(); ++i)
|
||||||
{
|
{
|
||||||
float length = 0.0f;
|
float length = 0.0f;
|
||||||
std::map<int, float>::const_iterator findIter = markerLengths.find(ids[i]);
|
std::map<int, float>::const_iterator findIter = extraMarkerLengths.find(ids[i]);
|
||||||
if(!depth.empty() && (markerLength_ == 0 || (markerLength_<0 && findIter==markerLengths.end())))
|
if(markerLengths_.empty() && !depth.empty() && (markerLength_ == 0 || (markerLength_<0 && findIter==extraMarkerLengths.end())))
|
||||||
{
|
{
|
||||||
float d = util2d::getDepth(depth, (corners[i][0].x + (corners[i][2].x-corners[i][0].x)/2.0f)*rgbToDepthFactorX, (corners[i][0].y + (corners[i][2].y-corners[i][0].y)/2.0f)*rgbToDepthFactorY, true, 0.02f, true);
|
float d = util2d::getDepth(depth, (corners[i][0].x + (corners[i][2].x-corners[i][0].x)/2.0f)*rgbToDepthFactorX, (corners[i][0].y + (corners[i][2].y-corners[i][0].y)/2.0f)*rgbToDepthFactorY, true, 0.02f, true);
|
||||||
float d1 = util2d::getDepth(depth, corners[i][0].x*rgbToDepthFactorX, corners[i][0].y*rgbToDepthFactorY, true, 0.02f, true);
|
float d1 = util2d::getDepth(depth, corners[i][0].x*rgbToDepthFactorX, corners[i][0].y*rgbToDepthFactorY, true, 0.02f, true);
|
||||||
@@ -438,18 +666,41 @@ std::map<int, MarkerInfo> MarkerDetector::detect(const cv::Mat & image,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(markerLength_ < 0)
|
else if(!markerLengths_.empty() || findIter!=extraMarkerLengths.end())
|
||||||
{
|
{
|
||||||
if(findIter!=markerLengths.end())
|
std::map<int, float>::const_iterator paramIter = markerLengths_.find(ids[i]);
|
||||||
|
if(paramIter != markerLengths_.end())
|
||||||
|
{
|
||||||
|
if(findIter!=extraMarkerLengths.end() && findIter->second != paramIter->second)
|
||||||
|
{
|
||||||
|
UWARN("Marker's length of %d is defined both in extra lengths "
|
||||||
|
"(%f m) and the parameter %s (%f m), we will use the length "
|
||||||
|
"from extra lengths.",
|
||||||
|
findIter->second,
|
||||||
|
Parameters::kMarkerLengths().c_str(),
|
||||||
|
paramIter->second);
|
||||||
|
length = findIter->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = paramIter->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(findIter!=extraMarkerLengths.end())
|
||||||
{
|
{
|
||||||
length = findIter->second;
|
length = findIter->second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UWARN("Cannot find marker length for marker %d, ignoring this marker (count=%d)", ids[i], (int)markerLengths.size());
|
UERROR("Not supposed to reach this case, ignoring detection %d", ids[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(markerLength_ < 0)
|
||||||
|
{
|
||||||
|
UWARN("Cannot find marker length for marker %d, ignoring this marker (count=%d)", ids[i], (int)extraMarkerLengths.size());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if(markerLength_ > 0)
|
else if(markerLength_ > 0)
|
||||||
{
|
{
|
||||||
length = markerLength_;
|
length = markerLength_;
|
||||||
|
|||||||
@@ -238,6 +238,9 @@ const std::map<std::string, std::pair<bool, std::string> > & Parameters::getRemo
|
|||||||
{
|
{
|
||||||
// removed parameters
|
// removed parameters
|
||||||
|
|
||||||
|
// 0.23.7
|
||||||
|
removedParameters_.insert(std::make_pair("Marker/CornerRefinementMethod", std::make_pair(true, Parameters::kMarkerOpenCVCornerRefinementMethod())));
|
||||||
|
|
||||||
// 0.23.1
|
// 0.23.1
|
||||||
removedParameters_.insert(std::make_pair("OdomVINS/ConfigPath", std::make_pair(true, Parameters::kOdomVINSFusionConfigPath())));
|
removedParameters_.insert(std::make_pair("OdomVINS/ConfigPath", std::make_pair(true, Parameters::kOdomVINSFusionConfigPath())));
|
||||||
|
|
||||||
@@ -290,7 +293,7 @@ const std::map<std::string, std::pair<bool, std::string> > & Parameters::getRemo
|
|||||||
removedParameters_.insert(std::make_pair("Aruco/MaxDepthError", std::make_pair(true, Parameters::kMarkerMaxDepthError())));
|
removedParameters_.insert(std::make_pair("Aruco/MaxDepthError", std::make_pair(true, Parameters::kMarkerMaxDepthError())));
|
||||||
removedParameters_.insert(std::make_pair("Aruco/VarianceLinear", std::make_pair(true, Parameters::kMarkerVarianceLinear())));
|
removedParameters_.insert(std::make_pair("Aruco/VarianceLinear", std::make_pair(true, Parameters::kMarkerVarianceLinear())));
|
||||||
removedParameters_.insert(std::make_pair("Aruco/VarianceAngular", std::make_pair(true, Parameters::kMarkerVarianceAngular())));
|
removedParameters_.insert(std::make_pair("Aruco/VarianceAngular", std::make_pair(true, Parameters::kMarkerVarianceAngular())));
|
||||||
removedParameters_.insert(std::make_pair("Aruco/CornerRefinementMethod", std::make_pair(true, Parameters::kMarkerCornerRefinementMethod())));
|
removedParameters_.insert(std::make_pair("Aruco/CornerRefinementMethod", std::make_pair(true, Parameters::kMarkerOpenCVCornerRefinementMethod())));
|
||||||
|
|
||||||
// 0.17.5
|
// 0.17.5
|
||||||
removedParameters_.insert(std::make_pair("Grid/OctoMapOccupancyThr", std::make_pair(true, Parameters::kGridGlobalOccupancyThr())));
|
removedParameters_.insert(std::make_pair("Grid/OctoMapOccupancyThr", std::make_pair(true, Parameters::kGridGlobalOccupancyThr())));
|
||||||
@@ -681,6 +684,12 @@ ParametersMap Parameters::parseArguments(int argc, char * argv[], bool onlyParam
|
|||||||
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
|
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
|
||||||
#else
|
#else
|
||||||
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
|
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
|
||||||
|
#endif
|
||||||
|
str = "With AprilTag:";
|
||||||
|
#ifdef RTABMAP_APRILTAG
|
||||||
|
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
|
||||||
|
#else
|
||||||
|
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
str = "With OpenGV:";
|
str = "With OpenGV:";
|
||||||
#ifdef RTABMAP_OPENGV
|
#ifdef RTABMAP_OPENGV
|
||||||
|
|||||||
@@ -107,6 +107,13 @@ AboutDialog::AboutDialog(QWidget * parent) :
|
|||||||
_ui->label_fastcv->setText("No");
|
_ui->label_fastcv->setText("No");
|
||||||
_ui->label_fastcv_license->setEnabled(false);
|
_ui->label_fastcv_license->setEnabled(false);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RTABMAP_APRILTAG
|
||||||
|
_ui->label_apriltag->setText("Yes");
|
||||||
|
_ui->label_apriltag_license->setEnabled(true);
|
||||||
|
#else
|
||||||
|
_ui->label_apriltag->setText("No");
|
||||||
|
_ui->label_apriltag_license->setEnabled(false);
|
||||||
|
#endif
|
||||||
#ifdef RTABMAP_PDAL
|
#ifdef RTABMAP_PDAL
|
||||||
_ui->label_pdal->setText("Yes");
|
_ui->label_pdal->setText("Yes");
|
||||||
_ui->label_pdal_license->setEnabled(true);
|
_ui->label_pdal_license->setEnabled(true);
|
||||||
|
|||||||
@@ -476,14 +476,23 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//if OpenCV < 3.4.2
|
//if OpenCV < 3.4.2
|
||||||
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION <4 || (CV_MINOR_VERSION ==4 && CV_SUBMINOR_VERSION<2)))
|
#if !defined(RTABMAP_APRILTAG) && (CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION <4 || (CV_MINOR_VERSION ==4 && CV_SUBMINOR_VERSION<2))))
|
||||||
_ui->ArucoDictionary->setItemData(17, 0, Qt::UserRole - 1);
|
_ui->MarkerDictionary->setItemData(17, 0, Qt::UserRole - 1);
|
||||||
_ui->ArucoDictionary->setItemData(18, 0, Qt::UserRole - 1);
|
_ui->MarkerDictionary->setItemData(18, 0, Qt::UserRole - 1);
|
||||||
_ui->ArucoDictionary->setItemData(19, 0, Qt::UserRole - 1);
|
_ui->MarkerDictionary->setItemData(19, 0, Qt::UserRole - 1);
|
||||||
_ui->ArucoDictionary->setItemData(20, 0, Qt::UserRole - 1);
|
_ui->MarkerDictionary->setItemData(20, 0, Qt::UserRole - 1);
|
||||||
|
#endif
|
||||||
|
#if !defined(RTABMAP_APRILTAG) && (CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <8))
|
||||||
|
_ui->MarkerDictionary->setItemData(21, 0, Qt::UserRole - 1);
|
||||||
|
#endif
|
||||||
|
#if !defined(HAVE_OPENCV_ARUCO) && !defined(RTABMAP_APRILTAG)
|
||||||
|
_ui->label_markerDetection->setText(_ui->label_markerDetection->text()+" This option works only if OpenCV has been built with \"aruco\" module and/or RTAB-Map has been built with AprilTag library support.");
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_OPENCV_ARUCO
|
#ifndef HAVE_OPENCV_ARUCO
|
||||||
_ui->label_markerDetection->setText(_ui->label_markerDetection->text()+" This option works only if OpenCV has been built with \"aruco\" module.");
|
_ui->MarkerStrategy->setItemData(0, 0, Qt::UserRole - 1);
|
||||||
|
#endif
|
||||||
|
#ifndef RTABMAP_APRILTAG
|
||||||
|
_ui->MarkerStrategy->setItemData(1, 0, Qt::UserRole - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RTABMAP_MADGWICK
|
#ifndef RTABMAP_MADGWICK
|
||||||
@@ -1752,6 +1761,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
|
|
||||||
// Aruco marker
|
// Aruco marker
|
||||||
_ui->MarkerStrategy->setObjectName(Parameters::kMarkerStrategy().c_str());
|
_ui->MarkerStrategy->setObjectName(Parameters::kMarkerStrategy().c_str());
|
||||||
|
connect(_ui->MarkerStrategy, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_markerStrategy, SLOT(setCurrentIndex(int)));
|
||||||
|
_ui->MarkerStrategy->setCurrentIndex(Parameters::defaultMarkerStrategy());
|
||||||
_ui->MarkerDictionary->setObjectName(Parameters::kMarkerDictionary().c_str());
|
_ui->MarkerDictionary->setObjectName(Parameters::kMarkerDictionary().c_str());
|
||||||
_ui->ArucoMarkerLength->setObjectName(Parameters::kMarkerLength().c_str());
|
_ui->ArucoMarkerLength->setObjectName(Parameters::kMarkerLength().c_str());
|
||||||
_ui->ArucoMaxDepthError->setObjectName(Parameters::kMarkerMaxDepthError().c_str());
|
_ui->ArucoMaxDepthError->setObjectName(Parameters::kMarkerMaxDepthError().c_str());
|
||||||
@@ -1763,7 +1774,13 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
_ui->ArucoMarkerPriors->setObjectName(Parameters::kMarkerPriors().c_str());
|
_ui->ArucoMarkerPriors->setObjectName(Parameters::kMarkerPriors().c_str());
|
||||||
_ui->ArucoPriorsVarianceLinear->setObjectName(Parameters::kMarkerPriorsVarianceLinear().c_str());
|
_ui->ArucoPriorsVarianceLinear->setObjectName(Parameters::kMarkerPriorsVarianceLinear().c_str());
|
||||||
_ui->ArucoPriorsVarianceAngular->setObjectName(Parameters::kMarkerPriorsVarianceAngular().c_str());
|
_ui->ArucoPriorsVarianceAngular->setObjectName(Parameters::kMarkerPriorsVarianceAngular().c_str());
|
||||||
_ui->ArucoCornerRefinementMethod->setObjectName(Parameters::kMarkerCornerRefinementMethod().c_str());
|
_ui->ArucoCornerRefinementMethod->setObjectName(Parameters::kMarkerOpenCVCornerRefinementMethod().c_str());
|
||||||
|
_ui->apriltag_nthreads->setObjectName(Parameters::kMarkerAprilTagNThreads().c_str());
|
||||||
|
_ui->apriltag_quad_decimate->setObjectName(Parameters::kMarkerAprilTagQuadDecimate().c_str());
|
||||||
|
_ui->apriltag_quad_sigma->setObjectName(Parameters::kMarkerAprilTagQuadSigma().c_str());
|
||||||
|
_ui->apriltag_refine_edges->setObjectName(Parameters::kMarkerAprilTagRefineEdges().c_str());
|
||||||
|
_ui->apriltag_decode_sharpening->setObjectName(Parameters::kMarkerAprilTagDecodeSharpening().c_str());
|
||||||
|
_ui->apriltag_debug->setObjectName(Parameters::kMarkerAprilTagDebug().c_str());
|
||||||
|
|
||||||
// IMU filter
|
// IMU filter
|
||||||
_ui->doubleSpinBox_imuFilterMadgwickGain->setObjectName(Parameters::kImuFilterMadgwickGain().c_str());
|
_ui->doubleSpinBox_imuFilterMadgwickGain->setObjectName(Parameters::kImuFilterMadgwickGain().c_str());
|
||||||
@@ -3939,15 +3956,25 @@ bool PreferencesDialog::validateForm()
|
|||||||
_ui->checkbox_odomDisabled->setChecked(false);
|
_ui->checkbox_odomDisabled->setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION <4 || (CV_MINOR_VERSION ==4 && CV_SUBMINOR_VERSION<2)))
|
|
||||||
if(_ui->ArucoDictionary->currentIndex()>=17)
|
|
||||||
{
|
|
||||||
QMessageBox::warning(this, tr("Parameter warning"),
|
|
||||||
tr("ArUco dictionary: cannot select AprilTag dictionary, OpenCV version should be at least 3.4.2. Setting back to 0."));
|
|
||||||
_ui->ArucoDictionary->setCurrentIndex(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
if(_ui->MarkerStrategy->currentIndex() == 0)
|
||||||
|
{
|
||||||
|
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION <4 || (CV_MINOR_VERSION ==4 && CV_SUBMINOR_VERSION<2)))
|
||||||
|
if(_ui->MarkerDictionary->currentIndex()>=17)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Parameter warning"),
|
||||||
|
tr("opencv-aruco: cannot use the selected dictionary (%1), OpenCV version should be at least 3.4.2. Setting back to 0.").arg(_ui->MarkerDictionary->currentIndex()));
|
||||||
|
_ui->MarkerDictionary->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
#elif CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <8)
|
||||||
|
if(_ui->MarkerDictionary->currentIndex()>=21)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Parameter warning"),
|
||||||
|
tr("opencv-aruco: cannot use selected dictionary (%1), OpenCV version should be at least 4.8.0. Setting back to 0.").arg(_ui->MarkerDictionary->currentIndex()));
|
||||||
|
_ui->MarkerDictionary->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1524
-1491
File diff suppressed because it is too large
Load Diff
+506
-327
@@ -63,7 +63,7 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>-700</y>
|
<y>-526</y>
|
||||||
<width>684</width>
|
<width>684</width>
|
||||||
<height>5218</height>
|
<height>5218</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -15505,7 +15505,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_78">
|
<widget class="QWidget" name="page_78">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_137">
|
<layout class="QVBoxLayout" name="verticalLayout_137" stretch="0,1">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_markerDetection2">
|
<widget class="QGroupBox" name="groupBox_markerDetection2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -15514,10 +15514,69 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_136">
|
<layout class="QVBoxLayout" name="verticalLayout_136">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_63" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_63" columnstretch="0,1">
|
||||||
<item row="9" column="1">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_space2_14">
|
<widget class="QComboBox" name="MarkerStrategy">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>opencv-aruco</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>apriltag</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<widget class="QCheckBox" name="ArucoVarianceOrientationIgnored">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Maximum detection range (0=unlimited).</string>
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="ArucoVarianceLinear">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000001000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="ArucoMarkerLength">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> m</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_15">
|
||||||
|
<property name="text">
|
||||||
|
<string>World prior locations of the markers. The map will be transformed in marker's world frame when a tag is detected. Format is the marker's ID followed by its position (angles in rad), markers are separated by a vertical line ("id1 x y z roll pitch yaw|id2 x y z roll pitch yaw"). Example: "1 0 0 1 0 0 0|2 1 0 1 0 0 1.57" (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -15527,7 +15586,68 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="0">
|
<item row="10" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="ArucoMarkerRangeMax">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> m</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Angular variance to set on marker detections. If variance is adjusted to ignore orientation (see below), the angular variance is ignored with Optimizer/Strategy=1 (g2o) and it corresponds to bearing variance with Optimizer/Strategy=2 (GTSAM).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Marker length. The length (m) of the markers' side. Value <=0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization). If 0, the length is estimated only on the first marker detected, then re-used for all next detections (i.e., this assumes that markers have all the same length). With <0, the length is estimated once for each unique marker, then re-used for next detections with the same marker ID.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="12" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_16">
|
||||||
|
<property name="text">
|
||||||
|
<string>Linear variance to set on marker priors.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="13" column="0">
|
||||||
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceAngular">
|
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceAngular">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string/>
|
<string/>
|
||||||
@@ -15549,97 +15669,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_15">
|
|
||||||
<property name="text">
|
|
||||||
<string>World prior locations of the markers. The map will be transformed in marker's world frame when a tag is detected. Format is the marker's ID followed by its position (angles in rad), markers are separated by a vertical line ("id1 x y z roll pitch yaw|id2 x y z roll pitch yaw"). Example: "1 0 0 1 0 0 0|2 1 0 1 0 0 1.57" (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Linear variance to set on marker detections. If variance is adjusted to ignore orientation (see below) and Optimizer/Strategy=2 (GTSAM): it is the variance of the range factor, with 9999 to disable range factor and to do only bearing.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_13">
|
|
||||||
<property name="text">
|
|
||||||
<string>Minimum detection range (0=disabled).</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="12" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_17">
|
|
||||||
<property name="text">
|
|
||||||
<string>Angular variance to set on marker priors.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="ArucoMaxDepthError">
|
|
||||||
<property name="suffix">
|
|
||||||
<string> m</string>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>0.000100000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.010000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_10">
|
|
||||||
<property name="text">
|
|
||||||
<string>Dictionary to use.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="10" column="0">
|
|
||||||
<widget class="QLineEdit" name="ArucoMarkerPriors">
|
|
||||||
<property name="placeholderText">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QComboBox" name="MarkerDictionary">
|
<widget class="QComboBox" name="MarkerDictionary">
|
||||||
<item>
|
<item>
|
||||||
@@ -15749,10 +15778,10 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QLabel" name="label_space2_7">
|
<widget class="QLabel" name="label_space2_10">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Marker length. The length (m) of the markers' side. Value <=0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization). If 0, the length is estimated only on the first marker detected, then re-used for all next detections (i.e., this assumes that markers have all the same length). With <0, the length is estimated once for each unique marker, then re-used for next detections with the same marker ID.</string>
|
<string>Dictionary to use.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -15762,138 +15791,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_9">
|
|
||||||
<property name="text">
|
|
||||||
<string>Angular variance to set on marker detections. If variance is adjusted to ignore orientation (see below), the angular variance is ignored with Optimizer/Strategy=1 (g2o) and it corresponds to bearing variance with Optimizer/Strategy=2 (GTSAM).</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="RGBDMarkerDetection">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="11" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_16">
|
|
||||||
<property name="text">
|
|
||||||
<string>Linear variance to set on marker priors.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="ArucoMarkerRangeMax">
|
|
||||||
<property name="suffix">
|
|
||||||
<string> m</string>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>0.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>999.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="11" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceLinear">
|
|
||||||
<property name="suffix">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>0.000001000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.001000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.001000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QCheckBox" name="ArucoVarianceOrientationIgnored">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_8">
|
|
||||||
<property name="text">
|
|
||||||
<string>Maximum depth error between all corners of a marker when estimating the marker length (when marker length above is 0). The smaller it is, the more perpendicular the camera should be toward the marker to initialize the length.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="QLabel" name="label_space2_20">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>When this setting is false, the landmark's orientation is optimized during graph optimization. When this setting is true, only the position of the landmark is optimized. This can be useful when the landmark's orientation estimation is not reliable. Note that for Optimizer/Strategy=1 (g2o), only Marker/VarianceLinear needs be set if we ignore orientation. For Optimizer/Strategy=2 (GTSAM), instead of optimizing the landmark's position directly, a bearing/range factor is used, with Marker/VarianceLinear as the variance of the range factor (with 9999 to optimize the position with only a bearing factor) and Marker/VarianceAngular as the variance of the bearing factor (pitch/yaw).</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Adjust variance to ignore orientation during optimization. Mouseover for more details.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="ArucoVarianceAngular">
|
|
||||||
<property name="suffix">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>0.000001000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>9999.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.001000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.001000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_markerDetection">
|
<widget class="QLabel" name="label_markerDetection">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -15907,26 +15804,56 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="6" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="ArucoVarianceLinear">
|
<widget class="QLabel" name="label_space2_6">
|
||||||
<property name="suffix">
|
<property name="text">
|
||||||
<string/>
|
<string>Linear variance to set on marker detections. If variance is adjusted to ignore orientation (see below) and Optimizer/Strategy=2 (GTSAM): it is the variance of the range factor, with 9999 to disable range factor and to do only bearing.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="decimals">
|
<property name="wordWrap">
|
||||||
<number>6</number>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="textInteractionFlags">
|
||||||
<double>0.000001000000000</double>
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.001000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.001000000000000</double>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0">
|
<item row="11" column="0">
|
||||||
|
<widget class="QLineEdit" name="ArucoMarkerPriors">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="13" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_17">
|
||||||
|
<property name="text">
|
||||||
|
<string>Angular variance to set on marker priors.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_20">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>When this setting is false, the landmark's orientation is optimized during graph optimization. When this setting is true, only the position of the landmark is optimized. This can be useful when the landmark's orientation estimation is not reliable. Note that for Optimizer/Strategy=1 (g2o), only Marker/VarianceLinear needs be set if we ignore orientation. For Optimizer/Strategy=2 (GTSAM), instead of optimizing the landmark's position directly, a bearing/range factor is used, with Marker/VarianceLinear as the variance of the range factor (with 9999 to optimize the position with only a bearing factor) and Marker/VarianceAngular as the variance of the bearing factor (pitch/yaw).</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Adjust variance to ignore orientation during optimization. Mouseover for more details.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
<widget class="QDoubleSpinBox" name="ArucoMarkerRangeMin">
|
<widget class="QDoubleSpinBox" name="ArucoMarkerRangeMin">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> m</string>
|
<string> m</string>
|
||||||
@@ -15948,8 +15875,47 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="9" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="ArucoMarkerLength">
|
<widget class="QLabel" name="label_space2_13">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimum detection range (0=disabled).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_14">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum detection range (0=unlimited).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum depth error between all corners of a marker when estimating the marker length (when marker length above is 0). The smaller it is, the more perpendicular the camera should be toward the marker to initialize the length.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="ArucoMaxDepthError">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> m</string>
|
<string> m</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -15957,7 +15923,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<number>4</number>
|
<number>4</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<double>-1.000000000000000</double>
|
<double>0.000100000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="singleStep">
|
<property name="singleStep">
|
||||||
<double>0.010000000000000</double>
|
<double>0.010000000000000</double>
|
||||||
@@ -15967,18 +15933,30 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QComboBox" name="MarkerStrategy">
|
<widget class="QCheckBox" name="RGBDMarkerDetection">
|
||||||
<item>
|
<property name="text">
|
||||||
<property name="text">
|
<string/>
|
||||||
<string>opencv-aruco</string>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="12" column="0">
|
||||||
<property name="text">
|
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceLinear">
|
||||||
<string>apriltag</string>
|
<property name="suffix">
|
||||||
</property>
|
<string/>
|
||||||
</item>
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000001000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
@@ -15994,77 +15972,278 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="ArucoVarianceAngular">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000001000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>9999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLineEdit" name="ArucoMarkerLengths">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_25">
|
||||||
|
<property name="text">
|
||||||
|
<string>List of markers to detect. Format is the marker's ID followed by its length (in meters), markers are separated by a vertical line ("id1 length|id2 length"). If empty, all markers of the chosen dictionary can be detected and their length is set/estimated based on Marker Length. For example, to detect only markers 12 and 14 with lengths of 8 and 15 cm respectively, set "12 0.08|14 0.15".</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_31">
|
<widget class="QStackedWidget" name="stackedWidget_markerStrategy">
|
||||||
<property name="title">
|
<property name="currentIndex">
|
||||||
<string>OpenCV</string>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_106" columnstretch="0,1">
|
<widget class="QWidget" name="page_104">
|
||||||
<item row="1" column="0">
|
<layout class="QVBoxLayout" name="verticalLayout_189">
|
||||||
<widget class="QComboBox" name="ArucoCornerRefinementMethod">
|
<item>
|
||||||
<item>
|
<widget class="QGroupBox" name="groupBox_opencv_aruco">
|
||||||
<property name="text">
|
<property name="title">
|
||||||
<string>None</string>
|
<string>OpenCV</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<layout class="QGridLayout" name="gridLayout_106" columnstretch="0,1">
|
||||||
<item>
|
<item row="1" column="1">
|
||||||
<property name="text">
|
<widget class="QLabel" name="label_space2_11">
|
||||||
<string>Subpixel</string>
|
<property name="text">
|
||||||
|
<string>Corner refinement method.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QComboBox" name="ArucoCornerRefinementMethod">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Subpixel</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Contour</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>AprilTag 2</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<spacer name="verticalSpacer_94">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_105">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_190">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_apriltag">
|
||||||
|
<property name="title">
|
||||||
|
<string>AprilTag</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<layout class="QGridLayout" name="gridLayout_140" columnstretch="0,1">
|
||||||
<item>
|
<item row="4" column="1">
|
||||||
<property name="text">
|
<widget class="QLabel" name="label_space2_28">
|
||||||
<string>Contour</string>
|
<property name="text">
|
||||||
</property>
|
<string>decode_sharpening: How much sharpening should be done to decoded images? This can help decode small tags but may or may not help in odd lighting conditions or low light conditions.</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="wordWrap">
|
||||||
<property name="text">
|
<bool>true</bool>
|
||||||
<string>AprilTag 2</string>
|
</property>
|
||||||
</property>
|
<property name="textInteractionFlags">
|
||||||
</item>
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item row="1" column="1">
|
</item>
|
||||||
<widget class="QLabel" name="label_space2_11">
|
<item row="0" column="1">
|
||||||
<property name="text">
|
<widget class="QLabel" name="label_space2_22">
|
||||||
<string>Corner refinement method.</string>
|
<property name="text">
|
||||||
</property>
|
<string>nthreads: How many threads should be used?</string>
|
||||||
<property name="wordWrap">
|
</property>
|
||||||
<bool>true</bool>
|
<property name="wordWrap">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="textInteractionFlags">
|
</property>
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
<property name="textInteractionFlags">
|
||||||
</property>
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
</layout>
|
</item>
|
||||||
</widget>
|
<item row="0" column="0">
|
||||||
</item>
|
<widget class="QSpinBox" name="apriltag_nthreads">
|
||||||
<item>
|
<property name="minimum">
|
||||||
<widget class="QGroupBox" name="groupBox_43">
|
<number>1</number>
|
||||||
<property name="title">
|
</property>
|
||||||
<string>AprilTag</string>
|
<property name="value">
|
||||||
</property>
|
<number>1</number>
|
||||||
<layout class="QGridLayout" name="gridLayout_140" columnstretch="0,1">
|
</property>
|
||||||
<item row="0" column="1">
|
</widget>
|
||||||
<widget class="QLabel" name="label_space2_22">
|
</item>
|
||||||
<property name="text">
|
<item row="1" column="1">
|
||||||
<string>nthreads.</string>
|
<widget class="QLabel" name="label_space2_23">
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="wordWrap">
|
<string>quad_decimate: Detection of quads can be done on a lower-resolution image, improving speed at a cost of pose accuracy and a slight decrease in detection rate. Decoding the binary payload is still done at full resolution.</string>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
<property name="wordWrap">
|
||||||
<property name="textInteractionFlags">
|
<bool>true</bool>
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
</property>
|
||||||
</property>
|
<property name="textInteractionFlags">
|
||||||
</widget>
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
</item>
|
</property>
|
||||||
<item row="0" column="0">
|
</widget>
|
||||||
<widget class="QSpinBox" name="apriltag_nthreads"/>
|
</item>
|
||||||
</item>
|
<item row="3" column="1">
|
||||||
</layout>
|
<widget class="QLabel" name="label_space2_27">
|
||||||
|
<property name="text">
|
||||||
|
<string>refine_edges: When true, the edges of the each quad are adjusted to "snap to" strong gradients nearby. This is useful when decimation is employed, as it can increase the quality of the initial quad estimate substantially. Generally recommended to be on (true). Very computationally inexpensive. Option is ignored if quad_decimate = 1.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_26">
|
||||||
|
<property name="text">
|
||||||
|
<string>quad_sigma: What Gaussian blur should be applied to the segmented image (used for quad detection?) Parameter is the standard deviation in pixels. Very noisy images benefit from non-zero values (e.g. 0.8).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="label_space2_29">
|
||||||
|
<property name="text">
|
||||||
|
<string>debug: When true, write a variety of debugging images to the working directory where the app started (not RTAB-Map's working directory) at various stages through the detection process. (Somewhat slow).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="apriltag_debug">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="apriltag_refine_edges">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="apriltag_decode_sharpening">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.050000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.250000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="apriltag_quad_sigma">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>99.900000000000006</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QSpinBox" name="apriltag_quad_decimate">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
Reference in New Issue
Block a user