Refactored Odometry class:

-new odometry parameters
-new Optical flow strategy
-Stereo data support 
Refactored SensorData class to support stereo images
Updated default parameters (mostly odometry ones)
util3d: new methods to handle/reconstruct 3D clouds from disparity image / stereo images
PreferencesDialog: added Odometry/BOW and Odometry/OpticalFLow panels.
DatabaseViewer: fixed a crash when database is empty. Added cloud reconstruction of stereo images if saved in database
Camera: added 1 second delay to avoid dark images at the starting


git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1849 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2014-10-13 19:10:22 +00:00
parent a3f7415821
commit 8b67633b34
25 changed files with 2108 additions and 498 deletions

View File

@@ -65,7 +65,7 @@
<x>0</x>
<y>0</y>
<width>744</width>
<height>974</height>
<height>1019</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
@@ -86,7 +86,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>24</number>
</property>
<widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29">
@@ -3281,7 +3281,7 @@ generate the number of words requested.</string>
<item row="6" column="1">
<widget class="QLabel" name="label_101">
<property name="text">
<string>ROI ratios [left, right, top, bottom].</string>
<string>ROI ratios [left, right, top, bottom] between 0 and 1.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -5832,37 +5832,81 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_8">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_44">
<layout class="QGridLayout" name="gridLayout_27" columnstretch="0,1">
<item row="4" column="1">
<widget class="QLabel" name="label_47">
<property name="text">
<string>Feature detector </string>
<string>Automatically reset odometry after X consecutive images on which odometry cannot be computed (value=0 disables auto-reset).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QSpinBox" name="odom_localHistory">
<item row="0" column="0">
<widget class="QComboBox" name="odom_strategy">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>BOW (bag-of-words)</string>
</property>
</item>
<item>
<property name="text">
<string>Optical Flow</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_46">
<property name="text">
<string>Angular update: minimum angular distance to update the odometry.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QSpinBox" name="odom_refine_iterations">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>999999</number>
<number>10000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
<number>10</number>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="10" column="1">
<widget class="QLabel" name="label_111">
<property name="text">
<string>Local history size: If &gt; 0 (example 5000), the odometry will maintain a local map of X maximum words. This will decrease odometry drifting when the camera is not moving.</string>
<string>Refine iterations of the resulting transformation computed by RANSAC. 0 means no refining.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QSpinBox" name="odom_maxFeatures">
<property name="maximum">
<number>999999</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_136">
<property name="text">
<string>Max features extracted from the images (0 means inf).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -5870,32 +5914,6 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</widget>
</item>
<item row="3" column="0">
<widget class="QDoubleSpinBox" name="odom_linearUpdate">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.015000000000000</double>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Linear update: minimum linear distance to update the odometry.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QDoubleSpinBox" name="odom_angularUpdate">
<property name="suffix">
<string> m</string>
@@ -5911,96 +5929,10 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_46">
<property name="text">
<string>Angular update: minimum angular distance to update the odometry.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QSpinBox" name="odom_countdown">
<property name="maximum">
<number>999999</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_47">
<property name="text">
<string>Automatically reset odometry after X consecutive images on which odometry cannot be computed (value=0 disables auto-reset).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QSpinBox" name="odom_maxFeatures">
<property name="maximum">
<number>999999</number>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_136">
<property name="text">
<string>Max features extracted from the images (0 means inf).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QDoubleSpinBox" name="odom_inlierDistance">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.005000000000000</double>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QLabel" name="label_149">
<property name="text">
<string>Maximum distance for visual word correspondences. Lower the value, higher the precision but higher the chance of RED screens (odometry lost).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QSpinBox" name="odom_minInliers">
<property name="minimum">
<number>8</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="label_145">
<property name="text">
<string>Minimum visual word correspondences to compute geometry transform.</string>
<string>RANSAC: Maximum distance for 3D feature correspondences. Lower the value, higher the precision but higher the chance of RED screens (odometry lost).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -6023,17 +5955,14 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="label_36">
<property name="text">
<string>Maximum iterations to compute the transform from visual words.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
<item row="4" column="0">
<widget class="QSpinBox" name="odom_countdown">
<property name="maximum">
<number>999999</number>
</property>
</widget>
</item>
<item row="10" column="0">
<item row="11" column="0">
<widget class="QDoubleSpinBox" name="odom_ratio">
<property name="suffix">
<string/>
@@ -6055,7 +5984,7 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</property>
</widget>
</item>
<item row="10" column="1">
<item row="11" column="1">
<widget class="QLabel" name="label_90">
<property name="text">
<string>Minmum ratio of keypoints between the current image and the last image to compute odometry.</string>
@@ -6065,7 +5994,7 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</property>
</widget>
</item>
<item row="11" column="0">
<item row="12" column="0">
<widget class="QDoubleSpinBox" name="odom_maxDepth">
<property name="suffix">
<string> m</string>
@@ -6084,7 +6013,7 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</property>
</widget>
</item>
<item row="11" column="1">
<item row="12" column="1">
<widget class="QLabel" name="label_104">
<property name="text">
<string>Max feature depth.</string>
@@ -6094,49 +6023,75 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QComboBox" name="odom_bin_nn">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>FLANN Linear</string>
</property>
</item>
<item>
<property name="text">
<string>FLANN KdTree</string>
</property>
</item>
<item>
<property name="text">
<string>FLANN LSH</string>
</property>
</item>
<item>
<property name="text">
<string>Brute Force</string>
</property>
</item>
<item>
<property name="text">
<string>Brute Force GPU</string>
</property>
</item>
</widget>
</item>
<item row="12" column="1">
<widget class="QLabel" name="label_103">
<item row="7" column="1">
<widget class="QLabel" name="label_145">
<property name="text">
<string>Nearest neighbor strategy. FLANN KdTree must be used only with SURF/SIFT. FLANN LSH must be used only with binary feature detector.</string>
<string>Minimum feature correspondences to compute geometry transform.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="9" column="1">
<widget class="QLabel" name="label_36">
<property name="text">
<string>RANSAC: Maximum iterations to compute the transform from 3D features.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QSpinBox" name="odom_minInliers">
<property name="minimum">
<number>8</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QDoubleSpinBox" name="odom_linearUpdate">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.015000000000000</double>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QDoubleSpinBox" name="odom_inlierDistance">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.005000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="odom_type">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
@@ -6183,34 +6138,55 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</item>
</widget>
</item>
<item row="13" column="1">
<widget class="QLabel" name="label_123">
<item row="2" column="1">
<widget class="QLabel" name="label_45">
<property name="text">
<string>NNDR ratio
(A matching pair is accepted, if its distance is closer than X times the distance of the second nearest neighbor)
Lower the ratio -&gt; higher the precision. 0 means disabled, matching the nearest.</string>
<string>Linear update: minimum linear distance to update the odometry.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QDoubleSpinBox" name="odom_bin_nndrRatio">
<property name="decimals">
<number>1</number>
<item row="1" column="1">
<widget class="QLabel" name="label_44">
<property name="text">
<string>Feature detector. In BOW mode, the related descriptor is also used. In Optical flow mode, only the keypoint detector is used.</string>
</property>
<property name="minimum">
<double>0.100000000000000</double>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_103">
<property name="text">
<string>Odometry strategy:
1-BOW matches features extracted from both frames using nearest neighbor with descriptors, then computes RANSAC transformation estimation with corresponding 3D features.
2-Optical flow estimate the location of 2D features from last frame to new frame, then computes RANSAC transformation with corresponding 3D features.</string>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="value">
<double>0.700000000000000</double>
</widget>
</item>
<item row="6" column="0">
<widget class="QLineEdit" name="lineEdit_odom_roi">
<property name="text">
<string>0.0 0.0 0.0 0.0</string>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_123">
<property name="text">
<string>ROI ratios [left, right, top, bottom] between 0 and 1.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
@@ -6258,6 +6234,378 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
</item>
</layout>
</widget>
<widget class="QWidget" name="page_26">
<layout class="QVBoxLayout" name="verticalLayout_54">
<item>
<widget class="QGroupBox" name="groupBox_odometryBOW3">
<property name="title">
<string>BOW</string>
</property>
<layout class="QGridLayout" name="gridLayout_29" columnstretch="0,1">
<item row="0" column="0">
<widget class="QSpinBox" name="odom_localHistory">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_190">
<property name="text">
<string>Local history size: If &gt; 0 (example 5000), the odometry will maintain a local map of X maximum words. This will decrease odometry drifting when the camera is not moving.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="odom_bin_nn">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>FLANN Linear</string>
</property>
</item>
<item>
<property name="text">
<string>FLANN KdTree</string>
</property>
</item>
<item>
<property name="text">
<string>FLANN LSH</string>
</property>
</item>
<item>
<property name="text">
<string>Brute Force</string>
</property>
</item>
<item>
<property name="text">
<string>Brute Force GPU</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_201">
<property name="text">
<string>Nearest neighbor strategy. FLANN KdTree must be used only with SURF/SIFT. FLANN LSH must be used only with binary feature detector.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QDoubleSpinBox" name="odom_bin_nndrRatio">
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.700000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_202">
<property name="text">
<string>NNDR ratio
(A matching pair is accepted, if its distance is closer than X times the distance of the second nearest neighbor)
Lower the ratio -&gt; higher the precision. 0 means disabled, matching the nearest.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_27">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>670</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_28">
<layout class="QVBoxLayout" name="verticalLayout_55">
<item>
<widget class="QGroupBox" name="groupBox_odometryFlow3">
<property name="title">
<string>Optical Flow</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_53">
<item>
<widget class="QLabel" name="label_199">
<property name="text">
<string>The process is as follow:
- Features from the last frame are estimated in the new frame using an optical flow approach (see cv::calcOpticalFlowPyrLK()).
- 3D features from the new frame are extracted from the estimated positions.
- Using RANSAC, a transformation is estimated between corresponding 3D features.
- New features are extracted from the new frame to be used for the next time.
- Optionally, the 2D position of the features can be refined for sub pixel precision (see cv::cornerSubPix()). </string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>calcOpticalFlowPyrLK()</string>
</property>
<layout class="QGridLayout" name="gridLayout_30" columnstretch="0,1">
<item row="0" column="0">
<widget class="QSpinBox" name="odom_flow_winSize">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>21</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_192">
<property name="text">
<string>Window size.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QSpinBox" name="odom_flow_iterations">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>30</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_193">
<property name="text">
<string>Iterations.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QDoubleSpinBox" name="odom_flow_eps">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_194">
<property name="text">
<string>Epsilon.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_195">
<property name="text">
<string>Max level.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QSpinBox" name="odom_flow_maxLevel">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>cornerSubPix()</string>
</property>
<layout class="QGridLayout" name="gridLayout_31" columnstretch="0,1">
<item row="0" column="0">
<widget class="QSpinBox" name="odom_flow_subpix_winSize">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_196">
<property name="text">
<string>Window size for sub pixel estimation.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QSpinBox" name="odom_flow_subpix_iterations">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>20</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_197">
<property name="text">
<string>Iterations for sub pixel estimation. 0 disables sub pixel refining.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QDoubleSpinBox" name="odom_flow_subpix_eps">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.030000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_198">
<property name="text">
<string>Epsilon for sub pixel estimation.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_28">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>518</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>