Fixed crash when adding new words to incremental FLANN (after some were removed from the dictionnary and deleted when transferring to database)

This commit is contained in:
matlabbe
2015-10-15 14:08:30 -04:00
parent 78164c9770
commit a8b5311d88
3 changed files with 67 additions and 4 deletions

View File

@@ -85,6 +85,8 @@ public:
} }
nextIndex_ = 0; nextIndex_ = 0;
isLSH_ = false; isLSH_ = false;
addedDescriptors_.clear();
removedIndexes_.clear();
} }
unsigned int indexedFeatures() const unsigned int indexedFeatures() const
@@ -142,6 +144,14 @@ public:
index_ = new rtflann::Index<rtflann::L2<float> >(dataset, params); index_ = new rtflann::Index<rtflann::L2<float> >(dataset, params);
((rtflann::Index<rtflann::L2<float> >*)index_)->buildIndex(); ((rtflann::Index<rtflann::L2<float> >*)index_)->buildIndex();
} }
if(features.rows == 1)
{
// incremental FLANN
addedDescriptors_.insert(std::make_pair(nextIndex_, features));
}
// else assume that the features are kept in memory outside this class (e.g., dataTree_)
nextIndex_ = features.rows; nextIndex_ = features.rows;
} }
@@ -165,14 +175,41 @@ public:
UASSERT(feature.rows == 1); UASSERT(feature.rows == 1);
if(featuresType_ == CV_8UC1) if(featuresType_ == CV_8UC1)
{ {
rtflann::Matrix<unsigned char> dataset(feature.data, feature.rows, feature.cols); rtflann::Matrix<unsigned char> point(feature.data, feature.rows, feature.cols);
((rtflann::Index<rtflann::Hamming<unsigned char> >*)index_)->addPoints(dataset); rtflann::Index<rtflann::Hamming<unsigned char> > * index = (rtflann::Index<rtflann::Hamming<unsigned char> >*)index_;
index->addPoints(point, 0);
// Rebuild index if it doubles in size
if(index->sizeAtBuild() * 2 < index->size()+index->removedCount())
{
// clean not used features
for(std::list<int>::iterator iter=removedIndexes_.begin(); iter!=removedIndexes_.end(); ++iter)
{
addedDescriptors_.erase(*iter);
}
removedIndexes_.clear();
index->buildIndex();
}
} }
else else
{ {
rtflann::Matrix<float> dataset((float*)feature.data, feature.rows, feature.cols); rtflann::Matrix<float> point((float*)feature.data, feature.rows, feature.cols);
((rtflann::Index<rtflann::L2<float> >*)index_)->addPoints(dataset); rtflann::Index<rtflann::L2<float> > * index = (rtflann::Index<rtflann::L2<float> >*)index_;
index->addPoints(point, 0);
// Rebuild index if it doubles in size
if(index->sizeAtBuild() * 2 < index->size()+index->removedCount())
{
// clean not used features
for(std::list<int>::iterator iter=removedIndexes_.begin(); iter!=removedIndexes_.end(); ++iter)
{
addedDescriptors_.erase(*iter);
} }
removedIndexes_.clear();
index->buildIndex();
}
}
addedDescriptors_.insert(std::make_pair(nextIndex_, feature));
return nextIndex_++; return nextIndex_++;
} }
@@ -197,6 +234,7 @@ public:
{ {
((rtflann::Index<rtflann::L2<float> >*)index_)->removePoint(index); ((rtflann::Index<rtflann::L2<float> >*)index_)->removePoint(index);
} }
removedIndexes_.push_back(index);
} }
void knnSearch( void knnSearch(
@@ -236,6 +274,11 @@ private:
int featuresType_; int featuresType_;
int featuresDim_; int featuresDim_;
bool isLSH_; bool isLSH_;
// keep feature in memory until the tree is rebuilt
// (in case the word is deleted when removed from the VWDictionary)
std::map<int, cv::Mat> addedDescriptors_;
std::list<int> removedIndexes_;
}; };
const int VWDictionary::ID_START = 1; const int VWDictionary::ID_START = 1;

View File

@@ -203,6 +203,16 @@ public:
return size_ - removed_count_; return size_ - removed_count_;
} }
inline size_t removedCount() const
{
return removed_count_;
}
inline size_t sizeAtBuild() const
{
return size_at_build_;
}
/** /**
* @return The dimensionality of the features in this index. * @return The dimensionality of the features in this index.
*/ */

View File

@@ -200,6 +200,16 @@ public:
return nnIndex_->size(); return nnIndex_->size();
} }
size_t removedCount() const
{
return nnIndex_->removedCount();
}
size_t sizeAtBuild() const
{
return nnIndex_->sizeAtBuild();
}
/** /**
* \returns The index type (kdtree, kmeans,...) * \returns The index type (kdtree, kmeans,...)
*/ */