Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef OPENCV_FLANN_BASE_HPP_
00032 #define OPENCV_FLANN_BASE_HPP_
00033
00034 #include <vector>
00035 #include <string>
00036 #include <cassert>
00037 #include <cstdio>
00038
00039 #include "general.h"
00040 #include "matrix.h"
00041 #include "params.h"
00042 #include "saving.h"
00043
00044 #include "all_indices.h"
00045
00046 namespace cvflann
00047 {
00048
00053 inline void log_verbosity(int level)
00054 {
00055 if (level >= 0) {
00056 Logger::setLevel(level);
00057 }
00058 }
00059
00063 struct SavedIndexParams : public IndexParams
00064 {
00065 SavedIndexParams(std::string filename)
00066 {
00067 (* this)["algorithm"] = FLANN_INDEX_SAVED;
00068 (*this)["filename"] = filename;
00069 }
00070 };
00071
00072
00073 template<typename Distance>
00074 NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const std::string& filename, Distance distance)
00075 {
00076 typedef typename Distance::ElementType ElementType;
00077
00078 FILE* fin = fopen(filename.c_str(), "rb");
00079 if (fin == NULL) {
00080 return NULL;
00081 }
00082 IndexHeader header = load_header(fin);
00083 if (header.data_type != Datatype<ElementType>::type()) {
00084 throw FLANNException("Datatype of saved index is different than of the one to be created.");
00085 }
00086 if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) {
00087 throw FLANNException("The index saved belongs to a different dataset");
00088 }
00089
00090 IndexParams params;
00091 params["algorithm"] = header.index_type;
00092 NNIndex<Distance>* nnIndex = create_index_by_type<Distance>(dataset, params, distance);
00093 nnIndex->loadIndex(fin);
00094 fclose(fin);
00095
00096 return nnIndex;
00097 }
00098
00099
00100 template<typename Distance>
00101 class Index : public NNIndex<Distance>
00102 {
00103 public:
00104 typedef typename Distance::ElementType ElementType;
00105 typedef typename Distance::ResultType DistanceType;
00106
00107 Index(const Matrix<ElementType>& features, const IndexParams& params, Distance distance = Distance() )
00108 : index_params_(params)
00109 {
00110 flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
00111 loaded_ = false;
00112
00113 if (index_type == FLANN_INDEX_SAVED) {
00114 nnIndex_ = load_saved_index<Distance>(features, get_param<std::string>(params,"filename"), distance);
00115 loaded_ = true;
00116 }
00117 else {
00118 nnIndex_ = create_index_by_type<Distance>(features, params, distance);
00119 }
00120 }
00121
00122 ~Index()
00123 {
00124 delete nnIndex_;
00125 }
00126
00130 void buildIndex()
00131 {
00132 if (!loaded_) {
00133 nnIndex_->buildIndex();
00134 }
00135 }
00136
00137 void save(std::string filename)
00138 {
00139 FILE* fout = fopen(filename.c_str(), "wb");
00140 if (fout == NULL) {
00141 throw FLANNException("Cannot open file");
00142 }
00143 save_header(fout, *nnIndex_);
00144 saveIndex(fout);
00145 fclose(fout);
00146 }
00147
00152 virtual void saveIndex(FILE* stream)
00153 {
00154 nnIndex_->saveIndex(stream);
00155 }
00156
00161 virtual void loadIndex(FILE* stream)
00162 {
00163 nnIndex_->loadIndex(stream);
00164 }
00165
00169 size_t veclen() const
00170 {
00171 return nnIndex_->veclen();
00172 }
00173
00177 size_t size() const
00178 {
00179 return nnIndex_->size();
00180 }
00181
00185 flann_algorithm_t getType() const
00186 {
00187 return nnIndex_->getType();
00188 }
00189
00193 virtual int usedMemory() const
00194 {
00195 return nnIndex_->usedMemory();
00196 }
00197
00198
00202 IndexParams getParameters() const
00203 {
00204 return nnIndex_->getParameters();
00205 }
00206
00215 void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params)
00216 {
00217 nnIndex_->knnSearch(queries, indices, dists, knn, params);
00218 }
00219
00229 int radiusSearch(const Matrix<ElementType>& query, Matrix<int>& indices, Matrix<DistanceType>& dists, float radius, const SearchParams& params)
00230 {
00231 return nnIndex_->radiusSearch(query, indices, dists, radius, params);
00232 }
00233
00237 void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
00238 {
00239 nnIndex_->findNeighbors(result, vec, searchParams);
00240 }
00241
00245 FLANN_DEPRECATED NNIndex<Distance>* getIndex()
00246 {
00247 return nnIndex_;
00248 }
00249
00254 FLANN_DEPRECATED const IndexParams* getIndexParameters()
00255 {
00256 return &index_params_;
00257 }
00258
00259 private:
00261 NNIndex<Distance>* nnIndex_;
00263 bool loaded_;
00265 IndexParams index_params_;
00266 };
00267
00279 template <typename Distance>
00280 int hierarchicalClustering(const Matrix<typename Distance::ElementType>& points, Matrix<typename Distance::ResultType>& centers,
00281 const KMeansIndexParams& params, Distance d = Distance())
00282 {
00283 KMeansIndex<Distance> kmeans(points, params, d);
00284 kmeans.buildIndex();
00285
00286 int clusterNum = kmeans.getClusterCenters(centers);
00287 return clusterNum;
00288 }
00289
00290 }
00291 #endif