~iliaplatone/spacedrone.eu/inova-sis-pack

« back to all changes in this revision

Viewing changes to usr/include/opencv2/flann.hpp

  • Committer: Ilia Platone
  • Date: 2022-11-15 16:19:28 UTC
  • Revision ID: git-v1:b9f4c8dff67bb705341db6a18f84a3d5f61c23ce
Initial commit

Show diffs side-by-side

added added

removed removed

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