You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			549 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
		
		
			
		
	
	
			549 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
| 
								 
											3 years ago
										 
									 | 
							
								/***********************************************************************
							 | 
						||
| 
								 | 
							
								 * Software License Agreement (BSD License)
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
							 | 
						||
| 
								 | 
							
								 * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * THE BSD LICENSE
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Redistribution and use in source and binary forms, with or without
							 | 
						||
| 
								 | 
							
								 * modification, are permitted provided that the following conditions
							 | 
						||
| 
								 | 
							
								 * are met:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * 1. Redistributions of source code must retain the above copyright
							 | 
						||
| 
								 | 
							
								 *    notice, this list of conditions and the following disclaimer.
							 | 
						||
| 
								 | 
							
								 * 2. Redistributions in binary form must reproduce the above copyright
							 | 
						||
| 
								 | 
							
								 *    notice, this list of conditions and the following disclaimer in the
							 | 
						||
| 
								 | 
							
								 *    documentation and/or other materials provided with the distribution.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
							 | 
						||
| 
								 | 
							
								 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
							 | 
						||
| 
								 | 
							
								 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
							 | 
						||
| 
								 | 
							
								 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
							 | 
						||
| 
								 | 
							
								 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
							 | 
						||
| 
								 | 
							
								 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
							 | 
						||
| 
								 | 
							
								 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
							 | 
						||
| 
								 | 
							
								 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
							 | 
						||
| 
								 | 
							
								 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
							 | 
						||
| 
								 | 
							
								 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
							 | 
						||
| 
								 | 
							
								 *************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef OPENCV_FLANN_RESULTSET_H
							 | 
						||
| 
								 | 
							
								#define OPENCV_FLANN_RESULTSET_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//! @cond IGNORED
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <algorithm>
							 | 
						||
| 
								 | 
							
								#include <cstring>
							 | 
						||
| 
								 | 
							
								#include <iostream>
							 | 
						||
| 
								 | 
							
								#include <limits>
							 | 
						||
| 
								 | 
							
								#include <set>
							 | 
						||
| 
								 | 
							
								#include <vector>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace cvflann
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* This record represents a branch point when finding neighbors in
							 | 
						||
| 
								 | 
							
								    the tree.  It contains a record of the minimum distance to the query
							 | 
						||
| 
								 | 
							
								    point, as well as the node at which the search resumes.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename T, typename DistanceType>
							 | 
						||
| 
								 | 
							
								struct BranchStruct
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    T node;           /* Tree node at which search resumes */
							 | 
						||
