~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/modules/flann/include/opencv2/flann/flann_base.hpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***********************************************************************
 
2
 * Software License Agreement (BSD License)
 
3
 *
 
4
 * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
 
5
 * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
 
6
 *
 
7
 * THE BSD LICENSE
 
8
 *
 
9
 * Redistribution and use in source and binary forms, with or without
 
10
 * modification, are permitted provided that the following conditions
 
11
 * are met:
 
12
 *
 
13
 * 1. Redistributions of source code must retain the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer.
 
15
 * 2. Redistributions in binary form must reproduce the above copyright
 
16
 *    notice, this list of conditions and the following disclaimer in the
 
17
 *    documentation and/or other materials provided with the distribution.
 
18
 *
 
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
20
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
21
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
22
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
23
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
24
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 *************************************************************************/
 
30
 
 
31
#ifndef OPENCV_FLANN_BASE_HPP_
 
32
#define OPENCV_FLANN_BASE_HPP_
 
33
 
 
34
#include <vector>
 
35
#include <cassert>
 
36
#include <cstdio>
 
37
 
 
38
#include "general.h"
 
39
#include "matrix.h"
 
40
#include "params.h"
 
41
#include "saving.h"
 
42
 
 
43
#include "all_indices.h"
 
44
 
 
45
namespace cvflann
 
46
{
 
47
 
 
48
/**
 
49
 * Sets the log level used for all flann functions
 
50
 * @param level Verbosity level
 
51
 */
 
52
inline void log_verbosity(int level)
 
53
{
 
54
    if (level >= 0) {
 
55
        Logger::setLevel(level);
 
56
    }
 
57
}
 
58
 
 
59
/**
 
60
 * (Deprecated) Index parameters for creating a saved index.
 
61
 */
 
62
struct SavedIndexParams : public IndexParams
 
63
{
 
64
    SavedIndexParams(cv::String filename)
 
65
    {
 
66
        (* this)["algorithm"] = FLANN_INDEX_SAVED;
 
67
        (*this)["filename"] = filename;
 
68
    }
 
69
};
 
70
 
 
71
 
 
72
template<typename Distance>
 
73
NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const cv::String& filename, Distance distance)
 
74
{
 
75
    typedef typename Distance::ElementType ElementType;
 
76
 
 
77
    FILE* fin = fopen(filename.c_str(), "rb");
 
78
    if (fin == NULL) {
 
79
        return NULL;
 
80
    }
 
81
    IndexHeader header = load_header(fin);
 
82
    if (header.data_type != Datatype<ElementType>::type()) {
 
83
        throw FLANNException("Datatype of saved index is different than of the one to be created.");
 
84
    }
 
85
    if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) {
 
86
        throw FLANNException("The index saved belongs to a different dataset");
 
87
    }
 
88
 
 
89
    IndexParams params;
 
90
    params["algorithm"] = header.index_type;
 
91
    NNIndex<Distance>* nnIndex = create_index_by_type<Distance>(dataset, params, distance);
 
92
    nnIndex->loadIndex(fin);
 
93
    fclose(fin);
 
94
 
 
95
    return nnIndex;
 
96
}
 
97
 
 
98
 
 
99
template<typename Distance>
 
100
class Index : public NNIndex<Distance>
 
101
{
 
102
public:
 
103
    typedef typename Distance::ElementType ElementType;
 
104
    typedef typename Distance::ResultType DistanceType;
 
105
 
 
106
    Index(const Matrix<ElementType>& features, const IndexParams& params, Distance distance = Distance() )
 
107
        : index_params_(params)
 
108
    {
 
109
        flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
 
110
        loaded_ = false;
 
111
 
 
112
        if (index_type == FLANN_INDEX_SAVED) {
 
113
            nnIndex_ = load_saved_index<Distance>(features, get_param<cv::String>(params,"filename"), distance);
 
114
            loaded_ = true;
 
115
        }
 
116
        else {
 
117
            nnIndex_ = create_index_by_type<Distance>(features, params, distance);
 
118
        }
 
119
    }
 
120
 
 
121
    ~Index()
 
122
    {
 
123
        delete nnIndex_;
 
124
    }
 
125
 
 
126
    /**
 
127
     * Builds the index.
 
128
     */
 
129
    void buildIndex()
 
130
    {
 
131
        if (!loaded_) {
 
132
            nnIndex_->buildIndex();
 
133
        }
 
134
    }
 
135
 
 
136
    void save(cv::String filename)
 
137
    {
 
138
        FILE* fout = fopen(filename.c_str(), "wb");
 
139
        if (fout == NULL) {
 
140
            throw FLANNException("Cannot open file");
 
141
        }
 
142
        save_header(fout, *nnIndex_);
 
143
        saveIndex(fout);
 
144
        fclose(fout);
 
145
    }
 
146
 
 
147
    /**
 
148
     * \brief Saves the index to a stream
 
149
     * \param stream The stream to save the index to
 
150
     */
 
151
    virtual void saveIndex(FILE* stream)
 
152
    {
 
153
        nnIndex_->saveIndex(stream);
 
154
    }
 
155
 
 
156
    /**
 
157
     * \brief Loads the index from a stream
 
158
     * \param stream The stream from which the index is loaded
 
159
     */
 
160
    virtual void loadIndex(FILE* stream)
 
161
    {
 
162
        nnIndex_->loadIndex(stream);
 
163
    }
 
164
 
 
165
    /**
 
166
     * \returns number of features in this index.
 
167
     */
 
168
    size_t veclen() const
 
169
    {
 
170
        return nnIndex_->veclen();
 
171
    }
 
172
 
 
173
    /**
 
174
     * \returns The dimensionality of the features in this index.
 
175
     */
 
176
    size_t size() const
 
177
    {
 
178
        return nnIndex_->size();
 
179
    }
 
180
 
 
181
    /**
 
182
     * \returns The index type (kdtree, kmeans,...)
 
183
     */
 
184
    flann_algorithm_t getType() const
 
185
    {
 
186
        return nnIndex_->getType();
 
187
    }
 
188
 
 
189
    /**
 
190
     * \returns The amount of memory (in bytes) used by the index.
 
191
     */
 
192
    virtual int usedMemory() const
 
193
    {
 
194
        return nnIndex_->usedMemory();
 
195
    }
 
196
 
 
197
 
 
198
    /**
 
199
     * \returns The index parameters
 
200
     */
 
201
    IndexParams getParameters() const
 
202
    {
 
203
        return nnIndex_->getParameters();
 
204
    }
 
205
 
 
206
    /**
 
207
     * \brief Perform k-nearest neighbor search
 
208
     * \param[in] queries The query points for which to find the nearest neighbors
 
209
     * \param[out] indices The indices of the nearest neighbors found
 
210
     * \param[out] dists Distances to the nearest neighbors found
 
211
     * \param[in] knn Number of nearest neighbors to return
 
212
     * \param[in] params Search parameters
 
213
     */
 
214
    void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params)
 
