Refactored OdometryOpticalFlow (added optical flow guess using previous odometry transform, merged stereo/depth stuff)

This commit is contained in:
matlabbe
2015-06-15 14:44:44 -04:00
parent b8dccc2228
commit dfbf6e721e
14 changed files with 785 additions and 671 deletions

View File

@@ -105,6 +105,7 @@ private slots:
void resetConstraint();
void rejectConstraint();
void updateConstraintView();
void updateStereo();
private:
QString getIniFilePath() const;

View File

@@ -102,6 +102,8 @@ DatabaseViewer::DatabaseViewer(QWidget * parent) :
ui_->constraintsViewer->setCameraLockZ(false);
ui_->constraintsViewer->setCameraFree();
ui_->graphicsView_stereo->setAlpha(255);
this->readSettings();
if(RTABMAP_NONFREE == 0)
@@ -215,6 +217,20 @@ DatabaseViewer::DatabaseViewer(QWidget * parent) :
connect(ui_->spinBox_projDecimation, SIGNAL(editingFinished()), this, SLOT(updateGrid()));
connect(ui_->doubleSpinBox_projMaxDepth, SIGNAL(editingFinished()), this, SLOT(updateGrid()));
connect(ui_->spinBox_stereo_flowIterations, SIGNAL(valueChanged(int)), this, SLOT(updateStereo()));
connect(ui_->spinBox_stereo_flowMaxLevel, SIGNAL(valueChanged(int)), this, SLOT(updateStereo()));
connect(ui_->spinBox_stereo_flowWinSize, SIGNAL(valueChanged(int)), this, SLOT(updateStereo()));
connect(ui_->spinBox_stereo_gfttBlockSize, SIGNAL(valueChanged(int)), this, SLOT(updateStereo()));
connect(ui_->doubleSpinBox_stereo_flowEps, SIGNAL(valueChanged(double)), this, SLOT(updateStereo()));
connect(ui_->doubleSpinBox_stereo_gfttMinDistance, SIGNAL(valueChanged(double)), this, SLOT(updateStereo()));
connect(ui_->doubleSpinBox_stereo_gfttQuality, SIGNAL(valueChanged(double)), this, SLOT(updateStereo()));
connect(ui_->doubleSpinBox_stereo_maxSlope, SIGNAL(valueChanged(double)), this, SLOT(updateStereo()));
connect(ui_->checkBox_stereo_subpix, SIGNAL(stateChanged(int)), this, SLOT(updateStereo()));
ui_->label_stereo_inliers_name->setStyleSheet("QLabel {color : blue; }");
ui_->label_stereo_flowOutliers_name->setStyleSheet("QLabel {color : red; }");
ui_->label_stereo_slopeOutliers_name->setStyleSheet("QLabel {color : yellow; }");
ui_->label_stereo_disparityOutliers_name->setStyleSheet("QLabel {color : magenta; }");
// connect configuration changed
connect(ui_->graphViewer, SIGNAL(configChanged()), this, SLOT(configModified()));
@@ -263,6 +279,16 @@ DatabaseViewer::DatabaseViewer(QWidget * parent) :
connect(ui_->doubleSpinBox_detectMore_radius, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_detectMore_angle, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->spinBox_detectMore_iterations, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
//stereo parameters
connect(ui_->spinBox_stereo_flowIterations, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_stereo_flowMaxLevel, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_stereo_flowWinSize, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_stereo_gfttBlockSize, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_stereo_flowEps, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_stereo_gfttMinDistance, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_stereo_gfttQuality, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_stereo_maxSlope, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->checkBox_stereo_subpix, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
// dockwidget
QList<QDockWidget*> dockWidgets = this->findChildren<QDockWidget*>();
for(int i=0; i<dockWidgets.size(); ++i)
@@ -387,6 +413,19 @@ void DatabaseViewer::readSettings()
ui_->spinBox_detectMore_iterations->setValue(settings.value("detectMoreIterations", ui_->spinBox_detectMore_iterations->value()).toInt());
settings.endGroup();
//Stereo parameters
settings.beginGroup("stereo");
ui_->spinBox_stereo_flowIterations->setValue(settings.value("flowIterations", ui_->spinBox_stereo_flowIterations->value()).toInt());
ui_->spinBox_stereo_flowMaxLevel->setValue(settings.value("flowMaxLevel", ui_->spinBox_stereo_flowMaxLevel->value()).toInt());
ui_->spinBox_stereo_flowWinSize->setValue(settings.value("flowWinSize", ui_->spinBox_stereo_flowWinSize->value()).toInt());
ui_->spinBox_stereo_gfttBlockSize->setValue(settings.value("gfttBlockSize", ui_->spinBox_stereo_gfttBlockSize->value()).toInt());
ui_->doubleSpinBox_stereo_flowEps->setValue(settings.value("flowEps", ui_->doubleSpinBox_stereo_flowEps->value()).toDouble());
ui_->doubleSpinBox_stereo_gfttMinDistance->setValue(settings.value("gfttMinDistance", ui_->doubleSpinBox_stereo_gfttMinDistance->value()).toDouble());
ui_->doubleSpinBox_stereo_gfttQuality->setValue(settings.value("gfttQuality", ui_->doubleSpinBox_stereo_gfttQuality->value()).toDouble());
ui_->doubleSpinBox_stereo_maxSlope->setValue(settings.value("maxSlope", ui_->doubleSpinBox_stereo_maxSlope->value()).toDouble());
ui_->checkBox_stereo_subpix->setChecked(settings.value("subpix", ui_->checkBox_stereo_subpix->isChecked()).toBool());
settings.endGroup();
settings.endGroup(); // DatabaseViewer
}
@@ -468,6 +507,19 @@ void DatabaseViewer::writeSettings()
settings.setValue("detectMoreIterations", ui_->spinBox_detectMore_iterations->value());
settings.endGroup();
//Stereo parameters
settings.beginGroup("stereo");
settings.setValue("flowIterations", ui_->spinBox_stereo_flowIterations->value());
settings.setValue("flowMaxLevel", ui_->spinBox_stereo_flowMaxLevel->value());
settings.setValue("flowWinSize", ui_->spinBox_stereo_flowWinSize->value());
settings.setValue("gfttBlockSize", ui_->spinBox_stereo_gfttBlockSize->value());
settings.setValue("flowEps", ui_->doubleSpinBox_stereo_flowEps->value());
settings.setValue("gfttMinDistance", ui_->doubleSpinBox_stereo_gfttMinDistance->value());
settings.setValue("gfttQuality", ui_->doubleSpinBox_stereo_gfttQuality->value());
settings.setValue("maxSlope", ui_->doubleSpinBox_stereo_maxSlope->value());
settings.setValue("subpix", ui_->checkBox_stereo_subpix->isChecked());
settings.endGroup();
settings.endGroup(); // DatabaseViewer
this->setWindowModified(false);
@@ -1535,6 +1587,11 @@ void DatabaseViewer::update(int value,
{
this->updateStereo(&data);
}
else
{
ui_->stereoViewer->clear();
ui_->graphicsView_stereo->clear();
}
// 3d view
if(view3D->isVisible() && !data.getDepthRaw().empty())
@@ -1688,6 +1745,16 @@ void DatabaseViewer::update(int value,
}
}
void DatabaseViewer::updateStereo()
{
if(ui_->horizontalSlider_A->maximum())
{
int id = ids_.at(ui_->horizontalSlider_A->value());
Signature data = memory_->getSignatureData(id, true);
updateStereo(&data);
}
}
void DatabaseViewer::updateStereo(const Signature * data)
{
if(data && ui_->dockWidget_stereoView->isVisible() && !data->getImageRaw().empty() && !data->getDepthRaw().empty() && data->getDepthRaw().type() == CV_8UC1)
@@ -1708,8 +1775,10 @@ void DatabaseViewer::updateStereo(const Signature * data)
std::vector<cv::KeyPoint> kpts;
cv::Rect roi = Feature2D::computeRoi(leftMono, "0.03 0.03 0.04 0.04");
ParametersMap parameters;
parameters.insert(ParametersPair(Parameters::kKpWordsPerImage(), "1000"));
parameters.insert(ParametersPair(Parameters::kGFTTMinDistance(), "5"));
parameters.insert(ParametersPair(Parameters::kKpWordsPerImage(), "0"));
parameters.insert(ParametersPair(Parameters::kGFTTMinDistance(), uNumber2Str(ui_->doubleSpinBox_stereo_gfttMinDistance->value())));
parameters.insert(ParametersPair(Parameters::kGFTTQualityLevel(), uNumber2Str(ui_->doubleSpinBox_stereo_gfttQuality->value())));
parameters.insert(ParametersPair(Parameters::kGFTTBlockSize(), uNumber2Str(ui_->spinBox_stereo_gfttBlockSize->value())));
Feature2D::Type type = Feature2D::kFeatureGfttBrief;
Feature2D * kptDetector = Feature2D::create(type, parameters);
kpts = kptDetector->generateKeypoints(leftMono, roi);
@@ -1720,6 +1789,19 @@ void DatabaseViewer::updateStereo(const Signature * data)
std::vector<cv::Point2f> leftCorners;
cv::KeyPoint::convert(kpts, leftCorners);
int subPixWinSize = 3;
int subPixIterations = 30;
double subPixEps = 0.02;
if(ui_->checkBox_stereo_subpix->isChecked())
{
UDEBUG("cv::cornerSubPix() begin");
cv::cornerSubPix(leftMono, leftCorners,
cv::Size( subPixWinSize, subPixWinSize ),
cv::Size( -1, -1 ),
cv::TermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, subPixIterations, subPixEps ) );
UDEBUG("cv::cornerSubPix() end");
}
// Find features in the new left image
std::vector<unsigned char> status;
std::vector<float> err;
@@ -1731,8 +1813,8 @@ void DatabaseViewer::updateStereo(const Signature * data)
rightCorners,
status,
err,
cv::Size(Parameters::defaultStereoWinSize(), Parameters::defaultStereoWinSize()), Parameters::defaultStereoMaxLevel(),
cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, Parameters::defaultStereoIterations(), Parameters::defaultStereoEps()));
cv::Size(ui_->spinBox_stereo_flowWinSize->value(), ui_->spinBox_stereo_flowWinSize->value()), ui_->spinBox_stereo_flowMaxLevel->value(),
cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, ui_->spinBox_stereo_flowIterations->value(), ui_->doubleSpinBox_stereo_flowEps->value()));
float timeFlow = timer.ticks();
@@ -1741,6 +1823,10 @@ void DatabaseViewer::updateStereo(const Signature * data)
float bad_point = std::numeric_limits<float>::quiet_NaN ();
UASSERT(status.size() == kpts.size());
int oi = 0;
int inliers = 0;
int flowOutliers= 0;
int slopeOutliers= 0;
int negativeDisparityOutliers = 0;
for(unsigned int i=0; i<status.size(); ++i)
{
pcl::PointXYZ pt(bad_point, bad_point, bad_point);
@@ -1749,7 +1835,7 @@ void DatabaseViewer::updateStereo(const Signature * data)
float disparity = leftCorners[i].x - rightCorners[i].x;
if(disparity > 0.0f)
{
if(fabs((leftCorners[i].y-rightCorners[i].y) / (leftCorners[i].x-rightCorners[i].x)) < Parameters::defaultStereoMaxSlope())
if(fabs((leftCorners[i].y-rightCorners[i].y) / (leftCorners[i].x-rightCorners[i].x)) < ui_->doubleSpinBox_stereo_maxSlope->value())
{
pcl::PointXYZ tmpPt = util3d::projectDisparityTo3D(
leftCorners[i],
@@ -1759,23 +1845,32 @@ void DatabaseViewer::updateStereo(const Signature * data)
if(pcl::isFinite(tmpPt))
{
pt = pcl::transformPoint(tmpPt, data->getLocalTransform().toEigen3f());
if(fabs(pt.x) > 2 || fabs(pt.y) > 2 || fabs(pt.z) > 2)
{
status[i] = 100; //blue
}
status[i] = 100; //blue
++inliers;
cloud->at(oi++) = pt;
}
}
else if(fabs(leftCorners[i].y-rightCorners[i].y) <=1.0f)
{
status[i] = 110; //cyan
++inliers;
}
else
{
status[i] = 101; //yellow
++slopeOutliers;
}
}
else
{
status[i] = 102; //magenta
++negativeDisparityOutliers;
}
}
else
{
++flowOutliers;
}
}
cloud->resize(oi);
@@ -1786,6 +1881,11 @@ void DatabaseViewer::updateStereo(const Signature * data)
ui_->stereoViewer->addOrUpdateCloud("stereo", cloud);
ui_->stereoViewer->update();
ui_->label_stereo_inliers->setNum(inliers);
ui_->label_stereo_flowOutliers->setNum(flowOutliers);
ui_->label_stereo_slopeOutliers->setNum(slopeOutliers);
ui_->label_stereo_disparityOutliers->setNum(negativeDisparityOutliers);
std::vector<cv::KeyPoint> rightKpts;
cv::KeyPoint::convert(rightCorners, rightKpts);
std::vector<cv::DMatch> good_matches(kpts.size());
@@ -1832,6 +1932,10 @@ void DatabaseViewer::updateStereo(const Signature * data)
{
c = Qt::magenta;
}
else if(status[i] == 110)
{
c = Qt::cyan;
}
ui_->graphicsView_stereo->addLine(
kpts[i].pt.x,
kpts[i].pt.y,

View File

@@ -880,20 +880,21 @@ void MainWindow::processOdometry(const rtabmap::SensorData & data, const rtabmap
{
//draw lines
UASSERT(info.refCorners.size() == info.newCorners.size());
for(unsigned int i=0; i<info.cornerInliers.size(); ++i)
std::set<int> inliers(info.cornerInliers.begin(), info.cornerInliers.end());
for(unsigned int i=0; i<info.refCorners.size(); ++i)
{
if(_ui->imageView_odometry->isFeaturesShown())
if(_ui->imageView_odometry->isFeaturesShown() && inliers.find(i) != inliers.end())
{
_ui->imageView_odometry->setFeatureColor(info.cornerInliers[i], Qt::green); // inliers
_ui->imageView_odometry->setFeatureColor(i, Qt::green); // inliers
}
if(_ui->imageView_odometry->isLinesShown())
{
_ui->imageView_odometry->addLine(
info.refCorners[info.cornerInliers[i]].x,
info.refCorners[info.cornerInliers[i]].y,
info.newCorners[info.cornerInliers[i]].x,
info.newCorners[info.cornerInliers[i]].y,
Qt::blue);
info.refCorners[i].x,
info.refCorners[i].y,
info.newCorners[i].x,
info.newCorners[i].y,
inliers.find(i) != inliers.end()?Qt::blue:Qt::yellow);
}
}
}
@@ -975,6 +976,10 @@ void MainWindow::processOdometry(const rtabmap::SensorData & data, const rtabmap
_ui->statsToolBox->updateStat("Odometry/Interval/ms", (float)data.id(), info.interval*1000.f);
_ui->statsToolBox->updateStat("Odometry/Speed/kph", (float)data.id(), x/info.interval*3.6f);
}
if(info.distanceTravelled > 0)
{
_ui->statsToolBox->updateStat("Odometry/Distance/m", (float)data.id(), info.distanceTravelled);
}
_ui->statsToolBox->updateStat("/Gui refresh odom/ms", (float)data.id(), time.elapsed()*1000.0);
_processingOdometry = false;
@@ -993,7 +998,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
int loopMapId = uValue(stat.getMapIds(), stat.loopClosureId(), uValue(stat.getMapIds(), stat.localLoopClosureId(), -1));
_ui->label_refId->setText(QString("New ID = %1 [%2]").arg(stat.refImageId()).arg(refMapId));
_ui->label_matchId->clear();
if(stat.extended())
{
@@ -1252,6 +1256,10 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
_ui->label_stats_loopClosuresDetected->setText(QString::number(_ui->label_stats_loopClosuresDetected->text().toInt() + 1));
_ui->label_matchId->setText(QString("Match ID = %1 [%2]").arg(stat.loopClosureId()).arg(loopMapId));
}
else
{
_ui->label_matchId->clear();
}
float elapsedTime = static_cast<float>(totalTime.elapsed());
UINFO("Updating GUI time = %fs", elapsedTime/1000.0f);
_ui->statsToolBox->updateStat("/Gui refresh stats/ms", stat.refImageId(), elapsedTime);
@@ -2902,7 +2910,14 @@ void MainWindow::startDetection()
if(_dataRecorder)
{
UEventsManager::createPipe(_camera, _dataRecorder, "CameraEvent");
if(_camera)
{
UEventsManager::createPipe(_camera, _dataRecorder, "CameraEvent");
}
else if(_dbReader)
{
UEventsManager::createPipe(_dbReader, _dataRecorder, "CameraEvent");
}
}
_lastOdomPose.setNull();

View File

@@ -50,7 +50,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>172</width>
<width>196</width>
<height>184</height>
</rect>
</property>
@@ -200,6 +200,9 @@
</item>
<item>
<widget class="QSlider" name="horizontalSlider_A">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -233,7 +236,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>172</width>
<width>195</width>
<height>184</height>
</rect>
</property>
@@ -383,6 +386,9 @@
</item>
<item>
<widget class="QSlider" name="horizontalSlider_B">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -479,6 +485,9 @@
</item>
<item row="0" column="1">
<widget class="QSlider" name="horizontalSlider_neighbors">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -496,6 +505,9 @@
</item>
<item row="1" column="1">
<widget class="QSlider" name="horizontalSlider_loops">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -654,6 +666,9 @@
</item>
<item>
<widget class="QSlider" name="horizontalSlider_iterations">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -783,14 +798,14 @@
<item>
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>1</number>
<number>5</number>
</property>
<widget class="QWidget" name="page">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>315</width>
<width>312</width>
<height>314</height>
</rect>
</property>
@@ -1009,7 +1024,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-12</y>
<y>0</y>
<width>351</width>
<height>355</height>
</rect>
@@ -1510,7 +1525,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>315</width>
<width>248</width>
<height>319</height>
</rect>
</property>
@@ -1704,8 +1719,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>330</width>
<height>186</height>
<width>201</width>
<height>126</height>
</rect>
</property>
<attribute name="label">
@@ -1799,6 +1814,217 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page_6">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>283</width>
<height>322</height>
</rect>
</property>
<attribute name="label">
<string>Stereo correspondences</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_13">
<item row="2" column="0">
<widget class="QSpinBox" name="spinBox_stereo_gfttBlockSize">
<property name="suffix">
<string> pixels</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_stereo_gfttQuality">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.001000000000000</double>
</property>
<property name="value">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_59">
<property name="text">
<string>Optical Flow eps</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_55">
<property name="text">
<string>GFTT block size</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QSpinBox" name="spinBox_stereo_flowWinSize">
<property name="suffix">
<string> pixels</string>
</property>
<property name="minimum">
<number>3</number>
</property>
<property name="value">
<number>16</number>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_56">
<property name="text">
<string>Optical Flow win size</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QSpinBox" name="spinBox_stereo_flowMaxLevel">
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_61">
<property name="text">
<string>GFTT min distance</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_stereo_flowEps">
<property name="decimals">
<number>4</number>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_57">
<property name="text">
<string>Optical Flow max level</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_58">
<property name="text">
<string>Optical Flow iterations</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_54">
<property name="text">
<string>GFTT quality level</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QSpinBox" name="spinBox_stereo_flowIterations">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>30</number>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_stereo_maxSlope">
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<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="0" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_stereo_gfttMinDistance">
<property name="suffix">
<string> pixels</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="value">
<double>5.000000000000000</double>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="label_62">
<property name="text">
<string>Sub pixel</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_60">
<property name="text">
<string>Matches max slope</string>
</property>
</widget>
</item>
<item row="9" column="1">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="checkBox_stereo_subpix">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
@@ -1812,12 +2038,110 @@
<number>4</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_5">
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,1">
<layout class="QVBoxLayout" name="verticalLayout_11" stretch="1,0">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="rtabmap::ImageView" name="graphicsView_stereo" native="true"/>
<layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,1">
<item>
<widget class="rtabmap::ImageView" name="graphicsView_stereo" native="true"/>
</item>
<item>
<widget class="rtabmap::CloudViewer" name="stereoViewer" native="true"/>
</item>
</layout>
</item>
<item>
<widget class="rtabmap::CloudViewer" name="stereoViewer" native="true"/>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_stereo_inliers_name">
<property name="text">
<string>Inliers:</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_stereo_inliers">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_stereo_slopeOutliers_name">
<property name="text">
<string>Slope outliers:</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_stereo_slopeOutliers">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_stereo_disparityOutliers_name">
<property name="text">
<string>Negative disparity outliers:</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_stereo_disparityOutliers">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_stereo_flowOutliers_name">
<property name="text">
<string>Flow outliers:</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_stereo_flowOutliers">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>

View File

@@ -63,7 +63,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-613</y>
<y>-450</y>
<width>755</width>
<height>1591</height>
</rect>
@@ -86,7 +86,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>3</number>
<number>23</number>
</property>
<widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29">
@@ -7222,11 +7222,14 @@ Lower the ratio -&gt; higher the precision. 0 means disabled, matching the neare
<string> m</string>
</property>
<property name="decimals">
<number>2</number>
<number>0</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>