| 
								 | 
							
								    DistanceType mindist;     /* Minimum distance to query for all nodes below. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BranchStruct() {}
							 | 
						||
| 
								 | 
							
								    BranchStruct(const T& aNode, DistanceType dist) : node(aNode), mindist(dist) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bool operator<(const BranchStruct<T, DistanceType>& rhs) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return mindist<rhs.mindist;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <typename DistanceType>
							 | 
						||
| 
								 | 
							
								class ResultSet
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    virtual ~ResultSet() {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual bool full() const = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void addPoint(DistanceType dist, int index) = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual DistanceType worstDist() const = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * KNNSimpleResultSet does not ensure that the element it holds are unique.
							 | 
						||
| 
								 | 
							
								 * Is used in those cases where the nearest neighbour algorithm used does not
							 | 
						||
| 
								 | 
							
								 * attempt to insert the same element multiple times.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template <typename DistanceType>
							 | 
						||
| 
								 | 
							
								class KNNSimpleResultSet : public ResultSet<DistanceType>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int* indices;
							 | 
						||
| 
								 | 
							
								    DistanceType* dists;
							 | 
						||
| 
								 | 
							
								    int capacity;
							 | 
						||
| 
								 | 
							
								    int count;
							 | 
						||
| 
								 | 
							
								    DistanceType worst_distance_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    KNNSimpleResultSet(int capacity_) : capacity(capacity_), count(0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void init(int* indices_, DistanceType* dists_)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        indices = indices_;
							 | 
						||
| 
								 | 
							
								        dists = dists_;
							 | 
						||
| 
								 | 
							
								        count = 0;
							 | 
						||
| 
								 | 
							
								        worst_distance_ = (std::numeric_limits<DistanceType>::max)();
							 | 
						||
| 
								 | 
							
								        dists[capacity-1] = worst_distance_;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    size_t size() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return count;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bool full() const CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return count == capacity;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void addPoint(DistanceType dist, int index) CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (dist >= worst_distance_) return;
							 | 
						||
| 
								 | 
							
								        int i;
							 | 
						||
| 
								 | 
							
								        for (i=count; i>0; --i) {
							 | 
						||
| 
								 | 
							
								#ifdef FLANN_FIRST_MATCH
							 | 
						||
| 
								 | 
							
								            if ( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) )
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								            if (dists[i-1]>dist)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (i<capacity) {
							 | 
						||
| 
								 | 
							
								                    dists[i] = dists[i-1];
							 | 
						||
| 
								 | 
							
								                    indices[i] = indices[i-1];
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (count < capacity) ++count;
							 | 
						||
| 
								 | 
							
								        dists[i] = dist;
							 | 
						||
| 
								 | 
							
								        indices[i] = index;
							 | 
						||
| 
								 | 
							
								        worst_distance_ = dists[capacity-1];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DistanceType worstDist() const CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return worst_distance_;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * K-Nearest neighbour result set. Ensures that the elements inserted are unique
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template <typename DistanceType>
							 | 
						||
| 
								 | 
							
								class KNNResultSet : public ResultSet<DistanceType>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int* indices;
							 | 
						||
| 
								 | 
							
								    DistanceType* dists;
							 | 
						||
| 
								 | 
							
								    int capacity;
							 | 
						||
| 
								 | 
							
								    int count;
							 | 
						||
| 
								 | 
							
								    DistanceType worst_distance_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    KNNResultSet(int capacity_)
							 | 
						||
| 
								 | 
							
								        : indices(NULL), dists(NULL), capacity(capacity_), count(0), worst_distance_(0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void init(int* indices_, DistanceType* dists_)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        indices = indices_;
							 | 
						||
| 
								 | 
							
								        dists = dists_;
							 | 
						||
| 
								 | 
							
								        count = 0;
							 | 
						||
| 
								 | 
							
								        worst_distance_ = (std::numeric_limits<DistanceType>::max)();
							 | 
						||
| 
								 | 
							
								        dists[capacity-1] = worst_distance_;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    size_t size() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return count;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bool full() const CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return count == capacity;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void addPoint(DistanceType dist, int index) CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        CV_DbgAssert(indices);
							 | 
						||
| 
								 | 
							
								        CV_DbgAssert(dists);
							 | 
						||
| 
								 | 
							
								        if (dist >= worst_distance_) return;
							 | 
						||
| 
								 | 
							
								        int i;
							 | 
						||
| 
								 | 
							
								        for (i = count; i > 0; --i) {
							 | 
						||
| 
								 | 
							
								#ifdef FLANN_FIRST_MATCH
							 | 
						||
| 
								 | 
							
								            if ( (dists[i-1]<=dist) && ((dist!=dists[i-1])||(indices[i-1]<=index)) )
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								            if (dists[i-1]<=dist)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                // Check for duplicate indices
							 | 
						||
| 
								 | 
							
								                for (int j = i; dists[j] == dist && j--;) {
							 | 
						||
| 
								 | 
							
								                    if (indices[j] == index) {
							 | 
						||
| 
								 | 
							
								                        return;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (count < capacity) ++count;
							 | 
						||
| 
								 | 
							
								        for (int j = count-1; j > i; --j) {
							 | 
						||
| 
								 | 
							
								            dists[j] = dists[j-1];
							 | 
						||
| 
								 | 
							
								            indices[j] = indices[j-1];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        dists[i] = dist;
							 | 
						||
| 
								 | 
							
								        indices[i] = index;
							 | 
						||
| 
								 | 
							
								        worst_distance_ = dists[capacity-1];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DistanceType worstDist() const CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return worst_distance_;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A result-set class used when performing a radius based search.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template <typename DistanceType>
							 | 
						||
| 
								 | 
							
								class RadiusResultSet : public ResultSet<DistanceType>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DistanceType radius;
							 | 
						||
| 
								 | 
							
								    int* indices;
							 | 
						||
| 
								 | 
							
								    DistanceType* dists;
							 | 
						||
| 
								 | 
							
								    size_t capacity;
							 | 
						||
| 
								 | 
							
								    size_t count;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    RadiusResultSet(DistanceType radius_, int* indices_, DistanceType* dists_, int capacity_) :
							 | 
						||
| 
								 | 
							
								        radius(radius_), indices(indices_), dists(dists_), capacity(capacity_)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        init();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ~RadiusResultSet()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void init()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        count = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    size_t size() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return count;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bool full() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void addPoint(DistanceType dist, int index)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (dist<radius) {
							 | 
						||
| 
								 | 
							
								            if ((capacity>0)&&(count < capacity)) {
							 | 
						||
| 
								 | 
							
								                dists[count] = dist;
							 | 
						||
| 
								 | 
							
								                indices[count] = index;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            count++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DistanceType worstDist() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return radius;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** Class that holds the k NN neighbors
							 | 
						||
| 
								 | 
							
								 * Faster than KNNResultSet as it uses a binary heap and does not maintain two arrays
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template<typename DistanceType>
							 | 
						||
| 
								 | 
							
								class UniqueResultSet : public ResultSet<DistanceType>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    struct DistIndex
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        DistIndex(DistanceType dist, unsigned int index) :
							 | 
						||
| 
								 | 
							
								            dist_(dist), index_(index)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        bool operator<(const DistIndex dist_index) const
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return (dist_ < dist_index.dist_) || ((dist_ == dist_index.dist_) && index_ < dist_index.index_);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        DistanceType dist_;
							 | 
						||
| 
								 | 
							
								        unsigned int index_;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Default constructor */
							 | 
						||
