Added parameter Kp/NewWordsComparedTogether for dictionary, always true but when comparing loop closures with Reextracting features, it is set to false to save time.

fixed crash when calling getMap without rtabmap yet initialized.
Parameter "LccReextract/LoopClosureFeatures" is now named "LccReextract/Activated"


git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1855 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2014-10-14 21:48:50 +00:00
parent 39a9c4ebd8
commit 22ce2525fc
7 changed files with 86 additions and 58 deletions

View File

@@ -174,6 +174,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Kp, Parallelized, bool, true, "If the dictionary update and signature creation were parallelized."); RTABMAP_PARAM(Kp, Parallelized, bool, true, "If the dictionary update and signature creation were parallelized.");
RTABMAP_PARAM_STR(Kp, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom]."); RTABMAP_PARAM_STR(Kp, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom].");
RTABMAP_PARAM_STR(Kp, DictionaryPath, "", "Path of the pre-computed dictionary"); RTABMAP_PARAM_STR(Kp, DictionaryPath, "", "Path of the pre-computed dictionary");
RTABMAP_PARAM(Kp, NewWordsComparedTogether, bool, true, "When adding new words to dictionary, they are compared also with each other (to detect same words in the same signature).");
//Database //Database
RTABMAP_PARAM(DbSqlite3, InMemory, bool, false, "Using database in the memory instead of a file on the hard disk."); RTABMAP_PARAM(DbSqlite3, InMemory, bool, false, "Using database in the memory instead of a file on the hard disk.");
@@ -294,7 +295,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(LccBow, Iterations, int, 100, "Maximum iterations to compute the transform from visual words."); RTABMAP_PARAM(LccBow, Iterations, int, 100, "Maximum iterations to compute the transform from visual words.");
RTABMAP_PARAM(LccBow, MaxDepth, float, 5.0, "Max depth of the words (0 means no limit)."); RTABMAP_PARAM(LccBow, MaxDepth, float, 5.0, "Max depth of the words (0 means no limit).");
RTABMAP_PARAM(LccBow, Force2D, bool, false, "Force 2D transform (3Dof: x,y and yaw).") RTABMAP_PARAM(LccBow, Force2D, bool, false, "Force 2D transform (3Dof: x,y and yaw).")
RTABMAP_PARAM(LccReextract, LoopClosureFeatures, bool, false, "Re-extract features on global loop closure."); RTABMAP_PARAM(LccReextract, Activated, bool, false, "Activate re-extracting features on global loop closure.");
RTABMAP_PARAM(LccReextract, NNType, int, 3, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4."); RTABMAP_PARAM(LccReextract, NNType, int, 3, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4.");
RTABMAP_PARAM(LccReextract, NNDR, float, 0.7, "NNDR: nearest neighbor distance ratio."); RTABMAP_PARAM(LccReextract, NNDR, float, 0.7, "NNDR: nearest neighbor distance ratio.");
RTABMAP_PARAM(LccReextract, FeatureType, int, 4, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK."); RTABMAP_PARAM(LccReextract, FeatureType, int, 4, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK.");

View File

@@ -98,6 +98,7 @@ private:
bool _incrementalDictionary; bool _incrementalDictionary;
float _nndrRatio; float _nndrRatio;
std::string _dictionaryPath; // a pre-computed dictionary (.txt) std::string _dictionaryPath; // a pre-computed dictionary (.txt)
bool _newWordsComparedTogether;
int _lastWordId; int _lastWordId;
cv::flann::Index * _flannIndex; cv::flann::Index * _flannIndex;
cv::Mat _dataTree; cv::Mat _dataTree;

View File

