openCV library for Renesas RZ/A

Dependents:   RZ_A2M_Mbed_samples

Committer:
RyoheiHagimoto
Date:
Fri Jan 29 04:53:38 2021 +0000
Revision:
0:0e0631af0305
copied from https://github.com/d-kato/opencv-lib.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RyoheiHagimoto 0:0e0631af0305 1 /***********************************************************************
RyoheiHagimoto 0:0e0631af0305 2 * Software License Agreement (BSD License)
RyoheiHagimoto 0:0e0631af0305 3 *
RyoheiHagimoto 0:0e0631af0305 4 * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
RyoheiHagimoto 0:0e0631af0305 5 * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
RyoheiHagimoto 0:0e0631af0305 6 *
RyoheiHagimoto 0:0e0631af0305 7 * THE BSD LICENSE
RyoheiHagimoto 0:0e0631af0305 8 *
RyoheiHagimoto 0:0e0631af0305 9 * Redistribution and use in source and binary forms, with or without
RyoheiHagimoto 0:0e0631af0305 10 * modification, are permitted provided that the following conditions
RyoheiHagimoto 0:0e0631af0305 11 * are met:
RyoheiHagimoto 0:0e0631af0305 12 *
RyoheiHagimoto 0:0e0631af0305 13 * 1. Redistributions of source code must retain the above copyright
RyoheiHagimoto 0:0e0631af0305 14 * notice, this list of conditions and the following disclaimer.
RyoheiHagimoto 0:0e0631af0305 15 * 2. Redistributions in binary form must reproduce the above copyright
RyoheiHagimoto 0:0e0631af0305 16 * notice, this list of conditions and the following disclaimer in the
RyoheiHagimoto 0:0e0631af0305 17 * documentation and/or other materials provided with the distribution.
RyoheiHagimoto 0:0e0631af0305 18 *
RyoheiHagimoto 0:0e0631af0305 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
RyoheiHagimoto 0:0e0631af0305 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
RyoheiHagimoto 0:0e0631af0305 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
RyoheiHagimoto 0:0e0631af0305 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
RyoheiHagimoto 0:0e0631af0305 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
RyoheiHagimoto 0:0e0631af0305 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
RyoheiHagimoto 0:0e0631af0305 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
RyoheiHagimoto 0:0e0631af0305 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
RyoheiHagimoto 0:0e0631af0305 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
RyoheiHagimoto 0:0e0631af0305 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RyoheiHagimoto 0:0e0631af0305 29 *************************************************************************/
RyoheiHagimoto 0:0e0631af0305 30
RyoheiHagimoto 0:0e0631af0305 31 #ifndef OPENCV_FLANN_BASE_HPP_
RyoheiHagimoto 0:0e0631af0305 32 #define OPENCV_FLANN_BASE_HPP_
RyoheiHagimoto 0:0e0631af0305 33
RyoheiHagimoto 0:0e0631af0305 34 #include <vector>
RyoheiHagimoto 0:0e0631af0305 35 #include <cassert>
RyoheiHagimoto 0:0e0631af0305 36 #include <cstdio>
RyoheiHagimoto 0:0e0631af0305 37
RyoheiHagimoto 0:0e0631af0305 38 #include "general.h"
RyoheiHagimoto 0:0e0631af0305 39 #include "matrix.h"
RyoheiHagimoto 0:0e0631af0305 40 #include "params.h"
RyoheiHagimoto 0:0e0631af0305 41 #include "saving.h"
RyoheiHagimoto 0:0e0631af0305 42
RyoheiHagimoto 0:0e0631af0305 43 #include "all_indices.h"
RyoheiHagimoto 0:0e0631af0305 44
RyoheiHagimoto 0:0e0631af0305 45 namespace cvflann
RyoheiHagimoto 0:0e0631af0305 46 {
RyoheiHagimoto 0:0e0631af0305 47
RyoheiHagimoto 0:0e0631af0305 48 /**
RyoheiHagimoto 0:0e0631af0305 49 * Sets the log level used for all flann functions
RyoheiHagimoto 0:0e0631af0305 50 * @param level Verbosity level
RyoheiHagimoto 0:0e0631af0305 51 */
RyoheiHagimoto 0:0e0631af0305 52 inline void log_verbosity(int level)
RyoheiHagimoto 0:0e0631af0305 53 {
RyoheiHagimoto 0:0e0631af0305 54 if (level >= 0) {
RyoheiHagimoto 0:0e0631af0305 55 Logger::setLevel(level);
RyoheiHagimoto 0:0e0631af0305 56 }
RyoheiHagimoto 0:0e0631af0305 57 }
RyoheiHagimoto 0:0e0631af0305 58
RyoheiHagimoto 0:0e0631af0305 59 /**
RyoheiHagimoto 0:0e0631af0305 60 * (Deprecated) Index parameters for creating a saved index.
RyoheiHagimoto 0:0e0631af0305 61 */
RyoheiHagimoto 0:0e0631af0305 62 struct SavedIndexParams : public IndexParams
RyoheiHagimoto 0:0e0631af0305 63 {
RyoheiHagimoto 0:0e0631af0305 64 SavedIndexParams(cv::String filename)
RyoheiHagimoto 0:0e0631af0305 65 {
RyoheiHagimoto 0:0e0631af0305 66 (* this)["algorithm"] = FLANN_INDEX_SAVED;
RyoheiHagimoto 0:0e0631af0305 67 (*this)["filename"] = filename;
RyoheiHagimoto 0:0e0631af0305 68 }
RyoheiHagimoto 0:0e0631af0305 69 };
RyoheiHagimoto 0:0e0631af0305 70
RyoheiHagimoto 0:0e0631af0305 71
RyoheiHagimoto 0:0e0631af0305 72 template<typename Distance>
RyoheiHagimoto 0:0e0631af0305 73 NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const cv::String& filename, Distance distance)
RyoheiHagimoto 0:0e0631af0305 74 {
RyoheiHagimoto 0:0e0631af0305 75 typedef typename Distance::ElementType ElementType;
RyoheiHagimoto 0:0e0631af0305 76
RyoheiHagimoto 0:0e0631af0305 77 FILE* fin = fopen(filename.c_str(), "rb");
RyoheiHagimoto 0:0e0631af0305 78 if (fin == NULL) {
RyoheiHagimoto 0:0e0631af0305 79 return NULL;
RyoheiHagimoto 0:0e0631af0305 80 }
RyoheiHagimoto 0:0e0631af0305 81 IndexHeader header = load_header(fin);
RyoheiHagimoto 0:0e0631af0305 82 if (header.data_type != Datatype<ElementType>::type()) {
RyoheiHagimoto 0:0e0631af0305 83 throw FLANNException("Datatype of saved index is different than of the one to be created.");
RyoheiHagimoto 0:0e0631af0305 84 }
RyoheiHagimoto 0:0e0631af0305 85 if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) {
RyoheiHagimoto 0:0e0631af0305 86 throw FLANNException("The index saved belongs to a different dataset");
RyoheiHagimoto 0:0e0631af0305 87 }
RyoheiHagimoto 0:0e0631af0305 88
RyoheiHagimoto 0:0e0631af0305 89 IndexParams params;
RyoheiHagimoto 0:0e0631af0305 90 params["algorithm"] = header.index_type;
RyoheiHagimoto 0:0e0631af0305 91 NNIndex<Distance>* nnIndex = create_index_by_type<Distance>(dataset, params, distance);
RyoheiHagimoto 0:0e0631af0305 92 nnIndex->loadIndex(fin);
RyoheiHagimoto 0:0e0631af0305 93 fclose(fin);
RyoheiHagimoto 0:0e0631af0305 94
RyoheiHagimoto 0:0e0631af0305 95 return nnIndex;
RyoheiHagimoto 0:0e0631af0305 96 }
RyoheiHagimoto 0:0e0631af0305 97
RyoheiHagimoto 0:0e0631af0305 98
RyoheiHagimoto 0:0e0631af0305 99 template<typename Distance>
RyoheiHagimoto 0:0e0631af0305 100 class Index : public NNIndex<Distance>
RyoheiHagimoto 0:0e0631af0305 101 {
RyoheiHagimoto 0:0e0631af0305 102 public:
RyoheiHagimoto 0:0e0631af0305 103 typedef typename Distance::ElementType ElementType;
RyoheiHagimoto 0:0e0631af0305 104 typedef typename Distance::ResultType DistanceType;
RyoheiHagimoto 0:0e0631af0305 105
RyoheiHagimoto 0:0e0631af0305 106 Index(const Matrix<ElementType>& features, const IndexParams& params, Distance distance = Distance() )
RyoheiHagimoto 0:0e0631af0305 107 : index_params_(params)
RyoheiHagimoto 0:0e0631af0305 108 {
RyoheiHagimoto 0:0e0631af0305 109 flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
RyoheiHagimoto 0:0e0631af0305 110 loaded_ = false;
RyoheiHagimoto 0:0e0631af0305 111
RyoheiHagimoto 0:0e0631af0305 112 if (index_type == FLANN_INDEX_SAVED) {
RyoheiHagimoto 0:0e0631af0305 113 nnIndex_ = load_saved_index<Distance>(features, get_param<cv::String>(params,"filename"), distance);
RyoheiHagimoto 0:0e0631af0305 114 loaded_ = true;
RyoheiHagimoto 0:0e0631af0305 115 }
RyoheiHagimoto 0:0e0631af0305 116 else {
RyoheiHagimoto 0:0e0631af0305 117 nnIndex_ = create_index_by_type<Distance>(features, params, distance);
RyoheiHagimoto 0:0e0631af0305 118 }
RyoheiHagimoto 0:0e0631af0305 119 }
RyoheiHagimoto 0:0e0631af0305 120
RyoheiHagimoto 0:0e0631af0305 121 ~Index()
RyoheiHagimoto 0:0e0631af0305 122 {
RyoheiHagimoto 0:0e0631af0305 123 delete nnIndex_;
RyoheiHagimoto 0:0e0631af0305 124 }
RyoheiHagimoto 0:0e0631af0305 125
RyoheiHagimoto 0:0e0631af0305 126 /**
RyoheiHagimoto 0:0e0631af0305 127 * Builds the index.
RyoheiHagimoto 0:0e0631af0305 128 */
RyoheiHagimoto 0:0e0631af0305 129 void buildIndex()
RyoheiHagimoto 0:0e0631af0305 130 {
RyoheiHagimoto 0:0e0631af0305 131 if (!loaded_) {
RyoheiHagimoto 0:0e0631af0305 132 nnIndex_->buildIndex();
RyoheiHagimoto 0:0e0631af0305 133 }
RyoheiHagimoto 0:0e0631af0305 134 }
RyoheiHagimoto 0:0e0631af0305 135
RyoheiHagimoto 0:0e0631af0305 136 void save(cv::String filename)
RyoheiHagimoto 0:0e0631af0305 137 {
RyoheiHagimoto 0:0e0631af0305 138 FILE* fout = fopen(filename.c_str(), "wb");
RyoheiHagimoto 0:0e0631af0305 139 if (fout == NULL) {
RyoheiHagimoto 0:0e0631af0305 140 throw FLANNException("Cannot open file");
RyoheiHagimoto 0:0e0631af0305 141 }
RyoheiHagimoto 0:0e0631af0305 142 save_header(fout, *nnIndex_);
RyoheiHagimoto 0:0e0631af0305 143 saveIndex(fout);
RyoheiHagimoto 0:0e0631af0305 144 fclose(fout);
RyoheiHagimoto 0:0e0631af0305 145 }
RyoheiHagimoto 0:0e0631af0305 146
RyoheiHagimoto 0:0e0631af0305 147 /**
RyoheiHagimoto 0:0e0631af0305 148 * \brief Saves the index to a stream
RyoheiHagimoto 0:0e0631af0305 149 * \param stream The stream to save the index to
RyoheiHagimoto 0:0e0631af0305 150 */
RyoheiHagimoto 0:0e0631af0305 151 virtual void saveIndex(FILE* stream)
RyoheiHagimoto 0:0e0631af0305 152 {
RyoheiHagimoto 0:0e0631af0305 153 nnIndex_->saveIndex(stream);
RyoheiHagimoto 0:0e0631af0305 154 }
RyoheiHagimoto 0:0e0631af0305 155
RyoheiHagimoto 0:0e0631af0305 156 /**
RyoheiHagimoto 0:0e0631af0305 157 * \brief Loads the index from a stream
RyoheiHagimoto 0:0e0631af0305 158 * \param stream The stream from which the index is loaded
RyoheiHagimoto 0:0e0631af0305 159 */
RyoheiHagimoto 0:0e0631af0305 160 virtual void loadIndex(FILE* stream)
RyoheiHagimoto 0:0e0631af0305 161 {
RyoheiHagimoto 0:0e0631af0305 162 nnIndex_->loadIndex(stream);
RyoheiHagimoto 0:0e0631af0305 163 }
RyoheiHagimoto 0:0e0631af0305 164
RyoheiHagimoto 0:0e0631af0305 165 /**
RyoheiHagimoto 0:0e0631af0305 166 * \returns number of features in this index.
RyoheiHagimoto 0:0e0631af0305 167 */
RyoheiHagimoto 0:0e0631af0305 168 size_t veclen() const
RyoheiHagimoto 0:0e0631af0305 169 {
RyoheiHagimoto 0:0e0631af0305 170 return nnIndex_->veclen();
RyoheiHagimoto 0:0e0631af0305 171 }
RyoheiHagimoto 0:0e0631af0305 172
RyoheiHagimoto 0:0e0631af0305 173 /**
RyoheiHagimoto 0:0e0631af0305 174 * \returns The dimensionality of the features in this index.
RyoheiHagimoto 0:0e0631af0305 175 */
RyoheiHagimoto 0:0e0631af0305 176 size_t size() const
RyoheiHagimoto 0:0e0631af0305 177 {
RyoheiHagimoto 0:0e0631af0305 178 return nnIndex_->size();
RyoheiHagimoto 0:0e0631af0305 179 }
RyoheiHagimoto 0:0e0631af0305 180
RyoheiHagimoto 0:0e0631af0305 181 /**
RyoheiHagimoto 0:0e0631af0305 182 * \returns The index type (kdtree, kmeans,...)
RyoheiHagimoto 0:0e0631af0305 183 */
RyoheiHagimoto 0:0e0631af0305 184 flann_algorithm_t getType() const
RyoheiHagimoto 0:0e0631af0305 185 {
RyoheiHagimoto 0:0e0631af0305 186 return nnIndex_->getType();
RyoheiHagimoto 0:0e0631af0305 187 }
RyoheiHagimoto 0:0e0631af0305 188
RyoheiHagimoto 0:0e0631af0305 189 /**
RyoheiHagimoto 0:0e0631af0305 190 * \returns The amount of memory (in bytes) used by the index.
RyoheiHagimoto 0:0e0631af0305 191 */
RyoheiHagimoto 0:0e0631af0305 192 virtual int usedMemory() const
RyoheiHagimoto 0:0e0631af0305 193 {
RyoheiHagimoto 0:0e0631af0305 194 return nnIndex_->usedMemory();
RyoheiHagimoto 0:0e0631af0305 195 }
RyoheiHagimoto 0:0e0631af0305 196
RyoheiHagimoto 0:0e0631af0305 197
RyoheiHagimoto 0:0e0631af0305 198 /**
RyoheiHagimoto 0:0e0631af0305 199 * \returns The index parameters
RyoheiHagimoto 0:0e0631af0305 200 */
RyoheiHagimoto 0:0e0631af0305 201 IndexParams getParameters() const
RyoheiHagimoto 0:0e0631af0305 202 {
RyoheiHagimoto 0:0e0631af0305 203 return nnIndex_->getParameters();
RyoheiHagimoto 0:0e0631af0305 204 }
RyoheiHagimoto 0:0e0631af0305 205
RyoheiHagimoto 0:0e0631af0305 206 /**
RyoheiHagimoto 0:0e0631af0305 207 * \brief Perform k-nearest neighbor search
RyoheiHagimoto 0:0e0631af0305 208 * \param[in] queries The query points for which to find the nearest neighbors
RyoheiHagimoto 0:0e0631af0305 209 * \param[out] indices The indices of the nearest neighbors found
RyoheiHagimoto 0:0e0631af0305 210 * \param[out] dists Distances to the nearest neighbors found
RyoheiHagimoto 0:0e0631af0305 211 * \param[in] knn Number of nearest neighbors to return
RyoheiHagimoto 0:0e0631af0305 212 * \param[in] params Search parameters
RyoheiHagimoto 0:0e0631af0305 213 */
RyoheiHagimoto 0:0e0631af0305 214 void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params)
RyoheiHagimoto 0:0e0631af0305 215 {
RyoheiHagimoto 0:0e0631af0305 216 nnIndex_->knnSearch(queries, indices, dists, knn, params);
RyoheiHagimoto 0:0e0631af0305 217 }
RyoheiHagimoto 0:0e0631af0305 218
RyoheiHagimoto 0:0e0631af0305 219 /**
RyoheiHagimoto 0:0e0631af0305 220 * \brief Perform radius search
RyoheiHagimoto 0:0e0631af0305 221 * \param[in] query The query point
RyoheiHagimoto 0:0e0631af0305 222 * \param[out] indices The indinces of the neighbors found within the given radius
RyoheiHagimoto 0:0e0631af0305 223 * \param[out] dists The distances to the nearest neighbors found
RyoheiHagimoto 0:0e0631af0305 224 * \param[in] radius The radius used for search
RyoheiHagimoto 0:0e0631af0305 225 * \param[in] params Search parameters
RyoheiHagimoto 0:0e0631af0305 226 * \returns Number of neighbors found
RyoheiHagimoto 0:0e0631af0305 227 */
RyoheiHagimoto 0:0e0631af0305 228 int radiusSearch(const Matrix<ElementType>& query, Matrix<int>& indices, Matrix<DistanceType>& dists, float radius, const SearchParams& params)
RyoheiHagimoto 0:0e0631af0305 229 {
RyoheiHagimoto 0:0e0631af0305 230 return nnIndex_->radiusSearch(query, indices, dists, radius, params);
RyoheiHagimoto 0:0e0631af0305 231 }
RyoheiHagimoto 0:0e0631af0305 232
RyoheiHagimoto 0:0e0631af0305 233 /**
RyoheiHagimoto 0:0e0631af0305 234 * \brief Method that searches for nearest-neighbours
RyoheiHagimoto 0:0e0631af0305 235 */
RyoheiHagimoto 0:0e0631af0305 236 void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
RyoheiHagimoto 0:0e0631af0305 237 {
RyoheiHagimoto 0:0e0631af0305 238 nnIndex_->findNeighbors(result, vec, searchParams);
RyoheiHagimoto 0:0e0631af0305 239 }
RyoheiHagimoto 0:0e0631af0305 240
RyoheiHagimoto 0:0e0631af0305 241 /**
RyoheiHagimoto 0:0e0631af0305 242 * \brief Returns actual index
RyoheiHagimoto 0:0e0631af0305 243 */
RyoheiHagimoto 0:0e0631af0305 244 FLANN_DEPRECATED NNIndex<Distance>* getIndex()
RyoheiHagimoto 0:0e0631af0305 245 {
RyoheiHagimoto 0:0e0631af0305 246 return nnIndex_;
RyoheiHagimoto 0:0e0631af0305 247 }
RyoheiHagimoto 0:0e0631af0305 248
RyoheiHagimoto 0:0e0631af0305 249 /**
RyoheiHagimoto 0:0e0631af0305 250 * \brief Returns index parameters.
RyoheiHagimoto 0:0e0631af0305 251 * \deprecated use getParameters() instead.
RyoheiHagimoto 0:0e0631af0305 252 */
RyoheiHagimoto 0:0e0631af0305 253 FLANN_DEPRECATED const IndexParams* getIndexParameters()
RyoheiHagimoto 0:0e0631af0305 254 {
RyoheiHagimoto 0:0e0631af0305 255 return &index_params_;
RyoheiHagimoto 0:0e0631af0305 256 }
RyoheiHagimoto 0:0e0631af0305 257
RyoheiHagimoto 0:0e0631af0305 258 private:
RyoheiHagimoto 0:0e0631af0305 259 /** Pointer to actual index class */
RyoheiHagimoto 0:0e0631af0305 260 NNIndex<Distance>* nnIndex_;
RyoheiHagimoto 0:0e0631af0305 261 /** Indices if the index was loaded from a file */
RyoheiHagimoto 0:0e0631af0305 262 bool loaded_;
RyoheiHagimoto 0:0e0631af0305 263 /** Parameters passed to the index */
RyoheiHagimoto 0:0e0631af0305 264 IndexParams index_params_;
RyoheiHagimoto 0:0e0631af0305 265 };
RyoheiHagimoto 0:0e0631af0305 266
RyoheiHagimoto 0:0e0631af0305 267 /**
RyoheiHagimoto 0:0e0631af0305 268 * Performs a hierarchical clustering of the points passed as argument and then takes a cut in the
RyoheiHagimoto 0:0e0631af0305 269 * the clustering tree to return a flat clustering.
RyoheiHagimoto 0:0e0631af0305 270 * @param[in] points Points to be clustered
RyoheiHagimoto 0:0e0631af0305 271 * @param centers The computed cluster centres. Matrix should be preallocated and centers.rows is the
RyoheiHagimoto 0:0e0631af0305 272 * number of clusters requested.
RyoheiHagimoto 0:0e0631af0305 273 * @param params Clustering parameters (The same as for cvflann::KMeansIndex)
RyoheiHagimoto 0:0e0631af0305 274 * @param d Distance to be used for clustering (eg: cvflann::L2)
RyoheiHagimoto 0:0e0631af0305 275 * @return number of clusters computed (can be different than clusters.rows and is the highest number
RyoheiHagimoto 0:0e0631af0305 276 * of the form (branching-1)*K+1 smaller than clusters.rows).
RyoheiHagimoto 0:0e0631af0305 277 */
RyoheiHagimoto 0:0e0631af0305 278 template <typename Distance>
RyoheiHagimoto 0:0e0631af0305 279 int hierarchicalClustering(const Matrix<typename Distance::ElementType>& points, Matrix<typename Distance::ResultType>& centers,
RyoheiHagimoto 0:0e0631af0305 280 const KMeansIndexParams& params, Distance d = Distance())
RyoheiHagimoto 0:0e0631af0305 281 {
RyoheiHagimoto 0:0e0631af0305 282 KMeansIndex<Distance> kmeans(points, params, d);
RyoheiHagimoto 0:0e0631af0305 283 kmeans.buildIndex();
RyoheiHagimoto 0:0e0631af0305 284
RyoheiHagimoto 0:0e0631af0305 285 int clusterNum = kmeans.getClusterCenters(centers);
RyoheiHagimoto 0:0e0631af0305 286 return clusterNum;
RyoheiHagimoto 0:0e0631af0305 287 }
RyoheiHagimoto 0:0e0631af0305 288
RyoheiHagimoto 0:0e0631af0305 289 }
RyoheiHagimoto 0:0e0631af0305 290 #endif /* OPENCV_FLANN_BASE_HPP_ */