EstervQrCode 1.1.1
Library for qr code manipulation
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 
46 namespace 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 
54 template <typename T, typename DistanceType>
55 struct 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 
70 template <typename DistanceType>
71 class ResultSet
72 {
73 public:
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 
89 template <typename DistanceType>
90 class KNNSimpleResultSet : public ResultSet<DistanceType>
91 {
92  int* indices;
93  DistanceType* dists;
94  int capacity;
95  int count;
96  DistanceType worst_distance_;
97 
98 public:
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 
156 template <typename DistanceType>
157 class KNNResultSet : public ResultSet<DistanceType>
158 {
159  int* indices;
160  DistanceType* dists;
161  int capacity;
162  int count;
163  DistanceType worst_distance_;
164 
165 public:
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 
234 template <typename DistanceType>
235 class RadiusResultSet : public ResultSet<DistanceType>
236 {
237  DistanceType radius;
238  int* indices;
239  DistanceType* dists;
240  size_t capacity;
241  size_t count;
242 
243 public:
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 
292 template<typename DistanceType>
293 class UniqueResultSet : public ResultSet<DistanceType>
294 {
295 public:
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  }
376 protected:
378  bool is_full_;
379 
381  DistanceType worst_distance_;
382 
384  std::set<DistIndex> dist_indices_;
385 };
386 
388 
392 template<typename DistanceType>
393 class KNNUniqueResultSet : public UniqueResultSet<DistanceType>
394 {
395 public:
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 
436 protected:
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 
451 template<typename DistanceType>
452 class RadiusUniqueResultSet : public UniqueResultSet<DistanceType>
453 {
454 public:
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  }
496 private:
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 
509 template<typename DistanceType>
510 class KNNRadiusUniqueResultSet : public KNNUniqueResultSet<DistanceType>
511 {
512 public:
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  }
533 private:
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
softfloat max(const softfloat &a, const softfloat &b)
Definition: softfloat.hpp:440
#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