@@ -100,7 +100,7 @@ Rtabmap::Rtabmap() :
_toroIterations(Parameters::defaultRGBDToroIterations()), _toroIterations(Parameters::defaultRGBDToroIterations()),
_databasePath(""), _databasePath(""),
_optimizeFromGraphEnd(Parameters::defaultRGBDOptimizeFromGraphEnd()), _optimizeFromGraphEnd(Parameters::defaultRGBDOptimizeFromGraphEnd()),
_reextractLoopClosureFeatures(Parameters::defaultLccReextractLoopClosureFeatures()), _reextractLoopClosureFeatures(Parameters::defaultLccReextractActivated()),
_reextractNNType(Parameters::defaultLccReextractNNType()), _reextractNNType(Parameters::defaultLccReextractNNType()),
_reextractNNDR(Parameters::defaultLccReextractNNDR()), _reextractNNDR(Parameters::defaultLccReextractNNDR()),
_reextractFeatureType(Parameters::defaultLccReextractFeatureType()), _reextractFeatureType(Parameters::defaultLccReextractFeatureType()),
@@ -355,7 +355,7 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionMaxDiffID(), _localDetectMaxDiffID); Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionMaxDiffID(), _localDetectMaxDiffID);
Parameters::parse(parameters, Parameters::kRGBDToroIterations(), _toroIterations); Parameters::parse(parameters, Parameters::kRGBDToroIterations(), _toroIterations);
Parameters::parse(parameters, Parameters::kRGBDOptimizeFromGraphEnd(), _optimizeFromGraphEnd); Parameters::parse(parameters, Parameters::kRGBDOptimizeFromGraphEnd(), _optimizeFromGraphEnd);
Parameters::parse(parameters, Parameters::kLccReextractLoopClosureFeatures(), _reextractLoopClosureFeatures); Parameters::parse(parameters, Parameters::kLccReextractActivated(), _reextractLoopClosureFeatures);
Parameters::parse(parameters, Parameters::kLccReextractNNType(), _reextractNNType); Parameters::parse(parameters, Parameters::kLccReextractNNType(), _reextractNNType);
Parameters::parse(parameters, Parameters::kLccReextractNNDR(), _reextractNNDR); Parameters::parse(parameters, Parameters::kLccReextractNNDR(), _reextractNNDR);
Parameters::parse(parameters, Parameters::kLccReextractFeatureType(), _reextractFeatureType); Parameters::parse(parameters, Parameters::kLccReextractFeatureType(), _reextractFeatureType);
@@ -1286,6 +1286,7 @@ bool Rtabmap::process(const SensorData & data)
uInsert(customParameters, ParametersPair(Parameters::kMemRehearsalSimilarity(), "1.0")); // desactivate rehearsal uInsert(customParameters, ParametersPair(Parameters::kMemRehearsalSimilarity(), "1.0")); // desactivate rehearsal
uInsert(customParameters, ParametersPair(Parameters::kMemImageKept(), "false")); uInsert(customParameters, ParametersPair(Parameters::kMemImageKept(), "false"));
uInsert(customParameters, ParametersPair(Parameters::kMemSTMSize(), "0")); uInsert(customParameters, ParametersPair(Parameters::kMemSTMSize(), "0"));
uInsert(customParameters, ParametersPair(Parameters::kKpNewWordsComparedTogether(), "false"));
uInsert(customParameters, ParametersPair(Parameters::kKpNNStrategy(), uNumber2Str(_reextractNNType))); // bruteforce uInsert(customParameters, ParametersPair(Parameters::kKpNNStrategy(), uNumber2Str(_reextractNNType))); // bruteforce
uInsert(customParameters, ParametersPair(Parameters::kKpNndrRatio(), uNumber2Str(_reextractNNDR))); uInsert(customParameters, ParametersPair(Parameters::kKpNndrRatio(), uNumber2Str(_reextractNNDR)));
uInsert(customParameters, ParametersPair(Parameters::kKpDetectorStrategy(), uNumber2Str(_reextractFeatureType))); // FAST/BRIEF uInsert(customParameters, ParametersPair(Parameters::kKpDetectorStrategy(), uNumber2Str(_reextractFeatureType))); // FAST/BRIEF
@@ -2296,6 +2297,7 @@ void Rtabmap::get3DMap(std::map<int, std::vector<unsigned char> > & images,
bool optimized, bool optimized,
bool global) const bool global) const
{ {
UDEBUG("");
if(_memory && _memory->getLastWorkingSignature()) if(_memory && _memory->getLastWorkingSignature())
{ {
if(optimized) if(optimized)
@@ -2349,10 +2351,14 @@ void Rtabmap::get3DMap(std::map<int, std::vector<unsigned char> > & images,
mapIds.insert(std::make_pair(*iter, _memory->getMapId(*iter))); mapIds.insert(std::make_pair(*iter, _memory->getMapId(*iter)));
} }
} }
else if(_memory->getStMem().size() || _memory->getWorkingMem().size()) else if(_memory && (_memory->getStMem().size() || _memory->getWorkingMem().size()))
{ {
UERROR("Last working signature is null!?"); UERROR("Last working signature is null!?");
} }
else if(_memory == 0)
{
UWARN("Memory not initialized...");
}
} }
void Rtabmap::getGraph( void Rtabmap::getGraph(
@@ -2386,10 +2392,14 @@ void Rtabmap::getGraph(
mapIds.insert(std::make_pair(*iter, _memory->getMapId(*iter))); mapIds.insert(std::make_pair(*iter, _memory->getMapId(*iter)));
} }
} }
else if(_memory->getStMem().size() || _memory->getWorkingMem().size()) else if(_memory && (_memory->getStMem().size() || _memory->getWorkingMem().size()))
{ {
UERROR("Last working signature is null!?"); UERROR("Last working signature is null!?");
} }
else if(_memory == 0)
{
UWARN("Memory not initialized...");
}
} }
void Rtabmap::readParameters(const std::string & configFile, ParametersMap & parameters) void Rtabmap::readParameters(const std::string & configFile, ParametersMap & parameters)

