1 /*********************************************************************
2 * Software License Agreement (BSD License)
4 * Copyright (c) 2009, Willow Garage, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
36 #include "flann/flann.hpp"
43 ::flann::Index* LinearIndexParams::createIndex(const Mat& dataset) const
45 CV_Assert(dataset.type() == CV_32F);
46 CV_Assert(dataset.isContinuous());
48 // TODO: fix ::flann::Matrix class so it can be constructed with a const float*
49 ::flann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
51 return new ::flann::Index(mat, ::flann::LinearIndexParams());
54 ::flann::Index* KDTreeIndexParams::createIndex(const Mat& dataset) const
56 CV_Assert(dataset.type() == CV_32F);
57 CV_Assert(dataset.isContinuous());
59 // TODO: fix ::flann::Matrix class so it can be constructed with a const float*
60 ::flann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
62 return new ::flann::Index(mat, ::flann::KDTreeIndexParams(trees));
65 ::flann::Index* KMeansIndexParams::createIndex(const Mat& dataset) const
67 CV_Assert(dataset.type() == CV_32F);
68 CV_Assert(dataset.isContinuous());
70 // TODO: fix ::flann::Matrix class so it can be constructed with a const float*
71 ::flann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
73 return new ::flann::Index(mat, ::flann::KMeansIndexParams(branching,iterations, (::flann_centers_init_t)centers_init, cb_index));
76 ::flann::Index* CompositeIndexParams::createIndex(const Mat& dataset) const
78 CV_Assert(dataset.type() == CV_32F);
79 CV_Assert(dataset.isContinuous());
81 // TODO: fix ::flann::Matrix class so it can be constructed with a const float*
82 ::flann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
84 return new ::flann::Index(mat, ::flann::CompositeIndexParams(trees, branching, iterations, (::flann_centers_init_t)centers_init, cb_index));
87 ::flann::Index* AutotunedIndexParams::createIndex(const Mat& dataset) const
89 CV_Assert(dataset.type() == CV_32F);
90 CV_Assert(dataset.isContinuous());
92 // TODO: fix ::flann::Matrix class so it can be constructed with a const float*
93 ::flann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
95 return new ::flann::Index(mat, ::flann::AutotunedIndexParams(target_precision, build_weight, memory_weight, sample_fraction));
98 ::flann::Index* SavedIndexParams::createIndex(const Mat& dataset) const
100 CV_Assert(dataset.type() == CV_32F);
101 CV_Assert(dataset.isContinuous());
103 // TODO: fix ::flann::Matrix class so it can be constructed with a const float*
104 ::flann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
106 return new ::flann::Index(mat, ::flann::SavedIndexParams(filename));
111 Index::Index(const Mat& dataset, const IndexParams& params)
113 nnIndex = params.createIndex(dataset);
121 void Index::knnSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, int knn, const SearchParams& searchParams)
124 ::flann::Matrix<float> m_query(1, query.size(), (float*)&query[0]);
125 ::flann::Matrix<int> m_indices(1, indices.size(), &indices[0]);
126 ::flann::Matrix<float> m_dists(1, dists.size(), &dists[0]);
128 nnIndex->knnSearch(m_query,m_indices,m_dists,knn,::flann::SearchParams(searchParams.checks));
132 void Index::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const SearchParams& searchParams)
135 CV_Assert(queries.type() == CV_32F);
136 CV_Assert(queries.isContinuous());
137 ::flann::Matrix<float> m_queries(queries.rows, queries.cols, (float*)queries.ptr<float>(0));
139 CV_Assert(indices.type() == CV_32S);
140 CV_Assert(indices.isContinuous());
141 ::flann::Matrix<int> m_indices(indices.rows, indices.cols, (int*)indices.ptr<int>(0));
143 CV_Assert(dists.type() == CV_32F);
144 CV_Assert(dists.isContinuous());
145 ::flann::Matrix<float> m_dists(dists.rows, dists.cols, (float*)dists.ptr<float>(0));
147 nnIndex->knnSearch(m_queries,m_indices,m_dists,knn,::flann::SearchParams(searchParams.checks));
150 int Index::radiusSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, float radius, const SearchParams& searchParams)
152 ::flann::Matrix<float> m_query(1, query.size(), (float*)&query[0]);
153 ::flann::Matrix<int> m_indices(1, indices.size(), &indices[0]);
154 ::flann::Matrix<float> m_dists(1, dists.size(), &dists[0]);
156 return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,::flann::SearchParams(searchParams.checks));
160 int Index::radiusSearch(const Mat& query, Mat& indices, Mat& dists, float radius, const SearchParams& searchParams)
162 CV_Assert(query.type() == CV_32F);
163 CV_Assert(query.isContinuous());
164 ::flann::Matrix<float> m_query(query.rows, query.cols, (float*)query.ptr<float>(0));
166 CV_Assert(indices.type() == CV_32S);
167 CV_Assert(indices.isContinuous());
168 ::flann::Matrix<int> m_indices(indices.rows, indices.cols, (int*)indices.ptr<int>(0));
170 CV_Assert(dists.type() == CV_32F);
171 CV_Assert(dists.isContinuous());
172 ::flann::Matrix<float> m_dists(dists.rows, dists.cols, (float*)dists.ptr<float>(0));
174 return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,::flann::SearchParams(searchParams.checks));
178 void Index::save(string filename)
180 nnIndex->save(filename);
183 int Index::size() const
185 return nnIndex->size();
188 int Index::veclen() const
190 return nnIndex->veclen();
194 int hierarchicalClustering(const Mat& features, Mat& centers, const KMeansIndexParams& params)
196 CV_Assert(features.type() == CV_32F);
197 CV_Assert(features.isContinuous());
198 ::flann::Matrix<float> m_features(features.rows, features.cols, (float*)features.ptr<float>(0));
200 CV_Assert(features.type() == CV_32F);
201 CV_Assert(features.isContinuous());
202 ::flann::Matrix<float> m_centers(centers.rows, centers.cols, (float*)centers.ptr<float>(0));
204 return ::flann::hierarchicalClustering(m_features, m_centers, ::flann::KMeansIndexParams(params.branching, params.iterations,
205 (::flann_centers_init_t)params.centers_init, params.cb_index));