flann.cpp 7.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2009, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Willow Garage nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

#include "precomp.hpp"
#include "flann/flann.hpp"

namespace cv
{

V
Victor Erukhimov 已提交
41
namespace flann {
42

43
::cvflann::Index* LinearIndexParams::createIndex(const Mat& dataset) const
44 45 46 47
{
	CV_Assert(dataset.type() == CV_32F);
	CV_Assert(dataset.isContinuous());

48 49
	// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
	::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
50

51
	return new ::cvflann::Index(mat, ::cvflann::LinearIndexParams());
52 53
}

54
::cvflann::Index* KDTreeIndexParams::createIndex(const Mat& dataset) const
55 56 57 58
{
	CV_Assert(dataset.type() == CV_32F);
	CV_Assert(dataset.isContinuous());

59 60
	// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
	::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
61

62
	return new ::cvflann::Index(mat, ::cvflann::KDTreeIndexParams(trees));
63 64
}

65
::cvflann::Index* KMeansIndexParams::createIndex(const Mat& dataset) const
66 67 68 69
{
	CV_Assert(dataset.type() == CV_32F);
	CV_Assert(dataset.isContinuous());

70 71
	// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
	::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
72

73
	return new ::cvflann::Index(mat, ::cvflann::KMeansIndexParams(branching,iterations, (::flann_centers_init_t)centers_init, cb_index));
74 75
}

76
::cvflann::Index* CompositeIndexParams::createIndex(const Mat& dataset) const
77 78 79 80
{
	CV_Assert(dataset.type() == CV_32F);
	CV_Assert(dataset.isContinuous());

81 82
	// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
	::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
83

84
	return new ::cvflann::Index(mat, ::cvflann::CompositeIndexParams(trees, branching, iterations, (::flann_centers_init_t)centers_init, cb_index));
85 86
}

87
::cvflann::Index* AutotunedIndexParams::createIndex(const Mat& dataset) const
88 89 90 91
{
	CV_Assert(dataset.type() == CV_32F);
	CV_Assert(dataset.isContinuous());

92 93
	// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
	::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
94

95
	return new ::cvflann::Index(mat, ::cvflann::AutotunedIndexParams(target_precision, build_weight, memory_weight, sample_fraction));
96 97
}

98
::cvflann::Index* SavedIndexParams::createIndex(const Mat& dataset) const
99 100 101 102
{
	CV_Assert(dataset.type() == CV_32F);
	CV_Assert(dataset.isContinuous());

103 104
	// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
	::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0));
105

106
	return new ::cvflann::Index(mat, ::cvflann::SavedIndexParams(filename));
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
}



Index::Index(const Mat& dataset, const IndexParams& params)
{
	nnIndex = params.createIndex(dataset);
}

Index::~Index()
{
	delete nnIndex;
}

void Index::knnSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, int knn, const SearchParams& searchParams)
{

124 125 126
	::cvflann::Matrix<float> m_query(1, query.size(), (float*)&query[0]);
	::cvflann::Matrix<int> m_indices(1, indices.size(), &indices[0]);
	::cvflann::Matrix<float> m_dists(1, dists.size(), &dists[0]);
127

128
	nnIndex->knnSearch(m_query,m_indices,m_dists,knn,::cvflann::SearchParams(searchParams.checks));
129 130 131 132 133 134 135 136
}


void Index::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const SearchParams& searchParams)
{

	CV_Assert(queries.type() == CV_32F);
	CV_Assert(queries.isContinuous());
137
	::cvflann::Matrix<float> m_queries(queries.rows, queries.cols, (float*)queries.ptr<float>(0));
138 139 140

	CV_Assert(indices.type() == CV_32S);
	CV_Assert(indices.isContinuous());
141
	::cvflann::Matrix<int> m_indices(indices.rows, indices.cols, (int*)indices.ptr<int>(0));
142 143 144

	CV_Assert(dists.type() == CV_32F);
	CV_Assert(dists.isContinuous());
145
	::cvflann::Matrix<float> m_dists(dists.rows, dists.cols, (float*)dists.ptr<float>(0));
146

147
	nnIndex->knnSearch(m_queries,m_indices,m_dists,knn,::cvflann::SearchParams(searchParams.checks));
148 149 150 151
}

int Index::radiusSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, float radius, const SearchParams& searchParams)
{
152 153 154
	::cvflann::Matrix<float> m_query(1, query.size(), (float*)&query[0]);
	::cvflann::Matrix<int> m_indices(1, indices.size(), &indices[0]);
	::cvflann::Matrix<float> m_dists(1, dists.size(), &dists[0]);
155

156
	return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,::cvflann::SearchParams(searchParams.checks));
157 158 159 160 161 162 163
}


int Index::radiusSearch(const Mat& query, Mat& indices, Mat& dists, float radius, const SearchParams& searchParams)
{
	CV_Assert(query.type() == CV_32F);
	CV_Assert(query.isContinuous());
164
	::cvflann::Matrix<float> m_query(query.rows, query.cols, (float*)query.ptr<float>(0));
165 166 167

	CV_Assert(indices.type() == CV_32S);
	CV_Assert(indices.isContinuous());
168
	::cvflann::Matrix<int> m_indices(indices.rows, indices.cols, (int*)indices.ptr<int>(0));
169 170 171

	CV_Assert(dists.type() == CV_32F);
	CV_Assert(dists.isContinuous());
172
	::cvflann::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,::cvflann::SearchParams(searchParams.checks));
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
}


void Index::save(string filename)
{
	nnIndex->save(filename);
}

int Index::size() const
{
	return nnIndex->size();
}

int Index::veclen() const
{
	return nnIndex->veclen();
}


int hierarchicalClustering(const Mat& features, Mat& centers, const KMeansIndexParams& params)
{
	CV_Assert(features.type() == CV_32F);
	CV_Assert(features.isContinuous());
198
	::cvflann::Matrix<float> m_features(features.rows, features.cols, (float*)features.ptr<float>(0));
199 200 201

	CV_Assert(features.type() == CV_32F);
	CV_Assert(features.isContinuous());
202
	::cvflann::Matrix<float> m_centers(centers.rows, centers.cols, (float*)centers.ptr<float>(0));
203

204
	return ::cvflann::hierarchicalClustering(m_features, m_centers, ::cvflann::KMeansIndexParams(params.branching, params.iterations,
205 206 207 208 209 210 211
			(::flann_centers_init_t)params.centers_init, params.cb_index));
}


}

}