View File

@@ -50,6 +50,7 @@ VWDictionary::VWDictionary(const ParametersMap & parameters) :
_incrementalDictionary(Parameters::defaultKpIncrementalDictionary()), _incrementalDictionary(Parameters::defaultKpIncrementalDictionary()),
_nndrRatio(Parameters::defaultKpNndrRatio()), _nndrRatio(Parameters::defaultKpNndrRatio()),
_dictionaryPath(Parameters::defaultKpDictionaryPath()), _dictionaryPath(Parameters::defaultKpDictionaryPath()),
_newWordsComparedTogether(Parameters::defaultKpNewWordsComparedTogether()),
_lastWordId(0), _lastWordId(0),
_flannIndex(new cv::flann::Index()), _flannIndex(new cv::flann::Index()),
_strategy(kNNUndef) _strategy(kNNUndef)
@@ -68,6 +69,7 @@ void VWDictionary::parseParameters(const ParametersMap & parameters)
{ {
ParametersMap::const_iterator iter; ParametersMap::const_iterator iter;
Parameters::parse(parameters, Parameters::kKpNndrRatio(), _nndrRatio); Parameters::parse(parameters, Parameters::kKpNndrRatio(), _nndrRatio);
Parameters::parse(parameters, Parameters::kKpNewWordsComparedTogether(), _newWordsComparedTogether);
UASSERT(_nndrRatio > 0.0f); UASSERT(_nndrRatio > 0.0f);
@@ -505,7 +507,7 @@ std::list<int> VWDictionary::addNewWords(const cv::Mat & descriptors,
} }
// Check if this descriptor matches with a word from the last signature (a word not already added to the tree) // Check if this descriptor matches with a word from the last signature (a word not already added to the tree)
if(newWords.rows) if(_newWordsComparedTogether && newWords.rows)
{ {
cv::flann::Index linearSeach; cv::flann::Index linearSeach;
linearSeach.build(newWords, cv::flann::LinearIndexParams(), type == CV_32F?cvflann::FLANN_DIST_L2:cvflann::FLANN_DIST_HAMMING); linearSeach.build(newWords, cv::flann::LinearIndexParams(), type == CV_32F?cvflann::FLANN_DIST_L2:cvflann::FLANN_DIST_HAMMING);

View File

@@ -1879,7 +1879,7 @@ void optimizeTOROGraph(
"TORO is not able to find the root of the graph!)"); "TORO is not able to find the root of the graph!)");
pg.initializeOptimization(); pg.initializeOptimization();
UDEBUG("TORO iterate begin"); UDEBUG("TORO iterate begin (iterations=%d)", toroIterations);
for (int i=0; i<toroIterations; i++) for (int i=0; i<toroIterations; i++)
{ {
if(intermediateGraphes && (toroInitialGuess || i>0)) if(intermediateGraphes && (toroInitialGuess || i>0))

View File

@@ -346,6 +346,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->lineEdit_kp_roi->setObjectName(Parameters::kKpRoiRatios().c_str()); _ui->lineEdit_kp_roi->setObjectName(Parameters::kKpRoiRatios().c_str());
_ui->lineEdit_dictionaryPath->setObjectName(Parameters::kKpDictionaryPath().c_str()); _ui->lineEdit_dictionaryPath->setObjectName(Parameters::kKpDictionaryPath().c_str());
connect(_ui->toolButton_dictionaryPath, SIGNAL(clicked()), this, SLOT(changeDictionaryPath())); connect(_ui->toolButton_dictionaryPath, SIGNAL(clicked()), this, SLOT(changeDictionaryPath()));
_ui->checkBox_kp_newWordsComparedTogether->setObjectName(Parameters::kKpNewWordsComparedTogether().c_str());
//SURF detector //SURF detector
_ui->surf_doubleSpinBox_hessianThr->setObjectName(Parameters::kSURFHessianThreshold().c_str()); _ui->surf_doubleSpinBox_hessianThr->setObjectName(Parameters::kSURFHessianThreshold().c_str());
@@ -429,7 +430,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->loopClosure_bowMaxDepth->setObjectName(Parameters::kLccBowMaxDepth().c_str()); _ui->loopClosure_bowMaxDepth->setObjectName(Parameters::kLccBowMaxDepth().c_str());
_ui->loopClosure_bowForce2D->setObjectName(Parameters::kLccBowForce2D().c_str()); _ui->loopClosure_bowForce2D->setObjectName(Parameters::kLccBowForce2D().c_str());
_ui->groupBox_reextract->setObjectName(Parameters::kLccReextractLoopClosureFeatures().c_str()); _ui->groupBox_reextract->setObjectName(Parameters::kLccReextractActivated().c_str());
_ui->reextract_nn->setObjectName(Parameters::kLccReextractNNType().c_str()); _ui->reextract_nn->setObjectName(Parameters::kLccReextractNNType().c_str());
_ui->reextract_nndrRatio->setObjectName(Parameters::kLccReextractNNDR().c_str()); _ui->reextract_nndrRatio->setObjectName(Parameters::kLccReextractNNDR().c_str());
_ui->reextract_type->setObjectName(Parameters::kLccReextractFeatureType().c_str()); _ui->reextract_type->setObjectName(Parameters::kLccReextractFeatureType().c_str());
@@ -1834,64 +1835,57 @@ 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)
{ {
if(obj->isEnabled()) QSpinBox * spin = qobject_cast<QSpinBox *>(obj);
QDoubleSpinBox * doubleSpin = qobject_cast<QDoubleSpinBox *>(obj);
QComboBox * combo = qobject_cast<QComboBox *>(obj);
QCheckBox * check = qobject_cast<QCheckBox *>(obj);
QRadioButton * radio = qobject_cast<QRadioButton *>(obj);
QLineEdit * lineEdit = qobject_cast<QLineEdit *>(obj);
QGroupBox * groupBox = qobject_cast<QGroupBox *>(obj);
bool ok;
if(spin)
{ {
QSpinBox * spin = qobject_cast<QSpinBox *>(obj); spin->setValue(QString(value.c_str()).toInt(&ok));
QDoubleSpinBox * doubleSpin = qobject_cast<QDoubleSpinBox *>(obj); if(!ok)
QComboBox * combo = qobject_cast<QComboBox *>(obj);
QCheckBox * check = qobject_cast<QCheckBox *>(obj);
QRadioButton * radio = qobject_cast<QRadioButton *>(obj);
QLineEdit * lineEdit = qobject_cast<QLineEdit *>(obj);
QGroupBox * groupBox = qobject_cast<QGroupBox *>(obj);
bool ok;
if(spin)
{ {
spin->setValue(QString(value.c_str()).toInt(&ok)); UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
if(!ok)
{
UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
}
} }
else if(doubleSpin) }
else if(doubleSpin)
{
doubleSpin->setValue(QString(value.c_str()).toDouble(&ok));
if(!ok)
{ {
doubleSpin->setValue(QString(value.c_str()).toDouble(&ok)); UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
if(!ok)
{
UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
}
} }
else if(combo) }
else if(combo)
{
combo->setCurrentIndex(QString(value.c_str()).toInt(&ok));
if(!ok)
{ {
combo->setCurrentIndex(QString(value.c_str()).toInt(&ok)); UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
if(!ok)
{
UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
}
}
else if(check)
{
check->setChecked(uStr2Bool(value.c_str()));
}
else if(radio)
{
radio->setChecked(uStr2Bool(value.c_str()));
}
else if(lineEdit)
{
lineEdit->setText(value.c_str());
}
else if(groupBox)
{
groupBox->setChecked(uStr2Bool(value.c_str()));
}
else
{
ULOGGER_WARN("QObject called %s can't be cast to a supported widget", key.c_str());
} }
} }
else if(check)
{
check->setChecked(uStr2Bool(value.c_str()));
}
else if(radio)
{
radio->setChecked(uStr2Bool(value.c_str()));
}
else if(lineEdit)
{
lineEdit->setText(value.c_str());
}
else if(groupBox)
{
groupBox->setChecked(uStr2Bool(value.c_str()));
}
else else
{ {
UDEBUG("Ignoring parameter %s because it is disabled.", key.c_str()); ULOGGER_WARN("QObject called %s can't be cast to a supported widget", key.c_str());
} }
} }
else else

View File

@@ -65,7 +65,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>744</width> <width>744</width>
<height>1019</height> <height>900</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_16"> <layout class="QVBoxLayout" name="verticalLayout_16">
@@ -86,7 +86,7 @@
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>24</number> <number>9</number>
</property> </property>
<widget class="QWidget" name="page_22"> <widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29"> <layout class="QVBoxLayout" name="verticalLayout_29">
@@ -3561,6 +3561,26 @@ When set to false, no new words are added to dictionary, so no more updates are
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_kp_newWordsComparedTogether">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_186">
<property name="text">
<string>When adding new words to dictionary, they are compared also with each other (to detect same words in the same signature).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>