mirror of
https://github.com/storytold/LiveScan3D.git
synced 2026-10-17 00:23:00 +00:00
Moved to Visual Studio 2015, OpenCV 3.2.0, x64
This commit is contained in:
+36
-16
@@ -44,13 +44,11 @@ struct base_any_policy
|
||||
virtual void clone(void* const* src, void** dest) = 0;
|
||||
virtual void move(void* const* src, void** dest) = 0;
|
||||
virtual void* get_value(void** src) = 0;
|
||||
virtual const void* get_value(void* const * src) = 0;
|
||||
virtual ::size_t get_size() = 0;
|
||||
virtual const std::type_info& type() = 0;
|
||||
virtual void print(std::ostream& out, void* const* src) = 0;
|
||||
|
||||
#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
|
||||
virtual ~base_any_policy() {}
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -72,6 +70,7 @@ struct small_any_policy : typed_base_any_policy<T>
|
||||
virtual void clone(void* const* src, void** dest) { *dest = *src; }
|
||||
virtual void move(void* const* src, void** dest) { *dest = *src; }
|
||||
virtual void* get_value(void** src) { return reinterpret_cast<void*>(src); }
|
||||
virtual const void* get_value(void* const * src) { return reinterpret_cast<const void*>(src); }
|
||||
virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(src); }
|
||||
};
|
||||
|
||||
@@ -80,7 +79,8 @@ struct big_any_policy : typed_base_any_policy<T>
|
||||
{
|
||||
virtual void static_delete(void** x)
|
||||
{
|
||||
if (* x) delete (* reinterpret_cast<T**>(x)); *x = NULL;
|
||||
if (* x) delete (* reinterpret_cast<T**>(x));
|
||||
*x = NULL;
|
||||
}
|
||||
virtual void copy_from_value(void const* src, void** dest)
|
||||
{
|
||||
@@ -96,6 +96,7 @@ struct big_any_policy : typed_base_any_policy<T>
|
||||
**reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src);
|
||||
}
|
||||
virtual void* get_value(void** src) { return *src; }
|
||||
virtual const void* get_value(void* const * src) { return *src; }
|
||||
virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(*src); }
|
||||
};
|
||||
|
||||
@@ -109,6 +110,11 @@ template<> inline void big_any_policy<flann_algorithm_t>::print(std::ostream& ou
|
||||
out << int(*reinterpret_cast<flann_algorithm_t const*>(*src));
|
||||
}
|
||||
|
||||
template<> inline void big_any_policy<cv::String>::print(std::ostream& out, void* const* src)
|
||||
{
|
||||
out << (*reinterpret_cast<cv::String const*>(*src)).c_str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct choose_policy
|
||||
{
|
||||
@@ -150,13 +156,27 @@ SMALL_POLICY(bool);
|
||||
|
||||
#undef SMALL_POLICY
|
||||
|
||||
/// This function will return a different policy for each type.
|
||||
template<typename T>
|
||||
base_any_policy* get_policy()
|
||||
template <typename T>
|
||||
class SinglePolicy
|
||||
{
|
||||
SinglePolicy();
|
||||
SinglePolicy(const SinglePolicy& other);
|
||||
SinglePolicy& operator=(const SinglePolicy& other);
|
||||
|
||||
public:
|
||||
static base_any_policy* get_policy();
|
||||
|
||||
private:
|
||||
static typename choose_policy<T>::type policy;
|
||||
return &policy;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
typename choose_policy<T>::type SinglePolicy<T>::policy;
|
||||
|
||||
/// This function will return a different policy for each type.
|
||||
template <typename T>
|
||||
inline base_any_policy* SinglePolicy<T>::get_policy() { return &policy; }
|
||||
|
||||
} // namespace anyimpl
|
||||
|
||||
struct any
|
||||
@@ -170,26 +190,26 @@ public:
|
||||
/// Initializing constructor.
|
||||
template <typename T>
|
||||
any(const T& x)
|
||||
: policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
|
||||
: policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
|
||||
{
|
||||
assign(x);
|
||||
}
|
||||
|
||||
/// Empty constructor.
|
||||
any()
|
||||
: policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
|
||||
: policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
|
||||
{ }
|
||||
|
||||
/// Special initializing constructor for string literals.
|
||||
any(const char* x)
|
||||
: policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
|
||||
: policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
|
||||
{
|
||||
assign(x);
|
||||
}
|
||||
|
||||
/// Copy constructor.
|
||||
any(const any& x)
|
||||
: policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL)
|
||||
: policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
|
||||
{
|
||||
assign(x);
|
||||
}
|
||||
@@ -214,7 +234,7 @@ public:
|
||||
any& assign(const T& x)
|
||||
{
|
||||
reset();
|
||||
policy = anyimpl::get_policy<T>();
|
||||
policy = anyimpl::SinglePolicy<T>::get_policy();
|
||||
policy->copy_from_value(&x, &object);
|
||||
return *this;
|
||||
}
|
||||
@@ -255,7 +275,7 @@ public:
|
||||
const T& cast() const
|
||||
{
|
||||
if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
|
||||
T* r = reinterpret_cast<T*>(policy->get_value(const_cast<void **>(&object)));
|
||||
const T* r = reinterpret_cast<const T*>(policy->get_value(&object));
|
||||
return *r;
|
||||
}
|
||||
|
||||
@@ -269,7 +289,7 @@ public:
|
||||
void reset()
|
||||
{
|
||||
policy->static_delete(&object);
|
||||
policy = anyimpl::get_policy<anyimpl::empty_any>();
|
||||
policy = anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy();
|
||||
}
|
||||
|
||||
/// Returns true if the two types are the same.
|
||||
|
||||
@@ -99,18 +99,22 @@ public:
|
||||
*/
|
||||
virtual void buildIndex()
|
||||
{
|
||||
std::ostringstream stream;
|
||||
bestParams_ = estimateBuildParams();
|
||||
print_params(bestParams_, stream);
|
||||
Logger::info("----------------------------------------------------\n");
|
||||
Logger::info("Autotuned parameters:\n");
|
||||
print_params(bestParams_);
|
||||
Logger::info("%s", stream.str().c_str());
|
||||
Logger::info("----------------------------------------------------\n");
|
||||
|
||||
bestIndex_ = create_index_by_type(dataset_, bestParams_, distance_);
|
||||
bestIndex_->buildIndex();
|
||||
speedup_ = estimateSearchParams(bestSearchParams_);
|
||||
stream.str(std::string());
|
||||
print_params(bestSearchParams_, stream);
|
||||
Logger::info("----------------------------------------------------\n");
|
||||
Logger::info("Search parameters:\n");
|
||||
print_params(bestSearchParams_);
|
||||
Logger::info("%s", stream.str().c_str());
|
||||
Logger::info("----------------------------------------------------\n");
|
||||
}
|
||||
|
||||
@@ -270,7 +274,7 @@ private:
|
||||
// struct KMeansSimpleDownhillFunctor {
|
||||
//
|
||||
// Autotune& autotuner;
|
||||
// KMeansSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {};
|
||||
// KMeansSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {}
|
||||
//
|
||||
// float operator()(int* params) {
|
||||
//
|
||||
@@ -295,7 +299,7 @@ private:
|
||||
// struct KDTreeSimpleDownhillFunctor {
|
||||
//
|
||||
// Autotune& autotuner;
|
||||
// KDTreeSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {};
|
||||
// KDTreeSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {}
|
||||
//
|
||||
// float operator()(int* params) {
|
||||
// float maxFloat = numeric_limits<float>::max();
|
||||
@@ -373,6 +377,7 @@ private:
|
||||
// evaluate kdtree for all parameter combinations
|
||||
for (size_t i = 0; i < FLANN_ARRAY_LEN(testTrees); ++i) {
|
||||
CostData cost;
|
||||
cost.params["algorithm"] = FLANN_INDEX_KDTREE;
|
||||
cost.params["trees"] = testTrees[i];
|
||||
|
||||
evaluate_kdtree(cost);
|
||||
|
||||
@@ -107,6 +107,7 @@ enum flann_centers_init_t
|
||||
FLANN_CENTERS_RANDOM = 0,
|
||||
FLANN_CENTERS_GONZALES = 1,
|
||||
FLANN_CENTERS_KMEANSPP = 2,
|
||||
FLANN_CENTERS_GROUPWISE = 3,
|
||||
|
||||
// deprecated constants, should use the FLANN_CENTERS_* ones instead
|
||||
CENTERS_RANDOM = 0,
|
||||
|
||||
+129
-41
@@ -384,41 +384,6 @@ struct HammingLUT
|
||||
typedef unsigned char ElementType;
|
||||
typedef int ResultType;
|
||||
|
||||
/** this will count the bits in a ^ b
|
||||
*/
|
||||
ResultType operator()(const unsigned char* a, const unsigned char* b, int size) const
|
||||
{
|
||||
static const uchar popCountTable[] =
|
||||
{
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
|
||||
};
|
||||
ResultType result = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
result += popCountTable[a[i] ^ b[i]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
|
||||
* bit count of A exclusive XOR'ed with B
|
||||
*/
|
||||
struct HammingLUT2
|
||||
{
|
||||
typedef False is_kdtree_distance;
|
||||
typedef False is_vector_space_distance;
|
||||
|
||||
typedef unsigned char ElementType;
|
||||
typedef int ResultType;
|
||||
|
||||
/** this will count the bits in a ^ b
|
||||
*/
|
||||
ResultType operator()(const unsigned char* a, const unsigned char* b, size_t size) const
|
||||
@@ -630,7 +595,7 @@ struct HellingerDistance
|
||||
typedef typename Accumulator<T>::Type ResultType;
|
||||
|
||||
/**
|
||||
* Compute the histogram intersection distance
|
||||
* Compute the Hellinger distance
|
||||
*/
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
|
||||
@@ -663,7 +628,8 @@ struct HellingerDistance
|
||||
template <typename U, typename V>
|
||||
inline ResultType accum_dist(const U& a, const V& b, int) const
|
||||
{
|
||||
return sqrt(static_cast<ResultType>(a)) - sqrt(static_cast<ResultType>(b));
|
||||
ResultType diff = sqrt(static_cast<ResultType>(a)) - sqrt(static_cast<ResultType>(b));
|
||||
return diff * diff;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -741,7 +707,7 @@ struct KL_Divergence
|
||||
Iterator1 last = a + size;
|
||||
|
||||
while (a < last) {
|
||||
if (* a != 0) {
|
||||
if (* b != 0) {
|
||||
ResultType ratio = (ResultType)(*a / *b);
|
||||
if (ratio>0) {
|
||||
result += *a * log(ratio);
|
||||
@@ -764,9 +730,11 @@ struct KL_Divergence
|
||||
inline ResultType accum_dist(const U& a, const V& b, int) const
|
||||
{
|
||||
ResultType result = ResultType();
|
||||
ResultType ratio = (ResultType)(a / b);
|
||||
if (ratio>0) {
|
||||
result = a * log(ratio);
|
||||
if( *b != 0 ) {
|
||||
ResultType ratio = (ResultType)(a / b);
|
||||
if (ratio>0) {
|
||||
result = a * log(ratio);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -812,6 +780,126 @@ struct ZeroIterator
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Depending on processed distances, some of them are already squared (e.g. L2)
|
||||
* and some are not (e.g.Hamming). In KMeans++ for instance we want to be sure
|
||||
* we are working on ^2 distances, thus following templates to ensure that.
|
||||
*/
|
||||
template <typename Distance, typename ElementType>
|
||||
struct squareDistance
|
||||
{
|
||||
typedef typename Distance::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return dist*dist; }
|
||||
};
|
||||
|
||||
|
||||
template <typename ElementType>
|
||||
struct squareDistance<L2_Simple<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename L2_Simple<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return dist; }
|
||||
};
|
||||
|
||||
template <typename ElementType>
|
||||
struct squareDistance<L2<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename L2<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return dist; }
|
||||
};
|
||||
|
||||
|
||||
template <typename ElementType>
|
||||
struct squareDistance<MinkowskiDistance<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return dist; }
|
||||
};
|
||||
|
||||
template <typename ElementType>
|
||||
struct squareDistance<HellingerDistance<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename HellingerDistance<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return dist; }
|
||||
};
|
||||
|
||||
template <typename ElementType>
|
||||
struct squareDistance<ChiSquareDistance<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return dist; }
|
||||
};
|
||||
|
||||
|
||||
template <typename Distance>
|
||||
typename Distance::ResultType ensureSquareDistance( typename Distance::ResultType dist )
|
||||
{
|
||||
typedef typename Distance::ElementType ElementType;
|
||||
|
||||
squareDistance<Distance, ElementType> dummy;
|
||||
return dummy( dist );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ...and a template to ensure the user that he will process the normal distance,
|
||||
* and not squared distance, without loosing processing time calling sqrt(ensureSquareDistance)
|
||||
* that will result in doing actually sqrt(dist*dist) for L1 distance for instance.
|
||||
*/
|
||||
template <typename Distance, typename ElementType>
|
||||
struct simpleDistance
|
||||
{
|
||||
typedef typename Distance::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return dist; }
|
||||
};
|
||||
|
||||
|
||||
template <typename ElementType>
|
||||
struct simpleDistance<L2_Simple<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename L2_Simple<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return sqrt(dist); }
|
||||
};
|
||||
|
||||
template <typename ElementType>
|
||||
struct simpleDistance<L2<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename L2<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return sqrt(dist); }
|
||||
};
|
||||
|
||||
|
||||
template <typename ElementType>
|
||||
struct simpleDistance<MinkowskiDistance<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return sqrt(dist); }
|
||||
};
|
||||
|
||||
template <typename ElementType>
|
||||
struct simpleDistance<HellingerDistance<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename HellingerDistance<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return sqrt(dist); }
|
||||
};
|
||||
|
||||
template <typename ElementType>
|
||||
struct simpleDistance<ChiSquareDistance<ElementType>, ElementType>
|
||||
{
|
||||
typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
|
||||
ResultType operator()( ResultType dist ) { return sqrt(dist); }
|
||||
};
|
||||
|
||||
|
||||
template <typename Distance>
|
||||
typename Distance::ResultType ensureSimpleDistance( typename Distance::ResultType dist )
|
||||
{
|
||||
typedef typename Distance::ElementType ElementType;
|
||||
|
||||
simpleDistance<Distance, ElementType> dummy;
|
||||
return dummy( dist );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //OPENCV_FLANN_DIST_H_
|
||||
|
||||
@@ -57,14 +57,14 @@ namespace cvflann {
|
||||
class DynamicBitset
|
||||
{
|
||||
public:
|
||||
/** @param default constructor
|
||||
/** default constructor
|
||||
*/
|
||||
DynamicBitset()
|
||||
{
|
||||
}
|
||||
|
||||
/** @param only constructor we use in our code
|
||||
* @param the size of the bitset (in bits)
|
||||
/** only constructor we use in our code
|
||||
* @param sz the size of the bitset (in bits)
|
||||
*/
|
||||
DynamicBitset(size_t sz)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
return bitset_.empty();
|
||||
}
|
||||
|
||||
/** @param set all the bits to 0
|
||||
/** set all the bits to 0
|
||||
*/
|
||||
void reset()
|
||||
{
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
}
|
||||
|
||||
/** @brief set one bit to 0
|
||||
* @param
|
||||
* @param index
|
||||
*/
|
||||
void reset(size_t index)
|
||||
{
|
||||
@@ -106,15 +106,15 @@ public:
|
||||
* This function is useful when resetting a given set of bits so that the
|
||||
* whole bitset ends up being 0: if that's the case, we don't care about setting
|
||||
* other bits to 0
|
||||
* @param
|
||||
* @param index
|
||||
*/
|
||||
void reset_block(size_t index)
|
||||
{
|
||||
bitset_[index / cell_bit_size_] = 0;
|
||||
}
|
||||
|
||||
/** @param resize the bitset so that it contains at least size bits
|
||||
* @param size
|
||||
/** resize the bitset so that it contains at least sz bits
|
||||
* @param sz
|
||||
*/
|
||||
void resize(size_t sz)
|
||||
{
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
bitset_.resize(sz / cell_bit_size_ + 1);
|
||||
}
|
||||
|
||||
/** @param set a bit to true
|
||||
/** set a bit to true
|
||||
* @param index the index of the bit to set to 1
|
||||
*/
|
||||
void set(size_t index)
|
||||
@@ -130,14 +130,14 @@ public:
|
||||
bitset_[index / cell_bit_size_] |= size_t(1) << (index % cell_bit_size_);
|
||||
}
|
||||
|
||||
/** @param gives the number of contained bits
|
||||
/** gives the number of contained bits
|
||||
*/
|
||||
size_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
/** @param check if a bit is set
|
||||
/** check if a bit is set
|
||||
* @param index the index of the bit to check
|
||||
* @return true if the bit is set
|
||||
*/
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -40,388 +41,8 @@
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef _OPENCV_FLANN_HPP_
|
||||
#define _OPENCV_FLANN_HPP_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "opencv2/core/types_c.h"
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/flann/flann_base.hpp"
|
||||
#include "opencv2/flann/miniflann.hpp"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
CV_EXPORTS flann_distance_t flann_distance_type();
|
||||
FLANN_DEPRECATED CV_EXPORTS void set_distance_type(flann_distance_t distance_type, int order);
|
||||
}
|
||||
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace flann
|
||||
{
|
||||
|
||||
template <typename T> struct CvType {};
|
||||
template <> struct CvType<unsigned char> { static int type() { return CV_8U; } };
|
||||
template <> struct CvType<char> { static int type() { return CV_8S; } };
|
||||
template <> struct CvType<unsigned short> { static int type() { return CV_16U; } };
|
||||
template <> struct CvType<short> { static int type() { return CV_16S; } };
|
||||
template <> struct CvType<int> { static int type() { return CV_32S; } };
|
||||
template <> struct CvType<float> { static int type() { return CV_32F; } };
|
||||
template <> struct CvType<double> { static int type() { return CV_64F; } };
|
||||
|
||||
|
||||
// bring the flann parameters into this namespace
|
||||
using ::cvflann::get_param;
|
||||
using ::cvflann::print_params;
|
||||
|
||||
// bring the flann distances into this namespace
|
||||
using ::cvflann::L2_Simple;
|
||||
using ::cvflann::L2;
|
||||
using ::cvflann::L1;
|
||||
using ::cvflann::MinkowskiDistance;
|
||||
using ::cvflann::MaxDistance;
|
||||
using ::cvflann::HammingLUT;
|
||||
using ::cvflann::Hamming;
|
||||
using ::cvflann::Hamming2;
|
||||
using ::cvflann::HistIntersectionDistance;
|
||||
using ::cvflann::HellingerDistance;
|
||||
using ::cvflann::ChiSquareDistance;
|
||||
using ::cvflann::KL_Divergence;
|
||||
|
||||
|
||||
|
||||
template <typename Distance>
|
||||
class GenericIndex
|
||||
{
|
||||
public:
|
||||
typedef typename Distance::ElementType ElementType;
|
||||
typedef typename Distance::ResultType DistanceType;
|
||||
|
||||
GenericIndex(const Mat& features, const ::cvflann::IndexParams& params, Distance distance = Distance());
|
||||
|
||||
~GenericIndex();
|
||||
|
||||
void knnSearch(const vector<ElementType>& query, vector<int>& indices,
|
||||
vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& params);
|
||||
void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params);
|
||||
|
||||
int radiusSearch(const vector<ElementType>& query, vector<int>& indices,
|
||||
vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& params);
|
||||
int radiusSearch(const Mat& query, Mat& indices, Mat& dists,
|
||||
DistanceType radius, const ::cvflann::SearchParams& params);
|
||||
|
||||
void save(std::string filename) { nnIndex->save(filename); }
|
||||
|
||||
int veclen() const { return nnIndex->veclen(); }
|
||||
|
||||
int size() const { return nnIndex->size(); }
|
||||
|
||||
::cvflann::IndexParams getParameters() { return nnIndex->getParameters(); }
|
||||
|
||||
FLANN_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() { return nnIndex->getIndexParameters(); }
|
||||
|
||||
private:
|
||||
::cvflann::Index<Distance>* nnIndex;
|
||||
};
|
||||
|
||||
|
||||
#define FLANN_DISTANCE_CHECK \
|
||||
if ( ::cvflann::flann_distance_type() != cvflann::FLANN_DIST_L2) { \
|
||||
printf("[WARNING] You are using cv::flann::Index (or cv::flann::GenericIndex) and have also changed "\
|
||||
"the distance using cvflann::set_distance_type. This is no longer working as expected "\
|
||||
"(cv::flann::Index always uses L2). You should create the index templated on the distance, "\
|
||||
"for example for L1 distance use: GenericIndex< L1<float> > \n"); \
|
||||
}
|
||||
|
||||
|
||||
template <typename Distance>
|
||||
GenericIndex<Distance>::GenericIndex(const Mat& dataset, const ::cvflann::IndexParams& params, Distance distance)
|
||||
{
|
||||
CV_Assert(dataset.type() == CvType<ElementType>::type());
|
||||
CV_Assert(dataset.isContinuous());
|
||||
::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
|
||||
|
||||
nnIndex = new ::cvflann::Index<Distance>(m_dataset, params, distance);
|
||||
|
||||
FLANN_DISTANCE_CHECK
|
||||
|
||||
nnIndex->buildIndex();
|
||||
}
|
||||
|
||||
template <typename Distance>
|
||||
GenericIndex<Distance>::~GenericIndex()
|
||||
{
|
||||
delete nnIndex;
|
||||
}
|
||||
|
||||
template <typename Distance>
|
||||
void GenericIndex<Distance>::knnSearch(const vector<ElementType>& query, vector<int>& indices, vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
|
||||
{
|
||||
::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
|
||||
::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
|
||||
::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
|
||||
|
||||
FLANN_DISTANCE_CHECK
|
||||
|
||||
nnIndex->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
|
||||
}
|
||||
|
||||
|
||||
template <typename Distance>
|
||||
void GenericIndex<Distance>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
|
||||
{
|
||||
CV_Assert(queries.type() == CvType<ElementType>::type());
|
||||
CV_Assert(queries.isContinuous());
|
||||
::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
|
||||
|
||||
CV_Assert(indices.type() == CV_32S);
|
||||
CV_Assert(indices.isContinuous());
|
||||
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
|
||||
|
||||
CV_Assert(dists.type() == CvType<DistanceType>::type());
|
||||
CV_Assert(dists.isContinuous());
|
||||
::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
|
||||
|
||||
FLANN_DISTANCE_CHECK
|
||||
|
||||
nnIndex->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
|
||||
}
|
||||
|
||||
template <typename Distance>
|
||||
int GenericIndex<Distance>::radiusSearch(const vector<ElementType>& query, vector<int>& indices, vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
|
||||
{
|
||||
::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
|
||||
::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
|
||||
::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
|
||||
|
||||
FLANN_DISTANCE_CHECK
|
||||
|
||||
return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
||||
}
|
||||
|
||||
template <typename Distance>
|
||||
int GenericIndex<Distance>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
|
||||
{
|
||||
CV_Assert(query.type() == CvType<ElementType>::type());
|
||||
CV_Assert(query.isContinuous());
|
||||
::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
|
||||
|
||||
CV_Assert(indices.type() == CV_32S);
|
||||
CV_Assert(indices.isContinuous());
|
||||
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
|
||||
|
||||
CV_Assert(dists.type() == CvType<DistanceType>::type());
|
||||
CV_Assert(dists.isContinuous());
|
||||
::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
|
||||
|
||||
FLANN_DISTANCE_CHECK
|
||||
|
||||
return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use GenericIndex class instead
|
||||
*/
|
||||
template <typename T>
|
||||
class
|
||||
#ifndef _MSC_VER
|
||||
FLANN_DEPRECATED
|
||||
#endif
|
||||
Index_ {
|
||||
public:
|
||||
typedef typename L2<T>::ElementType ElementType;
|
||||
typedef typename L2<T>::ResultType DistanceType;
|
||||
|
||||
Index_(const Mat& features, const ::cvflann::IndexParams& params);
|
||||
|
||||
~Index_();
|
||||
|
||||
void knnSearch(const vector<ElementType>& query, vector<int>& indices, vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& params);
|
||||
void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params);
|
||||
|
||||
int radiusSearch(const vector<ElementType>& query, vector<int>& indices, vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& params);
|
||||
int radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& params);
|
||||
|
||||
void save(std::string filename)
|
||||
{
|
||||
if (nnIndex_L1) nnIndex_L1->save(filename);
|
||||
if (nnIndex_L2) nnIndex_L2->save(filename);
|
||||
}
|
||||
|
||||
int veclen() const
|
||||
{
|
||||
if (nnIndex_L1) return nnIndex_L1->veclen();
|
||||
if (nnIndex_L2) return nnIndex_L2->veclen();
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
if (nnIndex_L1) return nnIndex_L1->size();
|
||||
if (nnIndex_L2) return nnIndex_L2->size();
|
||||
}
|
||||
|
||||
::cvflann::IndexParams getParameters()
|
||||
{
|
||||
if (nnIndex_L1) return nnIndex_L1->getParameters();
|
||||
if (nnIndex_L2) return nnIndex_L2->getParameters();
|
||||
|
||||
}
|
||||
|
||||
FLANN_DEPRECATED const ::cvflann::IndexParams* getIndexParameters()
|
||||
{
|
||||
if (nnIndex_L1) return nnIndex_L1->getIndexParameters();
|
||||
if (nnIndex_L2) return nnIndex_L2->getIndexParameters();
|
||||
}
|
||||
|
||||
private:
|
||||
// providing backwards compatibility for L2 and L1 distances (most common)
|
||||
::cvflann::Index< L2<ElementType> >* nnIndex_L2;
|
||||
::cvflann::Index< L1<ElementType> >* nnIndex_L1;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
template <typename T>
|
||||
class FLANN_DEPRECATED Index_;
|
||||
#ifdef __OPENCV_BUILD
|
||||
#error this is a compatibility header which should not be used inside the OpenCV library
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
Index_<T>::Index_(const Mat& dataset, const ::cvflann::IndexParams& params)
|
||||
{
|
||||
printf("[WARNING] The cv::flann::Index_<T> class is deperecated, use cv::flann::GenericIndex<Distance> instead\n");
|
||||
|
||||
CV_Assert(dataset.type() == CvType<ElementType>::type());
|
||||
CV_Assert(dataset.isContinuous());
|
||||
::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
|
||||
|
||||
if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
|
||||
nnIndex_L1 = NULL;
|
||||
nnIndex_L2 = new ::cvflann::Index< L2<ElementType> >(m_dataset, params);
|
||||
}
|
||||
else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
|
||||
nnIndex_L1 = new ::cvflann::Index< L1<ElementType> >(m_dataset, params);
|
||||
nnIndex_L2 = NULL;
|
||||
}
|
||||
else {
|
||||
printf("[ERROR] cv::flann::Index_<T> only provides backwards compatibility for the L1 and L2 distances. "
|
||||
"For other distance types you must use cv::flann::GenericIndex<Distance>\n");
|
||||
CV_Assert(0);
|
||||
}
|
||||
if (nnIndex_L1) nnIndex_L1->buildIndex();
|
||||
if (nnIndex_L2) nnIndex_L2->buildIndex();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Index_<T>::~Index_()
|
||||
{
|
||||
if (nnIndex_L1) delete nnIndex_L1;
|
||||
if (nnIndex_L2) delete nnIndex_L2;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Index_<T>::knnSearch(const vector<ElementType>& query, vector<int>& indices, vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
|
||||
{
|
||||
::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
|
||||
::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
|
||||
::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
|
||||
|
||||
if (nnIndex_L1) nnIndex_L1->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
|
||||
if (nnIndex_L2) nnIndex_L2->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void Index_<T>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
|
||||
{
|
||||
CV_Assert(queries.type() == CvType<ElementType>::type());
|
||||
CV_Assert(queries.isContinuous());
|
||||
::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
|
||||
|
||||
CV_Assert(indices.type() == CV_32S);
|
||||
CV_Assert(indices.isContinuous());
|
||||
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
|
||||
|
||||
CV_Assert(dists.type() == CvType<DistanceType>::type());
|
||||
CV_Assert(dists.isContinuous());
|
||||
::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
|
||||
|
||||
if (nnIndex_L1) nnIndex_L1->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
|
||||
if (nnIndex_L2) nnIndex_L2->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int Index_<T>::radiusSearch(const vector<ElementType>& query, vector<int>& indices, vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
|
||||
{
|
||||
::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
|
||||
::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
|
||||
::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
|
||||
|
||||
if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
||||
if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int Index_<T>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
|
||||
{
|
||||
CV_Assert(query.type() == CvType<ElementType>::type());
|
||||
CV_Assert(query.isContinuous());
|
||||
::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
|
||||
|
||||
CV_Assert(indices.type() == CV_32S);
|
||||
CV_Assert(indices.isContinuous());
|
||||
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
|
||||
|
||||
CV_Assert(dists.type() == CvType<DistanceType>::type());
|
||||
CV_Assert(dists.isContinuous());
|
||||
::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
|
||||
|
||||
if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
||||
if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
||||
}
|
||||
|
||||
|
||||
template <typename Distance>
|
||||
int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params,
|
||||
Distance d = Distance())
|
||||
{
|
||||
typedef typename Distance::ElementType ElementType;
|
||||
typedef typename Distance::ResultType DistanceType;
|
||||
|
||||
CV_Assert(features.type() == CvType<ElementType>::type());
|
||||
CV_Assert(features.isContinuous());
|
||||
::cvflann::Matrix<ElementType> m_features((ElementType*)features.ptr<ElementType>(0), features.rows, features.cols);
|
||||
|
||||
CV_Assert(centers.type() == CvType<DistanceType>::type());
|
||||
CV_Assert(centers.isContinuous());
|
||||
::cvflann::Matrix<DistanceType> m_centers((DistanceType*)centers.ptr<DistanceType>(0), centers.rows, centers.cols);
|
||||
|
||||
return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
|
||||
}
|
||||
|
||||
|
||||
template <typename ELEM_TYPE, typename DIST_TYPE>
|
||||
FLANN_DEPRECATED int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params)
|
||||
{
|
||||
printf("[WARNING] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> is deprecated, use "
|
||||
"cv::flann::hierarchicalClustering<Distance> instead\n");
|
||||
|
||||
if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
|
||||
return hierarchicalClustering< L2<ELEM_TYPE> >(features, centers, params);
|
||||
}
|
||||
else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
|
||||
return hierarchicalClustering< L1<ELEM_TYPE> >(features, centers, params);
|
||||
}
|
||||
else {
|
||||
printf("[ERROR] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> only provides backwards "
|
||||
"compatibility for the L1 and L2 distances. "
|
||||
"For other distance types you must use cv::flann::hierarchicalClustering<Distance>\n");
|
||||
CV_Assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
} } // namespace cv::flann
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
#include "opencv2/flann.hpp"
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#define OPENCV_FLANN_BASE_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
|
||||
@@ -62,7 +61,7 @@ inline void log_verbosity(int level)
|
||||
*/
|
||||
struct SavedIndexParams : public IndexParams
|
||||
{
|
||||
SavedIndexParams(std::string filename)
|
||||
SavedIndexParams(cv::String filename)
|
||||
{
|
||||
(* this)["algorithm"] = FLANN_INDEX_SAVED;
|
||||
(*this)["filename"] = filename;
|
||||
@@ -71,7 +70,7 @@ struct SavedIndexParams : public IndexParams
|
||||
|
||||
|
||||
template<typename Distance>
|
||||
NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const std::string& filename, Distance distance)
|
||||
NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const cv::String& filename, Distance distance)
|
||||
{
|
||||
typedef typename Distance::ElementType ElementType;
|
||||
|
||||
@@ -111,7 +110,7 @@ public:
|
||||
loaded_ = false;
|
||||
|
||||
if (index_type == FLANN_INDEX_SAVED) {
|
||||
nnIndex_ = load_saved_index<Distance>(features, get_param<std::string>(params,"filename"), distance);
|
||||
nnIndex_ = load_saved_index<Distance>(features, get_param<cv::String>(params,"filename"), distance);
|
||||
loaded_ = true;
|
||||
}
|
||||
else {
|
||||
@@ -134,7 +133,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void save(std::string filename)
|
||||
void save(cv::String filename)
|
||||
{
|
||||
FILE* fout = fopen(filename.c_str(), "wb");
|
||||
if (fout == NULL) {
|
||||
|
||||
@@ -31,19 +31,17 @@
|
||||
#ifndef OPENCV_FLANN_GENERAL_H_
|
||||
#define OPENCV_FLANN_GENERAL_H_
|
||||
|
||||
#include "defines.h"
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
class FLANNException : public std::runtime_error
|
||||
class FLANNException : public cv::Exception
|
||||
{
|
||||
public:
|
||||
FLANNException(const char* message) : std::runtime_error(message) { }
|
||||
FLANNException(const char* message) : cv::Exception(0, message, "", __FILE__, __LINE__) { }
|
||||
|
||||
FLANNException(const std::string& message) : std::runtime_error(message) { }
|
||||
FLANNException(const cv::String& message) : cv::Exception(0, message, "", __FILE__, __LINE__) { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ hid_t get_hdf5_type<double>() { return H5T_NATIVE_DOUBLE; }
|
||||
#define CHECK_ERROR(x,y) if ((x)<0) throw FLANNException((y));
|
||||
|
||||
template<typename T>
|
||||
void save_to_file(const cvflann::Matrix<T>& dataset, const std::string& filename, const std::string& name)
|
||||
void save_to_file(const cvflann::Matrix<T>& dataset, const String& filename, const String& name)
|
||||
{
|
||||
|
||||
#if H5Eset_auto_vers == 2
|
||||
@@ -125,7 +125,7 @@ void save_to_file(const cvflann::Matrix<T>& dataset, const std::string& filename
|
||||
|
||||
|
||||
template<typename T>
|
||||
void load_from_file(cvflann::Matrix<T>& dataset, const std::string& filename, const std::string& name)
|
||||
void load_from_file(cvflann::Matrix<T>& dataset, const String& filename, const String& name)
|
||||
{
|
||||
herr_t status;
|
||||
hid_t file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
|
||||
@@ -166,7 +166,7 @@ namespace mpi
|
||||
* @param name Name of dataset inside file
|
||||
*/
|
||||
template<typename T>
|
||||
void load_from_file(cvflann::Matrix<T>& dataset, const std::string& filename, const std::string& name)
|
||||
void load_from_file(cvflann::Matrix<T>& dataset, const String& filename, const String& name)
|
||||
{
|
||||
MPI_Comm comm = MPI_COMM_WORLD;
|
||||
MPI_Info info = MPI_INFO_NULL;
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#define OPENCV_FLANN_HIERARCHICAL_CLUSTERING_INDEX_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
@@ -210,8 +209,11 @@ private:
|
||||
assert(index >=0 && index < n);
|
||||
centers[0] = dsindices[index];
|
||||
|
||||
// Computing distance^2 will have the advantage of even higher probability further to pick new centers
|
||||
// far from previous centers (and this complies to "k-means++: the advantages of careful seeding" article)
|
||||
for (int i = 0; i < n; i++) {
|
||||
closestDistSq[i] = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols);
|
||||
closestDistSq[i] = ensureSquareDistance<Distance>( closestDistSq[i] );
|
||||
currentPot += closestDistSq[i];
|
||||
}
|
||||
|
||||
@@ -237,7 +239,10 @@ private:
|
||||
|
||||
// Compute the new potential
|
||||
double newPot = 0;
|
||||
for (int i = 0; i < n; i++) newPot += std::min( distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols), closestDistSq[i] );
|
||||
for (int i = 0; i < n; i++) {
|
||||
DistanceType dist = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols);
|
||||
newPot += std::min( ensureSquareDistance<Distance>(dist), closestDistSq[i] );
|
||||
}
|
||||
|
||||
// Store the best result
|
||||
if ((bestNewPot < 0)||(newPot < bestNewPot)) {
|
||||
@@ -249,7 +254,88 @@ private:
|
||||
// Add the appropriate center
|
||||
centers[centerCount] = dsindices[bestNewIndex];
|
||||
currentPot = bestNewPot;
|
||||
for (int i = 0; i < n; i++) closestDistSq[i] = std::min( distance(dataset[dsindices[i]], dataset[dsindices[bestNewIndex]], dataset.cols), closestDistSq[i] );
|
||||
for (int i = 0; i < n; i++) {
|
||||
DistanceType dist = distance(dataset[dsindices[i]], dataset[dsindices[bestNewIndex]], dataset.cols);
|
||||
closestDistSq[i] = std::min( ensureSquareDistance<Distance>(dist), closestDistSq[i] );
|
||||
}
|
||||
}
|
||||
|
||||
centers_length = centerCount;
|
||||
|
||||
delete[] closestDistSq;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Chooses the initial centers in a way inspired by Gonzales (by Pierre-Emmanuel Viel):
|
||||
* select the first point of the list as a candidate, then parse the points list. If another
|
||||
* point is further than current candidate from the other centers, test if it is a good center
|
||||
* of a local aggregation. If it is, replace current candidate by this point. And so on...
|
||||
*
|
||||
* Used with KMeansIndex that computes centers coordinates by averaging positions of clusters points,
|
||||
* this doesn't make a real difference with previous methods. But used with HierarchicalClusteringIndex
|
||||
* class that pick centers among existing points instead of computing the barycenters, there is a real
|
||||
* improvement.
|
||||
*
|
||||
* Params:
|
||||
* k = number of centers
|
||||
* vecs = the dataset of points
|
||||
* indices = indices in the dataset
|
||||
* Returns:
|
||||
*/
|
||||
void GroupWiseCenterChooser(int k, int* dsindices, int indices_length, int* centers, int& centers_length)
|
||||
{
|
||||
const float kSpeedUpFactor = 1.3f;
|
||||
|
||||
int n = indices_length;
|
||||
|
||||
DistanceType* closestDistSq = new DistanceType[n];
|
||||
|
||||
// Choose one random center and set the closestDistSq values
|
||||
int index = rand_int(n);
|
||||
assert(index >=0 && index < n);
|
||||
centers[0] = dsindices[index];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
closestDistSq[i] = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols);
|
||||
}
|
||||
|
||||
|
||||
// Choose each center
|
||||
int centerCount;
|
||||
for (centerCount = 1; centerCount < k; centerCount++) {
|
||||
|
||||
// Repeat several trials
|
||||
double bestNewPot = -1;
|
||||
int bestNewIndex = 0;
|
||||
DistanceType furthest = 0;
|
||||
for (index = 0; index < n; index++) {
|
||||
|
||||
// We will test only the potential of the points further than current candidate
|
||||
if( closestDistSq[index] > kSpeedUpFactor * (float)furthest ) {
|
||||
|
||||
// Compute the new potential
|
||||
double newPot = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
newPot += std::min( distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols)
|
||||
, closestDistSq[i] );
|
||||
}
|
||||
|
||||
// Store the best result
|
||||
if ((bestNewPot < 0)||(newPot <= bestNewPot)) {
|
||||
bestNewPot = newPot;
|
||||
bestNewIndex = index;
|
||||
furthest = closestDistSq[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the appropriate center
|
||||
centers[centerCount] = dsindices[bestNewIndex];
|
||||
for (int i = 0; i < n; i++) {
|
||||
closestDistSq[i] = std::min( distance(dataset[dsindices[i]], dataset[dsindices[bestNewIndex]], dataset.cols)
|
||||
, closestDistSq[i] );
|
||||
}
|
||||
}
|
||||
|
||||
centers_length = centerCount;
|
||||
@@ -291,6 +377,9 @@ public:
|
||||
else if (centers_init_==FLANN_CENTERS_KMEANSPP) {
|
||||
chooseCenters = &HierarchicalClusteringIndex::chooseCentersKMeanspp;
|
||||
}
|
||||
else if (centers_init_==FLANN_CENTERS_GROUPWISE) {
|
||||
chooseCenters = &HierarchicalClusteringIndex::GroupWiseCenterChooser;
|
||||
}
|
||||
else {
|
||||
throw FLANNException("Unknown algorithm for choosing initial centers.");
|
||||
}
|
||||
@@ -414,12 +503,6 @@ public:
|
||||
|
||||
void loadIndex(FILE* stream)
|
||||
{
|
||||
load_value(stream, branching_);
|
||||
load_value(stream, trees_);
|
||||
load_value(stream, centers_init_);
|
||||
load_value(stream, leaf_size_);
|
||||
load_value(stream, memoryCounter);
|
||||
|
||||
free_elements();
|
||||
|
||||
if (root!=NULL) {
|
||||
@@ -430,6 +513,12 @@ public:
|
||||
delete[] indices;
|
||||
}
|
||||
|
||||
load_value(stream, branching_);
|
||||
load_value(stream, trees_);
|
||||
load_value(stream, centers_init_);
|
||||
load_value(stream, leaf_size_);
|
||||
load_value(stream, memoryCounter);
|
||||
|
||||
indices = new int*[trees_];
|
||||
root = new NodePtr[trees_];
|
||||
for (int i=0; i<trees_; ++i) {
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#define OPENCV_FLANN_KMEANS_INDEX_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
@@ -211,6 +210,7 @@ public:
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
closestDistSq[i] = distance_(dataset_[indices[i]], dataset_[indices[index]], dataset_.cols);
|
||||
closestDistSq[i] = ensureSquareDistance<Distance>( closestDistSq[i] );
|
||||
currentPot += closestDistSq[i];
|
||||
}
|
||||
|
||||
@@ -236,7 +236,10 @@ public:
|
||||
|
||||
// Compute the new potential
|
||||
double newPot = 0;
|
||||
for (int i = 0; i < n; i++) newPot += std::min( distance_(dataset_[indices[i]], dataset_[indices[index]], dataset_.cols), closestDistSq[i] );
|
||||
for (int i = 0; i < n; i++) {
|
||||
DistanceType dist = distance_(dataset_[indices[i]], dataset_[indices[index]], dataset_.cols);
|
||||
newPot += std::min( ensureSquareDistance<Distance>(dist), closestDistSq[i] );
|
||||
}
|
||||
|
||||
// Store the best result
|
||||
if ((bestNewPot < 0)||(newPot < bestNewPot)) {
|
||||
@@ -248,7 +251,10 @@ public:
|
||||
// Add the appropriate center
|
||||
centers[centerCount] = indices[bestNewIndex];
|
||||
currentPot = bestNewPot;
|
||||
for (int i = 0; i < n; i++) closestDistSq[i] = std::min( distance_(dataset_[indices[i]], dataset_[indices[bestNewIndex]], dataset_.cols), closestDistSq[i] );
|
||||
for (int i = 0; i < n; i++) {
|
||||
DistanceType dist = distance_(dataset_[indices[i]], dataset_[indices[bestNewIndex]], dataset_.cols);
|
||||
closestDistSq[i] = std::min( ensureSquareDistance<Distance>(dist), closestDistSq[i] );
|
||||
}
|
||||
}
|
||||
|
||||
centers_length = centerCount;
|
||||
@@ -265,6 +271,71 @@ public:
|
||||
return FLANN_INDEX_KMEANS;
|
||||
}
|
||||
|
||||
class KMeansDistanceComputer : public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
KMeansDistanceComputer(Distance _distance, const Matrix<ElementType>& _dataset,
|
||||
const int _branching, const int* _indices, const Matrix<double>& _dcenters, const size_t _veclen,
|
||||
int* _count, int* _belongs_to, std::vector<DistanceType>& _radiuses, bool& _converged, cv::Mutex& _mtx)
|
||||
: distance(_distance)
|
||||
, dataset(_dataset)
|
||||
, branching(_branching)
|
||||
, indices(_indices)
|
||||
, dcenters(_dcenters)
|
||||
, veclen(_veclen)
|
||||
, count(_count)
|
||||
, belongs_to(_belongs_to)
|
||||
, radiuses(_radiuses)
|
||||
, converged(_converged)
|
||||
, mtx(_mtx)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const cv::Range& range) const
|
||||
{
|
||||
const int begin = range.start;
|
||||
const int end = range.end;
|
||||
|
||||
for( int i = begin; i<end; ++i)
|
||||
{
|
||||
DistanceType sq_dist = distance(dataset[indices[i]], dcenters[0], veclen);
|
||||
int new_centroid = 0;
|
||||
for (int j=1; j<branching; ++j) {
|
||||
DistanceType new_sq_dist = distance(dataset[indices[i]], dcenters[j], veclen);
|
||||
if (sq_dist>new_sq_dist) {
|
||||
new_centroid = j;
|
||||
sq_dist = new_sq_dist;
|
||||
}
|
||||
}
|
||||
if (sq_dist > radiuses[new_centroid]) {
|
||||
radiuses[new_centroid] = sq_dist;
|
||||
}
|
||||
if (new_centroid != belongs_to[i]) {
|
||||
count[belongs_to[i]]--;
|
||||
count[new_centroid]++;
|
||||
belongs_to[i] = new_centroid;
|
||||
mtx.lock();
|
||||
converged = false;
|
||||
mtx.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Distance distance;
|
||||
const Matrix<ElementType>& dataset;
|
||||
const int branching;
|
||||
const int* indices;
|
||||
const Matrix<double>& dcenters;
|
||||
const size_t veclen;
|
||||
int* count;
|
||||
int* belongs_to;
|
||||
std::vector<DistanceType>& radiuses;
|
||||
bool& converged;
|
||||
cv::Mutex& mtx;
|
||||
KMeansDistanceComputer& operator=( const KMeansDistanceComputer & ) { return *this; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Index constructor
|
||||
*
|
||||
@@ -370,6 +441,8 @@ public:
|
||||
}
|
||||
|
||||
root_ = pool_.allocate<KMeansNode>();
|
||||
std::memset(root_, 0, sizeof(KMeansNode));
|
||||
|
||||
computeNodeStatistics(root_, indices_, (int)size_);
|
||||
computeClustering(root_, indices_, (int)size_, branching_,0);
|
||||
}
|
||||
@@ -652,7 +725,8 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
int* centers_idx = new int[branching];
|
||||
cv::AutoBuffer<int> centers_idx_buf(branching);
|
||||
int* centers_idx = (int*)centers_idx_buf;
|
||||
int centers_length;
|
||||
(this->*chooseCenters)(branching, indices, indices_length, centers_idx, centers_length);
|
||||
|
||||
@@ -660,29 +734,30 @@ private:
|
||||
node->indices = indices;
|
||||
std::sort(node->indices,node->indices+indices_length);
|
||||
node->childs = NULL;
|
||||
delete [] centers_idx;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Matrix<double> dcenters(new double[branching*veclen_],branching,veclen_);
|
||||
cv::AutoBuffer<double> dcenters_buf(branching*veclen_);
|
||||
Matrix<double> dcenters((double*)dcenters_buf,branching,veclen_);
|
||||
for (int i=0; i<centers_length; ++i) {
|
||||
ElementType* vec = dataset_[centers_idx[i]];
|
||||
for (size_t k=0; k<veclen_; ++k) {
|
||||
dcenters[i][k] = double(vec[k]);
|
||||
}
|
||||
}
|
||||
delete[] centers_idx;
|
||||
|
||||
std::vector<DistanceType> radiuses(branching);
|
||||
int* count = new int[branching];
|
||||
cv::AutoBuffer<int> count_buf(branching);
|
||||
int* count = (int*)count_buf;
|
||||
for (int i=0; i<branching; ++i) {
|
||||
radiuses[i] = 0;
|
||||
count[i] = 0;
|
||||
}
|
||||
|
||||
// assign points to clusters
|
||||
int* belongs_to = new int[indices_length];
|
||||
cv::AutoBuffer<int> belongs_to_buf(indices_length);
|
||||
int* belongs_to = (int*)belongs_to_buf;
|
||||
for (int i=0; i<indices_length; ++i) {
|
||||
|
||||
DistanceType sq_dist = distance_(dataset_[indices[i]], dcenters[0], veclen_);
|
||||
@@ -726,27 +801,9 @@ private:
|
||||
}
|
||||
|
||||
// reassign points to clusters
|
||||
for (int i=0; i<indices_length; ++i) {
|
||||
DistanceType sq_dist = distance_(dataset_[indices[i]], dcenters[0], veclen_);
|
||||
int new_centroid = 0;
|
||||
for (int j=1; j<branching; ++j) {
|
||||
DistanceType new_sq_dist = distance_(dataset_[indices[i]], dcenters[j], veclen_);
|
||||
if (sq_dist>new_sq_dist) {
|
||||
new_centroid = j;
|
||||
sq_dist = new_sq_dist;
|
||||
}
|
||||
}
|
||||
if (sq_dist>radiuses[new_centroid]) {
|
||||
radiuses[new_centroid] = sq_dist;
|
||||
}
|
||||
if (new_centroid != belongs_to[i]) {
|
||||
count[belongs_to[i]]--;
|
||||
count[new_centroid]++;
|
||||
belongs_to[i] = new_centroid;
|
||||
|
||||
converged = false;
|
||||
}
|
||||
}
|
||||
cv::Mutex mtx;
|
||||
KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, count, belongs_to, radiuses, converged, mtx);
|
||||
parallel_for_(cv::Range(0, (int)indices_length), invoker);
|
||||
|
||||
for (int i=0; i<branching; ++i) {
|
||||
// if one cluster converges to an empty cluster,
|
||||
@@ -759,10 +816,13 @@ private:
|
||||
|
||||
for (int k=0; k<indices_length; ++k) {
|
||||
if (belongs_to[k]==j) {
|
||||
belongs_to[k] = i;
|
||||
count[j]--;
|
||||
count[i]++;
|
||||
break;
|
||||
// for cluster j, we move the furthest element from the center to the empty cluster i
|
||||
if ( distance_(dataset_[indices[k]], dcenters[j], veclen_) == radiuses[j] ) {
|
||||
belongs_to[k] = i;
|
||||
count[j]--;
|
||||
count[i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
converged = false;
|
||||
@@ -806,19 +866,16 @@ private:
|
||||
variance -= distance_(centers[c], ZeroIterator<ElementType>(), veclen_);
|
||||
|
||||
node->childs[c] = pool_.allocate<KMeansNode>();
|
||||
std::memset(node->childs[c], 0, sizeof(KMeansNode));
|
||||
node->childs[c]->radius = radiuses[c];
|
||||
node->childs[c]->pivot = centers[c];
|
||||
node->childs[c]->variance = variance;
|
||||
node->childs[c]->mean_radius = mean_radius;
|
||||
node->childs[c]->indices = NULL;
|
||||
computeClustering(node->childs[c],indices+start, end-start, branching, level+1);
|
||||
start=end;
|
||||
}
|
||||
|
||||
delete[] dcenters.data;
|
||||
delete[] centers;
|
||||
delete[] count;
|
||||
delete[] belongs_to;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -153,8 +153,10 @@ public:
|
||||
* @param feature_size is the size of the feature (considered as a ElementType[])
|
||||
* @param key_size is the number of bits that are turned on in the feature
|
||||
*/
|
||||
LshTable(unsigned int /*feature_size*/, unsigned int /*key_size*/)
|
||||
LshTable(unsigned int feature_size, unsigned int key_size)
|
||||
{
|
||||
(void)feature_size;
|
||||
(void)key_size;
|
||||
std::cerr << "LSH is not implemented for that type" << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
@@ -263,12 +265,10 @@ private:
|
||||
{
|
||||
const size_t key_size_lower_bound = 1;
|
||||
//a value (size_t(1) << key_size) must fit the size_t type so key_size has to be strictly less than size of size_t
|
||||
const size_t key_size_upper_bound = std::min(sizeof(BucketKey) * CHAR_BIT + 1, sizeof(size_t) * CHAR_BIT);
|
||||
const size_t key_size_upper_bound = (std::min)(sizeof(BucketKey) * CHAR_BIT + 1, sizeof(size_t) * CHAR_BIT);
|
||||
if (key_size < key_size_lower_bound || key_size >= key_size_upper_bound)
|
||||
{
|
||||
std::stringstream errorMessage;
|
||||
errorMessage << "Invalid key_size (=" << key_size << "). Valid values for your system are " << key_size_lower_bound << " <= key_size < " << key_size_upper_bound << ".";
|
||||
CV_Error(CV_StsBadArg, errorMessage.str());
|
||||
CV_Error(cv::Error::StsBadArg, cv::format("Invalid key_size (=%d). Valid values for your system are %d <= key_size < %d.", (int)key_size, (int)key_size_lower_bound, (int)key_size_upper_bound));
|
||||
}
|
||||
|
||||
speed_level_ = kHash;
|
||||
|
||||
@@ -40,12 +40,10 @@
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef _OPENCV_MINIFLANN_HPP_
|
||||
#define _OPENCV_MINIFLANN_HPP_
|
||||
#ifndef OPENCV_MINIFLANN_HPP
|
||||
#define OPENCV_MINIFLANN_HPP
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/flann/defines.h"
|
||||
|
||||
namespace cv
|
||||
@@ -59,20 +57,20 @@ struct CV_EXPORTS IndexParams
|
||||
IndexParams();
|
||||
~IndexParams();
|
||||
|
||||
std::string getString(const std::string& key, const std::string& defaultVal=std::string()) const;
|
||||
int getInt(const std::string& key, int defaultVal=-1) const;
|
||||
double getDouble(const std::string& key, double defaultVal=-1) const;
|
||||
String getString(const String& key, const String& defaultVal=String()) const;
|
||||
int getInt(const String& key, int defaultVal=-1) const;
|
||||
double getDouble(const String& key, double defaultVal=-1) const;
|
||||
|
||||
void setString(const std::string& key, const std::string& value);
|
||||
void setInt(const std::string& key, int value);
|
||||
void setDouble(const std::string& key, double value);
|
||||
void setFloat(const std::string& key, float value);
|
||||
void setBool(const std::string& key, bool value);
|
||||
void setString(const String& key, const String& value);
|
||||
void setInt(const String& key, int value);
|
||||
void setDouble(const String& key, double value);
|
||||
void setFloat(const String& key, float value);
|
||||
void setBool(const String& key, bool value);
|
||||
void setAlgorithm(int value);
|
||||
|
||||
void getAll(std::vector<std::string>& names,
|
||||
void getAll(std::vector<String>& names,
|
||||
std::vector<int>& types,
|
||||
std::vector<std::string>& strValues,
|
||||
std::vector<String>& strValues,
|
||||
std::vector<double>& numValues) const;
|
||||
|
||||
void* params;
|
||||
@@ -91,13 +89,13 @@ struct CV_EXPORTS LinearIndexParams : public IndexParams
|
||||
struct CV_EXPORTS CompositeIndexParams : public IndexParams
|
||||
{
|
||||
CompositeIndexParams(int trees = 4, int branching = 32, int iterations = 11,
|
||||
cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, float cb_index = 0.2 );
|
||||
cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, float cb_index = 0.2f );
|
||||
};
|
||||
|
||||
struct CV_EXPORTS AutotunedIndexParams : public IndexParams
|
||||
{
|
||||
AutotunedIndexParams(float target_precision = 0.8, float build_weight = 0.01,
|
||||
float memory_weight = 0, float sample_fraction = 0.1);
|
||||
AutotunedIndexParams(float target_precision = 0.8f, float build_weight = 0.01f,
|
||||
float memory_weight = 0, float sample_fraction = 0.1f);
|
||||
};
|
||||
|
||||
struct CV_EXPORTS HierarchicalClusteringIndexParams : public IndexParams
|
||||
@@ -109,7 +107,7 @@ struct CV_EXPORTS HierarchicalClusteringIndexParams : public IndexParams
|
||||
struct CV_EXPORTS KMeansIndexParams : public IndexParams
|
||||
{
|
||||
KMeansIndexParams(int branching = 32, int iterations = 11,
|
||||
cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, float cb_index = 0.2 );
|
||||
cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, float cb_index = 0.2f );
|
||||
};
|
||||
|
||||
struct CV_EXPORTS LshIndexParams : public IndexParams
|
||||
@@ -119,7 +117,7 @@ struct CV_EXPORTS LshIndexParams : public IndexParams
|
||||
|
||||
struct CV_EXPORTS SavedIndexParams : public IndexParams
|
||||
{
|
||||
SavedIndexParams(const std::string& filename);
|
||||
SavedIndexParams(const String& filename);
|
||||
};
|
||||
|
||||
struct CV_EXPORTS SearchParams : public IndexParams
|
||||
@@ -142,8 +140,8 @@ public:
|
||||
OutputArray dists, double radius, int maxResults,
|
||||
const SearchParams& params=SearchParams());
|
||||
|
||||
CV_WRAP virtual void save(const std::string& filename) const;
|
||||
CV_WRAP virtual bool load(InputArray features, const std::string& filename);
|
||||
CV_WRAP virtual void save(const String& filename) const;
|
||||
CV_WRAP virtual bool load(InputArray features, const String& filename);
|
||||
CV_WRAP virtual void release();
|
||||
CV_WRAP cvflann::flann_distance_t getDistance() const;
|
||||
CV_WRAP cvflann::flann_algorithm_t getAlgorithm() const;
|
||||
@@ -157,6 +155,4 @@ protected:
|
||||
|
||||
} } // namespace cv::flann
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
#ifndef OPENCV_FLANN_NNINDEX_H
|
||||
#define OPENCV_FLANN_NNINDEX_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "general.h"
|
||||
#include "matrix.h"
|
||||
#include "result_set.h"
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
typedef std::map<std::string, any> IndexParams;
|
||||
typedef std::map<cv::String, any> IndexParams;
|
||||
|
||||
struct SearchParams : public IndexParams
|
||||
{
|
||||
@@ -56,7 +56,7 @@ struct SearchParams : public IndexParams
|
||||
|
||||
|
||||
template<typename T>
|
||||
T get_param(const IndexParams& params, std::string name, const T& default_value)
|
||||
T get_param(const IndexParams& params, cv::String name, const T& default_value)
|
||||
{
|
||||
IndexParams::const_iterator it = params.find(name);
|
||||
if (it != params.end()) {
|
||||
@@ -68,28 +68,31 @@ T get_param(const IndexParams& params, std::string name, const T& default_value)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T get_param(const IndexParams& params, std::string name)
|
||||
T get_param(const IndexParams& params, cv::String name)
|
||||
{
|
||||
IndexParams::const_iterator it = params.find(name);
|
||||
if (it != params.end()) {
|
||||
return it->second.cast<T>();
|
||||
}
|
||||
else {
|
||||
throw FLANNException(std::string("Missing parameter '")+name+std::string("' in the parameters given"));
|
||||
throw FLANNException(cv::String("Missing parameter '")+name+cv::String("' in the parameters given"));
|
||||
}
|
||||
}
|
||||
|
||||
inline void print_params(const IndexParams& params, std::ostream& stream)
|
||||
{
|
||||
IndexParams::const_iterator it;
|
||||
|
||||
for(it=params.begin(); it!=params.end(); ++it) {
|
||||
stream << it->first << " : " << it->second << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
inline void print_params(const IndexParams& params)
|
||||
{
|
||||
IndexParams::const_iterator it;
|
||||
|
||||
for(it=params.begin(); it!=params.end(); ++it) {
|
||||
std::cout << it->first << " : " << it->second << std::endl;
|
||||
}
|
||||
print_params(params, std::cout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -449,7 +449,7 @@ class RadiusUniqueResultSet : public UniqueResultSet<DistanceType>
|
||||
{
|
||||
public:
|
||||
/** Constructor
|
||||
* @param capacity the number of neighbors to store at max
|
||||
* @param radius the maximum distance of a neighbor
|
||||
*/
|
||||
RadiusUniqueResultSet(DistanceType radius) :
|
||||
radius_(radius)
|
||||
@@ -509,6 +509,7 @@ 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)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
#define OPENCV_FLANN_TIMER_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
@@ -44,7 +45,7 @@ namespace cvflann
|
||||
*/
|
||||
class StartStopTimer
|
||||
{
|
||||
clock_t startTime;
|
||||
int64 startTime;
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -66,7 +67,7 @@ public:
|
||||
*/
|
||||
void start()
|
||||
{
|
||||
startTime = clock();
|
||||
startTime = cv::getTickCount();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,8 +75,8 @@ public:
|
||||
*/
|
||||
void stop()
|
||||
{
|
||||
clock_t stopTime = clock();
|
||||
value += ( (double)stopTime - startTime) / CLOCKS_PER_SEC;
|
||||
int64 stopTime = cv::getTickCount();
|
||||
value += ( (double)stopTime - startTime) / cv::getTickFrequency();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user