This commit is contained in:
matlabbe
2025-04-13 15:58:21 -07:00
parent 08f031e11c
commit b750e94eaa
6 changed files with 50 additions and 16 deletions

View File

@@ -612,6 +612,13 @@ void Optimizer::computeBACorrespondences(
sFrom.setWordsDescriptors(cv::Mat()); sFrom.setWordsDescriptors(cv::Mat());
sTo.setWordsDescriptors(cv::Mat()); sTo.setWordsDescriptors(cv::Mat());
} }
else if(sFrom.getWordsDescriptors().empty() && sTo.getWordsDescriptors().empty())
{
UWARN("Rematching features is enabled but signatures (%d and %d) don't have word descriptors!? "
"Features won't be rematched. If it is an old database, do rtabmap-reprocess "
"so that signatures contain word desriptors.",
sFrom.id(), sTo.id());
}
RegistrationInfo info; RegistrationInfo info;
Transform t = reg.computeTransformationMod(sFrom, sTo, Transform(), &info); Transform t = reg.computeTransformationMod(sFrom, sTo, Transform(), &info);

View File

@@ -372,7 +372,7 @@ Transform RegistrationVis::computeTransformationImpl(
(_estimationType==1 || toSignature.getWords3().size())) // required only for 3D->3D and 2D->2D (_estimationType==1 || toSignature.getWords3().size())) // required only for 3D->3D and 2D->2D
{ {
// no need to extract new features, we have all the data we need // no need to extract new features, we have all the data we need
UDEBUG("Bypassing feature matching as descriptors and images are empty. We assume features are already matched."); UDEBUG("Bypassing feature matching as descriptors are empty. We assume features are already matched.");
} }
else else
{ {

View File

@@ -54,7 +54,7 @@ public:
void setWorkingDirectory(const QString & path); void setWorkingDirectory(const QString & path);
void exportBundler( void exportBundler(
const std::map<int, Transform> & poses, std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
const QMap<int, Signature> & signatures, const QMap<int, Signature> & signatures,
const ParametersMap & parameters); const ParametersMap & parameters);

View File

@@ -165,7 +165,7 @@ void ExportBundlerDialog::getPath()
} }
void ExportBundlerDialog::exportBundler( void ExportBundlerDialog::exportBundler(
const std::map<int, Transform> & poses, std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
const QMap<int, Signature> & signatures, const QMap<int, Signature> & signatures,
const ParametersMap & parameters) const ParametersMap & parameters)
@@ -185,7 +185,6 @@ void ExportBundlerDialog::exportBundler(
std::map<int, cv::Point3f> points3DMap; std::map<int, cv::Point3f> points3DMap;
std::map<int, std::map<int, FeatureBA> > wordReferences; std::map<int, std::map<int, FeatureBA> > wordReferences;
std::map<int, Transform> newPoses = poses;
if(_ui->groupBox_export_points->isEnabled() && _ui->groupBox_export_points->isChecked()) if(_ui->groupBox_export_points->isEnabled() && _ui->groupBox_export_points->isChecked())
{ {
std::map<int, Transform> posesOut; std::map<int, Transform> posesOut;
@@ -197,7 +196,7 @@ void ExportBundlerDialog::exportBundler(
uInsert(parametersSBA, std::make_pair(Parameters::kg2oPixelVariance(), uNumber2Str(_ui->sba_variance->value()))); uInsert(parametersSBA, std::make_pair(Parameters::kg2oPixelVariance(), uNumber2Str(_ui->sba_variance->value())));
Optimizer * sba = Optimizer::create(sbaType, parametersSBA); Optimizer * sba = Optimizer::create(sbaType, parametersSBA);
sba->getConnectedGraph(poses.begin()->first, poses, links, posesOut, linksOut); sba->getConnectedGraph(poses.begin()->first, poses, links, posesOut, linksOut);
newPoses = sba->optimizeBA( poses = sba->optimizeBA(
posesOut.begin()->first, posesOut.begin()->first,
posesOut, posesOut,
linksOut, linksOut,
@@ -207,7 +206,7 @@ void ExportBundlerDialog::exportBundler(
_ui->sba_rematchFeatures->isChecked()); _ui->sba_rematchFeatures->isChecked());
delete sba; delete sba;
if(newPoses.empty()) if(poses.empty())
{ {
QMessageBox::warning(this, tr("Exporting cameras..."), tr("SBA optimization failed! Cannot export with 3D points.").arg(path)); QMessageBox::warning(this, tr("Exporting cameras..."), tr("SBA optimization failed! Cannot export with 3D points.").arg(path));
return; return;
@@ -231,7 +230,7 @@ void ExportBundlerDialog::exportBundler(
std::map<int, int> cameraIndexes; std::map<int, int> cameraIndexes;
int camIndex = 0; int camIndex = 0;
std::map<int, QColor> colors; std::map<int, QColor> colors;
for(std::map<int, Transform>::const_iterator iter=newPoses.begin(); iter!=newPoses.end(); ++iter) for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{ {
QMap<int, Signature>::const_iterator ster = signatures.find(iter->first); QMap<int, Signature>::const_iterator ster = signatures.find(iter->first);
if(ster!= signatures.end()) if(ster!= signatures.end())
@@ -536,10 +535,10 @@ void ExportBundlerDialog::exportBundler(
QMessageBox::information(this, QMessageBox::information(this,
tr("Exporting cameras in Bundler format..."), tr("Exporting cameras in Bundler format..."),
tr("%1 cameras/images and %2 points exported to directory \"%3\".%4") tr("%1 cameras/images and %2 points exported to directory \"%3\".%4")
.arg(newPoses.size()) .arg(poses.size())
.arg(points3DMap.size()) .arg(points3DMap.size())
.arg(path) .arg(path)
.arg(newPoses.size()>cameras.size()?tr(" %1/%2 cameras ignored for too fast motion and/or blur level.").arg(newPoses.size()-cameras.size()).arg(newPoses.size()):"")); .arg(poses.size()>cameras.size()?tr(" %1/%2 cameras ignored for too fast motion and/or blur level.").arg(poses.size()-cameras.size()).arg(poses.size()):""));
} }
else else
{ {

View File

@@ -8320,6 +8320,21 @@ void MainWindow::exportBundlerFormat()
_currentLinksMap, _currentLinksMap,
_cachedSignatures, _cachedSignatures,
_preferencesDialog->getAllParameters()); _preferencesDialog->getAllParameters());
if(!poses.empty())
{
UINFO("Updating map...");
this->updateMapCloud(
poses,
std::multimap<int, Link>(_currentLinksMap),
std::map<int, int>(_currentMapIds),
std::map<int, std::string>(_currentLabels),
std::map<int, Transform>(_currentGTPosesMap),
std::map<int, Transform>(),
std::multimap<int, Link>(),
false);
UINFO("Updating map... done!");
}
} }
else else
{ {

View File

@@ -4810,8 +4810,6 @@ void PreferencesDialog::setParameter(const std::string & key, const std::string
QWidget * obj = _ui->stackedWidget->findChild<QWidget*>(key.c_str()); QWidget * obj = _ui->stackedWidget->findChild<QWidget*>(key.c_str());
if(obj) if(obj)
{ {
uInsert(_parameters, ParametersPair(key, value));
QSpinBox * spin = qobject_cast<QSpinBox *>(obj); QSpinBox * spin = qobject_cast<QSpinBox *>(obj);
QDoubleSpinBox * doubleSpin = qobject_cast<QDoubleSpinBox *>(obj); QDoubleSpinBox * doubleSpin = qobject_cast<QDoubleSpinBox *>(obj);
QComboBox * combo = qobject_cast<QComboBox *>(obj); QComboBox * combo = qobject_cast<QComboBox *>(obj);
@@ -4822,18 +4820,28 @@ void PreferencesDialog::setParameter(const std::string & key, const std::string
bool ok; bool ok;
if(spin) if(spin)
{ {
spin->setValue(QString(value.c_str()).toInt(&ok)); int v = QString(value.c_str()).toInt(&ok);
if(!ok) if(!ok)
{ {
UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str()); UERROR("Conversion failed from \"%s\" for parameter %s. Original value (%d) is kept.", value.c_str(), key.c_str(), spin->value());
}
else
{
spin->setValue(v);
uInsert(_parameters, ParametersPair(key, value));
} }
} }
else if(doubleSpin) else if(doubleSpin)
{ {
doubleSpin->setValue(QString(value.c_str()).toDouble(&ok)); double v = QString(value.c_str()).toDouble(&ok);
if(!ok) if(!ok)
{ {
UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str()); UERROR("Conversion failed from \"%s\" for parameter %s. Original value (%f) is kept.", value.c_str(), key.c_str(), doubleSpin->value());
}
else
{
doubleSpin->setValue(v);
uInsert(_parameters, ParametersPair(key, value));
} }
} }
else if(combo) else if(combo)
@@ -4856,7 +4864,7 @@ void PreferencesDialog::setParameter(const std::string & key, const std::string
int valueInt = QString(valueCpy.c_str()).toInt(&ok); int valueInt = QString(valueCpy.c_str()).toInt(&ok);
if(!ok) if(!ok)
{ {
UERROR("Conversion failed from \"%s\" for parameter %s", valueCpy.c_str(), key.c_str()); UERROR("Conversion failed from \"%s\" for parameter %s. Original value (%d) is kept.", valueCpy.c_str(), key.c_str(), combo->currentIndex());
} }
else else
{ {
@@ -4935,6 +4943,7 @@ void PreferencesDialog::setParameter(const std::string & key, const std::string
if(ok) if(ok)
{ {
combo->setCurrentIndex(valueInt); combo->setCurrentIndex(valueInt);
uInsert(_parameters, ParametersPair(key, uNumber2Str(valueInt)));
} }
} }
@@ -4944,18 +4953,22 @@ void PreferencesDialog::setParameter(const std::string & key, const std::string
_ui->checkBox_useOdomFeatures->blockSignals(true); _ui->checkBox_useOdomFeatures->blockSignals(true);
check->setChecked(uStr2Bool(value.c_str())); check->setChecked(uStr2Bool(value.c_str()));
_ui->checkBox_useOdomFeatures->blockSignals(false); _ui->checkBox_useOdomFeatures->blockSignals(false);
uInsert(_parameters, ParametersPair(key, uBool2Str(check->isChecked())));
} }
else if(radio) else if(radio)
{ {
radio->setChecked(uStr2Bool(value.c_str())); radio->setChecked(uStr2Bool(value.c_str()));
uInsert(_parameters, ParametersPair(key, uBool2Str(radio->isChecked())));
} }
else if(lineEdit) else if(lineEdit)
{ {
lineEdit->setText(value.c_str()); lineEdit->setText(value.c_str());
uInsert(_parameters, ParametersPair(key, value));
} }
else if(groupBox) else if(groupBox)
{ {
groupBox->setChecked(uStr2Bool(value.c_str())); groupBox->setChecked(uStr2Bool(value.c_str()));
uInsert(_parameters, ParametersPair(key, uBool2Str(groupBox->isChecked())));
} }
else else
{ {