New parameter: Marker/Strategy (default opencv-aruco as before). Optimized multicameras marker detection (do only once with stitched image)

This commit is contained in:
matlabbe
2026-05-14 14:12:23 -07:00
parent 19515f0c65
commit 09c8bc80c1
4 changed files with 640 additions and 536 deletions
+2 -1
View File
@@ -1750,7 +1750,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->stereosgbm_mode->setObjectName(Parameters::kStereoSGBMMode().c_str());
// Aruco marker
_ui->ArucoDictionary->setObjectName(Parameters::kMarkerDictionary().c_str());
_ui->MarkerStrategy->setObjectName(Parameters::kMarkerStrategy().c_str());
_ui->MarkerDictionary->setObjectName(Parameters::kMarkerDictionary().c_str());
_ui->ArucoMarkerLength->setObjectName(Parameters::kMarkerLength().c_str());
_ui->ArucoMaxDepthError->setObjectName(Parameters::kMarkerMaxDepthError().c_str());
_ui->ArucoVarianceLinear->setObjectName(Parameters::kMarkerVarianceLinear().c_str());
+389 -337
View File
@@ -95,7 +95,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>14</number>
<number>18</number>
</property>
<widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,0">
@@ -15494,73 +15494,10 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<layout class="QVBoxLayout" name="verticalLayout_136">
<item>
<layout class="QGridLayout" name="gridLayout_63" columnstretch="0,1">
<item row="7" 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="4" 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="1" 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="8" column="1">
<widget class="QLabel" name="label_space2_15">
<item row="9" column="1">
<widget class="QLabel" name="label_space2_14">
<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 (&quot;id1 x y z roll pitch yaw|id2 x y z roll pitch yaw&quot;). Example: &quot;1 0 0 1 0 0 0|2 1 0 1 0 0 1.57&quot; (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).</string>
<string>Maximum detection range (0=unlimited).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -15570,20 +15507,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="6" 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="10" column="0">
<item row="12" column="0">
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceAngular">
<property name="suffix">
<string/>
@@ -15605,10 +15529,10 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="label_space2_16">
<item row="10" column="1">
<widget class="QLabel" name="label_space2_15">
<property name="text">
<string>Linear variance to set on marker priors.</string>
<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 (&quot;id1 x y z roll pitch yaw|id2 x y z roll pitch yaw&quot;). Example: &quot;1 0 0 1 0 0 0|2 1 0 1 0 0 1.57&quot; (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -15618,7 +15542,33 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="10" column="1">
<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>
@@ -15631,33 +15581,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="RGBDMarkerDetection">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" 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="2" column="0">
<item row="4" column="0">
<widget class="QDoubleSpinBox" name="ArucoMaxDepthError">
<property name="suffix">
<string> m</string>
@@ -15676,7 +15600,313 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</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">
<widget class="QComboBox" name="MarkerDictionary">
<item>
<property name="text">
<string>ARUCO_4X4_50</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_4X4_100</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_4X4_250</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_4X4_1000</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_5X5_50</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_5X5_100</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_5X5_250</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_5X5_1000</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_6X6_50</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_6X6_100</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_6X6_250</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_6X6_1000</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_7X7_50</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_7X7_100</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_7X7_250</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_7X7_1000</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_ORIGINAL</string>
</property>
</item>
<item>
<property name="text">
<string>APRILTAG_16h5</string>
</property>
</item>
<item>
<property name="text">
<string>APRILTAG_25h9</string>
</property>
</item>
<item>
<property name="text">
<string>APRILTAG_36h10</string>
</property>
</item>
<item>
<property name="text">
<string>APRILTAG_36h11</string>
</property>
</item>
</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 &lt;=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 &lt;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="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">
<widget class="QLabel" name="label_markerDetection">
<property name="text">
<string>Detect static markers to be added as landmarks for graph optimization. If input data have already landmarks, this will be ignored.</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="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="8" column="0">
<widget class="QDoubleSpinBox" name="ArucoMarkerRangeMin">
<property name="suffix">
<string> m</string>
@@ -15698,88 +15928,43 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="2" 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="3" 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="4" 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="9" column="0">
<widget class="QDoubleSpinBox" name="ArucoPriorsVarianceLinear">
<item row="3" column="0">
<widget class="QDoubleSpinBox" name="ArucoMarkerLength">
<property name="suffix">
<string/>
<string> m</string>
</property>
<property name="decimals">
<number>6</number>
<number>4</number>
</property>
<property name="minimum">
<double>0.000001000000000</double>
<double>-1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.001000000000000</double>
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.001000000000000</double>
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="7" 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="8" column="0">
<widget class="QLineEdit" name="ArucoMarkerPriors">
<property name="placeholderText">
<string/>
</property>
<item row="1" column="0">
<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="1" column="1">
<widget class="QLabel" name="label_space2_7">
<widget class="QLabel" name="label_space2_24">
<property name="text">
<string>Marker length. The length (m) of the markers' side. 0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization).</string>
<string>Detector implementation. Note that both aruco and apriltag dictionaries can be used with either strategy.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -15789,172 +15974,14 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_markerDetection">
<property name="text">
<string>Detect static markers to be added as landmarks for graph optimization. If input data have already landmarks, this will be ignored.</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_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="5" column="0">
<widget class="QCheckBox" name="ArucoVarianceOrientationIgnored">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_31">
<property name="title">
<string>ArUco</string>
<string>OpenCV</string>
</property>
<layout class="QGridLayout" name="gridLayout_106" columnstretch="0,1">
<item row="0" column="0">
<widget class="QComboBox" name="ArucoDictionary">
<item>
<property name="text">
<string>4X4_50</string>
</property>
</item>
<item>
<property name="text">
<string>4X4_100</string>
</property>
</item>
<item>
<property name="text">
<string>4X4_250</string>
</property>
</item>
<item>
<property name="text">
<string>4X4_1000</string>
</property>
</item>
<item>
<property name="text">
<string>5X5_50</string>
</property>
</item>
<item>
<property name="text">
<string>5X5_100</string>
</property>
</item>
<item>
<property name="text">
<string>5X5_250</string>
</property>
</item>
<item>
<property name="text">
<string>5X5_1000</string>
</property>
</item>
<item>
<property name="text">
<string>6X6_50</string>
</property>
</item>
<item>
<property name="text">
<string>6X6_100</string>
</property>
</item>
<item>
<property name="text">
<string>6X6_250</string>
</property>
</item>
<item>
<property name="text">
<string>6X6_1000</string>
</property>
</item>
<item>
<property name="text">
<string>7X7_50</string>
</property>
</item>
<item>
<property name="text">
<string>7X7_100</string>
</property>
</item>
<item>
<property name="text">
<string>7X7_250</string>
</property>
</item>
<item>
<property name="text">
<string>7X7_1000</string>
</property>
</item>
<item>
<property name="text">
<string>ARUCO_ORIGINAL</string>
</property>
</item>
<item>
<property name="text">
<string>APRILTAG_16h5</string>
</property>
</item>
<item>
<property name="text">
<string>APRILTAG_25h9</string>
</property>
</item>
<item>
<property name="text">
<string>APRILTAG_36h10</string>
</property>
</item>
<item>
<property name="text">
<string>APRILTAG_36h11</string>
</property>
</item>
</widget>
</item>
<item row="0" 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="1" column="0">
<widget class="QComboBox" name="ArucoCornerRefinementMethod">
<item>
@@ -15995,6 +16022,31 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_43">
<property name="title">
<string>AprilTag</string>
</property>
<layout class="QGridLayout" name="gridLayout_140" columnstretch="0,1">
<item row="0" column="1">
<widget class="QLabel" name="label_space2_22">
<property name="text">
<string>nthreads.</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="QSpinBox" name="apriltag_nthreads"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>