From b4e97e450d2c1331a3c9d0318241e94fee6efc60 Mon Sep 17 00:00:00 2001 From: matlabbe Date: Tue, 23 Jun 2015 18:21:30 -0400 Subject: [PATCH] First draft of a fixed vocabulary (issue #2) --- src/FindObject.cpp | 21 +++++++++++------- src/Vocabulary.cpp | 54 +++++++++++++++++++++++++++++++++++----------- src/Vocabulary.h | 2 +- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/FindObject.cpp b/src/FindObject.cpp index ed984d81..352a2345 100644 --- a/src/FindObject.cpp +++ b/src/FindObject.cpp @@ -801,11 +801,15 @@ void FindObject::updateVocabulary() sessionModified_ = true; QTime time; time.start(); - bool incremental = Settings::getGeneral_vocabularyIncremental(); + bool incremental = Settings::getGeneral_vocabularyIncremental() && !Settings::getGeneral_vocabularyFixed(); if(incremental) { UINFO("Creating incremental vocabulary..."); } + else if(Settings::getGeneral_vocabularyFixed()) + { + UINFO("Updating vocabulary correspondences only (vocabulary is fixed)..."); + } else { UINFO("Creating vocabulary..."); @@ -816,7 +820,7 @@ void FindObject::updateVocabulary() int addedWords = 0; for(int i=0; i words = vocabulary_->addWords(objectsList[i]->descriptors(), objectsList.at(i)->id(), incremental); + QMultiMap words = vocabulary_->addWords(objectsList[i]->descriptors(), objectsList.at(i)->id()); objectsList[i]->setWords(words); addedWords += words.uniqueKeys().size(); bool updated = false; @@ -834,7 +838,7 @@ void FindObject::updateVocabulary() localTime.restart(), updated?"updated":""); } - if(addedWords) + if(addedWords && !Settings::getGeneral_vocabularyFixed()) { vocabulary_->update(); } @@ -843,6 +847,10 @@ void FindObject::updateVocabulary() { UINFO("Creating incremental vocabulary... done! size=%d (%d ms)", vocabulary_->size(), time.elapsed()); } + else if(Settings::getGeneral_vocabularyFixed()) + { + UINFO("Updating vocabulary correspondences only (vocabulary is fixed)... done! size=%d (%d ms)", time.elapsed()); + } else { UINFO("Creating vocabulary... done! size=%d (%d ms)", vocabulary_->size(), time.elapsed()); @@ -1191,11 +1199,8 @@ bool FindObject::detect(const cv::Mat & image, find_object::DetectionInfo & info vocabulary_->clear(); // CREATE INDEX for the scene UDEBUG("CREATE INDEX FOR THE SCENE"); - words = vocabulary_->addWords(info.sceneDescriptors_, -1, Settings::getGeneral_vocabularyIncremental()); - if(!Settings::getGeneral_vocabularyIncremental()) - { - vocabulary_->update(); - } + words = vocabulary_->addWords(info.sceneDescriptors_, -1); + vocabulary_->update(); info.timeStamps_.insert(DetectionInfo::kTimeIndexing, time.restart()); } diff --git a/src/Vocabulary.cpp b/src/Vocabulary.cpp index 2fb02291..3ec43405 100644 --- a/src/Vocabulary.cpp +++ b/src/Vocabulary.cpp @@ -54,10 +54,17 @@ Vocabulary::~Vocabulary() void Vocabulary::clear() { - indexedDescriptors_ = cv::Mat(); - notIndexedDescriptors_ = cv::Mat(); wordToObjects_.clear(); + notIndexedDescriptors_ = cv::Mat(); notIndexedWordIds_.clear(); + + if(Settings::getGeneral_vocabularyFixed() && Settings::getGeneral_invertedSearch()) + { + // If the dictionary is fixed, don't clear indexed descriptors + return; + } + + indexedDescriptors_ = cv::Mat(); } void Vocabulary::save(QDataStream & streamPtr) const @@ -95,7 +102,7 @@ void Vocabulary::load(QDataStream & streamPtr) update(); } -QMultiMap Vocabulary::addWords(const cv::Mat & descriptors, int objectId, bool incremental) +QMultiMap Vocabulary::addWords(const cv::Mat & descriptors, int objectId) { QMultiMap words; if (descriptors.empty()) @@ -103,7 +110,7 @@ QMultiMap Vocabulary::addWords(const cv::Mat & descriptors, int object return words; } - if(incremental) + if(Settings::getGeneral_vocabularyIncremental() || Settings::getGeneral_vocabularyFixed()) { int k = 2; cv::Mat results; @@ -125,8 +132,11 @@ QMultiMap Vocabulary::addWords(const cv::Mat & descriptors, int object globalSearch = true; } - notIndexedWordIds_.reserve(notIndexedWordIds_.size() + descriptors.rows); - notIndexedDescriptors_.reserve(notIndexedDescriptors_.rows + descriptors.rows); + if(!Settings::getGeneral_vocabularyFixed()) + { + notIndexedWordIds_.reserve(notIndexedWordIds_.size() + descriptors.rows); + notIndexedDescriptors_.reserve(notIndexedDescriptors_.rows + descriptors.rows); + } int matches = 0; for(int i = 0; i < descriptors.rows; ++i) { @@ -199,21 +209,37 @@ QMultiMap Vocabulary::addWords(const cv::Mat & descriptors, int object } } - bool match = false; - // Apply NNDR - if(fullResults.size() >= 2 && + bool matched = false; + if(Settings::getNearestNeighbor_3nndrRatioUsed() && + fullResults.size() >= 2 && fullResults.begin().key() <= Settings::getNearestNeighbor_4nndrRatio() * (++fullResults.begin()).key()) { - match = true; + matched = true; + } + if((matched || !Settings::getNearestNeighbor_3nndrRatioUsed()) && + Settings::getNearestNeighbor_5minDistanceUsed()) + { + if(fullResults.begin().key() <= Settings::getNearestNeighbor_6minDistance()) + { + matched = true; + } + else + { + matched = false; + } + } + if(!matched && !Settings::getNearestNeighbor_3nndrRatioUsed() && !Settings::getNearestNeighbor_5minDistanceUsed()) + { + matched = true; // no criterion, match to the nearest descriptor } - if(match) + if(matched) { words.insert(fullResults.begin().value(), i); wordToObjects_.insert(fullResults.begin().value(), objectId); ++matches; } - else + else if(!Settings::getGeneral_invertedSearch() || !Settings::getGeneral_vocabularyFixed()) { //concatenate new words notIndexedWordIds_.push_back(indexedDescriptors_.rows + notIndexedDescriptors_.rows); @@ -221,6 +247,10 @@ QMultiMap Vocabulary::addWords(const cv::Mat & descriptors, int object words.insert(notIndexedWordIds_.back(), i); wordToObjects_.insert(notIndexedWordIds_.back(), objectId); } + else + { + words.insert(-1, i); // invalid word + } } } else diff --git a/src/Vocabulary.h b/src/Vocabulary.h index 427d93cb..8e9360e9 100644 --- a/src/Vocabulary.h +++ b/src/Vocabulary.h @@ -40,7 +40,7 @@ public: virtual ~Vocabulary(); void clear(); - QMultiMap addWords(const cv::Mat & descriptors, int objectId, bool incremental); + QMultiMap addWords(const cv::Mat & descriptors, int objectId); void update(); void search(const cv::Mat & descriptors, cv::Mat & results, cv::Mat & dists, int k); int size() const {return indexedDescriptors_.rows + notIndexedDescriptors_.rows;}