| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef FLANN_HPP_ |
| | #define FLANN_HPP_ |
| |
|
| |
|
| | #include <vector> |
| | #include <string> |
| | #include <cassert> |
| | #include <cstdio> |
| |
|
| | #include "FLANN/general.h" |
| | #include "FLANN/util/matrix.h" |
| | #include "FLANN/util/params.h" |
| | #include "FLANN/util/saving.h" |
| |
|
| | #include "FLANN/algorithms/all_indices.h" |
| |
|
| | namespace flann |
| | { |
| |
|
| | |
| | |
| | |
| | |
| | inline void log_verbosity(int level) |
| | { |
| | if (level >= 0) { |
| | Logger::setLevel(level); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | struct SavedIndexParams : public IndexParams |
| | { |
| | SavedIndexParams(std::string filename) |
| | { |
| | (*this)["algorithm"] = FLANN_INDEX_SAVED; |
| | (*this)["filename"] = filename; |
| | } |
| | }; |
| |
|
| |
|
| |
|
| | template<typename Distance> |
| | class Index |
| | { |
| | public: |
| | typedef typename Distance::ElementType ElementType; |
| | typedef typename Distance::ResultType DistanceType; |
| | typedef NNIndex<Distance> IndexType; |
| |
|
| | Index(const IndexParams& params, Distance distance = Distance() ) |
| | : index_params_(params) |
| | { |
| | flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm"); |
| | loaded_ = false; |
| |
|
| | Matrix<ElementType> features; |
| | if (index_type == FLANN_INDEX_SAVED) { |
| | nnIndex_ = load_saved_index(features, get_param<std::string>(params,"filename"), distance); |
| | loaded_ = true; |
| | } |
| | else { |
| | flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm"); |
| | nnIndex_ = create_index_by_type<Distance>(index_type, features, params, distance); |
| | } |
| | } |
| |
|
| |
|
| | Index(const Matrix<ElementType>& features, const IndexParams& params, Distance distance = Distance() ) |
| | : index_params_(params) |
| | { |
| | flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm"); |
| | loaded_ = false; |
| |
|
| | if (index_type == FLANN_INDEX_SAVED) { |
| | nnIndex_ = load_saved_index(features, get_param<std::string>(params,"filename"), distance); |
| | loaded_ = true; |
| | } |
| | else { |
| | flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm"); |
| | nnIndex_ = create_index_by_type<Distance>(index_type, features, params, distance); |
| | } |
| | } |
| |
|
| |
|
| | Index(const Index& other) : loaded_(other.loaded_), index_params_(other.index_params_) |
| | { |
| | nnIndex_ = other.nnIndex_->clone(); |
| | } |
| |
|
| | Index& operator=(Index other) |
| | { |
| | this->swap(other); |
| | return *this; |
| | } |
| |
|
| | virtual ~Index() |
| | { |
| | delete nnIndex_; |
| | } |
| |
|
| | |
| | |
| | |
| | void buildIndex() |
| | { |
| | if (!loaded_) { |
| | nnIndex_->buildIndex(); |
| | } |
| | } |
| |
|
| | void buildIndex(const Matrix<ElementType>& points) |
| | { |
| | nnIndex_->buildIndex(points); |
| | } |
| |
|
| | void addPoints(const Matrix<ElementType>& points, float rebuild_threshold = 2) |
| | { |
| | nnIndex_->addPoints(points, rebuild_threshold); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | void removePoint(size_t point_id) |
| | { |
| | nnIndex_->removePoint(point_id); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | ElementType* getPoint(size_t point_id) |
| | { |
| | return nnIndex_->getPoint(point_id); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | void save(std::string filename) |
| | { |
| | FILE* fout = fopen(filename.c_str(), "wb"); |
| | if (fout == NULL) { |
| | throw FLANNException("Cannot open file"); |
| | } |
| | nnIndex_->saveIndex(fout); |
| | fclose(fout); |
| | } |
| |
|
| | |
| | |
| | |
| | size_t veclen() const |
| | { |
| | return nnIndex_->veclen(); |
| | } |
| |
|
| | |
| | |
| | |
| | size_t size() const |
| | { |
| | return nnIndex_->size(); |
| | } |
| |
|
| | |
| | |
| | |
| | flann_algorithm_t getType() const |
| | { |
| | return nnIndex_->getType(); |
| | } |
| |
|
| | |
| | |
| | |
| | int usedMemory() const |
| | { |
| | return nnIndex_->usedMemory(); |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | IndexParams getParameters() const |
| | { |
| | return nnIndex_->getParameters(); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int knnSearch(const Matrix<ElementType>& queries, |
| | Matrix<size_t>& indices, |
| | Matrix<DistanceType>& dists, |
| | size_t knn, |
| | const SearchParams& params) const |
| | { |
| | return nnIndex_->knnSearch(queries, indices, dists, knn, params); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int knnSearch(const Matrix<ElementType>& queries, |
| | Matrix<int>& indices, |
| | Matrix<DistanceType>& dists, |
| | size_t knn, |
| | const SearchParams& params) const |
| | { |
| | return nnIndex_->knnSearch(queries, indices, dists, knn, params); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int knnSearch(const Matrix<ElementType>& queries, |
| | std::vector< std::vector<size_t> >& indices, |
| | std::vector<std::vector<DistanceType> >& dists, |
| | size_t knn, |
| | const SearchParams& params) const |
| | { |
| | return nnIndex_->knnSearch(queries, indices, dists, knn, params); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int knnSearch(const Matrix<ElementType>& queries, |
| | std::vector< std::vector<int> >& indices, |
| | std::vector<std::vector<DistanceType> >& dists, |
| | size_t knn, |
| | const SearchParams& params) const |
| | { |
| | return nnIndex_->knnSearch(queries, indices, dists, knn, params); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int radiusSearch(const Matrix<ElementType>& queries, |
| | Matrix<size_t>& indices, |
| | Matrix<DistanceType>& dists, |
| | float radius, |
| | const SearchParams& params) const |
| | { |
| | return nnIndex_->radiusSearch(queries, indices, dists, radius, params); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int radiusSearch(const Matrix<ElementType>& queries, |
| | Matrix<int>& indices, |
| | Matrix<DistanceType>& dists, |
| | float radius, |
| | const SearchParams& params) const |
| | { |
| | return nnIndex_->radiusSearch(queries, indices, dists, radius, params); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int radiusSearch(const Matrix<ElementType>& queries, |
| | std::vector< std::vector<size_t> >& indices, |
| | std::vector<std::vector<DistanceType> >& dists, |
| | float radius, |
| | const SearchParams& params) const |
| | { |
| | return nnIndex_->radiusSearch(queries, indices, dists, radius, params); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int radiusSearch(const Matrix<ElementType>& queries, |
| | std::vector< std::vector<int> >& indices, |
| | std::vector<std::vector<DistanceType> >& dists, |
| | float radius, |
| | const SearchParams& params) const |
| | { |
| | return nnIndex_->radiusSearch(queries, indices, dists, radius, params); |
| | } |
| |
|
| | private: |
| | IndexType* load_saved_index(const Matrix<ElementType>& dataset, const std::string& filename, Distance distance) |
| | { |
| | FILE* fin = fopen(filename.c_str(), "rb"); |
| | if (fin == NULL) { |
| | return NULL; |
| | } |
| | IndexHeader header = load_header(fin); |
| | if (header.h.data_type != flann_datatype_value<ElementType>::value) { |
| | throw FLANNException("Datatype of saved index is different than of the one to be loaded."); |
| | } |
| |
|
| | IndexParams params; |
| | params["algorithm"] = header.h.index_type; |
| | IndexType* nnIndex = create_index_by_type<Distance>(header.h.index_type, dataset, params, distance); |
| | rewind(fin); |
| | nnIndex->loadIndex(fin); |
| | fclose(fin); |
| |
|
| | return nnIndex; |
| | } |
| |
|
| | void swap( Index& other) |
| | { |
| | std::swap(nnIndex_, other.nnIndex_); |
| | std::swap(loaded_, other.loaded_); |
| | std::swap(index_params_, other.index_params_); |
| | } |
| |
|
| | private: |
| | |
| | IndexType* nnIndex_; |
| | |
| | bool loaded_; |
| | |
| | IndexParams index_params_; |
| | }; |
| |
|
| |
|
| |
|
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename Distance> |
| | int hierarchicalClustering(const Matrix<typename Distance::ElementType>& points, Matrix<typename Distance::ResultType>& centers, |
| | const KMeansIndexParams& params, Distance d = Distance()) |
| | { |
| | KMeansIndex<Distance> kmeans(points, params, d); |
| | kmeans.buildIndex(); |
| |
|
| | int clusterNum = kmeans.getClusterCenters(centers); |
| | return clusterNum; |
| | } |
| |
|
| | } |
| | #endif |
| |
|