| 
								 | 
							
								    UniqueResultSet() :
							 | 
						||
| 
								 | 
							
								        is_full_(false), worst_distance_(std::numeric_limits<DistanceType>::max())
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Check the status of the set
							 | 
						||
| 
								 | 
							
								     * @return true if we have k NN
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    inline bool full() const CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return is_full_;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Remove all elements in the set
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    virtual void clear() = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Copy the set to two C arrays
							 | 
						||
| 
								 | 
							
								     * @param indices pointer to a C array of indices
							 | 
						||
| 
								 | 
							
								     * @param dist pointer to a C array of distances
							 | 
						||
| 
								 | 
							
								     * @param n_neighbors the number of neighbors to copy
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    virtual void copy(int* indices, DistanceType* dist, int n_neighbors = -1) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (n_neighbors < 0) {
							 | 
						||
| 
								 | 
							
								            for (typename std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
							 | 
						||
| 
								 | 
							
								                     dist_indices_.end(); dist_index != dist_index_end; ++dist_index, ++indices, ++dist) {
							 | 
						||
| 
								 | 
							
								                *indices = dist_index->index_;
							 | 
						||
| 
								 | 
							
								                *dist = dist_index->dist_;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            int i = 0;
							 | 
						||
| 
								 | 
							
								            for (typename std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
							 | 
						||
| 
								 | 
							
								                     dist_indices_.end(); (dist_index != dist_index_end) && (i < n_neighbors); ++dist_index, ++indices, ++dist, ++i) {
							 | 
						||
| 
								 | 
							
								                *indices = dist_index->index_;
							 | 
						||
| 
								 | 
							
								                *dist = dist_index->dist_;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Copy the set to two C arrays but sort it according to the distance first
							 | 
						||
| 
								 | 
							
								     * @param indices pointer to a C array of indices
							 | 
						||
| 
								 | 
							
								     * @param dist pointer to a C array of distances
							 | 
						||
| 
								 | 
							
								     * @param n_neighbors the number of neighbors to copy
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    virtual void sortAndCopy(int* indices, DistanceType* dist, int n_neighbors = -1) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        copy(indices, dist, n_neighbors);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The number of neighbors in the set
							 | 
						||
| 
								 | 
							
								     * @return
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    size_t size() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return dist_indices_.size();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The distance of the furthest neighbor
							 | 
						||
| 
								 | 
							
								     * If we don't have enough neighbors, it returns the max possible value
							 | 
						||
| 
								 | 
							
								     * @return
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    inline DistanceType worstDist() const CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return worst_distance_;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								    /** Flag to say if the set is full */
							 | 
						||
| 
								 | 
							
								    bool is_full_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The worst distance found so far */
							 | 
						||
| 
								 | 
							
								    DistanceType worst_distance_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The best candidates so far */
							 | 
						||
| 
								 | 
							
								    std::set<DistIndex> dist_indices_;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** Class that holds the k NN neighbors
							 | 
						||
| 
								 | 
							
								 * Faster than KNNResultSet as it uses a binary heap and does not maintain two arrays
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template<typename DistanceType>
							 | 
						||
| 
								 | 
							
								class KNNUniqueResultSet : public UniqueResultSet<DistanceType>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    /** Constructor
							 | 
						||
| 
								 | 
							
								     * @param capacity the number of neighbors to store at max
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    KNNUniqueResultSet(unsigned int capacity) : capacity_(capacity)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        this->is_full_ = false;
							 | 
						||
| 
								 | 
							
								        this->clear();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Add a possible candidate to the best neighbors
							 | 
						||
| 
								 | 
							
								     * @param dist distance for that neighbor
							 | 
						||
| 
								 | 
							
								     * @param index index of that neighbor
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    inline void addPoint(DistanceType dist, int index) CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Don't do anything if we are worse than the worst
							 | 
						||
| 
								 | 
							
								        if (dist >= worst_distance_) return;
							 | 
						||
| 
								 | 
							
								        dist_indices_.insert(DistIndex(dist, index));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (is_full_) {
							 | 
						||
| 
								 | 
							
								            if (dist_indices_.size() > capacity_) {
							 | 
						||
| 
								 | 
							
								                dist_indices_.erase(*dist_indices_.rbegin());
							 | 
						||
| 
								 | 
							
								                worst_distance_ = dist_indices_.rbegin()->dist_;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (dist_indices_.size() == capacity_) {
							 | 
						||
| 
								 | 
							
								            is_full_ = true;
							 | 
						||
| 
								 | 
							
								            worst_distance_ = dist_indices_.rbegin()->dist_;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Remove all elements in the set
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    void clear() CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        dist_indices_.clear();
							 | 
						||
| 
								 | 
							
								        worst_distance_ = std::numeric_limits<DistanceType>::max();
							 | 
						||
| 
								 | 
							
								        is_full_ = false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								    typedef typename UniqueResultSet<DistanceType>::DistIndex DistIndex;
							 | 
						||
| 
								 | 
							
								    using UniqueResultSet<DistanceType>::is_full_;
							 | 
						||
| 
								 | 
							
								    using UniqueResultSet<DistanceType>::worst_distance_;
							 | 
						||
| 
								 | 
							
								    using UniqueResultSet<DistanceType>::dist_indices_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The number of neighbors to keep */
							 | 
						||
| 
								 | 
							
								    unsigned int capacity_;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** Class that holds the radius nearest neighbors
							 | 
						||
| 
								 | 
							
								 * It is more accurate than RadiusResult as it is not limited in the number of neighbors
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template<typename DistanceType>
							 | 
						||
| 
								 | 
							
								class RadiusUniqueResultSet : public UniqueResultSet<DistanceType>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    /** Constructor
							 | 
						||
| 
								 | 
							
								     * @param radius the maximum distance of a neighbor
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    RadiusUniqueResultSet(DistanceType radius) :
							 | 
						||
| 
								 | 
							
								        radius_(radius)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        is_full_ = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Add a possible candidate to the best neighbors
							 | 
						||
| 
								 | 
							
								     * @param dist distance for that neighbor
							 | 
						||
| 
								 | 
							
								     * @param index index of that neighbor
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    void addPoint(DistanceType dist, int index) CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (dist <= radius_) dist_indices_.insert(DistIndex(dist, index));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Remove all elements in the set
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    inline void clear() CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        dist_indices_.clear();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Check the status of the set
							 | 
						||
| 
								 | 
							
								     * @return alwys false
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    inline bool full() const CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The distance of the furthest neighbor
							 | 
						||
| 
								 | 
							
								     * If we don't have enough neighbors, it returns the max possible value
							 | 
						||
| 
								 | 
							
								     * @return
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    inline DistanceType worstDist() const CV_OVERRIDE
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return radius_;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    typedef typename UniqueResultSet<DistanceType>::DistIndex DistIndex;
							 | 
						||
| 
								 | 
							
								    using UniqueResultSet<DistanceType>::dist_indices_;
							 | 
						||
| 
								 | 
							
								    using UniqueResultSet<DistanceType>::is_full_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The furthest distance a neighbor can be */
							 | 
						||
| 
								 | 
							
								    DistanceType radius_;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** Class that holds the k NN neighbors within a radius distance
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template<typename DistanceType>
							 | 
						||
| 
								 | 
							
								class KNNRadiusUniqueResultSet : public KNNUniqueResultSet<DistanceType>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    /** Constructor
							 | 
						||
| 
								 | 
							
								     * @param capacity the number of neighbors to store at max
							 | 
						||
| 
								 | 
							
								     * @param radius the maximum distance of a neighbor
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    KNNRadiusUniqueResultSet(unsigned int capacity, DistanceType radius)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        this->capacity_ = capacity;
							 | 
						||
| 
								 | 
							
								        this->radius_ = radius;
							 | 
						||
| 
								 | 
							
								        this->dist_indices_.reserve(capacity_);
							 | 
						||
| 
								 | 
							
								        this->clear();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Remove all elements in the set
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    void clear()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        dist_indices_.clear();
							 | 
						||
| 
								 | 
							
								        worst_distance_ = radius_;
							 | 
						||
| 
								 | 
							
								        is_full_ = false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    using KNNUniqueResultSet<DistanceType>::dist_indices_;
							 | 
						||
| 
								 | 
							
								    using KNNUniqueResultSet<DistanceType>::is_full_;
							 | 
						||
| 
								 | 
							
								    using KNNUniqueResultSet<DistanceType>::worst_distance_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The maximum number of neighbors to consider */
							 | 
						||
| 
								 | 
							
								    unsigned int capacity_;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** The maximum distance of a neighbor */
							 | 
						||
| 
								 | 
							
								    DistanceType radius_;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//! @endcond
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //OPENCV_FLANN_RESULTSET_H
							 |