31
#ifndef OPENCV_FLANN_RESULTSET_H
32
#define OPENCV_FLANN_RESULTSET_H
51
template
<
typename
T,
typename
DistanceType>
58
BranchStruct(
const
T& aNode, DistanceType dist) : node(aNode), mindist(dist) {}
60
bool
operator<(
const
BranchStruct<T, DistanceType>& rhs)
const
62
return
mindist<rhs.mindist;
67
template
<
typename
DistanceType>
71
virtual
~ResultSet() {}
73
virtual
bool
full()
const
= 0;
75
virtual
void
addPoint(DistanceType dist,
int
index) = 0;
77
virtual
DistanceType worstDist()
const
= 0;
86
template
<
typename
DistanceType>
87
class
KNNSimpleResultSet :
public
ResultSet<DistanceType>
93
DistanceType worst_distance_;
96
KNNSimpleResultSet(
int
capacity_) : capacity(capacity_), count(0)
100
void
init(
int* indices_, DistanceType* dists_)
106
dists[capacity-1] = worst_distance_;
114
bool
full() const CV_OVERRIDE
116
return
count == capacity;
120
void
addPoint(DistanceType dist,
int
index) CV_OVERRIDE
122
if
(dist >= worst_distance_)
return;
124
for
(i=count; i>0; --i) {
125
#ifdef FLANN_FIRST_MATCH
126
if
( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) )
132
dists[i] = dists[i-1];
133
indices[i] = indices[i-1];
138
if
(count < capacity) ++count;
141
worst_distance_ = dists[capacity-1];
144
DistanceType worstDist() const CV_OVERRIDE
146
return
worst_distance_;
153
template
<
typename
DistanceType>
154
class
KNNResultSet :
public
ResultSet<DistanceType>
160
DistanceType worst_distance_;
163
KNNResultSet(
int
capacity_)
164
: indices(NULL), dists(NULL), capacity(capacity_), count(0), worst_distance_(0)
168
void
init(
int* indices_, DistanceType* dists_)
174
dists[capacity-1] = worst_distance_;
182
bool
full() const CV_OVERRIDE
184
return
count == capacity;
188
void
addPoint(DistanceType dist,
int
index) CV_OVERRIDE
192
if
(dist >= worst_distance_)
return;
194
for
(i = count; i > 0; --i) {
195
#ifdef FLANN_FIRST_MATCH
196
if
( (dists[i-1]<=dist) && ((dist!=dists[i-1])||(indices[i-1]<=index)) )
198
if
(dists[i-1]<=dist)
202
for
(
int
j = i; dists[j] == dist && j--;) {
203
if
(indices[j] == index) {
211
if
(count < capacity) ++count;
212
for
(
int
j = count-1; j > i; --j) {
213
dists[j] = dists[j-1];
214
indices[j] = indices[j-1];
218
worst_distance_ = dists[capacity-1];
221
DistanceType worstDist() const CV_OVERRIDE
223
return
worst_distance_;
231
template
<
typename
DistanceType>
232
class
RadiusResultSet :
public
ResultSet<DistanceType>
241
RadiusResultSet(DistanceType radius_,
int* indices_, DistanceType* dists_,
int
capacity_) :
242
radius(radius_), indices(indices_), dists(dists_), capacity(capacity_)
266
void
addPoint(DistanceType dist,
int
index)
269
if
((capacity>0)&&(count < capacity)) {
271
indices[count] = index;
277
DistanceType worstDist()
const
289
template<
typename
DistanceType>
290
class
UniqueResultSet :
public
ResultSet<DistanceType>
295
DistIndex(DistanceType dist,
unsigned
int
index) :
296
dist_(dist), index_(index)
299
bool
operator<(
const
DistIndex dist_index)
const
301
return
(dist_ < dist_index.dist_) || ((dist_ == dist_index.dist_) && index_ < dist_index.index_);
309
is_full_(false), worst_distance_(std::numeric_limits<DistanceType>::
max())
316
inline
bool
full() const CV_OVERRIDE
323
virtual
void
clear() = 0;
330
virtual
void
copy(
int* indices, DistanceType* dist,
int
n_neighbors = -1)
const
332
if
(n_neighbors < 0) {
333
for
(
typename
std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
334
dist_indices_.end(); dist_index != dist_index_end; ++dist_index, ++indices, ++dist) {
335
*indices = dist_index->index_;
336
*dist = dist_index->dist_;
341
for
(
typename
std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
342
dist_indices_.end(); (dist_index != dist_index_end) && (i < n_neighbors); ++dist_index, ++indices, ++dist, ++i) {
343
*indices = dist_index->index_;
344
*dist = dist_index->dist_;
354
virtual
void
sortAndCopy(
int* indices, DistanceType* dist,
int
n_neighbors = -1)
const
356
copy(indices, dist, n_neighbors);
364
return
dist_indices_.size();
371
inline
DistanceType worstDist() const CV_OVERRIDE
373
return
worst_distance_;
380
DistanceType worst_distance_;
383
std::set<DistIndex> dist_indices_;
391
template<
typename
DistanceType>
392
class
KNNUniqueResultSet :
public
UniqueResultSet<DistanceType>
398
KNNUniqueResultSet(
unsigned
int
capacity) : capacity_(capacity)
400
this->is_full_ =
false;
408
inline
void
addPoint(DistanceType dist,
int
index) CV_OVERRIDE
411
if
(dist >= worst_distance_)
return;
412
dist_indices_.insert(DistIndex(dist, index));
415
if
(dist_indices_.size() > capacity_) {
416
dist_indices_.erase(*dist_indices_.rbegin());
417
worst_distance_ = dist_indices_.rbegin()->dist_;
420
else
if
(dist_indices_.size() == capacity_) {
422
worst_distance_ = dist_indices_.rbegin()->dist_;
428
void
clear() CV_OVERRIDE
430
dist_indices_.clear();
436
typedef
typename
UniqueResultSet<DistanceType>::DistIndex DistIndex;
437
using
UniqueResultSet<DistanceType>::is_full_;
438
using
UniqueResultSet<DistanceType>::worst_distance_;
439
using
UniqueResultSet<DistanceType>::dist_indices_;
442
unsigned
int
capacity_;
450
template<
typename
DistanceType>
451
class
RadiusUniqueResultSet :
public
UniqueResultSet<DistanceType>
457
RadiusUniqueResultSet(DistanceType radius) :
467
void
addPoint(DistanceType dist,
int
index) CV_OVERRIDE
469
if
(dist <= radius_) dist_indices_.insert(DistIndex(dist, index));
474
inline
void
clear() CV_OVERRIDE
476
dist_indices_.clear();
483
inline
bool
full() const CV_OVERRIDE
492
inline
DistanceType worstDist() const CV_OVERRIDE
497
typedef
typename
UniqueResultSet<DistanceType>::DistIndex DistIndex;
498
using
UniqueResultSet<DistanceType>::dist_indices_;
499
using
UniqueResultSet<DistanceType>::is_full_;
502
DistanceType radius_;
509
template<
typename
DistanceType>
510
class
KNNRadiusUniqueResultSet :
public
KNNUniqueResultSet<DistanceType>
517
KNNRadiusUniqueResultSet(
unsigned
int
capacity, DistanceType radius)
519
this->capacity_ = capacity;
520
this->radius_ = radius;
521
this->dist_indices_.reserve(capacity_);
529
dist_indices_.clear();
530
worst_distance_ = radius_;
534
using
KNNUniqueResultSet<DistanceType>::dist_indices_;
535
using
KNNUniqueResultSet<DistanceType>::is_full_;
536
using
KNNUniqueResultSet<DistanceType>::worst_distance_;
539
unsigned
int
capacity_;
542
DistanceType radius_;
CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst)
Calculates per-element maximum of two arrays or an array and a scalar.
#define CV_DbgAssert(expr)
Definition:
base.hpp:375