mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-10 05:20:19 +08:00
DBReader: added ignore imu option, GUI: added tf overrides option (#1637)
* DBReader: added ignore imu option, GUI: added tf overrides option * transform offset
This commit is contained in:
@@ -59,6 +59,7 @@ public:
|
||||
int startMapId = 0,
|
||||
int stopMapId = -1,
|
||||
bool priorsIgnored = false,
|
||||
bool imuIgnored = false,
|
||||
const std::vector<Transform> & cameraLocalTransformOverrides = std::vector<Transform>());
|
||||
DBReader(const std::list<std::string> & databasePaths,
|
||||
float frameRate = 0.0f, // -1 = use Database stamps, 0 = inf
|
||||
@@ -74,6 +75,7 @@ public:
|
||||
int startMapId = 0,
|
||||
int stopMapId = -1,
|
||||
bool priorsIgnored = false,
|
||||
bool imuIgnored = false,
|
||||
const std::vector<Transform> & cameraLocalTransformOverrides = std::vector<Transform>());
|
||||
virtual ~DBReader();
|
||||
|
||||
@@ -107,6 +109,7 @@ private:
|
||||
bool _landmarksIgnored;
|
||||
bool _featuresIgnored;
|
||||
bool _priorsIgnored;
|
||||
bool _imuIgnored;
|
||||
int _startMapId;
|
||||
int _stopMapId;
|
||||
std::vector<Transform> _cameraLocalTransformOverrides;
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
inliersMeanDistance(0.0f),
|
||||
inliersDistribution(0.0f),
|
||||
matches(0),
|
||||
variance(0.0f),
|
||||
icpInliersRatio(0),
|
||||
icpTranslation(0.0f),
|
||||
icpRotation(0.0f),
|
||||
@@ -64,6 +65,7 @@ public:
|
||||
output.inliersDistribution = inliersDistribution;
|
||||
output.matches = matches;
|
||||
output.matchesPerCam = matchesPerCam;
|
||||
output.variance = variance;
|
||||
output.icpInliersRatio = icpInliersRatio;
|
||||
output.icpTranslation = icpTranslation;
|
||||
output.icpRotation = icpRotation;
|
||||
@@ -85,6 +87,7 @@ public:
|
||||
float inliersDistribution;
|
||||
std::vector<int> inliersIDs;
|
||||
int matches;
|
||||
float variance;
|
||||
std::vector<int> matchesIDs;
|
||||
std::vector<int> projectedIDs; // "From" IDs
|
||||
std::vector<int> inliersPerCam;
|
||||
|
||||
@@ -67,6 +67,7 @@ class RTABMAP_CORE_EXPORT Statistics
|
||||
RTABMAP_STATS(Loop, Visual_inliers,);
|
||||
RTABMAP_STATS(Loop, Visual_inliers_ratio,);
|
||||
RTABMAP_STATS(Loop, Visual_matches,);
|
||||
RTABMAP_STATS(Loop, Visual_variance,);
|
||||
RTABMAP_STATS(Loop, Distance_since_last_loc, m);
|
||||
RTABMAP_STATS(Loop, Last_id,);
|
||||
RTABMAP_STATS(Loop, Optimization_max_error, m);
|
||||
|
||||
@@ -80,6 +80,7 @@ std::map<int, cv::Point3f> RTABMAP_CORE_EXPORT generateWords3DMono(
|
||||
Transform & cameraTransform,
|
||||
float ransacReprojThreshold = 3.0f,
|
||||
float ransacConfidence = 0.99f,
|
||||
int varianceMedianRatio = 4,
|
||||
const std::map<int, cv::Point3f> & refGuess3D = std::map<int, cv::Point3f>(),
|
||||
double * variance = 0,
|
||||
std::vector<int> * matchesOut = 0);
|
||||
|
||||
@@ -56,6 +56,7 @@ DBReader::DBReader(const std::string & databasePath,
|
||||
int startMapId,
|
||||
int stopMapId,
|
||||
bool priorsIgnored,
|
||||
bool imuIgnored,
|
||||
const std::vector<Transform> & cameraLocalTransformOverrides) :
|
||||
Camera(frameRate),
|
||||
_paths(uSplit(databasePath, ';')),
|
||||
@@ -69,6 +70,7 @@ DBReader::DBReader(const std::string & databasePath,
|
||||
_landmarksIgnored(landmarksIgnored),
|
||||
_featuresIgnored(featuresIgnored),
|
||||
_priorsIgnored(priorsIgnored),
|
||||
_imuIgnored(imuIgnored),
|
||||
_startMapId(startMapId),
|
||||
_stopMapId(stopMapId),
|
||||
_cameraLocalTransformOverrides(cameraLocalTransformOverrides),
|
||||
@@ -96,6 +98,7 @@ DBReader::DBReader(const std::list<std::string> & databasePaths,
|
||||
int startMapId,
|
||||
int stopMapId,
|
||||
bool priorsIgnored,
|
||||
bool imuIgnored,
|
||||
const std::vector<Transform> & cameraLocalTransformOverrides) :
|
||||
Camera(frameRate),
|
||||
_paths(databasePaths),
|
||||
@@ -109,6 +112,7 @@ DBReader::DBReader(const std::list<std::string> & databasePaths,
|
||||
_landmarksIgnored(landmarksIgnored),
|
||||
_featuresIgnored(featuresIgnored),
|
||||
_priorsIgnored(priorsIgnored),
|
||||
_imuIgnored(imuIgnored),
|
||||
_startMapId(startMapId),
|
||||
_stopMapId(stopMapId),
|
||||
_cameraLocalTransformOverrides(cameraLocalTransformOverrides),
|
||||
@@ -463,14 +467,17 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
|
||||
}
|
||||
|
||||
Transform gravityTransform;
|
||||
std::multimap<int, Link> gravityLinks;
|
||||
_dbDriver->loadLinks(*_currentId, gravityLinks, Link::kGravity);
|
||||
if( gravityLinks.size() &&
|
||||
!gravityLinks.begin()->second.transform().isNull() &&
|
||||
gravityLinks.begin()->second.infMatrix().cols == 6 &&
|
||||
gravityLinks.begin()->second.infMatrix().rows == 6)
|
||||
if(!_imuIgnored)
|
||||
{
|
||||
gravityTransform = gravityLinks.begin()->second.transform();
|
||||
std::multimap<int, Link> gravityLinks;
|
||||
_dbDriver->loadLinks(*_currentId, gravityLinks, Link::kGravity);
|
||||
if( gravityLinks.size() &&
|
||||
!gravityLinks.begin()->second.transform().isNull() &&
|
||||
gravityLinks.begin()->second.infMatrix().cols == 6 &&
|
||||
gravityLinks.begin()->second.infMatrix().rows == 6)
|
||||
{
|
||||
gravityTransform = gravityLinks.begin()->second.transform();
|
||||
}
|
||||
}
|
||||
|
||||
Landmarks landmarks;
|
||||
|
||||
@@ -303,7 +303,7 @@ void Feature2D::limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vecto
|
||||
cv::Mat descriptorsTmp;
|
||||
if(ssc)
|
||||
{
|
||||
ULOGGER_DEBUG("too much words (%d), removing words with SSC", keypoints.size());
|
||||
ULOGGER_DEBUG("too many words (%d), removing words with SSC", keypoints.size());
|
||||
|
||||
// Sorting keypoints by deacreasing order of strength
|
||||
std::vector<float> responseVector;
|
||||
@@ -419,7 +419,7 @@ void Feature2D::limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std:
|
||||
inliers.resize(keypoints.size(), false);
|
||||
if(ssc)
|
||||
{
|
||||
ULOGGER_DEBUG("too much words (%d), removing words with SSC", keypoints.size());
|
||||
ULOGGER_DEBUG("too many words (%d), removing words with SSC", keypoints.size());
|
||||
|
||||
// Sorting keypoints by deacreasing order of strength
|
||||
std::vector<float> responseVector;
|
||||
|
||||
+13
-4
@@ -5836,7 +5836,6 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
cameraModels.size() == 1 &&
|
||||
words.size() &&
|
||||
(words3D.size() == 0 || (words.size() == words3D.size() && words3DValid!=(int)words3D.size())) &&
|
||||
_registrationPipeline->isImageRequired() &&
|
||||
_signatures.size() &&
|
||||
_signatures.rbegin()->second->mapId() == _idMapCount) // same map
|
||||
{
|
||||
@@ -5880,11 +5879,14 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
|
||||
// The following is used only to re-estimate the correspondences, the returned transform is ignored
|
||||
Transform tmpt;
|
||||
RegistrationVis reg(parameters_);
|
||||
ParametersMap tmpParams = parameters_;
|
||||
// Pure 2D-2D without guess would generate variance=1
|
||||
uInsert(tmpParams, ParametersPair(Parameters::kVisEpipolarGeometryVar(), "1"));
|
||||
RegistrationVis reg(tmpParams);
|
||||
if(_registrationPipeline->isScanRequired())
|
||||
{
|
||||
// If icp is used, remove it to just do visual registration
|
||||
RegistrationVis vis(parameters_);
|
||||
RegistrationVis vis(tmpParams);
|
||||
tmpt = vis.computeTransformationMod(cpCurrent, cpPrevious, cameraTransform);
|
||||
}
|
||||
else
|
||||
@@ -5906,11 +5908,18 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
||||
{
|
||||
previousWords.insert(std::make_pair(iter->first, cpPrevious.getWordsKpts()[iter->second]));
|
||||
}
|
||||
float reprojError = Parameters::defaultVisPnPReprojError();
|
||||
int varianceMedianRatio = Parameters::defaultVisPnPVarianceMedianRatio();
|
||||
Parameters::parse(parameters_, Parameters::kVisPnPReprojError(), reprojError);
|
||||
Parameters::parse(parameters_, Parameters::kVisPnPVarianceMedianRatio(), varianceMedianRatio);
|
||||
std::map<int, cv::Point3f> inliers = util3d::generateWords3DMono(
|
||||
currentWords,
|
||||
previousWords,
|
||||
cameraModels[0],
|
||||
cameraTransform);
|
||||
cameraTransform,
|
||||
reprojError,
|
||||
0.99f,
|
||||
varianceMedianRatio);
|
||||
|
||||
UDEBUG("inliers=%d", (int)inliers.size());
|
||||
|
||||
|
||||
@@ -529,6 +529,7 @@ Transform RegistrationIcp::computeTransformationImpl(
|
||||
double toComplexity = util3d::computeNormalsComplexity(toScan, guess, &complexityVectorsTo, &complexityValuesTo);
|
||||
float complexity = fromComplexity<toComplexity?fromComplexity:toComplexity;
|
||||
info.icpStructuralComplexity = complexity;
|
||||
UDEBUG("structural complexity: from=%f to=%f", fromComplexity, toComplexity);
|
||||
if(complexity < _pointToPlaneMinComplexity)
|
||||
{
|
||||
tooLowComplexityForPlaneToPlane = true;
|
||||
|
||||
@@ -321,6 +321,7 @@ Transform RegistrationVis::computeTransformationImpl(
|
||||
UDEBUG("%s=%d", Parameters::kVisPnPFlags().c_str(), _PnPFlags);
|
||||
UDEBUG("%s=%f", Parameters::kVisPnPMaxVariance().c_str(), _PnPMaxVar);
|
||||
UDEBUG("%s=%f", Parameters::kVisPnPSplitLinearCovComponents().c_str(), _PnPSplitLinearCovarianceComponents);
|
||||
UDEBUG("%s=%f", Parameters::kVisPnPVarianceMedianRatio().c_str(), _PnPVarMedianRatio);
|
||||
UDEBUG("%s=%d", Parameters::kVisCorType().c_str(), _correspondencesApproach);
|
||||
UDEBUG("%s=%d", Parameters::kVisCorFlowWinSize().c_str(), _flowWinSize);
|
||||
UDEBUG("%s=%d", Parameters::kVisCorFlowIterations().c_str(), _flowIterations);
|
||||
@@ -1632,6 +1633,7 @@ Transform RegistrationVis::computeTransformationImpl(
|
||||
cameraTransform,
|
||||
_PnPReprojError,
|
||||
0.99f,
|
||||
_PnPVarMedianRatio,
|
||||
words3A, // for scale estimation
|
||||
&variance,
|
||||
&matchesV);
|
||||
@@ -2204,6 +2206,10 @@ Transform RegistrationVis::computeTransformationImpl(
|
||||
info.matches = matchesCount;
|
||||
info.rejectedMsg = msg;
|
||||
info.covariance = covariance;
|
||||
if(!covariance.empty())
|
||||
{
|
||||
info.variance = covariance.at<double>(0,0);
|
||||
}
|
||||
|
||||
UDEBUG("inliers=%d/%d", info.inliers, info.matches);
|
||||
UDEBUG("transform=%s", transform.prettyPrint().c_str());
|
||||
|
||||
@@ -2613,6 +2613,7 @@ bool Rtabmap::process(
|
||||
int loopClosureVisualInliers = 0; // for statistics
|
||||
float loopClosureVisualInliersRatio = 0.0f;
|
||||
int loopClosureVisualMatches = 0;
|
||||
float loopClosureVisualVariance = 0.0f;
|
||||
float loopClosureLinearVariance = 0.0f;
|
||||
float loopClosureAngularVariance = 0.0f;
|
||||
float loopClosureVisualInliersMeanDist = 0;
|
||||
@@ -2795,6 +2796,7 @@ bool Rtabmap::process(
|
||||
loopClosureVisualInliers = info.inliers;
|
||||
loopClosureVisualInliersRatio = info.inliersRatio;
|
||||
loopClosureVisualMatches = info.matches;
|
||||
loopClosureVisualVariance = info.variance;
|
||||
|
||||
cv::Mat information = getInformation(info.covariance);
|
||||
loopClosureLinearVariance = 1.0/information.at<double>(0,0);
|
||||
@@ -3062,6 +3064,7 @@ bool Rtabmap::process(
|
||||
loopClosureVisualInliers = info.inliers;
|
||||
loopClosureVisualInliersRatio = info.inliersRatio;
|
||||
loopClosureVisualMatches = info.matches;
|
||||
loopClosureVisualVariance = info.variance;
|
||||
rejectedLoopClosure = transform.isNull();
|
||||
if(rejectedLoopClosure)
|
||||
{
|
||||
@@ -4049,6 +4052,7 @@ bool Rtabmap::process(
|
||||
statistics_.addStatistic(Statistics::kLoopVisual_inliers(), loopClosureVisualInliers);
|
||||
statistics_.addStatistic(Statistics::kLoopVisual_inliers_ratio(), loopClosureVisualInliersRatio);
|
||||
statistics_.addStatistic(Statistics::kLoopVisual_matches(), loopClosureVisualMatches);
|
||||
statistics_.addStatistic(Statistics::kLoopVisual_variance(), loopClosureVisualVariance);
|
||||
statistics_.addStatistic(Statistics::kLoopLinear_variance(), loopClosureLinearVariance);
|
||||
statistics_.addStatistic(Statistics::kLoopAngular_variance(), loopClosureAngularVariance);
|
||||
statistics_.addStatistic(Statistics::kLoopLast_id(), _memory->getLastGlobalLoopClosureId());
|
||||
|
||||
@@ -775,6 +775,7 @@ Transform OdometryMono::computeTransform(SensorData & data, const Transform & gu
|
||||
cameraTransform,
|
||||
fundMatrixReprojError_,
|
||||
fundMatrixConfidence_,
|
||||
4,
|
||||
refWords3Guess); // for scale estimation
|
||||
|
||||
if(cameraTransform.getNorm() < minTranslation_*5)
|
||||
|
||||
@@ -213,6 +213,7 @@ std::map<int, cv::Point3f> generateWords3DMono(
|
||||
Transform & cameraTransform,
|
||||
float ransacReprojThreshold,
|
||||
float ransacConfidence,
|
||||
int varianceMedianRatio,
|
||||
const std::map<int, cv::Point3f> & refGuess3D,
|
||||
double * varianceOut,
|
||||
std::vector<int> * matchesOut)
|
||||
@@ -345,7 +346,7 @@ std::map<int, cv::Point3f> generateWords3DMono(
|
||||
errorSqrdDists[j] = uNormSquared(refPt.x-newPt.x, refPt.y-newPt.y, refPt.z-newPt.z);
|
||||
}
|
||||
std::sort(errorSqrdDists.begin(), errorSqrdDists.end());
|
||||
double median_error_sqr = (double)errorSqrdDists[errorSqrdDists.size () >> 2];
|
||||
double median_error_sqr = (double)errorSqrdDists[errorSqrdDists.size () >> varianceMedianRatio];
|
||||
float var = 2.1981 * median_error_sqr;
|
||||
//UDEBUG("scale %d = %f variance = %f", (int)i, s, variance);
|
||||
|
||||
@@ -369,7 +370,7 @@ std::map<int, cv::Point3f> generateWords3DMono(
|
||||
errorSqrdDists[j] = uNormSquared(refPt.x-newPt.x, refPt.y-newPt.y, refPt.z-newPt.z);
|
||||
}
|
||||
std::sort(errorSqrdDists.begin(), errorSqrdDists.end());
|
||||
double median_error_sqr = (double)errorSqrdDists[errorSqrdDists.size () >> 2];
|
||||
double median_error_sqr = (double)errorSqrdDists[errorSqrdDists.size () >> varianceMedianRatio];
|
||||
variance = 2.1981 * median_error_sqr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -755,10 +755,13 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->source_checkBox_ignoreLandmarks, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_checkBox_ignoreFeatures, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_checkBox_ignorePriors, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_checkBox_ignoreIMU, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_spinBox_databaseStartId, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_spinBox_databaseStopId, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_checkBox_useDbStamps, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_lineEdit_databaseCameraIndex, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_checkBox_overrideLocalTransforms, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_lineEdit_databaseLocalTransformOffset, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_checkBox_stereoToDepthDB, SIGNAL(toggled(bool)), _ui->checkbox_stereo_depthGenerated, SLOT(setChecked(bool)));
|
||||
connect(_ui->checkbox_stereo_depthGenerated, SIGNAL(toggled(bool)), _ui->source_checkBox_stereoToDepthDB, SLOT(setChecked(bool)));
|
||||
|
||||
@@ -2194,10 +2197,13 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
||||
_ui->source_checkBox_ignoreLandmarks->setChecked(true);
|
||||
_ui->source_checkBox_ignoreFeatures->setChecked(true);
|
||||
_ui->source_checkBox_ignorePriors->setChecked(false);
|
||||
_ui->source_checkBox_ignoreIMU->setChecked(false);
|
||||
_ui->source_spinBox_databaseStartId->setValue(0);
|
||||
_ui->source_spinBox_databaseStopId->setValue(0);
|
||||
_ui->source_lineEdit_databaseCameraIndex->setText("");
|
||||
_ui->source_checkBox_useDbStamps->setChecked(true);
|
||||
_ui->source_checkBox_overrideLocalTransforms->setChecked(false);
|
||||
_ui->source_lineEdit_databaseLocalTransformOffset->setText("");
|
||||
|
||||
#ifdef _WIN32
|
||||
_ui->comboBox_cameraRGBD->setCurrentIndex(kSrcOpenNI2-kSrcRGBD); // openni2
|
||||
@@ -2951,10 +2957,14 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
|
||||
_ui->source_checkBox_ignoreLandmarks->setChecked(settings.value("ignoreLandmarks", _ui->source_checkBox_ignoreLandmarks->isChecked()).toBool());
|
||||
_ui->source_checkBox_ignoreFeatures->setChecked(settings.value("ignoreFeatures", _ui->source_checkBox_ignoreFeatures->isChecked()).toBool());
|
||||
_ui->source_checkBox_ignorePriors->setChecked(settings.value("ignorePriors", _ui->source_checkBox_ignorePriors->isChecked()).toBool());
|
||||
_ui->source_checkBox_ignoreIMU->setChecked(settings.value("ignoreImu", _ui->source_checkBox_ignoreIMU->isChecked()).toBool());
|
||||
|
||||
_ui->source_spinBox_databaseStartId->setValue(settings.value("startId", _ui->source_spinBox_databaseStartId->value()).toInt());
|
||||
_ui->source_spinBox_databaseStopId->setValue(settings.value("stopId", _ui->source_spinBox_databaseStopId->value()).toInt());
|
||||
_ui->source_lineEdit_databaseCameraIndex->setText(settings.value("cameraIndices", _ui->source_lineEdit_databaseCameraIndex->text()).toString());
|
||||
_ui->source_checkBox_useDbStamps->setChecked(settings.value("useDatabaseStamps", _ui->source_checkBox_useDbStamps->isChecked()).toBool());
|
||||
_ui->source_checkBox_overrideLocalTransforms->setChecked(settings.value("overrideLocalTransforms", _ui->source_checkBox_overrideLocalTransforms->isChecked()).toBool());
|
||||
_ui->source_lineEdit_databaseLocalTransformOffset->setText(settings.value("localTransformOffsets", _ui->source_lineEdit_databaseLocalTransformOffset->text()).toString());
|
||||
settings.endGroup(); // Database
|
||||
|
||||
settings.endGroup(); // Camera
|
||||
@@ -3566,10 +3576,13 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath) const
|
||||
settings.setValue("ignoreLandmarks", _ui->source_checkBox_ignoreLandmarks->isChecked());
|
||||
settings.setValue("ignoreFeatures", _ui->source_checkBox_ignoreFeatures->isChecked());
|
||||
settings.setValue("ignorePriors", _ui->source_checkBox_ignorePriors->isChecked());
|
||||
settings.setValue("ignoreImu", _ui->source_checkBox_ignoreIMU->isChecked());
|
||||
settings.setValue("startId", _ui->source_spinBox_databaseStartId->value());
|
||||
settings.setValue("stopId", _ui->source_spinBox_databaseStopId->value());
|
||||
settings.setValue("cameraIndices", _ui->source_lineEdit_databaseCameraIndex->text());
|
||||
settings.setValue("useDatabaseStamps", _ui->source_checkBox_useDbStamps->isChecked());
|
||||
settings.setValue("overrideLocalTransforms", _ui->source_checkBox_overrideLocalTransforms->isChecked());
|
||||
settings.setValue("localTransformOffsets", _ui->source_lineEdit_databaseLocalTransformOffset->text());
|
||||
settings.endGroup(); // Database
|
||||
|
||||
settings.endGroup(); // Camera
|
||||
@@ -7171,6 +7184,54 @@ Camera * PreferencesDialog::createCamera(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Transform> localTransformOverrides;
|
||||
if(_ui->source_checkBox_overrideLocalTransforms->isChecked())
|
||||
{
|
||||
if(!_ui->lineEdit_sourceLocalTransform->text().isEmpty())
|
||||
{
|
||||
std::list<std::string> transforms = uSplit(_ui->lineEdit_sourceLocalTransform->text().replace("PI_2", QString::number(3.141592/2.0)).toStdString(), ';');
|
||||
for(auto t: transforms)
|
||||
{
|
||||
localTransformOverrides.push_back(Transform::fromString(t));
|
||||
}
|
||||
|
||||
// offset(s)?
|
||||
if(!_ui->source_lineEdit_databaseLocalTransformOffset->text().isEmpty())
|
||||
{
|
||||
std::vector<float> localTransformOffsetOverrides;
|
||||
std::list<std::string> offsetStr = uSplit(_ui->source_lineEdit_databaseLocalTransformOffset->text().toStdString(), ' ');
|
||||
for(std::list<std::string>::iterator iter=offsetStr.begin(); iter!=offsetStr.end(); ++iter)
|
||||
{
|
||||
localTransformOffsetOverrides.push_back(uStr2Float(*iter));
|
||||
UINFO("Camera offset = %f", localTransformOffsetOverrides.back());
|
||||
}
|
||||
if(!localTransformOffsetOverrides.empty())
|
||||
{
|
||||
if(!localTransformOverrides.empty() && localTransformOffsetOverrides.size() > 1 && localTransformOffsetOverrides.size() != localTransformOverrides.size())
|
||||
{
|
||||
QMessageBox::warning(this, tr("DBReader"),
|
||||
tr( "Camera lens offset vector size (%1) is not equal to local transform overrides (%2). "
|
||||
"Camera lens offset vector should be one to affect all cameras or the same size than local transforms overrides.").arg(localTransformOffsetOverrides.size()).arg(localTransformOverrides.size()), QMessageBox::Ok);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
for(size_t i=0; i<localTransformOverrides.size(); ++i)
|
||||
{
|
||||
float offset = localTransformOffsetOverrides.size()==1?localTransformOffsetOverrides[0]:localTransformOffsetOverrides[i];
|
||||
localTransformOverrides[i] *= Transform(0, offset, 0);
|
||||
UINFO("Overriding camera's local transform %ld to %s (offset=%f)", i, localTransformOverrides[i].prettyPrint().c_str(), offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!_ui->source_lineEdit_databaseLocalTransformOffset->text().isEmpty())
|
||||
{
|
||||
UWARN("Overriding camera offsets can only be used when camera local transforms are overriden. Ignoring offsets :\"%s\"",
|
||||
_ui->source_lineEdit_databaseLocalTransformOffset->text().toStdString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
camera = new DBReader(_ui->source_database_lineEdit_path->text().toStdString(),
|
||||
_ui->source_checkBox_useDbStamps->isChecked()?-1:this->getGeneralInputRate(),
|
||||
@@ -7185,7 +7246,9 @@ Camera * PreferencesDialog::createCamera(
|
||||
_ui->source_checkBox_ignoreFeatures->isChecked(),
|
||||
0,
|
||||
-1,
|
||||
_ui->source_checkBox_ignorePriors->isChecked());
|
||||
_ui->source_checkBox_ignorePriors->isChecked(),
|
||||
_ui->source_checkBox_ignoreIMU->isChecked(),
|
||||
localTransformOverrides);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -778,7 +778,7 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
</item>
|
||||
<item row="52" column="0">
|
||||
<widget class="QLabel" name="label_48">
|
||||
<widget class="QLabel" name="label_481">
|
||||
<property name="text">
|
||||
<string>With cuVSLAM :</string>
|
||||
</property>
|
||||
|
||||
+205
-149
@@ -7180,17 +7180,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_9" columnstretch="0,1,0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QSpinBox" name="source_spinBox_databaseStartId">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QSpinBox" name="source_spinBox_databaseStopId">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
@@ -7203,19 +7193,6 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="source_database_lineEdit_path"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_72">
|
||||
<property name="text">
|
||||
<string>Ignore odometry saved in the database, so if RGB-D SLAM is activated, odometry will be recomputed.</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="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_useDbStamps">
|
||||
<property name="text">
|
||||
@@ -7223,60 +7200,13 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_263">
|
||||
<property name="text">
|
||||
<string>Ignore goals saved in the database.</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="QCheckBox" name="source_checkBox_ignoreOdometry">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_ignoreGoals">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="toolButton_dbViewer">
|
||||
<property name="toolTip">
|
||||
<string>Open database viewer</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../GuiLib.qrc">
|
||||
<normaloff>:/images/mag_glass.png</normaloff>:/images/mag_glass.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_ignoreGoalDelay">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_80">
|
||||
<property name="text">
|
||||
<string>Ignore goal delay.</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_644">
|
||||
<property name="text">
|
||||
@@ -7290,52 +7220,6 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_90">
|
||||
<property name="text">
|
||||
<string>Use database stamps as input rate.</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="1">
|
||||
<widget class="QLabel" name="label_529">
|
||||
<property name="text">
|
||||
<string>Stop position (node ID) is the last node to process. If 0, all nodes after start position are published.</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_315">
|
||||
<property name="text">
|
||||
<string>Camera index. If the database contains multi-camera data, you can choose which camera to use. Leave empty to use all cameras. Can also be multiple indices split by spaces in a string like "0 2" to stream cameras 0 and 2 only.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_stereoToDepthDB">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QToolButton" name="source_database_toolButton_selectSource">
|
||||
<property name="text">
|
||||
@@ -7343,24 +7227,10 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_ignoreGoals">
|
||||
<item row="12" column="1">
|
||||
<widget class="QLabel" name="label_784">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_ignoreLandmarks">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_546">
|
||||
<property name="text">
|
||||
<string>Ignore landmarks.</string>
|
||||
<string>Override camera local transform(s) with local transform(s) set above. For multi-cameras, use a ";" between each transform.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -7370,13 +7240,44 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_58">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_ignoreOdometry">
|
||||
<property name="text">
|
||||
<string>Start position (node ID).</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLineEdit" name="source_lineEdit_databaseCameraIndex"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_ignoreGoalDelay">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QLineEdit" name="source_lineEdit_databaseLocalTransformOffset"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="toolButton_dbViewer">
|
||||
<property name="toolTip">
|
||||
<string>Open database viewer</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../GuiLib.qrc">
|
||||
<normaloff>:/images/mag_glass.png</normaloff>:/images/mag_glass.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_overrideLocalTransforms">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -7387,10 +7288,10 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLabel" name="label_557">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_72">
|
||||
<property name="text">
|
||||
<string>If the database contains stereo data, generate disparity image and convert it to depth. The resulting output is a RGB-D image instead of stereo images. Dense disparity parameters can be found under StereoBM tab.</string>
|
||||
<string>Ignore odometry saved in the database, so if RGB-D SLAM is activated, odometry will be recomputed.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -7400,10 +7301,10 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="label_653">
|
||||
<item row="11" column="1">
|
||||
<widget class="QLabel" name="label_315">
|
||||
<property name="text">
|
||||
<string>Ignore priors.</string>
|
||||
<string>Camera index. If the database contains multi-camera data, you can choose which camera to use. Leave empty to use all cameras. Can also be multiple indices split by spaces in a string like "0 2" to stream cameras 0 and 2 only.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -7420,8 +7321,163 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLineEdit" name="source_lineEdit_databaseCameraIndex"/>
|
||||
<item row="13" column="1">
|
||||
<widget class="QLabel" name="label_785">
|
||||
<property name="text">
|
||||
<string>Add an y-axis offset before optical rotation on the overriden local transform(s). For multi-cameras,explicitly enumerate offsets if they are different (e.g., "0.05 0.075" for two cameras setup), or set single number to apply to all camera transforms.</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="QSpinBox" name="source_spinBox_databaseStartId">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_90">
|
||||
<property name="text">
|
||||
<string>Use database stamps as input rate.</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="source_checkBox_ignoreLandmarks">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="label_58">
|
||||
<property name="text">
|
||||
<string>Start position (node ID).</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QCheckBox" name="source_checkBox_stereoToDepthDB">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="label_653">
|
||||
<property name="text">
|
||||
<string>Ignore priors.</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_546">
|
||||
<property name="text">
|
||||
<string>Ignore landmarks.</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_80">
|
||||
<property name="text">
|
||||
<string>Ignore goal delay.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QLabel" name="label_557">
|
||||
<property name="text">
|
||||
<string>If the database contains stereo data, generate disparity image and convert it to depth. The resulting output is a RGB-D image instead of stereo images. Dense disparity parameters can be found under StereoBM tab.</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_529">
|
||||
<property name="text">
|
||||
<string>Stop position (node ID) is the last node to process. If 0, all nodes after start position are published.</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_263">
|
||||
<property name="text">
|
||||
<string>Ignore goals saved in the database.</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_786">
|
||||
<property name="text">
|
||||
<string>Ignore IMU (i.e., gravity links).</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="QCheckBox" name="source_checkBox_ignoreIMU">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
@@ -93,6 +93,7 @@ void showUsage()
|
||||
" e.g., \"0.05 0.075\" for two cameras setup.\n"
|
||||
" -nolandmark Don't republish landmarks contained in input database.\n"
|
||||
" -nopriors Don't republish priors contained in input database.\n"
|
||||
" -noimu Don't republish IMU contained in input database.\n"
|
||||
" -pub_loops Republish loop closures contained in input database.\n"
|
||||
" -loc_null On localization mode, reset localization pose to null and map correction to identity between sessions.\n"
|
||||
" -gt When reprocessing a single database, load its original optimized graph, then \n"
|
||||
@@ -272,6 +273,7 @@ int main(int argc, char * argv[])
|
||||
int framesToSkip = 0;
|
||||
bool ignoreLandmarks = false;
|
||||
bool ignorePriors = false;
|
||||
bool ignoreImu = false;
|
||||
bool republishLoopClosures = false;
|
||||
bool locNull = false;
|
||||
bool originalGraphAsGT = false;
|
||||
@@ -490,6 +492,11 @@ int main(int argc, char * argv[])
|
||||
ignorePriors = true;
|
||||
printf("Ignoring priors from input database (-nopriors option).\n");
|
||||
}
|
||||
else if(strcmp(argv[i], "-noimu") == 0 || strcmp(argv[i], "--noimu") == 0)
|
||||
{
|
||||
ignoreImu = true;
|
||||
printf("Ignoring IMU from input database (-noimu option).\n");
|
||||
}
|
||||
else if(strcmp(argv[i], "-pub_loops") == 0 || strcmp(argv[i], "--pub_loops") == 0)
|
||||
{
|
||||
republishLoopClosures = true;
|
||||
@@ -900,6 +907,7 @@ int main(int argc, char * argv[])
|
||||
startMapId,
|
||||
stopMapId,
|
||||
ignorePriors,
|
||||
ignoreImu,
|
||||
cameraLocalTransformOverrides);
|
||||
|
||||
dbReader->init();
|
||||
|
||||
Reference in New Issue
Block a user