github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/flann.hpp (about)

     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::DNAmmingLUT;
    99  using ::cvflann::DNAmming2;
   100  using ::cvflann::HistIntersectionDistance;
   101  using ::cvflann::HellingerDistance;
   102  using ::cvflann::ChiSquareDistance;
   103  using ::cvflann::KL_Divergence;
   104  
   105  
   106  /** @brief The FLANN nearest neighbor index class. This class is templated with the type of elements for which
   107  the index is built.
   108  
   109  `Distance` functor specifies the metric to be used to calculate the distance between two points.
   110  There are several `Distance` functors that are readily available:
   111  
   112  cv::cvflann::L2_Simple - Squared Euclidean distance functor.
   113  This is the simpler, unrolled version. This is preferable for very low dimensionality data (eg 3D points)
   114  
   115  cv::flann::L2 - Squared Euclidean distance functor, optimized version.
   116  
   117  cv::flann::L1 - Manhattan distance functor, optimized version.
   118  
   119  cv::flann::MinkowskiDistance -  The Minkowsky distance functor.
   120  This is highly optimised with loop unrolling.
   121  The computation of squared root at the end is omitted for efficiency.
   122  
   123  cv::flann::MaxDistance - The max distance functor. It computes the
   124  maximum distance between two vectors. This distance is not a valid kdtree distance, it's not
   125  dimensionwise additive.
   126  
   127  cv::flann::HammingLUT -  %Hamming distance functor. It counts the bit
   128  differences between two strings using a lookup table implementation.
   129  
   130  cv::flann::Hamming - %Hamming distance functor. Population count is
   131  performed using library calls, if available. Lookup table implementation is used as a fallback.
   132  
   133  cv::flann::Hamming2 - %Hamming distance functor. Population count is
   134  implemented in 12 arithmetic operations (one of which is multiplication).
   135  
   136  cv::flann::DNAmmingLUT -  %Adaptation of the Hamming distance functor to DNA comparison.
   137  As the four bases A, C, G, T of the DNA (or A, G, C, U for RNA) can be coded on 2 bits,
   138  it counts the bits pairs differences between two sequences using a lookup table implementation.
   139  
   140  cv::flann::DNAmming2 - %Adaptation of the Hamming distance functor to DNA comparison.
   141  Bases differences count are vectorised thanks to arithmetic operations using standard
   142  registers (AVX2 and AVX-512 should come in a near future).
   143  
   144  cv::flann::HistIntersectionDistance - The histogram
   145  intersection distance functor.
   146  
   147  cv::flann::HellingerDistance - The Hellinger distance functor.
   148  
   149  cv::flann::ChiSquareDistance - The chi-square distance functor.
   150  
   151  cv::flann::KL_Divergence - The Kullback-Leibler divergence functor.
   152  
   153  Although the provided implementations cover a vast range of cases, it is also possible to use
   154  a custom implementation. The distance functor is a class whose `operator()` computes the distance
   155  between two features. If the distance is also a kd-tree compatible distance, it should also provide an
   156  `accum_dist()` method that computes the distance between individual feature dimensions.
   157  
   158  In addition to `operator()` and `accum_dist()`, a distance functor should also define the
   159  `ElementType` and the `ResultType` as the types of the elements it operates on and the type of the
   160  result it computes. If a distance functor can be used as a kd-tree distance (meaning that the full
   161  distance between a pair of features can be accumulated from the partial distances between the
   162  individual dimensions) a typedef `is_kdtree_distance` should be present inside the distance functor.
   163  If the distance is not a kd-tree distance, but it's a distance in a vector space (the individual
   164  dimensions of the elements it operates on can be accessed independently) a typedef
   165  `is_vector_space_distance` should be defined inside the functor. If neither typedef is defined, the
   166  distance is assumed to be a metric distance and will only be used with indexes operating on
   167  generic metric distances.
   168   */
   169  template <typename Distance>
   170  class GenericIndex
   171  {
   172  public:
   173          typedef typename Distance::ElementType ElementType;
   174          typedef typename Distance::ResultType DistanceType;
   175  
   176          /** @brief Constructs a nearest neighbor search index for a given dataset.
   177  
   178          @param features Matrix of containing the features(points) to index. The size of the matrix is
   179          num_features x feature_dimensionality and the data type of the elements in the matrix must
   180          coincide with the type of the index.
   181          @param params Structure containing the index parameters. The type of index that will be
   182          constructed depends on the type of this parameter. See the description.
   183          @param distance
   184  
   185          The method constructs a fast search structure from a set of features using the specified algorithm
   186          with specified parameters, as defined by params. params is a reference to one of the following class
   187          IndexParams descendants:
   188  
   189          - **LinearIndexParams** When passing an object of this type, the index will perform a linear,
   190          brute-force search. :
   191          @code
   192          struct LinearIndexParams : public IndexParams
   193          {
   194          };
   195          @endcode
   196          - **KDTreeIndexParams** When passing an object of this type the index constructed will consist of
   197          a set of randomized kd-trees which will be searched in parallel. :
   198          @code
   199          struct KDTreeIndexParams : public IndexParams
   200          {
   201              KDTreeIndexParams( int trees = 4 );
   202          };
   203          @endcode
   204          - **HierarchicalClusteringIndexParams** When passing an object of this type the index constructed
   205          will be a hierarchical tree of clusters, dividing each set of points into n clusters whose centers
   206          are picked among the points without further refinement of their position.
   207          This algorithm fits both floating, integer and binary vectors. :
   208          @code
   209          struct HierarchicalClusteringIndexParams : public IndexParams
   210          {
   211              HierarchicalClusteringIndexParams(
   212                  int branching = 32,
   213                  flann_centers_init_t centers_init = CENTERS_RANDOM,
   214                  int trees = 4,
   215                  int leaf_size = 100);
   216  
   217          };
   218          @endcode
   219          - **KMeansIndexParams** When passing an object of this type the index constructed will be a
   220          hierarchical k-means tree (one tree by default), dividing each set of points into n clusters
   221          whose barycenters are refined iteratively.
   222          Note that this algorithm has been extended to the support of binary vectors as an alternative
   223          to LSH when knn search speed is the criterium. It will also outperform LSH when processing
   224          directly (i.e. without the use of MCA/PCA) datasets whose points share mostly the same values
   225          for most of the dimensions. It is recommended to set more than one tree with binary data. :
   226          @code
   227          struct KMeansIndexParams : public IndexParams
   228          {
   229              KMeansIndexParams(
   230                  int branching = 32,
   231                  int iterations = 11,
   232                  flann_centers_init_t centers_init = CENTERS_RANDOM,
   233                  float cb_index = 0.2,
   234                  int trees = 1);
   235          };
   236          @endcode
   237          - **CompositeIndexParams** When using a parameters object of this type the index created
   238          combines the randomized kd-trees and the hierarchical k-means tree. :
   239          @code
   240          struct CompositeIndexParams : public IndexParams
   241          {
   242              CompositeIndexParams(
   243                  int trees = 4,
   244                  int branching = 32,
   245                  int iterations = 11,
   246                  flann_centers_init_t centers_init = CENTERS_RANDOM,
   247                  float cb_index = 0.2 );
   248          };
   249          @endcode
   250          - **LshIndexParams** When using a parameters object of this type the index created uses
   251          multi-probe LSH (by Multi-Probe LSH: Efficient Indexing for High-Dimensional Similarity Search
   252          by Qin Lv, William Josephson, Zhe Wang, Moses Charikar, Kai Li., Proceedings of the 33rd
   253          International Conference on Very Large Data Bases (VLDB). Vienna, Austria. September 2007).
   254          This algorithm is designed for binary vectors. :
   255          @code
   256          struct LshIndexParams : public IndexParams
   257          {
   258              LshIndexParams(
   259                  int table_number,
   260                  int key_size,
   261                  int multi_probe_level );
   262          };
   263          @endcode
   264          - **AutotunedIndexParams** When passing an object of this type the index created is
   265          automatically tuned to offer the best performance, by choosing the optimal index type
   266          (randomized kd-trees, hierarchical kmeans, linear) and parameters for the dataset provided. :
   267          @code
   268          struct AutotunedIndexParams : public IndexParams
   269          {
   270              AutotunedIndexParams(
   271                  float target_precision = 0.9,
   272                  float build_weight = 0.01,
   273                  float memory_weight = 0,
   274                  float sample_fraction = 0.1 );
   275          };
   276          @endcode
   277          - **SavedIndexParams** This object type is used for loading a previously saved index from the
   278          disk. :
   279          @code
   280          struct SavedIndexParams : public IndexParams
   281          {
   282              SavedIndexParams( String filename );
   283          };
   284          @endcode
   285           */
   286          GenericIndex(const Mat& features, const ::cvflann::IndexParams& params, Distance distance = Distance());
   287  
   288          ~GenericIndex();
   289  
   290          /** @brief Performs a K-nearest neighbor search for a given query point using the index.
   291  
   292          @param query The query point
   293          @param indices Vector that will contain the indices of the K-nearest neighbors found. It must have
   294          at least knn size.
   295          @param dists Vector that will contain the distances to the K-nearest neighbors found. It must have
   296          at least knn size.
   297          @param knn Number of nearest neighbors to search for.
   298          @param params SearchParams
   299           */
   300          void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices,
   301                         std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& params);
   302          void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params);
   303  
   304          /** @brief Performs a radius nearest neighbor search for a given query point using the index.
   305  
   306          @param query The query point.
   307          @param indices Vector that will contain the indices of the nearest neighbors found.
   308          @param dists Vector that will contain the distances to the nearest neighbors found. It has the same
   309          number of elements as indices.
   310          @param radius The search radius.
   311          @param params SearchParams
   312  
   313          This function returns the number of nearest neighbors found.
   314          */
   315          int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices,
   316                           std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& params);
   317          int radiusSearch(const Mat& query, Mat& indices, Mat& dists,
   318                           DistanceType radius, const ::cvflann::SearchParams& params);
   319  
   320          void save(String filename) { nnIndex->save(filename); }
   321  
   322          int veclen() const { return nnIndex->veclen(); }
   323  
   324          int size() const { return (int)nnIndex->size(); }
   325  
   326          ::cvflann::IndexParams getParameters() { return nnIndex->getParameters(); }
   327  
   328          CV_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() { return nnIndex->getIndexParameters(); }
   329  
   330  private:
   331          ::cvflann::Index<Distance>* nnIndex;
   332          Mat _dataset;
   333  };
   334  
   335  //! @cond IGNORED
   336  
   337  #define FLANN_DISTANCE_CHECK \
   338      if ( ::cvflann::flann_distance_type() != cvflann::FLANN_DIST_L2) { \
   339          printf("[WARNING] You are using cv::flann::Index (or cv::flann::GenericIndex) and have also changed "\
   340          "the distance using cvflann::set_distance_type. This is no longer working as expected "\
   341          "(cv::flann::Index always uses L2). You should create the index templated on the distance, "\
   342          "for example for L1 distance use: GenericIndex< L1<float> > \n"); \
   343      }
   344  
   345  
   346  template <typename Distance>
   347  GenericIndex<Distance>::GenericIndex(const Mat& dataset, const ::cvflann::IndexParams& params, Distance distance)
   348  : _dataset(dataset)
   349  {
   350      CV_Assert(dataset.type() == CvType<ElementType>::type());
   351      CV_Assert(dataset.isContinuous());
   352      ::cvflann::Matrix<ElementType> m_dataset((ElementType*)_dataset.ptr<ElementType>(0), _dataset.rows, _dataset.cols);
   353  
   354      nnIndex = new ::cvflann::Index<Distance>(m_dataset, params, distance);
   355  
   356      FLANN_DISTANCE_CHECK
   357  
   358      nnIndex->buildIndex();
   359  }
   360  
   361  template <typename Distance>
   362  GenericIndex<Distance>::~GenericIndex()
   363  {
   364      delete nnIndex;
   365  }
   366  
   367  template <typename Distance>
   368  void GenericIndex<Distance>::knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
   369  {
   370      ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
   371      ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
   372      ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
   373  
   374      FLANN_DISTANCE_CHECK
   375  
   376      nnIndex->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
   377  }
   378  
   379  
   380  template <typename Distance>
   381  void GenericIndex<Distance>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
   382  {
   383      CV_Assert(queries.type() == CvType<ElementType>::type());
   384      CV_Assert(queries.isContinuous());
   385      ::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.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      nnIndex->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
   398  }
   399  
   400  template <typename Distance>
   401  int GenericIndex<Distance>::radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
   402  {
   403      ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
   404      ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
   405      ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
   406  
   407      FLANN_DISTANCE_CHECK
   408  
   409      return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
   410  }
   411  
   412  template <typename Distance>
   413  int GenericIndex<Distance>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
   414  {
   415      CV_Assert(query.type() == CvType<ElementType>::type());
   416      CV_Assert(query.isContinuous());
   417      ::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
   418  
   419      CV_Assert(indices.type() == CV_32S);
   420      CV_Assert(indices.isContinuous());
   421      ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
   422  
   423      CV_Assert(dists.type() == CvType<DistanceType>::type());
   424      CV_Assert(dists.isContinuous());
   425      ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
   426  
   427      FLANN_DISTANCE_CHECK
   428  
   429      return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
   430  }
   431  
   432  /**
   433   * @deprecated Use GenericIndex class instead
   434   */
   435  template <typename T>
   436  class Index_
   437  {
   438  public:
   439      typedef typename L2<T>::ElementType ElementType;
   440      typedef typename L2<T>::ResultType DistanceType;
   441  
   442      CV_DEPRECATED Index_(const Mat& dataset, const ::cvflann::IndexParams& params)
   443      {
   444          printf("[WARNING] The cv::flann::Index_<T> class is deperecated, use cv::flann::GenericIndex<Distance> instead\n");
   445  
   446          CV_Assert(dataset.type() == CvType<ElementType>::type());
   447          CV_Assert(dataset.isContinuous());
   448          ::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
   449  
   450          if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
   451              nnIndex_L1 = NULL;
   452              nnIndex_L2 = new ::cvflann::Index< L2<ElementType> >(m_dataset, params);
   453          }
   454          else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
   455              nnIndex_L1 = new ::cvflann::Index< L1<ElementType> >(m_dataset, params);
   456              nnIndex_L2 = NULL;
   457          }
   458          else {
   459              printf("[ERROR] cv::flann::Index_<T> only provides backwards compatibility for the L1 and L2 distances. "
   460                     "For other distance types you must use cv::flann::GenericIndex<Distance>\n");
   461              CV_Assert(0);
   462          }
   463          if (nnIndex_L1) nnIndex_L1->buildIndex();
   464          if (nnIndex_L2) nnIndex_L2->buildIndex();
   465      }
   466      CV_DEPRECATED ~Index_()
   467      {
   468          if (nnIndex_L1) delete nnIndex_L1;
   469          if (nnIndex_L2) delete nnIndex_L2;
   470      }
   471  
   472      CV_DEPRECATED void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
   473      {
   474          ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
   475          ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
   476          ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
   477  
   478          if (nnIndex_L1) nnIndex_L1->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
   479          if (nnIndex_L2) nnIndex_L2->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
   480      }
   481      CV_DEPRECATED void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
   482      {
   483          CV_Assert(queries.type() == CvType<ElementType>::type());
   484          CV_Assert(queries.isContinuous());
   485          ::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
   486  
   487          CV_Assert(indices.type() == CV_32S);
   488          CV_Assert(indices.isContinuous());
   489          ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
   490  
   491          CV_Assert(dists.type() == CvType<DistanceType>::type());
   492          CV_Assert(dists.isContinuous());
   493          ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
   494  
   495          if (nnIndex_L1) nnIndex_L1->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
   496          if (nnIndex_L2) nnIndex_L2->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
   497      }
   498  
   499      CV_DEPRECATED int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
   500      {
   501          ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
   502          ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
   503          ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
   504  
   505          if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
   506          if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
   507      }
   508  
   509      CV_DEPRECATED int radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
   510      {
   511          CV_Assert(query.type() == CvType<ElementType>::type());
   512          CV_Assert(query.isContinuous());
   513          ::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
   514  
   515          CV_Assert(indices.type() == CV_32S);
   516          CV_Assert(indices.isContinuous());
   517          ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
   518  
   519          CV_Assert(dists.type() == CvType<DistanceType>::type());
   520          CV_Assert(dists.isContinuous());
   521          ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
   522  
   523          if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
   524          if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
   525      }
   526  
   527      CV_DEPRECATED void save(String filename)
   528      {
   529          if (nnIndex_L1) nnIndex_L1->save(filename);
   530          if (nnIndex_L2) nnIndex_L2->save(filename);
   531      }
   532  
   533      CV_DEPRECATED int veclen() const
   534      {
   535          if (nnIndex_L1) return nnIndex_L1->veclen();
   536          if (nnIndex_L2) return nnIndex_L2->veclen();
   537      }
   538  
   539      CV_DEPRECATED int size() const
   540      {
   541          if (nnIndex_L1) return nnIndex_L1->size();
   542          if (nnIndex_L2) return nnIndex_L2->size();
   543      }
   544  
   545      CV_DEPRECATED ::cvflann::IndexParams getParameters()
   546      {
   547          if (nnIndex_L1) return nnIndex_L1->getParameters();
   548          if (nnIndex_L2) return nnIndex_L2->getParameters();
   549  
   550      }
   551  
   552      CV_DEPRECATED const ::cvflann::IndexParams* getIndexParameters()
   553      {
   554          if (nnIndex_L1) return nnIndex_L1->getIndexParameters();
   555          if (nnIndex_L2) return nnIndex_L2->getIndexParameters();
   556      }
   557  
   558  private:
   559      // providing backwards compatibility for L2 and L1 distances (most common)
   560      ::cvflann::Index< L2<ElementType> >* nnIndex_L2;
   561      ::cvflann::Index< L1<ElementType> >* nnIndex_L1;
   562  };
   563  
   564  //! @endcond
   565  
   566  /** @brief Clusters features using hierarchical k-means algorithm.
   567  
   568  @param features The points to be clustered. The matrix must have elements of type
   569  Distance::ElementType.
   570  @param centers The centers of the clusters obtained. The matrix must have type
   571  Distance::CentersType. The number of rows in this matrix represents the number of clusters desired,
   572  however, because of the way the cut in the hierarchical tree is chosen, the number of clusters
   573  computed will be the highest number of the form (branching-1)\*k+1 that's lower than the number of
   574  clusters desired, where branching is the tree's branching factor (see description of the
   575  KMeansIndexParams).
   576  @param params Parameters used in the construction of the hierarchical k-means tree.
   577  @param d Distance to be used for clustering.
   578  
   579  The method clusters the given feature vectors by constructing a hierarchical k-means tree and
   580  choosing a cut in the tree that minimizes the cluster's variance. It returns the number of clusters
   581  found.
   582   */
   583  template <typename Distance>
   584  int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params,
   585                             Distance d = Distance())
   586  {
   587      typedef typename Distance::ElementType ElementType;
   588      typedef typename Distance::CentersType CentersType;
   589  
   590      CV_Assert(features.type() == CvType<ElementType>::type());
   591      CV_Assert(features.isContinuous());
   592      ::cvflann::Matrix<ElementType> m_features((ElementType*)features.ptr<ElementType>(0), features.rows, features.cols);
   593  
   594      CV_Assert(centers.type() == CvType<CentersType>::type());
   595      CV_Assert(centers.isContinuous());
   596      ::cvflann::Matrix<CentersType> m_centers((CentersType*)centers.ptr<CentersType>(0), centers.rows, centers.cols);
   597  
   598      return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
   599  }
   600  
   601  //! @cond IGNORED
   602  
   603  template <typename ELEM_TYPE, typename DIST_TYPE>
   604  CV_DEPRECATED int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params)
   605  {
   606      printf("[WARNING] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> is deprecated, use "
   607          "cv::flann::hierarchicalClustering<Distance> instead\n");
   608  
   609      if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
   610          return hierarchicalClustering< L2<ELEM_TYPE> >(features, centers, params);
   611      }
   612      else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
   613          return hierarchicalClustering< L1<ELEM_TYPE> >(features, centers, params);
   614      }
   615      else {
   616          printf("[ERROR] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> only provides backwards "
   617          "compatibility for the L1 and L2 distances. "
   618          "For other distance types you must use cv::flann::hierarchicalClustering<Distance>\n");
   619          CV_Assert(0);
   620      }
   621  }
   622  
   623  //! @endcond
   624  
   625  //! @} flann
   626  
   627  } } // namespace cv::flann
   628  
   629  #endif