Update to 2.0.0 tree from current Fremantle build
[opencv] / src / cxcore / cxflann.cpp
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 *  Copyright (c) 2009, Willow Garage, Inc.
5 *  All rights reserved.
6 *
7 *  Redistribution and use in source and binary forms, with or without
8 *  modification, are permitted provided that the following conditions
9 *  are met:
10 *
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.
20 *
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 *********************************************************************/
34
35 #include <cxcore.h>
36 #include "flann/flann.hpp"
37
38 namespace cv
39 {
40
41 namespace flann {
42
43 ::flann::Index* LinearIndexParams::createIndex(const Mat& dataset) const
44 {
45         CV_Assert(dataset.type() == CV_32F);
46         CV_Assert(dataset.isContinuous());
47
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));
50
51         return new ::flann::Index(mat, ::flann::LinearIndexParams());
52 }
53
54 ::flann::Index* KDTreeIndexParams::createIndex(const Mat& dataset) const
55 {
56         CV_Assert(dataset.type() == CV_32F);
57         CV_Assert(dataset.isContinuous());
58
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));
61
62         return new ::flann::Index(mat, ::flann::KDTreeIndexParams(trees));
63 }
64
65 ::flann::Index* KMeansIndexParams::createIndex(const Mat& dataset) const
66 {
67         CV_Assert(dataset.type() == CV_32F);
68         CV_Assert(dataset.isContinuous());
69
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));
72
73         return new ::flann::Index(mat, ::flann::KMeansIndexParams(branching,iterations, (::flann_centers_init_t)centers_init, cb_index));
74 }
75
76 ::flann::Index* CompositeIndexParams::createIndex(const Mat& dataset) const
77 {
78         CV_Assert(dataset.type() == CV_32F);
79         CV_Assert(dataset.isContinuous());
80
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));
83
84         return new ::flann::Index(mat, ::flann::CompositeIndexParams(trees, branching, iterations, (::flann_centers_init_t)centers_init, cb_index));
85 }
86
87 ::flann::Index* AutotunedIndexParams::createIndex(const Mat& dataset) const
88 {
89         CV_Assert(dataset.type() == CV_32F);
90         CV_Assert(dataset.isContinuous());
91
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));
94
95         return new ::flann::Index(mat, ::flann::AutotunedIndexParams(target_precision, build_weight, memory_weight, sample_fraction));
96 }
97
98 ::flann::Index* SavedIndexParams::createIndex(const Mat& dataset) const
99 {
100         CV_Assert(dataset.type() == CV_32F);
101         CV_Assert(dataset.isContinuous());
102
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));
105
106         return new ::flann::Index(mat, ::flann::SavedIndexParams(filename));
107 }
108
109
110
111 Index::Index(const Mat& dataset, const IndexParams& params)
112 {
113         nnIndex = params.createIndex(dataset);
114 }
115
116 Index::~Index()
117 {
118         delete nnIndex;
119 }
120
121 void Index::knnSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, int knn, const SearchParams& searchParams)
122 {
123
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]);
127
128         nnIndex->knnSearch(m_query,m_indices,m_dists,knn,::flann::SearchParams(searchParams.checks));
129 }
130
131
132 void Index::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const SearchParams& searchParams)
133 {
134
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));
138
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));
142
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));
146
147         nnIndex->knnSearch(m_queries,m_indices,m_dists,knn,::flann::SearchParams(searchParams.checks));
148 }
149
150 int Index::radiusSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, float radius, const SearchParams& searchParams)
151 {
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]);
155
156         return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,::flann::SearchParams(searchParams.checks));
157 }
158
159
160 int Index::radiusSearch(const Mat& query, Mat& indices, Mat& dists, float radius, const SearchParams& searchParams)
161 {
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));
165
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));
169
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));
173
174         return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,::flann::SearchParams(searchParams.checks));
175 }
176
177
178 void Index::save(string filename)
179 {
180         nnIndex->save(filename);
181 }
182
183 int Index::size() const
184 {
185         return nnIndex->size();
186 }
187
188 int Index::veclen() const
189 {
190         return nnIndex->veclen();
191 }
192
193
194 int hierarchicalClustering(const Mat& features, Mat& centers, const KMeansIndexParams& params)
195 {
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));
199
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));
203
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));
206 }
207
208
209 }
210
211 }