215
    {
 
216
        nnIndex_->knnSearch(queries, indices, dists, knn, params);
 
217
    }
 
218
 
 
219
    /**
 
220
     * \brief Perform radius search
 
221
     * \param[in] query The query point
 
222
     * \param[out] indices The indinces of the neighbors found within the given radius
 
223
     * \param[out] dists The distances to the nearest neighbors found
 
224
     * \param[in] radius The radius used for search
 
225
     * \param[in] params Search parameters
 
226
     * \returns Number of neighbors found
 
227
     */
 
228
    int radiusSearch(const Matrix<ElementType>& query, Matrix<int>& indices, Matrix<DistanceType>& dists, float radius, const SearchParams& params)
 
229
    {
 
230
        return nnIndex_->radiusSearch(query, indices, dists, radius, params);
 
231
    }
 
232
 
 
233
    /**
 
234
     * \brief Method that searches for nearest-neighbours
 
235
     */
 
236
    void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
 
237
    {
 
238
        nnIndex_->findNeighbors(result, vec, searchParams);
 
239
    }
 
240
 
 
241
    /**
 
242
     * \brief Returns actual index
 
243
     */
 
244
    FLANN_DEPRECATED NNIndex<Distance>* getIndex()
 
245
    {
 
246
        return nnIndex_;
 
247
    }
 
248
 
 
249
    /**
 
250
     * \brief Returns index parameters.
 
251
     * \deprecated use getParameters() instead.
 
252
     */
 
253
    FLANN_DEPRECATED  const IndexParams* getIndexParameters()
 
254
    {
 
255
        return &index_params_;
 
256
    }
 
257
 
 
258
private:
 
259
    /** Pointer to actual index class */
 
260
    NNIndex<Distance>* nnIndex_;
 
261
    /** Indices if the index was loaded from a file */
 
262
    bool loaded_;
 
263
    /** Parameters passed to the index */
 
264
    IndexParams index_params_;
 
265
};
 
266
 
 
267
/**
 
268
 * Performs a hierarchical clustering of the points passed as argument and then takes a cut in the
 
269
 * the clustering tree to return a flat clustering.
 
270
 * @param[in] points Points to be clustered
 
271
 * @param centers The computed cluster centres. Matrix should be preallocated and centers.rows is the
 
272
 *  number of clusters requested.
 
273
 * @param params Clustering parameters (The same as for cvflann::KMeansIndex)
 
274
 * @param d Distance to be used for clustering (eg: cvflann::L2)
 
275
 * @return number of clusters computed (can be different than clusters.rows and is the highest number
 
276
 * of the form (branching-1)*K+1 smaller than clusters.rows).
 
277
 */
 
278
template <typename Distance>
 
279
int hierarchicalClustering(const Matrix<typename Distance::ElementType>& points, Matrix<typename Distance::ResultType>& centers,
 
280
                           const KMeansIndexParams& params, Distance d = Distance())
 
281
{
 
282
    KMeansIndex<Distance> kmeans(points, params, d);
 
283
    kmeans.buildIndex();
 
284
 
 
285
    int clusterNum = kmeans.getClusterCenters(centers);
 
286
    return clusterNum;
 
287
}
 
288
 
 
289
}
 
290
#endif /* OPENCV_FLANN_BASE_HPP_ */