opencv on mbed

Dependencies:   mbed

Committer:
joeverbout
Date:
Thu Mar 31 21:16:38 2016 +0000
Revision:
0:ea44dc9ed014
OpenCV on mbed attempt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
joeverbout 0:ea44dc9ed014 1 /*M///////////////////////////////////////////////////////////////////////////////////////
joeverbout 0:ea44dc9ed014 2 //
joeverbout 0:ea44dc9ed014 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
joeverbout 0:ea44dc9ed014 4 //
joeverbout 0:ea44dc9ed014 5 // By downloading, copying, installing or using the software you agree to this license.
joeverbout 0:ea44dc9ed014 6 // If you do not agree to this license, do not download, install,
joeverbout 0:ea44dc9ed014 7 // copy or use the software.
joeverbout 0:ea44dc9ed014 8 //
joeverbout 0:ea44dc9ed014 9 //
joeverbout 0:ea44dc9ed014 10 // License Agreement
joeverbout 0:ea44dc9ed014 11 // For Open Source Computer Vision Library
joeverbout 0:ea44dc9ed014 12 //
joeverbout 0:ea44dc9ed014 13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
joeverbout 0:ea44dc9ed014 14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
joeverbout 0:ea44dc9ed014 15 // Third party copyrights are property of their respective owners.
joeverbout 0:ea44dc9ed014 16 //
joeverbout 0:ea44dc9ed014 17 // Redistribution and use in source and binary forms, with or without modification,
joeverbout 0:ea44dc9ed014 18 // are permitted provided that the following conditions are met:
joeverbout 0:ea44dc9ed014 19 //
joeverbout 0:ea44dc9ed014 20 // * Redistribution's of source code must retain the above copyright notice,
joeverbout 0:ea44dc9ed014 21 // this list of conditions and the following disclaimer.
joeverbout 0:ea44dc9ed014 22 //
joeverbout 0:ea44dc9ed014 23 // * Redistribution's in binary form must reproduce the above copyright notice,
joeverbout 0:ea44dc9ed014 24 // this list of conditions and the following disclaimer in the documentation
joeverbout 0:ea44dc9ed014 25 // and/or other materials provided with the distribution.
joeverbout 0:ea44dc9ed014 26 //
joeverbout 0:ea44dc9ed014 27 // * The name of the copyright holders may not be used to endorse or promote products
joeverbout 0:ea44dc9ed014 28 // derived from this software without specific prior written permission.
joeverbout 0:ea44dc9ed014 29 //
joeverbout 0:ea44dc9ed014 30 // This software is provided by the copyright holders and contributors "as is" and
joeverbout 0:ea44dc9ed014 31 // any express or implied warranties, including, but not limited to, the implied
joeverbout 0:ea44dc9ed014 32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
joeverbout 0:ea44dc9ed014 33 // In no event shall the Intel Corporation or contributors be liable for any direct,
joeverbout 0:ea44dc9ed014 34 // indirect, incidental, special, exemplary, or consequential damages
joeverbout 0:ea44dc9ed014 35 // (including, but not limited to, procurement of substitute goods or services;
joeverbout 0:ea44dc9ed014 36 // loss of use, data, or profits; or business interruption) however caused
joeverbout 0:ea44dc9ed014 37 // and on any theory of liability, whether in contract, strict liability,
joeverbout 0:ea44dc9ed014 38 // or tort (including negligence or otherwise) arising in any way out of
joeverbout 0:ea44dc9ed014 39 // the use of this software, even if advised of the possibility of such damage.
joeverbout 0:ea44dc9ed014 40 //
joeverbout 0:ea44dc9ed014 41 //M*/
joeverbout 0:ea44dc9ed014 42
joeverbout 0:ea44dc9ed014 43 #ifndef _OPENCV_FLANN_HPP_
joeverbout 0:ea44dc9ed014 44 #define _OPENCV_FLANN_HPP_
joeverbout 0:ea44dc9ed014 45
joeverbout 0:ea44dc9ed014 46 #include "opencv2/core.hpp"
joeverbout 0:ea44dc9ed014 47 #include "opencv2/flann/miniflann.hpp"
joeverbout 0:ea44dc9ed014 48 #include "opencv2/flann/flann_base.hpp"
joeverbout 0:ea44dc9ed014 49
joeverbout 0:ea44dc9ed014 50 /**
joeverbout 0:ea44dc9ed014 51 @defgroup flann Clustering and Search in Multi-Dimensional Spaces
joeverbout 0:ea44dc9ed014 52
joeverbout 0:ea44dc9ed014 53 This section documents OpenCV's interface to the FLANN library. FLANN (Fast Library for Approximate
joeverbout 0:ea44dc9ed014 54 Nearest Neighbors) is a library that contains a collection of algorithms optimized for fast nearest
joeverbout 0:ea44dc9ed014 55 neighbor search in large datasets and for high dimensional features. More information about FLANN
joeverbout 0:ea44dc9ed014 56 can be found in @cite Muja2009 .
joeverbout 0:ea44dc9ed014 57 */
joeverbout 0:ea44dc9ed014 58
joeverbout 0:ea44dc9ed014 59 namespace cvflann
joeverbout 0:ea44dc9ed014 60 {
joeverbout 0:ea44dc9ed014 61 CV_EXPORTS flann_distance_t flann_distance_type();
joeverbout 0:ea44dc9ed014 62 FLANN_DEPRECATED CV_EXPORTS void set_distance_type(flann_distance_t distance_type, int order);
joeverbout 0:ea44dc9ed014 63 }
joeverbout 0:ea44dc9ed014 64
joeverbout 0:ea44dc9ed014 65
joeverbout 0:ea44dc9ed014 66 namespace cv
joeverbout 0:ea44dc9ed014 67 {
joeverbout 0:ea44dc9ed014 68 namespace flann
joeverbout 0:ea44dc9ed014 69 {
joeverbout 0:ea44dc9ed014 70
joeverbout 0:ea44dc9ed014 71
joeverbout 0:ea44dc9ed014 72 //! @addtogroup flann
joeverbout 0:ea44dc9ed014 73 //! @{
joeverbout 0:ea44dc9ed014 74
joeverbout 0:ea44dc9ed014 75 template <typename T> struct CvType {};
joeverbout 0:ea44dc9ed014 76 template <> struct CvType<unsigned char> { static int type() { return CV_8U; } };
joeverbout 0:ea44dc9ed014 77 template <> struct CvType<char> { static int type() { return CV_8S; } };
joeverbout 0:ea44dc9ed014 78 template <> struct CvType<unsigned short> { static int type() { return CV_16U; } };
joeverbout 0:ea44dc9ed014 79 template <> struct CvType<short> { static int type() { return CV_16S; } };
joeverbout 0:ea44dc9ed014 80 template <> struct CvType<int> { static int type() { return CV_32S; } };
joeverbout 0:ea44dc9ed014 81 template <> struct CvType<float> { static int type() { return CV_32F; } };
joeverbout 0:ea44dc9ed014 82 template <> struct CvType<double> { static int type() { return CV_64F; } };
joeverbout 0:ea44dc9ed014 83
joeverbout 0:ea44dc9ed014 84
joeverbout 0:ea44dc9ed014 85 // bring the flann parameters into this namespace
joeverbout 0:ea44dc9ed014 86 using ::cvflann::get_param;
joeverbout 0:ea44dc9ed014 87 using ::cvflann::print_params;
joeverbout 0:ea44dc9ed014 88
joeverbout 0:ea44dc9ed014 89 // bring the flann distances into this namespace
joeverbout 0:ea44dc9ed014 90 using ::cvflann::L2_Simple;
joeverbout 0:ea44dc9ed014 91 using ::cvflann::L2;
joeverbout 0:ea44dc9ed014 92 using ::cvflann::L1;
joeverbout 0:ea44dc9ed014 93 using ::cvflann::MinkowskiDistance;
joeverbout 0:ea44dc9ed014 94 using ::cvflann::MaxDistance;
joeverbout 0:ea44dc9ed014 95 using ::cvflann::HammingLUT;
joeverbout 0:ea44dc9ed014 96 using ::cvflann::Hamming;
joeverbout 0:ea44dc9ed014 97 using ::cvflann::Hamming2;
joeverbout 0:ea44dc9ed014 98 using ::cvflann::HistIntersectionDistance;
joeverbout 0:ea44dc9ed014 99 using ::cvflann::HellingerDistance;
joeverbout 0:ea44dc9ed014 100 using ::cvflann::ChiSquareDistance;
joeverbout 0:ea44dc9ed014 101 using ::cvflann::KL_Divergence;
joeverbout 0:ea44dc9ed014 102
joeverbout 0:ea44dc9ed014 103
joeverbout 0:ea44dc9ed014 104 /** @brief The FLANN nearest neighbor index class. This class is templated with the type of elements for which
joeverbout 0:ea44dc9ed014 105 the index is built.
joeverbout 0:ea44dc9ed014 106 */
joeverbout 0:ea44dc9ed014 107 template <typename Distance>
joeverbout 0:ea44dc9ed014 108 class GenericIndex
joeverbout 0:ea44dc9ed014 109 {
joeverbout 0:ea44dc9ed014 110 public:
joeverbout 0:ea44dc9ed014 111 typedef typename Distance::ElementType ElementType;
joeverbout 0:ea44dc9ed014 112 typedef typename Distance::ResultType DistanceType;
joeverbout 0:ea44dc9ed014 113
joeverbout 0:ea44dc9ed014 114 /** @brief Constructs a nearest neighbor search index for a given dataset.
joeverbout 0:ea44dc9ed014 115
joeverbout 0:ea44dc9ed014 116 @param features Matrix of containing the features(points) to index. The size of the matrix is
joeverbout 0:ea44dc9ed014 117 num_features x feature_dimensionality and the data type of the elements in the matrix must
joeverbout 0:ea44dc9ed014 118 coincide with the type of the index.
joeverbout 0:ea44dc9ed014 119 @param params Structure containing the index parameters. The type of index that will be
joeverbout 0:ea44dc9ed014 120 constructed depends on the type of this parameter. See the description.
joeverbout 0:ea44dc9ed014 121 @param distance
joeverbout 0:ea44dc9ed014 122
joeverbout 0:ea44dc9ed014 123 The method constructs a fast search structure from a set of features using the specified algorithm
joeverbout 0:ea44dc9ed014 124 with specified parameters, as defined by params. params is a reference to one of the following class
joeverbout 0:ea44dc9ed014 125 IndexParams descendants:
joeverbout 0:ea44dc9ed014 126
joeverbout 0:ea44dc9ed014 127 - **LinearIndexParams** When passing an object of this type, the index will perform a linear,
joeverbout 0:ea44dc9ed014 128 brute-force search. :
joeverbout 0:ea44dc9ed014 129 @code
joeverbout 0:ea44dc9ed014 130 struct LinearIndexParams : public IndexParams
joeverbout 0:ea44dc9ed014 131 {
joeverbout 0:ea44dc9ed014 132 };
joeverbout 0:ea44dc9ed014 133 @endcode
joeverbout 0:ea44dc9ed014 134 - **KDTreeIndexParams** When passing an object of this type the index constructed will consist of
joeverbout 0:ea44dc9ed014 135 a set of randomized kd-trees which will be searched in parallel. :
joeverbout 0:ea44dc9ed014 136 @code
joeverbout 0:ea44dc9ed014 137 struct KDTreeIndexParams : public IndexParams
joeverbout 0:ea44dc9ed014 138 {
joeverbout 0:ea44dc9ed014 139 KDTreeIndexParams( int trees = 4 );
joeverbout 0:ea44dc9ed014 140 };
joeverbout 0:ea44dc9ed014 141 @endcode
joeverbout 0:ea44dc9ed014 142 - **KMeansIndexParams** When passing an object of this type the index constructed will be a
joeverbout 0:ea44dc9ed014 143 hierarchical k-means tree. :
joeverbout 0:ea44dc9ed014 144 @code
joeverbout 0:ea44dc9ed014 145 struct KMeansIndexParams : public IndexParams
joeverbout 0:ea44dc9ed014 146 {
joeverbout 0:ea44dc9ed014 147 KMeansIndexParams(
joeverbout 0:ea44dc9ed014 148 int branching = 32,
joeverbout 0:ea44dc9ed014 149 int iterations = 11,
joeverbout 0:ea44dc9ed014 150 flann_centers_init_t centers_init = CENTERS_RANDOM,
joeverbout 0:ea44dc9ed014 151 float cb_index = 0.2 );
joeverbout 0:ea44dc9ed014 152 };
joeverbout 0:ea44dc9ed014 153 @endcode
joeverbout 0:ea44dc9ed014 154 - **CompositeIndexParams** When using a parameters object of this type the index created
joeverbout 0:ea44dc9ed014 155 combines the randomized kd-trees and the hierarchical k-means tree. :
joeverbout 0:ea44dc9ed014 156 @code
joeverbout 0:ea44dc9ed014 157 struct CompositeIndexParams : public IndexParams
joeverbout 0:ea44dc9ed014 158 {
joeverbout 0:ea44dc9ed014 159 CompositeIndexParams(
joeverbout 0:ea44dc9ed014 160 int trees = 4,
joeverbout 0:ea44dc9ed014 161 int branching = 32,
joeverbout 0:ea44dc9ed014 162 int iterations = 11,
joeverbout 0:ea44dc9ed014 163 flann_centers_init_t centers_init = CENTERS_RANDOM,
joeverbout 0:ea44dc9ed014 164 float cb_index = 0.2 );
joeverbout 0:ea44dc9ed014 165 };
joeverbout 0:ea44dc9ed014 166 @endcode
joeverbout 0:ea44dc9ed014 167 - **LshIndexParams** When using a parameters object of this type the index created uses
joeverbout 0:ea44dc9ed014 168 multi-probe LSH (by Multi-Probe LSH: Efficient Indexing for High-Dimensional Similarity Search
joeverbout 0:ea44dc9ed014 169 by Qin Lv, William Josephson, Zhe Wang, Moses Charikar, Kai Li., Proceedings of the 33rd
joeverbout 0:ea44dc9ed014 170 International Conference on Very Large Data Bases (VLDB). Vienna, Austria. September 2007) :
joeverbout 0:ea44dc9ed014 171 @code
joeverbout 0:ea44dc9ed014 172 struct LshIndexParams : public IndexParams
joeverbout 0:ea44dc9ed014 173 {
joeverbout 0:ea44dc9ed014 174 LshIndexParams(
joeverbout 0:ea44dc9ed014 175 unsigned int table_number,
joeverbout 0:ea44dc9ed014 176 unsigned int key_size,
joeverbout 0:ea44dc9ed014 177 unsigned int multi_probe_level );
joeverbout 0:ea44dc9ed014 178 };
joeverbout 0:ea44dc9ed014 179 @endcode
joeverbout 0:ea44dc9ed014 180 - **AutotunedIndexParams** When passing an object of this type the index created is
joeverbout 0:ea44dc9ed014 181 automatically tuned to offer the best performance, by choosing the optimal index type
joeverbout 0:ea44dc9ed014 182 (randomized kd-trees, hierarchical kmeans, linear) and parameters for the dataset provided. :
joeverbout 0:ea44dc9ed014 183 @code
joeverbout 0:ea44dc9ed014 184 struct AutotunedIndexParams : public IndexParams
joeverbout 0:ea44dc9ed014 185 {
joeverbout 0:ea44dc9ed014 186 AutotunedIndexParams(
joeverbout 0:ea44dc9ed014 187 float target_precision = 0.9,
joeverbout 0:ea44dc9ed014 188 float build_weight = 0.01,
joeverbout 0:ea44dc9ed014 189 float memory_weight = 0,
joeverbout 0:ea44dc9ed014 190 float sample_fraction = 0.1 );
joeverbout 0:ea44dc9ed014 191 };
joeverbout 0:ea44dc9ed014 192 @endcode
joeverbout 0:ea44dc9ed014 193 - **SavedIndexParams** This object type is used for loading a previously saved index from the
joeverbout 0:ea44dc9ed014 194 disk. :
joeverbout 0:ea44dc9ed014 195 @code
joeverbout 0:ea44dc9ed014 196 struct SavedIndexParams : public IndexParams
joeverbout 0:ea44dc9ed014 197 {
joeverbout 0:ea44dc9ed014 198 SavedIndexParams( String filename );
joeverbout 0:ea44dc9ed014 199 };
joeverbout 0:ea44dc9ed014 200 @endcode
joeverbout 0:ea44dc9ed014 201 */
joeverbout 0:ea44dc9ed014 202 GenericIndex(const Mat& features, const ::cvflann::IndexParams& params, Distance distance = Distance());
joeverbout 0:ea44dc9ed014 203
joeverbout 0:ea44dc9ed014 204 ~GenericIndex();
joeverbout 0:ea44dc9ed014 205
joeverbout 0:ea44dc9ed014 206 /** @brief Performs a K-nearest neighbor search for a given query point using the index.
joeverbout 0:ea44dc9ed014 207
joeverbout 0:ea44dc9ed014 208 @param query The query point
joeverbout 0:ea44dc9ed014 209 @param indices Vector that will contain the indices of the K-nearest neighbors found. It must have
joeverbout 0:ea44dc9ed014 210 at least knn size.
joeverbout 0:ea44dc9ed014 211 @param dists Vector that will contain the distances to the K-nearest neighbors found. It must have
joeverbout 0:ea44dc9ed014 212 at least knn size.
joeverbout 0:ea44dc9ed014 213 @param knn Number of nearest neighbors to search for.
joeverbout 0:ea44dc9ed014 214 @param params SearchParams
joeverbout 0:ea44dc9ed014 215 */
joeverbout 0:ea44dc9ed014 216 void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices,
joeverbout 0:ea44dc9ed014 217 std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& params);
joeverbout 0:ea44dc9ed014 218 void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params);
joeverbout 0:ea44dc9ed014 219
joeverbout 0:ea44dc9ed014 220 int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices,
joeverbout 0:ea44dc9ed014 221 std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& params);
joeverbout 0:ea44dc9ed014 222 int radiusSearch(const Mat& query, Mat& indices, Mat& dists,
joeverbout 0:ea44dc9ed014 223 DistanceType radius, const ::cvflann::SearchParams& params);
joeverbout 0:ea44dc9ed014 224
joeverbout 0:ea44dc9ed014 225 void save(String filename) { nnIndex->save(filename); }
joeverbout 0:ea44dc9ed014 226
joeverbout 0:ea44dc9ed014 227 int veclen() const { return nnIndex->veclen(); }
joeverbout 0:ea44dc9ed014 228
joeverbout 0:ea44dc9ed014 229 int size() const { return nnIndex->size(); }
joeverbout 0:ea44dc9ed014 230
joeverbout 0:ea44dc9ed014 231 ::cvflann::IndexParams getParameters() { return nnIndex->getParameters(); }
joeverbout 0:ea44dc9ed014 232
joeverbout 0:ea44dc9ed014 233 FLANN_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() { return nnIndex->getIndexParameters(); }
joeverbout 0:ea44dc9ed014 234
joeverbout 0:ea44dc9ed014 235 private:
joeverbout 0:ea44dc9ed014 236 ::cvflann::Index<Distance>* nnIndex;
joeverbout 0:ea44dc9ed014 237 };
joeverbout 0:ea44dc9ed014 238
joeverbout 0:ea44dc9ed014 239 //! @cond IGNORED
joeverbout 0:ea44dc9ed014 240
joeverbout 0:ea44dc9ed014 241 #define FLANN_DISTANCE_CHECK \
joeverbout 0:ea44dc9ed014 242 if ( ::cvflann::flann_distance_type() != cvflann::FLANN_DIST_L2) { \
joeverbout 0:ea44dc9ed014 243 printf("[WARNING] You are using cv::flann::Index (or cv::flann::GenericIndex) and have also changed "\
joeverbout 0:ea44dc9ed014 244 "the distance using cvflann::set_distance_type. This is no longer working as expected "\
joeverbout 0:ea44dc9ed014 245 "(cv::flann::Index always uses L2). You should create the index templated on the distance, "\
joeverbout 0:ea44dc9ed014 246 "for example for L1 distance use: GenericIndex< L1<float> > \n"); \
joeverbout 0:ea44dc9ed014 247 }
joeverbout 0:ea44dc9ed014 248
joeverbout 0:ea44dc9ed014 249
joeverbout 0:ea44dc9ed014 250 template <typename Distance>
joeverbout 0:ea44dc9ed014 251 GenericIndex<Distance>::GenericIndex(const Mat& dataset, const ::cvflann::IndexParams& params, Distance distance)
joeverbout 0:ea44dc9ed014 252 {
joeverbout 0:ea44dc9ed014 253 CV_Assert(dataset.type() == CvType<ElementType>::type());
joeverbout 0:ea44dc9ed014 254 CV_Assert(dataset.isContinuous());
joeverbout 0:ea44dc9ed014 255 ::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
joeverbout 0:ea44dc9ed014 256
joeverbout 0:ea44dc9ed014 257 nnIndex = new ::cvflann::Index<Distance>(m_dataset, params, distance);
joeverbout 0:ea44dc9ed014 258
joeverbout 0:ea44dc9ed014 259 FLANN_DISTANCE_CHECK
joeverbout 0:ea44dc9ed014 260
joeverbout 0:ea44dc9ed014 261 nnIndex->buildIndex();
joeverbout 0:ea44dc9ed014 262 }
joeverbout 0:ea44dc9ed014 263
joeverbout 0:ea44dc9ed014 264 template <typename Distance>
joeverbout 0:ea44dc9ed014 265 GenericIndex<Distance>::~GenericIndex()
joeverbout 0:ea44dc9ed014 266 {
joeverbout 0:ea44dc9ed014 267 delete nnIndex;
joeverbout 0:ea44dc9ed014 268 }
joeverbout 0:ea44dc9ed014 269
joeverbout 0:ea44dc9ed014 270 template <typename Distance>
joeverbout 0:ea44dc9ed014 271 void GenericIndex<Distance>::knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
joeverbout 0:ea44dc9ed014 272 {
joeverbout 0:ea44dc9ed014 273 ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
joeverbout 0:ea44dc9ed014 274 ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
joeverbout 0:ea44dc9ed014 275 ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
joeverbout 0:ea44dc9ed014 276
joeverbout 0:ea44dc9ed014 277 FLANN_DISTANCE_CHECK
joeverbout 0:ea44dc9ed014 278
joeverbout 0:ea44dc9ed014 279 nnIndex->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
joeverbout 0:ea44dc9ed014 280 }
joeverbout 0:ea44dc9ed014 281
joeverbout 0:ea44dc9ed014 282
joeverbout 0:ea44dc9ed014 283 template <typename Distance>
joeverbout 0:ea44dc9ed014 284 void GenericIndex<Distance>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
joeverbout 0:ea44dc9ed014 285 {
joeverbout 0:ea44dc9ed014 286 CV_Assert(queries.type() == CvType<ElementType>::type());
joeverbout 0:ea44dc9ed014 287 CV_Assert(queries.isContinuous());
joeverbout 0:ea44dc9ed014 288 ::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
joeverbout 0:ea44dc9ed014 289
joeverbout 0:ea44dc9ed014 290 CV_Assert(indices.type() == CV_32S);
joeverbout 0:ea44dc9ed014 291 CV_Assert(indices.isContinuous());
joeverbout 0:ea44dc9ed014 292 ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
joeverbout 0:ea44dc9ed014 293
joeverbout 0:ea44dc9ed014 294 CV_Assert(dists.type() == CvType<DistanceType>::type());
joeverbout 0:ea44dc9ed014 295 CV_Assert(dists.isContinuous());
joeverbout 0:ea44dc9ed014 296 ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
joeverbout 0:ea44dc9ed014 297
joeverbout 0:ea44dc9ed014 298 FLANN_DISTANCE_CHECK
joeverbout 0:ea44dc9ed014 299
joeverbout 0:ea44dc9ed014 300 nnIndex->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
joeverbout 0:ea44dc9ed014 301 }
joeverbout 0:ea44dc9ed014 302
joeverbout 0:ea44dc9ed014 303 template <typename Distance>
joeverbout 0:ea44dc9ed014 304 int GenericIndex<Distance>::radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
joeverbout 0:ea44dc9ed014 305 {
joeverbout 0:ea44dc9ed014 306 ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
joeverbout 0:ea44dc9ed014 307 ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
joeverbout 0:ea44dc9ed014 308 ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
joeverbout 0:ea44dc9ed014 309
joeverbout 0:ea44dc9ed014 310 FLANN_DISTANCE_CHECK
joeverbout 0:ea44dc9ed014 311
joeverbout 0:ea44dc9ed014 312 return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
joeverbout 0:ea44dc9ed014 313 }
joeverbout 0:ea44dc9ed014 314
joeverbout 0:ea44dc9ed014 315 template <typename Distance>
joeverbout 0:ea44dc9ed014 316 int GenericIndex<Distance>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
joeverbout 0:ea44dc9ed014 317 {
joeverbout 0:ea44dc9ed014 318 CV_Assert(query.type() == CvType<ElementType>::type());
joeverbout 0:ea44dc9ed014 319 CV_Assert(query.isContinuous());
joeverbout 0:ea44dc9ed014 320 ::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
joeverbout 0:ea44dc9ed014 321
joeverbout 0:ea44dc9ed014 322 CV_Assert(indices.type() == CV_32S);
joeverbout 0:ea44dc9ed014 323 CV_Assert(indices.isContinuous());
joeverbout 0:ea44dc9ed014 324 ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
joeverbout 0:ea44dc9ed014 325
joeverbout 0:ea44dc9ed014 326 CV_Assert(dists.type() == CvType<DistanceType>::type());
joeverbout 0:ea44dc9ed014 327 CV_Assert(dists.isContinuous());
joeverbout 0:ea44dc9ed014 328 ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
joeverbout 0:ea44dc9ed014 329
joeverbout 0:ea44dc9ed014 330 FLANN_DISTANCE_CHECK
joeverbout 0:ea44dc9ed014 331
joeverbout 0:ea44dc9ed014 332 return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
joeverbout 0:ea44dc9ed014 333 }
joeverbout 0:ea44dc9ed014 334
joeverbout 0:ea44dc9ed014 335 //! @endcond
joeverbout 0:ea44dc9ed014 336
joeverbout 0:ea44dc9ed014 337 /**
joeverbout 0:ea44dc9ed014 338 * @deprecated Use GenericIndex class instead
joeverbout 0:ea44dc9ed014 339 */
joeverbout 0:ea44dc9ed014 340 template <typename T>
joeverbout 0:ea44dc9ed014 341 class
joeverbout 0:ea44dc9ed014 342 #ifndef _MSC_VER
joeverbout 0:ea44dc9ed014 343 FLANN_DEPRECATED
joeverbout 0:ea44dc9ed014 344 #endif
joeverbout 0:ea44dc9ed014 345 Index_ {
joeverbout 0:ea44dc9ed014 346 public:
joeverbout 0:ea44dc9ed014 347 typedef typename L2<T>::ElementType ElementType;
joeverbout 0:ea44dc9ed014 348 typedef typename L2<T>::ResultType DistanceType;
joeverbout 0:ea44dc9ed014 349
joeverbout 0:ea44dc9ed014 350 Index_(const Mat& features, const ::cvflann::IndexParams& params);
joeverbout 0:ea44dc9ed014 351
joeverbout 0:ea44dc9ed014 352 ~Index_();
joeverbout 0:ea44dc9ed014 353
joeverbout 0:ea44dc9ed014 354 void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& params);
joeverbout 0:ea44dc9ed014 355 void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params);
joeverbout 0:ea44dc9ed014 356
joeverbout 0:ea44dc9ed014 357 int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& params);
joeverbout 0:ea44dc9ed014 358 int radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& params);
joeverbout 0:ea44dc9ed014 359
joeverbout 0:ea44dc9ed014 360 void save(String filename)
joeverbout 0:ea44dc9ed014 361 {
joeverbout 0:ea44dc9ed014 362 if (nnIndex_L1) nnIndex_L1->save(filename);
joeverbout 0:ea44dc9ed014 363 if (nnIndex_L2) nnIndex_L2->save(filename);
joeverbout 0:ea44dc9ed014 364 }
joeverbout 0:ea44dc9ed014 365
joeverbout 0:ea44dc9ed014 366 int veclen() const
joeverbout 0:ea44dc9ed014 367 {
joeverbout 0:ea44dc9ed014 368 if (nnIndex_L1) return nnIndex_L1->veclen();
joeverbout 0:ea44dc9ed014 369 if (nnIndex_L2) return nnIndex_L2->veclen();
joeverbout 0:ea44dc9ed014 370 }
joeverbout 0:ea44dc9ed014 371
joeverbout 0:ea44dc9ed014 372 int size() const
joeverbout 0:ea44dc9ed014 373 {
joeverbout 0:ea44dc9ed014 374 if (nnIndex_L1) return nnIndex_L1->size();
joeverbout 0:ea44dc9ed014 375 if (nnIndex_L2) return nnIndex_L2->size();
joeverbout 0:ea44dc9ed014 376 }
joeverbout 0:ea44dc9ed014 377
joeverbout 0:ea44dc9ed014 378 ::cvflann::IndexParams getParameters()
joeverbout 0:ea44dc9ed014 379 {
joeverbout 0:ea44dc9ed014 380 if (nnIndex_L1) return nnIndex_L1->getParameters();
joeverbout 0:ea44dc9ed014 381 if (nnIndex_L2) return nnIndex_L2->getParameters();
joeverbout 0:ea44dc9ed014 382
joeverbout 0:ea44dc9ed014 383 }
joeverbout 0:ea44dc9ed014 384
joeverbout 0:ea44dc9ed014 385 FLANN_DEPRECATED const ::cvflann::IndexParams* getIndexParameters()
joeverbout 0:ea44dc9ed014 386 {
joeverbout 0:ea44dc9ed014 387 if (nnIndex_L1) return nnIndex_L1->getIndexParameters();
joeverbout 0:ea44dc9ed014 388 if (nnIndex_L2) return nnIndex_L2->getIndexParameters();
joeverbout 0:ea44dc9ed014 389 }
joeverbout 0:ea44dc9ed014 390
joeverbout 0:ea44dc9ed014 391 private:
joeverbout 0:ea44dc9ed014 392 // providing backwards compatibility for L2 and L1 distances (most common)
joeverbout 0:ea44dc9ed014 393 ::cvflann::Index< L2<ElementType> >* nnIndex_L2;
joeverbout 0:ea44dc9ed014 394 ::cvflann::Index< L1<ElementType> >* nnIndex_L1;
joeverbout 0:ea44dc9ed014 395 };
joeverbout 0:ea44dc9ed014 396
joeverbout 0:ea44dc9ed014 397 #ifdef _MSC_VER
joeverbout 0:ea44dc9ed014 398 template <typename T>
joeverbout 0:ea44dc9ed014 399 class FLANN_DEPRECATED Index_;
joeverbout 0:ea44dc9ed014 400 #endif
joeverbout 0:ea44dc9ed014 401
joeverbout 0:ea44dc9ed014 402 //! @cond IGNORED
joeverbout 0:ea44dc9ed014 403
joeverbout 0:ea44dc9ed014 404 template <typename T>
joeverbout 0:ea44dc9ed014 405 Index_<T>::Index_(const Mat& dataset, const ::cvflann::IndexParams& params)
joeverbout 0:ea44dc9ed014 406 {
joeverbout 0:ea44dc9ed014 407 printf("[WARNING] The cv::flann::Index_<T> class is deperecated, use cv::flann::GenericIndex<Distance> instead\n");
joeverbout 0:ea44dc9ed014 408
joeverbout 0:ea44dc9ed014 409 CV_Assert(dataset.type() == CvType<ElementType>::type());
joeverbout 0:ea44dc9ed014 410 CV_Assert(dataset.isContinuous());
joeverbout 0:ea44dc9ed014 411 ::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
joeverbout 0:ea44dc9ed014 412
joeverbout 0:ea44dc9ed014 413 if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
joeverbout 0:ea44dc9ed014 414 nnIndex_L1 = NULL;
joeverbout 0:ea44dc9ed014 415 nnIndex_L2 = new ::cvflann::Index< L2<ElementType> >(m_dataset, params);
joeverbout 0:ea44dc9ed014 416 }
joeverbout 0:ea44dc9ed014 417 else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
joeverbout 0:ea44dc9ed014 418 nnIndex_L1 = new ::cvflann::Index< L1<ElementType> >(m_dataset, params);
joeverbout 0:ea44dc9ed014 419 nnIndex_L2 = NULL;
joeverbout 0:ea44dc9ed014 420 }
joeverbout 0:ea44dc9ed014 421 else {
joeverbout 0:ea44dc9ed014 422 printf("[ERROR] cv::flann::Index_<T> only provides backwards compatibility for the L1 and L2 distances. "
joeverbout 0:ea44dc9ed014 423 "For other distance types you must use cv::flann::GenericIndex<Distance>\n");
joeverbout 0:ea44dc9ed014 424 CV_Assert(0);
joeverbout 0:ea44dc9ed014 425 }
joeverbout 0:ea44dc9ed014 426 if (nnIndex_L1) nnIndex_L1->buildIndex();
joeverbout 0:ea44dc9ed014 427 if (nnIndex_L2) nnIndex_L2->buildIndex();
joeverbout 0:ea44dc9ed014 428 }
joeverbout 0:ea44dc9ed014 429
joeverbout 0:ea44dc9ed014 430 template <typename T>
joeverbout 0:ea44dc9ed014 431 Index_<T>::~Index_()
joeverbout 0:ea44dc9ed014 432 {
joeverbout 0:ea44dc9ed014 433 if (nnIndex_L1) delete nnIndex_L1;
joeverbout 0:ea44dc9ed014 434 if (nnIndex_L2) delete nnIndex_L2;
joeverbout 0:ea44dc9ed014 435 }
joeverbout 0:ea44dc9ed014 436
joeverbout 0:ea44dc9ed014 437 template <typename T>
joeverbout 0:ea44dc9ed014 438 void Index_<T>::knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
joeverbout 0:ea44dc9ed014 439 {
joeverbout 0:ea44dc9ed014 440 ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
joeverbout 0:ea44dc9ed014 441 ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
joeverbout 0:ea44dc9ed014 442 ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
joeverbout 0:ea44dc9ed014 443
joeverbout 0:ea44dc9ed014 444 if (nnIndex_L1) nnIndex_L1->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
joeverbout 0:ea44dc9ed014 445 if (nnIndex_L2) nnIndex_L2->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
joeverbout 0:ea44dc9ed014 446 }
joeverbout 0:ea44dc9ed014 447
joeverbout 0:ea44dc9ed014 448
joeverbout 0:ea44dc9ed014 449 template <typename T>
joeverbout 0:ea44dc9ed014 450 void Index_<T>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
joeverbout 0:ea44dc9ed014 451 {
joeverbout 0:ea44dc9ed014 452 CV_Assert(queries.type() == CvType<ElementType>::type());
joeverbout 0:ea44dc9ed014 453 CV_Assert(queries.isContinuous());
joeverbout 0:ea44dc9ed014 454 ::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
joeverbout 0:ea44dc9ed014 455
joeverbout 0:ea44dc9ed014 456 CV_Assert(indices.type() == CV_32S);
joeverbout 0:ea44dc9ed014 457 CV_Assert(indices.isContinuous());
joeverbout 0:ea44dc9ed014 458 ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
joeverbout 0:ea44dc9ed014 459
joeverbout 0:ea44dc9ed014 460 CV_Assert(dists.type() == CvType<DistanceType>::type());
joeverbout 0:ea44dc9ed014 461 CV_Assert(dists.isContinuous());
joeverbout 0:ea44dc9ed014 462 ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
joeverbout 0:ea44dc9ed014 463
joeverbout 0:ea44dc9ed014 464 if (nnIndex_L1) nnIndex_L1->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
joeverbout 0:ea44dc9ed014 465 if (nnIndex_L2) nnIndex_L2->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
joeverbout 0:ea44dc9ed014 466 }
joeverbout 0:ea44dc9ed014 467
joeverbout 0:ea44dc9ed014 468 template <typename T>
joeverbout 0:ea44dc9ed014 469 int Index_<T>::radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
joeverbout 0:ea44dc9ed014 470 {
joeverbout 0:ea44dc9ed014 471 ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
joeverbout 0:ea44dc9ed014 472 ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
joeverbout 0:ea44dc9ed014 473 ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
joeverbout 0:ea44dc9ed014 474
joeverbout 0:ea44dc9ed014 475 if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
joeverbout 0:ea44dc9ed014 476 if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
joeverbout 0:ea44dc9ed014 477 }
joeverbout 0:ea44dc9ed014 478
joeverbout 0:ea44dc9ed014 479 template <typename T>
joeverbout 0:ea44dc9ed014 480 int Index_<T>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
joeverbout 0:ea44dc9ed014 481 {
joeverbout 0:ea44dc9ed014 482 CV_Assert(query.type() == CvType<ElementType>::type());
joeverbout 0:ea44dc9ed014 483 CV_Assert(query.isContinuous());
joeverbout 0:ea44dc9ed014 484 ::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
joeverbout 0:ea44dc9ed014 485
joeverbout 0:ea44dc9ed014 486 CV_Assert(indices.type() == CV_32S);
joeverbout 0:ea44dc9ed014 487 CV_Assert(indices.isContinuous());
joeverbout 0:ea44dc9ed014 488 ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
joeverbout 0:ea44dc9ed014 489
joeverbout 0:ea44dc9ed014 490 CV_Assert(dists.type() == CvType<DistanceType>::type());
joeverbout 0:ea44dc9ed014 491 CV_Assert(dists.isContinuous());
joeverbout 0:ea44dc9ed014 492 ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
joeverbout 0:ea44dc9ed014 493
joeverbout 0:ea44dc9ed014 494 if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
joeverbout 0:ea44dc9ed014 495 if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
joeverbout 0:ea44dc9ed014 496 }
joeverbout 0:ea44dc9ed014 497
joeverbout 0:ea44dc9ed014 498 //! @endcond
joeverbout 0:ea44dc9ed014 499
joeverbout 0:ea44dc9ed014 500 /** @brief Clusters features using hierarchical k-means algorithm.
joeverbout 0:ea44dc9ed014 501
joeverbout 0:ea44dc9ed014 502 @param features The points to be clustered. The matrix must have elements of type
joeverbout 0:ea44dc9ed014 503 Distance::ElementType.
joeverbout 0:ea44dc9ed014 504 @param centers The centers of the clusters obtained. The matrix must have type
joeverbout 0:ea44dc9ed014 505 Distance::ResultType. The number of rows in this matrix represents the number of clusters desired,
joeverbout 0:ea44dc9ed014 506 however, because of the way the cut in the hierarchical tree is chosen, the number of clusters
joeverbout 0:ea44dc9ed014 507 computed will be the highest number of the form (branching-1)\*k+1 that's lower than the number of
joeverbout 0:ea44dc9ed014 508 clusters desired, where branching is the tree's branching factor (see description of the
joeverbout 0:ea44dc9ed014 509 KMeansIndexParams).
joeverbout 0:ea44dc9ed014 510 @param params Parameters used in the construction of the hierarchical k-means tree.
joeverbout 0:ea44dc9ed014 511 @param d Distance to be used for clustering.
joeverbout 0:ea44dc9ed014 512
joeverbout 0:ea44dc9ed014 513 The method clusters the given feature vectors by constructing a hierarchical k-means tree and
joeverbout 0:ea44dc9ed014 514 choosing a cut in the tree that minimizes the cluster's variance. It returns the number of clusters
joeverbout 0:ea44dc9ed014 515 found.
joeverbout 0:ea44dc9ed014 516 */
joeverbout 0:ea44dc9ed014 517 template <typename Distance>
joeverbout 0:ea44dc9ed014 518 int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params,
joeverbout 0:ea44dc9ed014 519 Distance d = Distance())
joeverbout 0:ea44dc9ed014 520 {
joeverbout 0:ea44dc9ed014 521 typedef typename Distance::ElementType ElementType;
joeverbout 0:ea44dc9ed014 522 typedef typename Distance::ResultType DistanceType;
joeverbout 0:ea44dc9ed014 523
joeverbout 0:ea44dc9ed014 524 CV_Assert(features.type() == CvType<ElementType>::type());
joeverbout 0:ea44dc9ed014 525 CV_Assert(features.isContinuous());
joeverbout 0:ea44dc9ed014 526 ::cvflann::Matrix<ElementType> m_features((ElementType*)features.ptr<ElementType>(0), features.rows, features.cols);
joeverbout 0:ea44dc9ed014 527
joeverbout 0:ea44dc9ed014 528 CV_Assert(centers.type() == CvType<DistanceType>::type());
joeverbout 0:ea44dc9ed014 529 CV_Assert(centers.isContinuous());
joeverbout 0:ea44dc9ed014 530 ::cvflann::Matrix<DistanceType> m_centers((DistanceType*)centers.ptr<DistanceType>(0), centers.rows, centers.cols);
joeverbout 0:ea44dc9ed014 531
joeverbout 0:ea44dc9ed014 532 return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
joeverbout 0:ea44dc9ed014 533 }
joeverbout 0:ea44dc9ed014 534
joeverbout 0:ea44dc9ed014 535 /** @deprecated
joeverbout 0:ea44dc9ed014 536 */
joeverbout 0:ea44dc9ed014 537 template <typename ELEM_TYPE, typename DIST_TYPE>
joeverbout 0:ea44dc9ed014 538 FLANN_DEPRECATED int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params)
joeverbout 0:ea44dc9ed014 539 {
joeverbout 0:ea44dc9ed014 540 printf("[WARNING] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> is deprecated, use "
joeverbout 0:ea44dc9ed014 541 "cv::flann::hierarchicalClustering<Distance> instead\n");
joeverbout 0:ea44dc9ed014 542
joeverbout 0:ea44dc9ed014 543 if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
joeverbout 0:ea44dc9ed014 544 return hierarchicalClustering< L2<ELEM_TYPE> >(features, centers, params);
joeverbout 0:ea44dc9ed014 545 }
joeverbout 0:ea44dc9ed014 546 else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
joeverbout 0:ea44dc9ed014 547 return hierarchicalClustering< L1<ELEM_TYPE> >(features, centers, params);
joeverbout 0:ea44dc9ed014 548 }
joeverbout 0:ea44dc9ed014 549 else {
joeverbout 0:ea44dc9ed014 550 printf("[ERROR] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> only provides backwards "
joeverbout 0:ea44dc9ed014 551 "compatibility for the L1 and L2 distances. "
joeverbout 0:ea44dc9ed014 552 "For other distance types you must use cv::flann::hierarchicalClustering<Distance>\n");
joeverbout 0:ea44dc9ed014 553 CV_Assert(0);
joeverbout 0:ea44dc9ed014 554 }
joeverbout 0:ea44dc9ed014 555 }
joeverbout 0:ea44dc9ed014 556
joeverbout 0:ea44dc9ed014 557 //! @} flann
joeverbout 0:ea44dc9ed014 558
joeverbout 0:ea44dc9ed014 559 } } // namespace cv::flann
joeverbout 0:ea44dc9ed014 560
joeverbout 0:ea44dc9ed014 561 #endif
joeverbout 0:ea44dc9ed014 562