opencv on mbed

Dependencies:   mbed

Committer:
joeverbout
Date:
Thu Mar 31 21:16:38 2016 +0000
Revision:
0:ea44dc9ed014
OpenCV on mbed attempt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
joeverbout 0:ea44dc9ed014 1 /***********************************************************************
joeverbout 0:ea44dc9ed014 2 * Software License Agreement (BSD License)
joeverbout 0:ea44dc9ed014 3 *
joeverbout 0:ea44dc9ed014 4 * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
joeverbout 0:ea44dc9ed014 5 * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
joeverbout 0:ea44dc9ed014 6 *
joeverbout 0:ea44dc9ed014 7 * THE BSD LICENSE
joeverbout 0:ea44dc9ed014 8 *
joeverbout 0:ea44dc9ed014 9 * Redistribution and use in source and binary forms, with or without
joeverbout 0:ea44dc9ed014 10 * modification, are permitted provided that the following conditions
joeverbout 0:ea44dc9ed014 11 * are met:
joeverbout 0:ea44dc9ed014 12 *
joeverbout 0:ea44dc9ed014 13 * 1. Redistributions of source code must retain the above copyright
joeverbout 0:ea44dc9ed014 14 * notice, this list of conditions and the following disclaimer.
joeverbout 0:ea44dc9ed014 15 * 2. Redistributions in binary form must reproduce the above copyright
joeverbout 0:ea44dc9ed014 16 * notice, this list of conditions and the following disclaimer in the
joeverbout 0:ea44dc9ed014 17 * documentation and/or other materials provided with the distribution.
joeverbout 0:ea44dc9ed014 18 *
joeverbout 0:ea44dc9ed014 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
joeverbout 0:ea44dc9ed014 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
joeverbout 0:ea44dc9ed014 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
joeverbout 0:ea44dc9ed014 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
joeverbout 0:ea44dc9ed014 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
joeverbout 0:ea44dc9ed014 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
joeverbout 0:ea44dc9ed014 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
joeverbout 0:ea44dc9ed014 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
joeverbout 0:ea44dc9ed014 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
joeverbout 0:ea44dc9ed014 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
joeverbout 0:ea44dc9ed014 29 *************************************************************************/
joeverbout 0:ea44dc9ed014 30
joeverbout 0:ea44dc9ed014 31 #ifndef OPENCV_FLANN_RESULTSET_H
joeverbout 0:ea44dc9ed014 32 #define OPENCV_FLANN_RESULTSET_H
joeverbout 0:ea44dc9ed014 33
joeverbout 0:ea44dc9ed014 34 #include <algorithm>
joeverbout 0:ea44dc9ed014 35 #include <cstring>
joeverbout 0:ea44dc9ed014 36 #include <iostream>
joeverbout 0:ea44dc9ed014 37 #include <limits>
joeverbout 0:ea44dc9ed014 38 #include <set>
joeverbout 0:ea44dc9ed014 39 #include <vector>
joeverbout 0:ea44dc9ed014 40
joeverbout 0:ea44dc9ed014 41 namespace cvflann
joeverbout 0:ea44dc9ed014 42 {
joeverbout 0:ea44dc9ed014 43
joeverbout 0:ea44dc9ed014 44 /* This record represents a branch point when finding neighbors in
joeverbout 0:ea44dc9ed014 45 the tree. It contains a record of the minimum distance to the query
joeverbout 0:ea44dc9ed014 46 point, as well as the node at which the search resumes.
joeverbout 0:ea44dc9ed014 47 */
joeverbout 0:ea44dc9ed014 48
joeverbout 0:ea44dc9ed014 49 template <typename T, typename DistanceType>
joeverbout 0:ea44dc9ed014 50 struct BranchStruct
joeverbout 0:ea44dc9ed014 51 {
joeverbout 0:ea44dc9ed014 52 T node; /* Tree node at which search resumes */
joeverbout 0:ea44dc9ed014 53 DistanceType mindist; /* Minimum distance to query for all nodes below. */
joeverbout 0:ea44dc9ed014 54
joeverbout 0:ea44dc9ed014 55 BranchStruct() {}
joeverbout 0:ea44dc9ed014 56 BranchStruct(const T& aNode, DistanceType dist) : node(aNode), mindist(dist) {}
joeverbout 0:ea44dc9ed014 57
joeverbout 0:ea44dc9ed014 58 bool operator<(const BranchStruct<T, DistanceType>& rhs) const
joeverbout 0:ea44dc9ed014 59 {
joeverbout 0:ea44dc9ed014 60 return mindist<rhs.mindist;
joeverbout 0:ea44dc9ed014 61 }
joeverbout 0:ea44dc9ed014 62 };
joeverbout 0:ea44dc9ed014 63
joeverbout 0:ea44dc9ed014 64
joeverbout 0:ea44dc9ed014 65 template <typename DistanceType>
joeverbout 0:ea44dc9ed014 66 class ResultSet
joeverbout 0:ea44dc9ed014 67 {
joeverbout 0:ea44dc9ed014 68 public:
joeverbout 0:ea44dc9ed014 69 virtual ~ResultSet() {}
joeverbout 0:ea44dc9ed014 70
joeverbout 0:ea44dc9ed014 71 virtual bool full() const = 0;
joeverbout 0:ea44dc9ed014 72
joeverbout 0:ea44dc9ed014 73 virtual void addPoint(DistanceType dist, int index) = 0;
joeverbout 0:ea44dc9ed014 74
joeverbout 0:ea44dc9ed014 75 virtual DistanceType worstDist() const = 0;
joeverbout 0:ea44dc9ed014 76
joeverbout 0:ea44dc9ed014 77 };
joeverbout 0:ea44dc9ed014 78
joeverbout 0:ea44dc9ed014 79 /**
joeverbout 0:ea44dc9ed014 80 * KNNSimpleResultSet does not ensure that the element it holds are unique.
joeverbout 0:ea44dc9ed014 81 * Is used in those cases where the nearest neighbour algorithm used does not
joeverbout 0:ea44dc9ed014 82 * attempt to insert the same element multiple times.
joeverbout 0:ea44dc9ed014 83 */
joeverbout 0:ea44dc9ed014 84 template <typename DistanceType>
joeverbout 0:ea44dc9ed014 85 class KNNSimpleResultSet : public ResultSet<DistanceType>
joeverbout 0:ea44dc9ed014 86 {
joeverbout 0:ea44dc9ed014 87 int* indices;
joeverbout 0:ea44dc9ed014 88 DistanceType* dists;
joeverbout 0:ea44dc9ed014 89 int capacity;
joeverbout 0:ea44dc9ed014 90 int count;
joeverbout 0:ea44dc9ed014 91 DistanceType worst_distance_;
joeverbout 0:ea44dc9ed014 92
joeverbout 0:ea44dc9ed014 93 public:
joeverbout 0:ea44dc9ed014 94 KNNSimpleResultSet(int capacity_) : capacity(capacity_), count(0)
joeverbout 0:ea44dc9ed014 95 {
joeverbout 0:ea44dc9ed014 96 }
joeverbout 0:ea44dc9ed014 97
joeverbout 0:ea44dc9ed014 98 void init(int* indices_, DistanceType* dists_)
joeverbout 0:ea44dc9ed014 99 {
joeverbout 0:ea44dc9ed014 100 indices = indices_;
joeverbout 0:ea44dc9ed014 101 dists = dists_;
joeverbout 0:ea44dc9ed014 102 count = 0;
joeverbout 0:ea44dc9ed014 103 worst_distance_ = (std::numeric_limits<DistanceType>::max)();
joeverbout 0:ea44dc9ed014 104 dists[capacity-1] = worst_distance_;
joeverbout 0:ea44dc9ed014 105 }
joeverbout 0:ea44dc9ed014 106
joeverbout 0:ea44dc9ed014 107 size_t size() const
joeverbout 0:ea44dc9ed014 108 {
joeverbout 0:ea44dc9ed014 109 return count;
joeverbout 0:ea44dc9ed014 110 }
joeverbout 0:ea44dc9ed014 111
joeverbout 0:ea44dc9ed014 112 bool full() const
joeverbout 0:ea44dc9ed014 113 {
joeverbout 0:ea44dc9ed014 114 return count == capacity;
joeverbout 0:ea44dc9ed014 115 }
joeverbout 0:ea44dc9ed014 116
joeverbout 0:ea44dc9ed014 117
joeverbout 0:ea44dc9ed014 118 void addPoint(DistanceType dist, int index)
joeverbout 0:ea44dc9ed014 119 {
joeverbout 0:ea44dc9ed014 120 if (dist >= worst_distance_) return;
joeverbout 0:ea44dc9ed014 121 int i;
joeverbout 0:ea44dc9ed014 122 for (i=count; i>0; --i) {
joeverbout 0:ea44dc9ed014 123 #ifdef FLANN_FIRST_MATCH
joeverbout 0:ea44dc9ed014 124 if ( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) )
joeverbout 0:ea44dc9ed014 125 #else
joeverbout 0:ea44dc9ed014 126 if (dists[i-1]>dist)
joeverbout 0:ea44dc9ed014 127 #endif
joeverbout 0:ea44dc9ed014 128 {
joeverbout 0:ea44dc9ed014 129 if (i<capacity) {
joeverbout 0:ea44dc9ed014 130 dists[i] = dists[i-1];
joeverbout 0:ea44dc9ed014 131 indices[i] = indices[i-1];
joeverbout 0:ea44dc9ed014 132 }
joeverbout 0:ea44dc9ed014 133 }
joeverbout 0:ea44dc9ed014 134 else break;
joeverbout 0:ea44dc9ed014 135 }
joeverbout 0:ea44dc9ed014 136 if (count < capacity) ++count;
joeverbout 0:ea44dc9ed014 137 dists[i] = dist;
joeverbout 0:ea44dc9ed014 138 indices[i] = index;
joeverbout 0:ea44dc9ed014 139 worst_distance_ = dists[capacity-1];
joeverbout 0:ea44dc9ed014 140 }
joeverbout 0:ea44dc9ed014 141
joeverbout 0:ea44dc9ed014 142 DistanceType worstDist() const
joeverbout 0:ea44dc9ed014 143 {
joeverbout 0:ea44dc9ed014 144 return worst_distance_;
joeverbout 0:ea44dc9ed014 145 }
joeverbout 0:ea44dc9ed014 146 };
joeverbout 0:ea44dc9ed014 147
joeverbout 0:ea44dc9ed014 148 /**
joeverbout 0:ea44dc9ed014 149 * K-Nearest neighbour result set. Ensures that the elements inserted are unique
joeverbout 0:ea44dc9ed014 150 */
joeverbout 0:ea44dc9ed014 151 template <typename DistanceType>
joeverbout 0:ea44dc9ed014 152 class KNNResultSet : public ResultSet<DistanceType>
joeverbout 0:ea44dc9ed014 153 {
joeverbout 0:ea44dc9ed014 154 int* indices;
joeverbout 0:ea44dc9ed014 155 DistanceType* dists;
joeverbout 0:ea44dc9ed014 156 int capacity;
joeverbout 0:ea44dc9ed014 157 int count;
joeverbout 0:ea44dc9ed014 158 DistanceType worst_distance_;
joeverbout 0:ea44dc9ed014 159
joeverbout 0:ea44dc9ed014 160 public:
joeverbout 0:ea44dc9ed014 161 KNNResultSet(int capacity_) : capacity(capacity_), count(0)
joeverbout 0:ea44dc9ed014 162 {
joeverbout 0:ea44dc9ed014 163 }
joeverbout 0:ea44dc9ed014 164
joeverbout 0:ea44dc9ed014 165 void init(int* indices_, DistanceType* dists_)
joeverbout 0:ea44dc9ed014 166 {
joeverbout 0:ea44dc9ed014 167 indices = indices_;
joeverbout 0:ea44dc9ed014 168 dists = dists_;
joeverbout 0:ea44dc9ed014 169 count = 0;
joeverbout 0:ea44dc9ed014 170 worst_distance_ = (std::numeric_limits<DistanceType>::max)();
joeverbout 0:ea44dc9ed014 171 dists[capacity-1] = worst_distance_;
joeverbout 0:ea44dc9ed014 172 }
joeverbout 0:ea44dc9ed014 173
joeverbout 0:ea44dc9ed014 174 size_t size() const
joeverbout 0:ea44dc9ed014 175 {
joeverbout 0:ea44dc9ed014 176 return count;
joeverbout 0:ea44dc9ed014 177 }
joeverbout 0:ea44dc9ed014 178
joeverbout 0:ea44dc9ed014 179 bool full() const
joeverbout 0:ea44dc9ed014 180 {
joeverbout 0:ea44dc9ed014 181 return count == capacity;
joeverbout 0:ea44dc9ed014 182 }
joeverbout 0:ea44dc9ed014 183
joeverbout 0:ea44dc9ed014 184
joeverbout 0:ea44dc9ed014 185 void addPoint(DistanceType dist, int index)
joeverbout 0:ea44dc9ed014 186 {
joeverbout 0:ea44dc9ed014 187 if (dist >= worst_distance_) return;
joeverbout 0:ea44dc9ed014 188 int i;
joeverbout 0:ea44dc9ed014 189 for (i = count; i > 0; --i) {
joeverbout 0:ea44dc9ed014 190 #ifdef FLANN_FIRST_MATCH
joeverbout 0:ea44dc9ed014 191 if ( (dists[i-1]<=dist) && ((dist!=dists[i-1])||(indices[i-1]<=index)) )
joeverbout 0:ea44dc9ed014 192 #else
joeverbout 0:ea44dc9ed014 193 if (dists[i-1]<=dist)
joeverbout 0:ea44dc9ed014 194 #endif
joeverbout 0:ea44dc9ed014 195 {
joeverbout 0:ea44dc9ed014 196 // Check for duplicate indices
joeverbout 0:ea44dc9ed014 197 int j = i - 1;
joeverbout 0:ea44dc9ed014 198 while ((j >= 0) && (dists[j] == dist)) {
joeverbout 0:ea44dc9ed014 199 if (indices[j] == index) {
joeverbout 0:ea44dc9ed014 200 return;
joeverbout 0:ea44dc9ed014 201 }
joeverbout 0:ea44dc9ed014 202 --j;
joeverbout 0:ea44dc9ed014 203 }
joeverbout 0:ea44dc9ed014 204 break;
joeverbout 0:ea44dc9ed014 205 }
joeverbout 0:ea44dc9ed014 206 }
joeverbout 0:ea44dc9ed014 207
joeverbout 0:ea44dc9ed014 208 if (count < capacity) ++count;
joeverbout 0:ea44dc9ed014 209 for (int j = count-1; j > i; --j) {
joeverbout 0:ea44dc9ed014 210 dists[j] = dists[j-1];
joeverbout 0:ea44dc9ed014 211 indices[j] = indices[j-1];
joeverbout 0:ea44dc9ed014 212 }
joeverbout 0:ea44dc9ed014 213 dists[i] = dist;
joeverbout 0:ea44dc9ed014 214 indices[i] = index;
joeverbout 0:ea44dc9ed014 215 worst_distance_ = dists[capacity-1];
joeverbout 0:ea44dc9ed014 216 }
joeverbout 0:ea44dc9ed014 217
joeverbout 0:ea44dc9ed014 218 DistanceType worstDist() const
joeverbout 0:ea44dc9ed014 219 {
joeverbout 0:ea44dc9ed014 220 return worst_distance_;
joeverbout 0:ea44dc9ed014 221 }
joeverbout 0:ea44dc9ed014 222 };
joeverbout 0:ea44dc9ed014 223
joeverbout 0:ea44dc9ed014 224
joeverbout 0:ea44dc9ed014 225 /**
joeverbout 0:ea44dc9ed014 226 * A result-set class used when performing a radius based search.
joeverbout 0:ea44dc9ed014 227 */
joeverbout 0:ea44dc9ed014 228 template <typename DistanceType>
joeverbout 0:ea44dc9ed014 229 class RadiusResultSet : public ResultSet<DistanceType>
joeverbout 0:ea44dc9ed014 230 {
joeverbout 0:ea44dc9ed014 231 DistanceType radius;
joeverbout 0:ea44dc9ed014 232 int* indices;
joeverbout 0:ea44dc9ed014 233 DistanceType* dists;
joeverbout 0:ea44dc9ed014 234 size_t capacity;
joeverbout 0:ea44dc9ed014 235 size_t count;
joeverbout 0:ea44dc9ed014 236
joeverbout 0:ea44dc9ed014 237 public:
joeverbout 0:ea44dc9ed014 238 RadiusResultSet(DistanceType radius_, int* indices_, DistanceType* dists_, int capacity_) :
joeverbout 0:ea44dc9ed014 239 radius(radius_), indices(indices_), dists(dists_), capacity(capacity_)
joeverbout 0:ea44dc9ed014 240 {
joeverbout 0:ea44dc9ed014 241 init();
joeverbout 0:ea44dc9ed014 242 }
joeverbout 0:ea44dc9ed014 243
joeverbout 0:ea44dc9ed014 244 ~RadiusResultSet()
joeverbout 0:ea44dc9ed014 245 {
joeverbout 0:ea44dc9ed014 246 }
joeverbout 0:ea44dc9ed014 247
joeverbout 0:ea44dc9ed014 248 void init()
joeverbout 0:ea44dc9ed014 249 {
joeverbout 0:ea44dc9ed014 250 count = 0;
joeverbout 0:ea44dc9ed014 251 }
joeverbout 0:ea44dc9ed014 252
joeverbout 0:ea44dc9ed014 253 size_t size() const
joeverbout 0:ea44dc9ed014 254 {
joeverbout 0:ea44dc9ed014 255 return count;
joeverbout 0:ea44dc9ed014 256 }
joeverbout 0:ea44dc9ed014 257
joeverbout 0:ea44dc9ed014 258 bool full() const
joeverbout 0:ea44dc9ed014 259 {
joeverbout 0:ea44dc9ed014 260 return true;
joeverbout 0:ea44dc9ed014 261 }
joeverbout 0:ea44dc9ed014 262
joeverbout 0:ea44dc9ed014 263 void addPoint(DistanceType dist, int index)
joeverbout 0:ea44dc9ed014 264 {
joeverbout 0:ea44dc9ed014 265 if (dist<radius) {
joeverbout 0:ea44dc9ed014 266 if ((capacity>0)&&(count < capacity)) {
joeverbout 0:ea44dc9ed014 267 dists[count] = dist;
joeverbout 0:ea44dc9ed014 268 indices[count] = index;
joeverbout 0:ea44dc9ed014 269 }
joeverbout 0:ea44dc9ed014 270 count++;
joeverbout 0:ea44dc9ed014 271 }
joeverbout 0:ea44dc9ed014 272 }
joeverbout 0:ea44dc9ed014 273
joeverbout 0:ea44dc9ed014 274 DistanceType worstDist() const
joeverbout 0:ea44dc9ed014 275 {
joeverbout 0:ea44dc9ed014 276 return radius;
joeverbout 0:ea44dc9ed014 277 }
joeverbout 0:ea44dc9ed014 278
joeverbout 0:ea44dc9ed014 279 };
joeverbout 0:ea44dc9ed014 280
joeverbout 0:ea44dc9ed014 281 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
joeverbout 0:ea44dc9ed014 282
joeverbout 0:ea44dc9ed014 283 /** Class that holds the k NN neighbors
joeverbout 0:ea44dc9ed014 284 * Faster than KNNResultSet as it uses a binary heap and does not maintain two arrays
joeverbout 0:ea44dc9ed014 285 */
joeverbout 0:ea44dc9ed014 286 template<typename DistanceType>
joeverbout 0:ea44dc9ed014 287 class UniqueResultSet : public ResultSet<DistanceType>
joeverbout 0:ea44dc9ed014 288 {
joeverbout 0:ea44dc9ed014 289 public:
joeverbout 0:ea44dc9ed014 290 struct DistIndex
joeverbout 0:ea44dc9ed014 291 {
joeverbout 0:ea44dc9ed014 292 DistIndex(DistanceType dist, unsigned int index) :
joeverbout 0:ea44dc9ed014 293 dist_(dist), index_(index)
joeverbout 0:ea44dc9ed014 294 {
joeverbout 0:ea44dc9ed014 295 }
joeverbout 0:ea44dc9ed014 296 bool operator<(const DistIndex dist_index) const
joeverbout 0:ea44dc9ed014 297 {
joeverbout 0:ea44dc9ed014 298 return (dist_ < dist_index.dist_) || ((dist_ == dist_index.dist_) && index_ < dist_index.index_);
joeverbout 0:ea44dc9ed014 299 }
joeverbout 0:ea44dc9ed014 300 DistanceType dist_;
joeverbout 0:ea44dc9ed014 301 unsigned int index_;
joeverbout 0:ea44dc9ed014 302 };
joeverbout 0:ea44dc9ed014 303
joeverbout 0:ea44dc9ed014 304 /** Default cosntructor */
joeverbout 0:ea44dc9ed014 305 UniqueResultSet() :
joeverbout 0:ea44dc9ed014 306 worst_distance_(std::numeric_limits<DistanceType>::max())
joeverbout 0:ea44dc9ed014 307 {
joeverbout 0:ea44dc9ed014 308 }
joeverbout 0:ea44dc9ed014 309
joeverbout 0:ea44dc9ed014 310 /** Check the status of the set
joeverbout 0:ea44dc9ed014 311 * @return true if we have k NN
joeverbout 0:ea44dc9ed014 312 */
joeverbout 0:ea44dc9ed014 313 inline bool full() const
joeverbout 0:ea44dc9ed014 314 {
joeverbout 0:ea44dc9ed014 315 return is_full_;
joeverbout 0:ea44dc9ed014 316 }
joeverbout 0:ea44dc9ed014 317
joeverbout 0:ea44dc9ed014 318 /** Remove all elements in the set
joeverbout 0:ea44dc9ed014 319 */
joeverbout 0:ea44dc9ed014 320 virtual void clear() = 0;
joeverbout 0:ea44dc9ed014 321
joeverbout 0:ea44dc9ed014 322 /** Copy the set to two C arrays
joeverbout 0:ea44dc9ed014 323 * @param indices pointer to a C array of indices
joeverbout 0:ea44dc9ed014 324 * @param dist pointer to a C array of distances
joeverbout 0:ea44dc9ed014 325 * @param n_neighbors the number of neighbors to copy
joeverbout 0:ea44dc9ed014 326 */
joeverbout 0:ea44dc9ed014 327 virtual void copy(int* indices, DistanceType* dist, int n_neighbors = -1) const
joeverbout 0:ea44dc9ed014 328 {
joeverbout 0:ea44dc9ed014 329 if (n_neighbors < 0) {
joeverbout 0:ea44dc9ed014 330 for (typename std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
joeverbout 0:ea44dc9ed014 331 dist_indices_.end(); dist_index != dist_index_end; ++dist_index, ++indices, ++dist) {
joeverbout 0:ea44dc9ed014 332 *indices = dist_index->index_;
joeverbout 0:ea44dc9ed014 333 *dist = dist_index->dist_;
joeverbout 0:ea44dc9ed014 334 }
joeverbout 0:ea44dc9ed014 335 }
joeverbout 0:ea44dc9ed014 336 else {
joeverbout 0:ea44dc9ed014 337 int i = 0;
joeverbout 0:ea44dc9ed014 338 for (typename std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
joeverbout 0:ea44dc9ed014 339 dist_indices_.end(); (dist_index != dist_index_end) && (i < n_neighbors); ++dist_index, ++indices, ++dist, ++i) {
joeverbout 0:ea44dc9ed014 340 *indices = dist_index->index_;
joeverbout 0:ea44dc9ed014 341 *dist = dist_index->dist_;
joeverbout 0:ea44dc9ed014 342 }
joeverbout 0:ea44dc9ed014 343 }
joeverbout 0:ea44dc9ed014 344 }
joeverbout 0:ea44dc9ed014 345
joeverbout 0:ea44dc9ed014 346 /** Copy the set to two C arrays but sort it according to the distance first
joeverbout 0:ea44dc9ed014 347 * @param indices pointer to a C array of indices
joeverbout 0:ea44dc9ed014 348 * @param dist pointer to a C array of distances
joeverbout 0:ea44dc9ed014 349 * @param n_neighbors the number of neighbors to copy
joeverbout 0:ea44dc9ed014 350 */
joeverbout 0:ea44dc9ed014 351 virtual void sortAndCopy(int* indices, DistanceType* dist, int n_neighbors = -1) const
joeverbout 0:ea44dc9ed014 352 {
joeverbout 0:ea44dc9ed014 353 copy(indices, dist, n_neighbors);
joeverbout 0:ea44dc9ed014 354 }
joeverbout 0:ea44dc9ed014 355
joeverbout 0:ea44dc9ed014 356 /** The number of neighbors in the set
joeverbout 0:ea44dc9ed014 357 * @return
joeverbout 0:ea44dc9ed014 358 */
joeverbout 0:ea44dc9ed014 359 size_t size() const
joeverbout 0:ea44dc9ed014 360 {
joeverbout 0:ea44dc9ed014 361 return dist_indices_.size();
joeverbout 0:ea44dc9ed014 362 }
joeverbout 0:ea44dc9ed014 363
joeverbout 0:ea44dc9ed014 364 /** The distance of the furthest neighbor
joeverbout 0:ea44dc9ed014 365 * If we don't have enough neighbors, it returns the max possible value
joeverbout 0:ea44dc9ed014 366 * @return
joeverbout 0:ea44dc9ed014 367 */
joeverbout 0:ea44dc9ed014 368 inline DistanceType worstDist() const
joeverbout 0:ea44dc9ed014 369 {
joeverbout 0:ea44dc9ed014 370 return worst_distance_;
joeverbout 0:ea44dc9ed014 371 }
joeverbout 0:ea44dc9ed014 372 protected:
joeverbout 0:ea44dc9ed014 373 /** Flag to say if the set is full */
joeverbout 0:ea44dc9ed014 374 bool is_full_;
joeverbout 0:ea44dc9ed014 375
joeverbout 0:ea44dc9ed014 376 /** The worst distance found so far */
joeverbout 0:ea44dc9ed014 377 DistanceType worst_distance_;
joeverbout 0:ea44dc9ed014 378
joeverbout 0:ea44dc9ed014 379 /** The best candidates so far */
joeverbout 0:ea44dc9ed014 380 std::set<DistIndex> dist_indices_;
joeverbout 0:ea44dc9ed014 381 };
joeverbout 0:ea44dc9ed014 382
joeverbout 0:ea44dc9ed014 383 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
joeverbout 0:ea44dc9ed014 384
joeverbout 0:ea44dc9ed014 385 /** Class that holds the k NN neighbors
joeverbout 0:ea44dc9ed014 386 * Faster than KNNResultSet as it uses a binary heap and does not maintain two arrays
joeverbout 0:ea44dc9ed014 387 */
joeverbout 0:ea44dc9ed014 388 template<typename DistanceType>
joeverbout 0:ea44dc9ed014 389 class KNNUniqueResultSet : public UniqueResultSet<DistanceType>
joeverbout 0:ea44dc9ed014 390 {
joeverbout 0:ea44dc9ed014 391 public:
joeverbout 0:ea44dc9ed014 392 /** Constructor
joeverbout 0:ea44dc9ed014 393 * @param capacity the number of neighbors to store at max
joeverbout 0:ea44dc9ed014 394 */
joeverbout 0:ea44dc9ed014 395 KNNUniqueResultSet(unsigned int capacity) : capacity_(capacity)
joeverbout 0:ea44dc9ed014 396 {
joeverbout 0:ea44dc9ed014 397 this->is_full_ = false;
joeverbout 0:ea44dc9ed014 398 this->clear();
joeverbout 0:ea44dc9ed014 399 }
joeverbout 0:ea44dc9ed014 400
joeverbout 0:ea44dc9ed014 401 /** Add a possible candidate to the best neighbors
joeverbout 0:ea44dc9ed014 402 * @param dist distance for that neighbor
joeverbout 0:ea44dc9ed014 403 * @param index index of that neighbor
joeverbout 0:ea44dc9ed014 404 */
joeverbout 0:ea44dc9ed014 405 inline void addPoint(DistanceType dist, int index)
joeverbout 0:ea44dc9ed014 406 {
joeverbout 0:ea44dc9ed014 407 // Don't do anything if we are worse than the worst
joeverbout 0:ea44dc9ed014 408 if (dist >= worst_distance_) return;
joeverbout 0:ea44dc9ed014 409 dist_indices_.insert(DistIndex(dist, index));
joeverbout 0:ea44dc9ed014 410
joeverbout 0:ea44dc9ed014 411 if (is_full_) {
joeverbout 0:ea44dc9ed014 412 if (dist_indices_.size() > capacity_) {
joeverbout 0:ea44dc9ed014 413 dist_indices_.erase(*dist_indices_.rbegin());
joeverbout 0:ea44dc9ed014 414 worst_distance_ = dist_indices_.rbegin()->dist_;
joeverbout 0:ea44dc9ed014 415 }
joeverbout 0:ea44dc9ed014 416 }
joeverbout 0:ea44dc9ed014 417 else if (dist_indices_.size() == capacity_) {
joeverbout 0:ea44dc9ed014 418 is_full_ = true;
joeverbout 0:ea44dc9ed014 419 worst_distance_ = dist_indices_.rbegin()->dist_;
joeverbout 0:ea44dc9ed014 420 }
joeverbout 0:ea44dc9ed014 421 }
joeverbout 0:ea44dc9ed014 422
joeverbout 0:ea44dc9ed014 423 /** Remove all elements in the set
joeverbout 0:ea44dc9ed014 424 */
joeverbout 0:ea44dc9ed014 425 void clear()
joeverbout 0:ea44dc9ed014 426 {
joeverbout 0:ea44dc9ed014 427 dist_indices_.clear();
joeverbout 0:ea44dc9ed014 428 worst_distance_ = std::numeric_limits<DistanceType>::max();
joeverbout 0:ea44dc9ed014 429 is_full_ = false;
joeverbout 0:ea44dc9ed014 430 }
joeverbout 0:ea44dc9ed014 431
joeverbout 0:ea44dc9ed014 432 protected:
joeverbout 0:ea44dc9ed014 433 typedef typename UniqueResultSet<DistanceType>::DistIndex DistIndex;
joeverbout 0:ea44dc9ed014 434 using UniqueResultSet<DistanceType>::is_full_;
joeverbout 0:ea44dc9ed014 435 using UniqueResultSet<DistanceType>::worst_distance_;
joeverbout 0:ea44dc9ed014 436 using UniqueResultSet<DistanceType>::dist_indices_;
joeverbout 0:ea44dc9ed014 437
joeverbout 0:ea44dc9ed014 438 /** The number of neighbors to keep */
joeverbout 0:ea44dc9ed014 439 unsigned int capacity_;
joeverbout 0:ea44dc9ed014 440 };
joeverbout 0:ea44dc9ed014 441
joeverbout 0:ea44dc9ed014 442 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
joeverbout 0:ea44dc9ed014 443
joeverbout 0:ea44dc9ed014 444 /** Class that holds the radius nearest neighbors
joeverbout 0:ea44dc9ed014 445 * It is more accurate than RadiusResult as it is not limited in the number of neighbors
joeverbout 0:ea44dc9ed014 446 */
joeverbout 0:ea44dc9ed014 447 template<typename DistanceType>
joeverbout 0:ea44dc9ed014 448 class RadiusUniqueResultSet : public UniqueResultSet<DistanceType>
joeverbout 0:ea44dc9ed014 449 {
joeverbout 0:ea44dc9ed014 450 public:
joeverbout 0:ea44dc9ed014 451 /** Constructor
joeverbout 0:ea44dc9ed014 452 * @param radius the maximum distance of a neighbor
joeverbout 0:ea44dc9ed014 453 */
joeverbout 0:ea44dc9ed014 454 RadiusUniqueResultSet(DistanceType radius) :
joeverbout 0:ea44dc9ed014 455 radius_(radius)
joeverbout 0:ea44dc9ed014 456 {
joeverbout 0:ea44dc9ed014 457 is_full_ = true;
joeverbout 0:ea44dc9ed014 458 }
joeverbout 0:ea44dc9ed014 459
joeverbout 0:ea44dc9ed014 460 /** Add a possible candidate to the best neighbors
joeverbout 0:ea44dc9ed014 461 * @param dist distance for that neighbor
joeverbout 0:ea44dc9ed014 462 * @param index index of that neighbor
joeverbout 0:ea44dc9ed014 463 */
joeverbout 0:ea44dc9ed014 464 void addPoint(DistanceType dist, int index)
joeverbout 0:ea44dc9ed014 465 {
joeverbout 0:ea44dc9ed014 466 if (dist <= radius_) dist_indices_.insert(DistIndex(dist, index));
joeverbout 0:ea44dc9ed014 467 }
joeverbout 0:ea44dc9ed014 468
joeverbout 0:ea44dc9ed014 469 /** Remove all elements in the set
joeverbout 0:ea44dc9ed014 470 */
joeverbout 0:ea44dc9ed014 471 inline void clear()
joeverbout 0:ea44dc9ed014 472 {
joeverbout 0:ea44dc9ed014 473 dist_indices_.clear();
joeverbout 0:ea44dc9ed014 474 }
joeverbout 0:ea44dc9ed014 475
joeverbout 0:ea44dc9ed014 476
joeverbout 0:ea44dc9ed014 477 /** Check the status of the set
joeverbout 0:ea44dc9ed014 478 * @return alwys false
joeverbout 0:ea44dc9ed014 479 */
joeverbout 0:ea44dc9ed014 480 inline bool full() const
joeverbout 0:ea44dc9ed014 481 {
joeverbout 0:ea44dc9ed014 482 return true;
joeverbout 0:ea44dc9ed014 483 }
joeverbout 0:ea44dc9ed014 484
joeverbout 0:ea44dc9ed014 485 /** The distance of the furthest neighbor
joeverbout 0:ea44dc9ed014 486 * If we don't have enough neighbors, it returns the max possible value
joeverbout 0:ea44dc9ed014 487 * @return
joeverbout 0:ea44dc9ed014 488 */
joeverbout 0:ea44dc9ed014 489 inline DistanceType worstDist() const
joeverbout 0:ea44dc9ed014 490 {
joeverbout 0:ea44dc9ed014 491 return radius_;
joeverbout 0:ea44dc9ed014 492 }
joeverbout 0:ea44dc9ed014 493 private:
joeverbout 0:ea44dc9ed014 494 typedef typename UniqueResultSet<DistanceType>::DistIndex DistIndex;
joeverbout 0:ea44dc9ed014 495 using UniqueResultSet<DistanceType>::dist_indices_;
joeverbout 0:ea44dc9ed014 496 using UniqueResultSet<DistanceType>::is_full_;
joeverbout 0:ea44dc9ed014 497
joeverbout 0:ea44dc9ed014 498 /** The furthest distance a neighbor can be */
joeverbout 0:ea44dc9ed014 499 DistanceType radius_;
joeverbout 0:ea44dc9ed014 500 };
joeverbout 0:ea44dc9ed014 501
joeverbout 0:ea44dc9ed014 502 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
joeverbout 0:ea44dc9ed014 503
joeverbout 0:ea44dc9ed014 504 /** Class that holds the k NN neighbors within a radius distance
joeverbout 0:ea44dc9ed014 505 */
joeverbout 0:ea44dc9ed014 506 template<typename DistanceType>
joeverbout 0:ea44dc9ed014 507 class KNNRadiusUniqueResultSet : public KNNUniqueResultSet<DistanceType>
joeverbout 0:ea44dc9ed014 508 {
joeverbout 0:ea44dc9ed014 509 public:
joeverbout 0:ea44dc9ed014 510 /** Constructor
joeverbout 0:ea44dc9ed014 511 * @param capacity the number of neighbors to store at max
joeverbout 0:ea44dc9ed014 512 * @param radius the maximum distance of a neighbor
joeverbout 0:ea44dc9ed014 513 */
joeverbout 0:ea44dc9ed014 514 KNNRadiusUniqueResultSet(unsigned int capacity, DistanceType radius)
joeverbout 0:ea44dc9ed014 515 {
joeverbout 0:ea44dc9ed014 516 this->capacity_ = capacity;
joeverbout 0:ea44dc9ed014 517 this->radius_ = radius;
joeverbout 0:ea44dc9ed014 518 this->dist_indices_.reserve(capacity_);
joeverbout 0:ea44dc9ed014 519 this->clear();
joeverbout 0:ea44dc9ed014 520 }
joeverbout 0:ea44dc9ed014 521
joeverbout 0:ea44dc9ed014 522 /** Remove all elements in the set
joeverbout 0:ea44dc9ed014 523 */
joeverbout 0:ea44dc9ed014 524 void clear()
joeverbout 0:ea44dc9ed014 525 {
joeverbout 0:ea44dc9ed014 526 dist_indices_.clear();
joeverbout 0:ea44dc9ed014 527 worst_distance_ = radius_;
joeverbout 0:ea44dc9ed014 528 is_full_ = false;
joeverbout 0:ea44dc9ed014 529 }
joeverbout 0:ea44dc9ed014 530 private:
joeverbout 0:ea44dc9ed014 531 using KNNUniqueResultSet<DistanceType>::dist_indices_;
joeverbout 0:ea44dc9ed014 532 using KNNUniqueResultSet<DistanceType>::is_full_;
joeverbout 0:ea44dc9ed014 533 using KNNUniqueResultSet<DistanceType>::worst_distance_;
joeverbout 0:ea44dc9ed014 534
joeverbout 0:ea44dc9ed014 535 /** The maximum number of neighbors to consider */
joeverbout 0:ea44dc9ed014 536 unsigned int capacity_;
joeverbout 0:ea44dc9ed014 537
joeverbout 0:ea44dc9ed014 538 /** The maximum distance of a neighbor */
joeverbout 0:ea44dc9ed014 539 DistanceType radius_;
joeverbout 0:ea44dc9ed014 540 };
joeverbout 0:ea44dc9ed014 541 }
joeverbout 0:ea44dc9ed014 542
joeverbout 0:ea44dc9ed014 543 #endif //OPENCV_FLANN_RESULTSET_H
joeverbout 0:ea44dc9ed014 544