EstervQrCode 2.0.0
Library for qr code manipulation
Loading...
Searching...
No Matches
result_set.h
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_RESULTSET_H
32#define OPENCV_FLANN_RESULTSET_H
33
35
36#include <algorithm>
37#include <cstring>
38#include <iostream>
39#include <limits>
40#include <set>
41#include <vector>
42
43#include "opencv2/core/base.hpp"
44#include "opencv2/core/cvdef.h"
45
46namespace cvflann
47{
48
49/* This record represents a branch point when finding neighbors in
50 the tree. It contains a record of the minimum distance to the query
51 point, as well as the node at which the search resumes.
52 */
53
54template <typename T, typename DistanceType>
55struct BranchStruct
56{
57 T node; /* Tree node at which search resumes */
58 DistanceType mindist; /* Minimum distance to query for all nodes below. */
59
60 BranchStruct() {}
61 BranchStruct(const T& aNode, DistanceType dist) : node(aNode), mindist(dist) {}
62
63 bool operator<(const BranchStruct<T, DistanceType>& rhs) const
64 {
65 return mindist<rhs.mindist;
66 }
67};
68
69
70template <typename DistanceType>
71class ResultSet
72{
73public:
74 virtual ~ResultSet() {}
75
76 virtual bool full() const = 0;
77
78 virtual void addPoint(DistanceType dist, int index) = 0;
79
80 virtual DistanceType worstDist() const = 0;
81
82};
83
89template <typename DistanceType>
90class KNNSimpleResultSet : public ResultSet<DistanceType>
91{
92 int* indices;
93 DistanceType* dists;
94 int capacity;
95 int count;
96 DistanceType worst_distance_;
97
98public:
99 KNNSimpleResultSet(int capacity_) : capacity(capacity_), count(0)
100 {
101 }
102
103 void init(int* indices_, DistanceType* dists_)
104 {
105 indices = indices_;
106 dists = dists_;
107 count = 0;
108 worst_distance_ = (std::numeric_limits<DistanceType>::max)();
109 dists[capacity-1] = worst_distance_;
110 }
111
112 size_t size() const
113 {
114 return count;
115 }
116
117 bool full() const CV_OVERRIDE
118 {
119 return count == capacity;
120 }
121
122
123 void addPoint(DistanceType dist, int index) CV_OVERRIDE
124 {
125 if (dist >= worst_distance_) return;
126 int i;
127 for (i=count; i>0; --i) {
128#ifdef FLANN_FIRST_MATCH
129 if ( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) )
130#else
131 if (dists[i-1]>dist)
132#endif
133 {
134 if (i<capacity) {
135 dists[i] = dists[i-1];
136 indices[i] = indices[i-1];
137 }
138 }
139 else break;
140 }
141 if (count < capacity) ++count;
142 dists[i] = dist;
143 indices[i] = index;
144 worst_distance_ = dists[capacity-1];
145 }
146
147 DistanceType worstDist() const CV_OVERRIDE
148 {
149 return worst_distance_;
150 }
151};
152
156template <typename DistanceType>
157class KNNResultSet : public ResultSet<DistanceType>
158{
159 int* indices;
160 DistanceType* dists;
161 int capacity;
162 int count;
163 DistanceType worst_distance_;
164
165public:
166 KNNResultSet(int capacity_)
167 : indices(NULL), dists(NULL), capacity(capacity_), count(0), worst_distance_(0)
168 {
169 }
170
171 void init(int* indices_, DistanceType* dists_)
172 {
173 indices = indices_;
174 dists = dists_;
175 count = 0;
176 worst_distance_ = (std::numeric_limits<DistanceType>::max)();
177 dists[capacity-1] = worst_distance_;
178 }
179
180 size_t size() const
181 {
182 return count;
183 }
184
185 bool full() const CV_OVERRIDE
186 {
187 return count == capacity;
188 }
189
190
191 void addPoint(DistanceType dist, int index) CV_OVERRIDE
192 {
193 CV_DbgAssert(indices);
194 CV_DbgAssert(dists);
195 if (dist >= worst_distance_) return;
196 int i;
197 for (i = count; i > 0; --i) {
198#ifdef FLANN_FIRST_MATCH
199 if ( (dists[i-1]<=dist) && ((dist!=dists[i-1])||(indices[i-1]<=index)) )
200#else
201 if (dists[i-1]<=dist)
202#endif
203 {
204 // Check for duplicate indices
205 for (int j = i; dists[j] == dist && j--;) {
206 if (indices[j] == index) {
207 return;
208 }
209 }
210 break;
211 }
212 }
213
214 if (count < capacity) ++count;
215 for (int j = count-1; j > i; --j) {
216 dists[j] = dists[j-1];
217 indices[j] = indices[j-1];
218 }
219 dists[i] = dist;
220 indices[i] = index;
221 worst_distance_ = dists[capacity-1];
222 }
223
224 DistanceType worstDist() const CV_OVERRIDE
225 {
226 return worst_distance_;
227 }
228};
229
230
234template <typename DistanceType>
235class RadiusResultSet : public ResultSet<DistanceType>
236{
237 DistanceType radius;
238 int* indices;
239 DistanceType* dists;
240 size_t capacity;
241 size_t count;
242
243public:
244 RadiusResultSet(DistanceType radius_, int* indices_, DistanceType* dists_, int capacity_) :
245 radius(radius_), indices(indices_), dists(dists_), capacity(capacity_)
246 {
247 init();
248 }
249
250 ~RadiusResultSet()
251 {
252 }
253
254 void init()
255 {
256 count = 0;
257 }
258
259 size_t size() const
260 {
261 return count;
262 }
263
264 bool full() const
265 {
266 return true;
267 }
268
269 void addPoint(DistanceType dist, int index)
270 {
271 if (dist<radius) {
272 if ((capacity>0)&&(count < capacity)) {
273 dists[count] = dist;
274 indices[count] = index;
275 }
276 count++;
277 }
278 }
279
280 DistanceType worstDist() const
281 {
282 return radius;
283 }
284
285};
286
288
292template<typename DistanceType>
293class UniqueResultSet : public ResultSet<DistanceType>
294{
295public:
296 struct DistIndex
297 {
298 DistIndex(DistanceType dist, unsigned int index) :
299 dist_(dist), index_(index)
300 {
301 }
302 bool operator<(const DistIndex dist_index) const
303 {
304 return (dist_ < dist_index.dist_) || ((dist_ == dist_index.dist_) && index_ < dist_index.index_);
305 }
306 DistanceType dist_;
307 unsigned int index_;
308 };
309
311 UniqueResultSet() :
312 is_full_(false), worst_distance_(std::numeric_limits<DistanceType>::max())
313 {
314 }
315
319 inline bool full() const CV_OVERRIDE
320 {
321 return is_full_;
322 }
323
326 virtual void clear() = 0;
327
333 virtual void copy(int* indices, DistanceType* dist, int n_neighbors = -1) const
334 {
335 if (n_neighbors < 0) {
336 for (typename std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
337 dist_indices_.end(); dist_index != dist_index_end; ++dist_index, ++indices, ++dist) {
338 *indices = dist_index->index_;
339 *dist = dist_index->dist_;
340 }
341 }
342 else {
343 int i = 0;
344 for (typename std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
345 dist_indices_.end(); (dist_index != dist_index_end) && (i < n_neighbors); ++dist_index, ++indices, ++dist, ++i) {
346 *indices = dist_index->index_;
347 *dist = dist_index->dist_;
348 }
349 }
350 }
351
357 virtual void sortAndCopy(int* indices, DistanceType* dist, int n_neighbors = -1) const
358 {
359 copy(indices, dist, n_neighbors);
360 }
361
364 size_t size() const
365 {
366 return dist_indices_.size();
367 }
368
372 inline DistanceType worstDist() const CV_OVERRIDE
373 {
374 return worst_distance_;
375 }
376protected:
378 bool is_full_;
379
381 DistanceType worst_distance_;
382
384 std::set<DistIndex> dist_indices_;
385};
386
388
392template<typename DistanceType>
393class KNNUniqueResultSet : public UniqueResultSet<DistanceType>
394{
395public:
399 KNNUniqueResultSet(unsigned int capacity) : capacity_(capacity)
400 {
401 this->is_full_ = false;
402 this->clear();
403 }
404
409 inline void addPoint(DistanceType dist, int index) CV_OVERRIDE
410 {
411 // Don't do anything if we are worse than the worst
412 if (dist >= worst_distance_) return;
413 dist_indices_.insert(DistIndex(dist, index));
414
415 if (is_full_) {
416 if (dist_indices_.size() > capacity_) {
417 dist_indices_.erase(*dist_indices_.rbegin());
418 worst_distance_ = dist_indices_.rbegin()->dist_;
419 }
420 }
421 else if (dist_indices_.size() == capacity_) {
422 is_full_ = true;
423 worst_distance_ = dist_indices_.rbegin()->dist_;
424 }
425 }
426
429 void clear() CV_OVERRIDE
430 {
431 dist_indices_.clear();
432 worst_distance_ = std::numeric_limits<DistanceType>::max();
433 is_full_ = false;
434 }
435
436protected:
437 typedef typename UniqueResultSet<DistanceType>::DistIndex DistIndex;
438 using UniqueResultSet<DistanceType>::is_full_;
439 using UniqueResultSet<DistanceType>::worst_distance_;
440 using UniqueResultSet<DistanceType>::dist_indices_;
441
443 unsigned int capacity_;
444};
445
447
451template<typename DistanceType>
452class RadiusUniqueResultSet : public UniqueResultSet<DistanceType>
453{
454public:
458 RadiusUniqueResultSet(DistanceType radius) :
459 radius_(radius)
460 {
461 is_full_ = true;
462 }
463
468 void addPoint(DistanceType dist, int index) CV_OVERRIDE
469 {
470 if (dist <= radius_) dist_indices_.insert(DistIndex(dist, index));
471 }
472
475 inline void clear() CV_OVERRIDE
476 {
477 dist_indices_.clear();
478 }
479
480
484 inline bool full() const CV_OVERRIDE
485 {
486 return true;
487 }
488
492 inline DistanceType worstDist() const CV_OVERRIDE
493 {
494 return radius_;
495 }
496private:
497 typedef typename UniqueResultSet<DistanceType>::DistIndex DistIndex;
498 using UniqueResultSet<DistanceType>::dist_indices_;
499 using UniqueResultSet<DistanceType>::is_full_;
500
502 DistanceType radius_;
503};
504
506
509template<typename DistanceType>
510class KNNRadiusUniqueResultSet : public KNNUniqueResultSet<DistanceType>
511{
512public:
517 KNNRadiusUniqueResultSet(unsigned int capacity, DistanceType radius)
518 {
519 this->capacity_ = capacity;
520 this->radius_ = radius;
521 this->dist_indices_.reserve(capacity_);
522 this->clear();
523 }
524
527 void clear()
528 {
529 dist_indices_.clear();
530 worst_distance_ = radius_;
531 is_full_ = false;
532 }
533private:
534 using KNNUniqueResultSet<DistanceType>::dist_indices_;
535 using KNNUniqueResultSet<DistanceType>::is_full_;
536 using KNNUniqueResultSet<DistanceType>::worst_distance_;
537
539 unsigned int capacity_;
540
542 DistanceType radius_;
543};
544}
545
547
548#endif //OPENCV_FLANN_RESULTSET_H
T begin(T... args)
T copy(T... args)
InputArrayOfArrays InputArrayOfArrays InputOutputArray InputOutputArray InputOutputArray InputOutputArray Size InputOutputArray InputOutputArray T
Definition calib3d.hpp:1867
int index
Definition core_c.h:634
CvSize size
Definition core_c.h:112
int count
Definition core_c.h:1413
#define CV_OVERRIDE
Definition cvdef.h:792
#define CV_DbgAssert(expr)
Definition base.hpp:375
CvPoint2D32f float * radius
Definition imgproc_c.h:534
T max(T... args)
Definition flann.hpp:60