Updated FLANN to version 1.5
This commit is contained in:
1
3rdparty/CMakeLists.txt
vendored
1
3rdparty/CMakeLists.txt
vendored
@@ -2,7 +2,6 @@ if(ANDROID)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/Android.mk.modules.in" "${CMAKE_CURRENT_BINARY_DIR}/Android.mk")
|
||||
endif()
|
||||
|
||||
add_subdirectory(flann)
|
||||
add_subdirectory(lapack)
|
||||
add_subdirectory(zlib)
|
||||
if(WITH_JASPER AND NOT JASPER_FOUND)
|
||||
|
107
3rdparty/flann/CMakeLists.txt
vendored
107
3rdparty/flann/CMakeLists.txt
vendored
@@ -1,107 +0,0 @@
|
||||
if(ANDROID)
|
||||
file(GLOB_RECURSE flann_sources_cpp *.cpp)
|
||||
define_android_manual(flann "${flann_sources_cpp}" "$(LOCAL_PATH)/../include $(LOCAL_PATH)/../include/flann")
|
||||
else(ANDROID)
|
||||
if (DEFINED OPENCV_VERSION)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# CMake file for libflann. See root CMakeLists.txt
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
project(flann)
|
||||
|
||||
# List of C++ files:
|
||||
|
||||
#set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/flann"
|
||||
)
|
||||
|
||||
# The .cpp files:
|
||||
file(GLOB flann_sources *.cpp *.h *.hpp)
|
||||
file(GLOB flann_h "${CMAKE_CURRENT_SOURCE_DIR}/../include/flann/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/../include/flann/*.hpp")
|
||||
|
||||
source_group("Src" FILES ${flann_sources})
|
||||
source_group("Include" FILES ${flann_h})
|
||||
|
||||
set(flann_sources ${flann_sources} ${flann_h})
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
# Define the library target:
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
set(the_target "flann")
|
||||
|
||||
add_library(${the_target} STATIC ${flann_sources})
|
||||
add_definitions(-Dflann_EXPORTS)
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
|
||||
add_definitions(-DJAS_WIN_MSVC_BUILD)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set_target_properties(${the_target}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${the_target}"
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/lib"
|
||||
)
|
||||
|
||||
ELSE()
|
||||
|
||||
INCLUDE_DIRECTORIES(algorithms util nn .)
|
||||
|
||||
ADD_SUBDIRECTORY( tests )
|
||||
|
||||
file(GLOB_RECURSE SOURCES *.cpp)
|
||||
#SET(SOURCES flann.cpp util/Random.cpp nn/Testing.cpp algorithms/NNIndex.cpp algorithms/dist.cpp util/Logger.cpp util/Saving.cpp)
|
||||
|
||||
ADD_LIBRARY(flann ${SOURCES})
|
||||
#ADD_LIBRARY(flann SHARED ${SOURCES}) #JL: Why the two versions??
|
||||
#ADD_LIBRARY(flann_s STATIC ${SOURCES})
|
||||
|
||||
IF(WIN32)
|
||||
INSTALL (
|
||||
TARGETS flann
|
||||
RUNTIME DESTINATION matlab
|
||||
)
|
||||
INSTALL (
|
||||
TARGETS flann
|
||||
RUNTIME DESTINATION python/pyflann/bindings
|
||||
)
|
||||
ELSE(WIN32)
|
||||
INSTALL (
|
||||
TARGETS flann
|
||||
LIBRARY DESTINATION python/pyflann/bindings
|
||||
)
|
||||
ENDIF(WIN32)
|
||||
|
||||
INSTALL (
|
||||
TARGETS flann # flann_s
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
|
||||
# INSTALL (
|
||||
# TARGETS flann flann_s
|
||||
# ARCHIVE DESTINATION ${PROJECT_SOURCE_DIR}/python
|
||||
# LIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/python
|
||||
# )
|
||||
|
||||
INSTALL (
|
||||
FILES flann.h constants.h
|
||||
DESTINATION include
|
||||
)
|
||||
|
||||
ENDIF()
|
||||
endif(ANDROID)#android
|
188
3rdparty/flann/allocator.h
vendored
188
3rdparty/flann/allocator.h
vendored
@@ -1,188 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 ALLOCATOR_H
|
||||
#define ALLOCATOR_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/**
|
||||
* Allocates (using C's malloc) a generic type T.
|
||||
*
|
||||
* Params:
|
||||
* count = number of instances to allocate.
|
||||
* Returns: pointer (of type T*) to memory buffer
|
||||
*/
|
||||
template <typename T>
|
||||
T* allocate(size_t count = 1)
|
||||
{
|
||||
T* mem = (T*) ::malloc(sizeof(T)*count);
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pooled storage allocator
|
||||
*
|
||||
* The following routines allow for the efficient allocation of storage in
|
||||
* small chunks from a specified pool. Rather than allowing each structure
|
||||
* to be freed individually, an entire pool of storage is freed at once.
|
||||
* This method has two advantages over just using malloc() and free(). First,
|
||||
* it is far more efficient for allocating small objects, as there is
|
||||
* no overhead for remembering all the information needed to free each
|
||||
* object or consolidating fragmented memory. Second, the decision about
|
||||
* how long to keep an object is made at the time of allocation, and there
|
||||
* is no need to track down all the objects to free them.
|
||||
*
|
||||
*/
|
||||
|
||||
const size_t WORDSIZE=16;
|
||||
const size_t BLOCKSIZE=8192;
|
||||
|
||||
class PooledAllocator
|
||||
{
|
||||
/* We maintain memory alignment to word boundaries by requiring that all
|
||||
allocations be in multiples of the machine wordsize. */
|
||||
/* Size of machine word in bytes. Must be power of 2. */
|
||||
/* Minimum number of bytes requested at a time from the system. Must be multiple of WORDSIZE. */
|
||||
|
||||
|
||||
int remaining; /* Number of bytes left in current block of storage. */
|
||||
void* base; /* Pointer to base of current block of storage. */
|
||||
void* loc; /* Current location in block to next allocate memory. */
|
||||
int blocksize;
|
||||
|
||||
|
||||
public:
|
||||
int usedMemory;
|
||||
int wastedMemory;
|
||||
|
||||
/**
|
||||
Default constructor. Initializes a new pool.
|
||||
*/
|
||||
PooledAllocator(int blocksize = BLOCKSIZE)
|
||||
{
|
||||
this->blocksize = blocksize;
|
||||
remaining = 0;
|
||||
base = NULL;
|
||||
|
||||
usedMemory = 0;
|
||||
wastedMemory = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor. Frees all the memory allocated in this pool.
|
||||
*/
|
||||
~PooledAllocator()
|
||||
{
|
||||
void *prev;
|
||||
|
||||
while (base != NULL) {
|
||||
prev = *((void **) base); /* Get pointer to prev block. */
|
||||
::free(base);
|
||||
base = prev;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to a piece of new memory of the given size in bytes
|
||||
* allocated from the pool.
|
||||
*/
|
||||
void* malloc(int size)
|
||||
{
|
||||
int blocksize;
|
||||
|
||||
/* Round size up to a multiple of wordsize. The following expression
|
||||
only works for WORDSIZE that is a power of 2, by masking last bits of
|
||||
incremented size to zero.
|
||||
*/
|
||||
size = (size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
|
||||
|
||||
/* Check whether a new block must be allocated. Note that the first word
|
||||
of a block is reserved for a pointer to the previous block.
|
||||
*/
|
||||
if (size > remaining) {
|
||||
|
||||
wastedMemory += remaining;
|
||||
|
||||
/* Allocate new storage. */
|
||||
blocksize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ?
|
||||
size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE;
|
||||
|
||||
// use the standard C malloc to allocate memory
|
||||
void* m = ::malloc(blocksize);
|
||||
if (!m) {
|
||||
fprintf(stderr,"Failed to allocate memory.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Fill first word of new block with pointer to previous block. */
|
||||
((void **) m)[0] = base;
|
||||
base = m;
|
||||
|
||||
int shift = 0;
|
||||
//int shift = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1);
|
||||
|
||||
remaining = blocksize - sizeof(void*) - shift;
|
||||
loc = ((char*)m + sizeof(void*) + shift);
|
||||
}
|
||||
void* rloc = loc;
|
||||
loc = (char*)loc + size;
|
||||
remaining -= size;
|
||||
|
||||
usedMemory += size;
|
||||
|
||||
return rloc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates (using this pool) a generic type T.
|
||||
*
|
||||
* Params:
|
||||
* count = number of instances to allocate.
|
||||
* Returns: pointer (of type T*) to memory buffer
|
||||
*/
|
||||
template <typename T>
|
||||
T* allocate(size_t count = 1)
|
||||
{
|
||||
T* mem = (T*) this->malloc((int)(sizeof(T)*count));
|
||||
return mem;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //ALLOCATOR_H
|
571
3rdparty/flann/autotuned_index.h
vendored
571
3rdparty/flann/autotuned_index.h
vendored
@@ -1,571 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 AUTOTUNEDINDEX_H_
|
||||
#define AUTOTUNEDINDEX_H_
|
||||
|
||||
#include "constants.h"
|
||||
#include "nn_index.h"
|
||||
#include "ground_truth.h"
|
||||
#include "index_testing.h"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
class AutotunedIndex : public NNIndex
|
||||
{
|
||||
NNIndex* bestIndex;
|
||||
IndexParams* bestParams;
|
||||
SearchParams bestSearchParams;
|
||||
|
||||
Matrix<float>* sampledDataset;
|
||||
Matrix<float>* testDataset;
|
||||
Matrix<int>* gt_matches;
|
||||
|
||||
float speedup;
|
||||
|
||||
/**
|
||||
* The dataset used by this index
|
||||
*/
|
||||
const Matrix<float> dataset;
|
||||
|
||||
/**
|
||||
* Index parameters
|
||||
*/
|
||||
const AutotunedIndexParams& params;
|
||||
|
||||
/**
|
||||
* Number of features in the dataset.
|
||||
*/
|
||||
int size_;
|
||||
|
||||
/**
|
||||
* Length of each feature.
|
||||
*/
|
||||
int veclen_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
AutotunedIndex(const Matrix<float>& inputData, const AutotunedIndexParams& params_ = AutotunedIndexParams() ) :
|
||||
dataset(inputData), params(params_)
|
||||
{
|
||||
size_ = dataset.rows;
|
||||
veclen_ = dataset.cols;
|
||||
|
||||
bestIndex = NULL;
|
||||
|
||||
}
|
||||
|
||||
virtual ~AutotunedIndex()
|
||||
{
|
||||
delete bestIndex;
|
||||
delete bestParams;
|
||||
};
|
||||
|
||||
/**
|
||||
Method responsible with building the index.
|
||||
*/
|
||||
virtual void buildIndex()
|
||||
{
|
||||
bestParams = estimateBuildParams();
|
||||
bestIndex = bestParams->createIndex(dataset);
|
||||
bestIndex->buildIndex();
|
||||
speedup = estimateSearchParams(bestSearchParams);
|
||||
}
|
||||
|
||||
/**
|
||||
Saves the index to a stream
|
||||
*/
|
||||
virtual void saveIndex(FILE* stream)
|
||||
{
|
||||
bestIndex->saveIndex(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
Loads the index from a stream
|
||||
*/
|
||||
virtual void loadIndex(FILE* stream)
|
||||
{
|
||||
bestIndex->loadIndex(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
Method that searches for nearest-neighbors
|
||||
*/
|
||||
virtual void findNeighbors(ResultSet& result, const float* vec, const SearchParams& /*searchParams*/)
|
||||
{
|
||||
bestIndex->findNeighbors(result, vec, bestSearchParams);
|
||||
}
|
||||
|
||||
/**
|
||||
Number of features in this index.
|
||||
*/
|
||||
virtual int size() const
|
||||
{
|
||||
return bestIndex->size();
|
||||
}
|
||||
|
||||
/**
|
||||
The length of each vector in this index.
|
||||
*/
|
||||
virtual int veclen() const
|
||||
{
|
||||
return bestIndex->veclen();
|
||||
}
|
||||
|
||||
/**
|
||||
The amount of memory (in bytes) this index uses.
|
||||
*/
|
||||
virtual int usedMemory() const
|
||||
{
|
||||
return bestIndex->usedMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Algorithm name
|
||||
*/
|
||||
virtual flann_algorithm_t getType() const
|
||||
{
|
||||
return bestIndex->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
Estimates the search parameters required in order to get a certain precision.
|
||||
If testset is not given it uses cross-validation.
|
||||
*/
|
||||
// virtual Params estimateSearchParams(float precision, Dataset<float>* testset = NULL)
|
||||
// {
|
||||
// Params params;
|
||||
//
|
||||
// return params;
|
||||
// }
|
||||
private:
|
||||
|
||||
struct CostData {
|
||||
float searchTimeCost;
|
||||
float buildTimeCost;
|
||||
float timeCost;
|
||||
float memoryCost;
|
||||
float totalCost;
|
||||
};
|
||||
|
||||
typedef pair<CostData, KDTreeIndexParams> KDTreeCostData;
|
||||
typedef pair<CostData, KMeansIndexParams> KMeansCostData;
|
||||
|
||||
|
||||
void evaluate_kmeans(CostData& cost, const KMeansIndexParams& kmeans_params)
|
||||
{
|
||||
StartStopTimer t;
|
||||
int checks;
|
||||
const int nn = 1;
|
||||
|
||||
logger.info("KMeansTree using params: max_iterations=%d, branching=%d\n", kmeans_params.iterations, kmeans_params.branching);
|
||||
KMeansIndex kmeans(*sampledDataset, kmeans_params);
|
||||
// measure index build time
|
||||
t.start();
|
||||
kmeans.buildIndex();
|
||||
t.stop();
|
||||
float buildTime = (float)t.value;
|
||||
|
||||
// measure search time
|
||||
float searchTime = test_index_precision(kmeans, *sampledDataset, *testDataset, *gt_matches, params.target_precision, checks, nn);;
|
||||
|
||||
float datasetMemory = (float)(sampledDataset->rows*sampledDataset->cols*sizeof(float));
|
||||
cost.memoryCost = (kmeans.usedMemory()+datasetMemory)/datasetMemory;
|
||||
cost.searchTimeCost = searchTime;
|
||||
cost.buildTimeCost = buildTime;
|
||||
cost.timeCost = (buildTime*params.build_weight+searchTime);
|
||||
logger.info("KMeansTree buildTime=%g, searchTime=%g, timeCost=%g, buildTimeFactor=%g\n",buildTime, searchTime, cost.timeCost, params.build_weight);
|
||||
}
|
||||
|
||||
|
||||
void evaluate_kdtree(CostData& cost, const KDTreeIndexParams& kdtree_params)
|
||||
{
|
||||
StartStopTimer t;
|
||||
int checks;
|
||||
const int nn = 1;
|
||||
|
||||
logger.info("KDTree using params: trees=%d\n",kdtree_params.trees);
|
||||
KDTreeIndex kdtree(*sampledDataset, kdtree_params);
|
||||
|
||||
t.start();
|
||||
kdtree.buildIndex();
|
||||
t.stop();
|
||||
float buildTime = (float)t.value;
|
||||
|
||||
//measure search time
|
||||
float searchTime = test_index_precision(kdtree, *sampledDataset, *testDataset, *gt_matches, params.target_precision, checks, nn);
|
||||
|
||||
float datasetMemory = (float)(sampledDataset->rows*sampledDataset->cols*sizeof(float));
|
||||
cost.memoryCost = (kdtree.usedMemory()+datasetMemory)/datasetMemory;
|
||||
cost.searchTimeCost = searchTime;
|
||||
cost.buildTimeCost = buildTime;
|
||||
cost.timeCost = (buildTime*params.build_weight+searchTime);
|
||||
logger.info("KDTree buildTime=%g, searchTime=%g, timeCost=%g\n",buildTime, searchTime, cost.timeCost);
|
||||
}
|
||||
|
||||
|
||||
// struct KMeansSimpleDownhillFunctor {
|
||||
//
|
||||
// Autotune& autotuner;
|
||||
// KMeansSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {};
|
||||
//
|
||||
// float operator()(int* params) {
|
||||
//
|
||||
// float maxFloat = numeric_limits<float>::max();
|
||||
//
|
||||
// if (params[0]<2) return maxFloat;
|
||||
// if (params[1]<0) return maxFloat;
|
||||
//
|
||||
// CostData c;
|
||||
// c.params["algorithm"] = KMEANS;
|
||||
// c.params["centers-init"] = CENTERS_RANDOM;
|
||||
// c.params["branching"] = params[0];
|
||||
// c.params["max-iterations"] = params[1];
|
||||
//
|
||||
// autotuner.evaluate_kmeans(c);
|
||||
//
|
||||
// return c.timeCost;
|
||||
//
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// struct KDTreeSimpleDownhillFunctor {
|
||||
//
|
||||
// Autotune& autotuner;
|
||||
// KDTreeSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {};
|
||||
//
|
||||
// float operator()(int* params) {
|
||||
// float maxFloat = numeric_limits<float>::max();
|
||||
//
|
||||
// if (params[0]<1) return maxFloat;
|
||||
//
|
||||
// CostData c;
|
||||
// c.params["algorithm"] = KDTREE;
|
||||
// c.params["trees"] = params[0];
|
||||
//
|
||||
// autotuner.evaluate_kdtree(c);
|
||||
//
|
||||
// return c.timeCost;
|
||||
//
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
|
||||
KMeansCostData optimizeKMeans()
|
||||
{
|
||||
logger.info("KMEANS, Step 1: Exploring parameter space\n");
|
||||
|
||||
// explore kmeans parameters space using combinations of the parameters below
|
||||
int maxIterations[] = { 1, 5, 10, 15 };
|
||||
int branchingFactors[] = { 16, 32, 64, 128, 256 };
|
||||
|
||||
int kmeansParamSpaceSize = ARRAY_LEN(maxIterations)*ARRAY_LEN(branchingFactors);
|
||||
|
||||
vector<KMeansCostData> kmeansCosts(kmeansParamSpaceSize);
|
||||
|
||||
// CostData* kmeansCosts = new CostData[kmeansParamSpaceSize];
|
||||
|
||||
// evaluate kmeans for all parameter combinations
|
||||
int cnt = 0;
|
||||
for (size_t i=0; i<ARRAY_LEN(maxIterations); ++i) {
|
||||
for (size_t j=0; j<ARRAY_LEN(branchingFactors); ++j) {
|
||||
|
||||
kmeansCosts[cnt].second.centers_init = CENTERS_RANDOM;
|
||||
kmeansCosts[cnt].second.branching = branchingFactors[j];
|
||||
kmeansCosts[cnt].second.iterations = maxIterations[j];
|
||||
|
||||
evaluate_kmeans(kmeansCosts[cnt].first, kmeansCosts[cnt].second);
|
||||
|
||||
int k = cnt;
|
||||
// order by time cost
|
||||
while (k>0 && kmeansCosts[k].first.timeCost < kmeansCosts[k-1].first.timeCost) {
|
||||
swap(kmeansCosts[k],kmeansCosts[k-1]);
|
||||
--k;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
|
||||
// logger.info("KMEANS, Step 2: simplex-downhill optimization\n");
|
||||
//
|
||||
// const int n = 2;
|
||||
// // choose initial simplex points as the best parameters so far
|
||||
// int kmeansNMPoints[n*(n+1)];
|
||||
// float kmeansVals[n+1];
|
||||
// for (int i=0;i<n+1;++i) {
|
||||
// kmeansNMPoints[i*n] = (int)kmeansCosts[i].params["branching"];
|
||||
// kmeansNMPoints[i*n+1] = (int)kmeansCosts[i].params["max-iterations"];
|
||||
// kmeansVals[i] = kmeansCosts[i].timeCost;
|
||||
// }
|
||||
// KMeansSimpleDownhillFunctor kmeans_cost_func(*this);
|
||||
// // run optimization
|
||||
// optimizeSimplexDownhill(kmeansNMPoints,n,kmeans_cost_func,kmeansVals);
|
||||
// // store results
|
||||
// for (int i=0;i<n+1;++i) {
|
||||
// kmeansCosts[i].params["branching"] = kmeansNMPoints[i*2];
|
||||
// kmeansCosts[i].params["max-iterations"] = kmeansNMPoints[i*2+1];
|
||||
// kmeansCosts[i].timeCost = kmeansVals[i];
|
||||
// }
|
||||
|
||||
float optTimeCost = kmeansCosts[0].first.timeCost;
|
||||
// recompute total costs factoring in the memory costs
|
||||
for (int i=0;i<kmeansParamSpaceSize;++i) {
|
||||
kmeansCosts[i].first.totalCost = (kmeansCosts[i].first.timeCost/optTimeCost + params.memory_weight * kmeansCosts[i].first.memoryCost);
|
||||
|
||||
int k = i;
|
||||
while (k>0 && kmeansCosts[k].first.totalCost < kmeansCosts[k-1].first.totalCost) {
|
||||
swap(kmeansCosts[k],kmeansCosts[k-1]);
|
||||
k--;
|
||||
}
|
||||
}
|
||||
// display the costs obtained
|
||||
for (int i=0;i<kmeansParamSpaceSize;++i) {
|
||||
logger.info("KMeans, branching=%d, iterations=%d, time_cost=%g[%g] (build=%g, search=%g), memory_cost=%g, cost=%g\n",
|
||||
kmeansCosts[i].second.branching, kmeansCosts[i].second.iterations,
|
||||
kmeansCosts[i].first.timeCost,kmeansCosts[i].first.timeCost/optTimeCost,
|
||||
kmeansCosts[i].first.buildTimeCost, kmeansCosts[i].first.searchTimeCost,
|
||||
kmeansCosts[i].first.memoryCost,kmeansCosts[i].first.totalCost);
|
||||
}
|
||||
|
||||
return kmeansCosts[0];
|
||||
}
|
||||
|
||||
|
||||
KDTreeCostData optimizeKDTree()
|
||||
{
|
||||
|
||||
logger.info("KD-TREE, Step 1: Exploring parameter space\n");
|
||||
|
||||
// explore kd-tree parameters space using the parameters below
|
||||
int testTrees[] = { 1, 4, 8, 16, 32 };
|
||||
|
||||
size_t kdtreeParamSpaceSize = ARRAY_LEN(testTrees);
|
||||
vector<KDTreeCostData> kdtreeCosts(kdtreeParamSpaceSize);
|
||||
|
||||
// evaluate kdtree for all parameter combinations
|
||||
int cnt = 0;
|
||||
for (size_t i=0; i<ARRAY_LEN(testTrees); ++i) {
|
||||
kdtreeCosts[cnt].second.trees = testTrees[i];
|
||||
|
||||
evaluate_kdtree(kdtreeCosts[cnt].first, kdtreeCosts[cnt].second);
|
||||
|
||||
int k = cnt;
|
||||
// order by time cost
|
||||
while (k>0 && kdtreeCosts[k].first.timeCost < kdtreeCosts[k-1].first.timeCost) {
|
||||
swap(kdtreeCosts[k],kdtreeCosts[k-1]);
|
||||
--k;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
|
||||
// logger.info("KD-TREE, Step 2: simplex-downhill optimization\n");
|
||||
//
|
||||
// const int n = 1;
|
||||
// // choose initial simplex points as the best parameters so far
|
||||
// int kdtreeNMPoints[n*(n+1)];
|
||||
// float kdtreeVals[n+1];
|
||||
// for (int i=0;i<n+1;++i) {
|
||||
// kdtreeNMPoints[i] = (int)kdtreeCosts[i].params["trees"];
|
||||
// kdtreeVals[i] = kdtreeCosts[i].timeCost;
|
||||
// }
|
||||
// KDTreeSimpleDownhillFunctor kdtree_cost_func(*this);
|
||||
// // run optimization
|
||||
// optimizeSimplexDownhill(kdtreeNMPoints,n,kdtree_cost_func,kdtreeVals);
|
||||
// // store results
|
||||
// for (int i=0;i<n+1;++i) {
|
||||
// kdtreeCosts[i].params["trees"] = kdtreeNMPoints[i];
|
||||
// kdtreeCosts[i].timeCost = kdtreeVals[i];
|
||||
// }
|
||||
|
||||
float optTimeCost = kdtreeCosts[0].first.timeCost;
|
||||
// recompute costs for kd-tree factoring in memory cost
|
||||
for (size_t i=0;i<kdtreeParamSpaceSize;++i) {
|
||||
kdtreeCosts[i].first.totalCost = (kdtreeCosts[i].first.timeCost/optTimeCost + params.memory_weight * kdtreeCosts[i].first.memoryCost);
|
||||
|
||||
int k = i;
|
||||
while (k>0 && kdtreeCosts[k].first.totalCost < kdtreeCosts[k-1].first.totalCost) {
|
||||
swap(kdtreeCosts[k],kdtreeCosts[k-1]);
|
||||
k--;
|
||||
}
|
||||
}
|
||||
// display costs obtained
|
||||
for (size_t i=0;i<kdtreeParamSpaceSize;++i) {
|
||||
logger.info("kd-tree, trees=%d, time_cost=%g[%g] (build=%g, search=%g), memory_cost=%g, cost=%g\n",
|
||||
kdtreeCosts[i].second.trees,kdtreeCosts[i].first.timeCost,kdtreeCosts[i].first.timeCost/optTimeCost,
|
||||
kdtreeCosts[i].first.buildTimeCost, kdtreeCosts[i].first.searchTimeCost,
|
||||
kdtreeCosts[i].first.memoryCost,kdtreeCosts[i].first.totalCost);
|
||||
}
|
||||
|
||||
return kdtreeCosts[0];
|
||||
}
|
||||
|
||||
/**
|
||||
Chooses the best nearest-neighbor algorithm and estimates the optimal
|
||||
parameters to use when building the index (for a given precision).
|
||||
Returns a dictionary with the optimal parameters.
|
||||
*/
|
||||
IndexParams* estimateBuildParams()
|
||||
{
|
||||
int sampleSize = int(params.sample_fraction*dataset.rows);
|
||||
int testSampleSize = min(sampleSize/10, 1000);
|
||||
|
||||
logger.info("Entering autotuning, dataset size: %d, sampleSize: %d, testSampleSize: %d\n",dataset.rows, sampleSize, testSampleSize);
|
||||
|
||||
// For a very small dataset, it makes no sense to build any fancy index, just
|
||||
// use linear search
|
||||
if (testSampleSize<10) {
|
||||
logger.info("Choosing linear, dataset too small\n");
|
||||
return new LinearIndexParams();
|
||||
}
|
||||
|
||||
// We use a fraction of the original dataset to speedup the autotune algorithm
|
||||
sampledDataset = dataset.sample(sampleSize);
|
||||
// We use a cross-validation approach, first we sample a testset from the dataset
|
||||
testDataset = sampledDataset->sample(testSampleSize,true);
|
||||
|
||||
// We compute the ground truth using linear search
|
||||
logger.info("Computing ground truth... \n");
|
||||
gt_matches = new Matrix<int>(testDataset->rows, 1);
|
||||
StartStopTimer t;
|
||||
t.start();
|
||||
compute_ground_truth(*sampledDataset, *testDataset, *gt_matches, 0);
|
||||
t.stop();
|
||||
float bestCost = (float)t.value;
|
||||
IndexParams* bestParams = new LinearIndexParams();
|
||||
|
||||
// Start parameter autotune process
|
||||
logger.info("Autotuning parameters...\n");
|
||||
|
||||
|
||||
KMeansCostData kmeansCost = optimizeKMeans();
|
||||
|
||||
if (kmeansCost.first.totalCost<bestCost) {
|
||||
bestParams = new KMeansIndexParams(kmeansCost.second);
|
||||
bestCost = kmeansCost.first.totalCost;
|
||||
}
|
||||
|
||||
KDTreeCostData kdtreeCost = optimizeKDTree();
|
||||
|
||||
if (kdtreeCost.first.totalCost<bestCost) {
|
||||
bestParams = new KDTreeIndexParams(kdtreeCost.second);
|
||||
bestCost = kdtreeCost.first.totalCost;
|
||||
}
|
||||
|
||||
// free the memory used by the datasets we sampled
|
||||
delete sampledDataset;
|
||||
delete testDataset;
|
||||
delete gt_matches;
|
||||
|
||||
return bestParams;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Estimates the search time parameters needed to get the desired precision.
|
||||
Precondition: the index is built
|
||||
Postcondition: the searchParams will have the optimum params set, also the speedup obtained over linear search.
|
||||
*/
|
||||
float estimateSearchParams(SearchParams& searchParams)
|
||||
{
|
||||
const int nn = 1;
|
||||
const long SAMPLE_COUNT = 1000;
|
||||
|
||||
assert(bestIndex!=NULL); // must have a valid index
|
||||
|
||||
float speedup = 0;
|
||||
|
||||
int samples = min(dataset.rows/10, SAMPLE_COUNT);
|
||||
if (samples>0) {
|
||||
Matrix<float>* testDataset = dataset.sample(samples);
|
||||
|
||||
logger.info("Computing ground truth\n");
|
||||
|
||||
// we need to compute the ground truth first
|
||||
Matrix<int> gt_matches(testDataset->rows,1);
|
||||
StartStopTimer t;
|
||||
t.start();
|
||||
compute_ground_truth(dataset, *testDataset, gt_matches,1);
|
||||
t.stop();
|
||||
float linear = (float)t.value;
|
||||
|
||||
int checks;
|
||||
logger.info("Estimating number of checks\n");
|
||||
|
||||
float searchTime;
|
||||
float cb_index;
|
||||
if (bestIndex->getType() == KMEANS) {
|
||||
|
||||
logger.info("KMeans algorithm, estimating cluster border factor\n");
|
||||
KMeansIndex* kmeans = (KMeansIndex*)bestIndex;
|
||||
float bestSearchTime = -1;
|
||||
float best_cb_index = -1;
|
||||
int best_checks = -1;
|
||||
for (cb_index = 0;cb_index<1.1f; cb_index+=0.2f) {
|
||||
kmeans->set_cb_index(cb_index);
|
||||
searchTime = test_index_precision(*kmeans, dataset, *testDataset, gt_matches, params.target_precision, checks, nn, 1);
|
||||
if (searchTime<bestSearchTime || bestSearchTime == -1) {
|
||||
bestSearchTime = searchTime;
|
||||
best_cb_index = cb_index;
|
||||
best_checks = checks;
|
||||
}
|
||||
}
|
||||
searchTime = bestSearchTime;
|
||||
cb_index = best_cb_index;
|
||||
checks = best_checks;
|
||||
|
||||
kmeans->set_cb_index(best_cb_index);
|
||||
logger.info("Optimum cb_index: %g\n",cb_index);
|
||||
((KMeansIndexParams*)bestParams)->cb_index = cb_index;
|
||||
}
|
||||
else {
|
||||
searchTime = test_index_precision(*bestIndex, dataset, *testDataset, gt_matches, params.target_precision, checks, nn, 1);
|
||||
}
|
||||
|
||||
logger.info("Required number of checks: %d \n",checks);;
|
||||
searchParams.checks = checks;
|
||||
delete testDataset;
|
||||
|
||||
speedup = linear/searchTime;
|
||||
}
|
||||
|
||||
return speedup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* AUTOTUNEDINDEX_H_ */
|
48
3rdparty/flann/common.h
vendored
48
3rdparty/flann/common.h
vendored
@@ -1,48 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 COMMOM_H
|
||||
#define COMMOM_H
|
||||
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
class FLANNException : public std::runtime_error {
|
||||
public:
|
||||
FLANNException(const char* message) : std::runtime_error(message) { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //COMMOM_H
|
128
3rdparty/flann/composite_index.h
vendored
128
3rdparty/flann/composite_index.h
vendored
@@ -1,128 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 COMPOSITETREE_H
|
||||
#define COMPOSITETREE_H
|
||||
|
||||
#include "constants.h"
|
||||
#include "nn_index.h"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
class CompositeIndex : public NNIndex
|
||||
{
|
||||
KMeansIndex* kmeans;
|
||||
KDTreeIndex* kdtree;
|
||||
|
||||
const Matrix<float> dataset;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
CompositeIndex(const Matrix<float>& inputData, const CompositeIndexParams& params = CompositeIndexParams() ) : dataset(inputData)
|
||||
{
|
||||
KDTreeIndexParams kdtree_params(params.trees);
|
||||
KMeansIndexParams kmeans_params(params.branching, params.iterations, params.centers_init, params.cb_index);
|
||||
|
||||
kdtree = new KDTreeIndex(inputData,kdtree_params);
|
||||
kmeans = new KMeansIndex(inputData,kmeans_params);
|
||||
|
||||
}
|
||||
|
||||
virtual ~CompositeIndex()
|
||||
{
|
||||
delete kdtree;
|
||||
delete kmeans;
|
||||
}
|
||||
|
||||
|
||||
flann_algorithm_t getType() const
|
||||
{
|
||||
return COMPOSITE;
|
||||
}
|
||||
|
||||
|
||||
int size() const
|
||||
{
|
||||
return dataset.rows;
|
||||
}
|
||||
|
||||
int veclen() const
|
||||
{
|
||||
return dataset.cols;
|
||||
}
|
||||
|
||||
|
||||
int usedMemory() const
|
||||
{
|
||||
return kmeans->usedMemory()+kdtree->usedMemory();
|
||||
}
|
||||
|
||||
void buildIndex()
|
||||
{
|
||||
logger.info("Building kmeans tree...\n");
|
||||
kmeans->buildIndex();
|
||||
logger.info("Building kdtree tree...\n");
|
||||
kdtree->buildIndex();
|
||||
}
|
||||
|
||||
|
||||
void saveIndex(FILE* /*stream*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loadIndex(FILE* /*stream*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void findNeighbors(ResultSet& result, const float* vec, const SearchParams& searchParams)
|
||||
{
|
||||
kmeans->findNeighbors(result,vec,searchParams);
|
||||
kdtree->findNeighbors(result,vec,searchParams);
|
||||
}
|
||||
|
||||
|
||||
// Params estimateSearchParams(float precision, Dataset<float>* testset = NULL)
|
||||
// {
|
||||
// Params params;
|
||||
//
|
||||
// return params;
|
||||
// }
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //COMPOSITETREE_H
|
68
3rdparty/flann/constants.h
vendored
68
3rdparty/flann/constants.h
vendored
@@ -1,68 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
|
||||
|
||||
const double FLANN_VERSION = 1.20;
|
||||
|
||||
/* Nearest neighbor index algorithms */
|
||||
enum flann_algorithm_t {
|
||||
LINEAR = 0,
|
||||
KDTREE = 1,
|
||||
KMEANS = 2,
|
||||
COMPOSITE = 3,
|
||||
SAVED = 254,
|
||||
AUTOTUNED = 255,
|
||||
};
|
||||
|
||||
enum flann_centers_init_t {
|
||||
CENTERS_RANDOM = 0,
|
||||
CENTERS_GONZALES = 1,
|
||||
CENTERS_KMEANSPP = 2
|
||||
};
|
||||
|
||||
|
||||
enum flann_log_level_t {
|
||||
LOG_NONE = 0,
|
||||
LOG_FATAL = 1,
|
||||
LOG_ERROR = 2,
|
||||
LOG_WARN = 3,
|
||||
LOG_INFO = 4
|
||||
};
|
||||
|
||||
enum flann_distance_t {
|
||||
EUCLIDEAN = 1,
|
||||
MANHATTAN = 2,
|
||||
MINKOWSKI = 3
|
||||
};
|
||||
|
||||
#endif // CONSTANTS_H
|
51
3rdparty/flann/dist.cpp
vendored
51
3rdparty/flann/dist.cpp
vendored
@@ -1,51 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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.
|
||||
*************************************************************************/
|
||||
|
||||
#include "dist.h"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/** Global variable indicating the distance metric
|
||||
* to be used.
|
||||
*/
|
||||
flann_distance_t flann_distance_type = EUCLIDEAN;
|
||||
|
||||
/**
|
||||
* Zero iterator that emulates a zero feature.
|
||||
*/
|
||||
ZeroIterator<float> zero;
|
||||
|
||||
/**
|
||||
* Order of Minkowski distance to use.
|
||||
*/
|
||||
int flann_minkowski_order;
|
||||
|
||||
}
|
211
3rdparty/flann/dist.h
vendored
211
3rdparty/flann/dist.h
vendored
@@ -1,211 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 DIST_H
|
||||
#define DIST_H
|
||||
|
||||
#include <cmath>
|
||||
using namespace std;
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/**
|
||||
* Distance function by default set to the custom distance
|
||||
* function. This can be set to a specific distance function
|
||||
* for further efficiency.
|
||||
*/
|
||||
#define flann_dist custom_dist
|
||||
//#define flann_dist euclidean_dist
|
||||
|
||||
|
||||
/**
|
||||
* Compute the squared Euclidean distance between two vectors.
|
||||
*
|
||||
* This is highly optimised, with loop unrolling, as it is one
|
||||
* of the most expensive inner loops.
|
||||
*
|
||||
* The computation of squared root at the end is omitted for
|
||||
* efficiency.
|
||||
*/
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
double euclidean_dist(Iterator1 first1, Iterator1 last1, Iterator2 first2, double acc = 0)
|
||||
{
|
||||
double distsq = acc;
|
||||
double diff0, diff1, diff2, diff3;
|
||||
Iterator1 lastgroup = last1 - 3;
|
||||
|
||||
/* Process 4 items with each loop for efficiency. */
|
||||
while (first1 < lastgroup) {
|
||||
diff0 = first1[0] - first2[0];
|
||||
diff1 = first1[1] - first2[1];
|
||||
diff2 = first1[2] - first2[2];
|
||||
diff3 = first1[3] - first2[3];
|
||||
distsq += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
|
||||
first1 += 4;
|
||||
first2 += 4;
|
||||
}
|
||||
/* Process last 0-3 pixels. Not needed for standard vector lengths. */
|
||||
while (first1 < last1) {
|
||||
diff0 = *first1++ - *first2++;
|
||||
distsq += diff0 * diff0;
|
||||
}
|
||||
return distsq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the Manhattan (L_1) distance between two vectors.
|
||||
*
|
||||
* This is highly optimised, with loop unrolling, as it is one
|
||||
* of the most expensive inner loops.
|
||||
*/
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
double manhattan_dist(Iterator1 first1, Iterator1 last1, Iterator2 first2, double acc = 0)
|
||||
{
|
||||
double distsq = acc;
|
||||
double diff0, diff1, diff2, diff3;
|
||||
Iterator1 lastgroup = last1 - 3;
|
||||
|
||||
/* Process 4 items with each loop for efficiency. */
|
||||
while (first1 < lastgroup) {
|
||||
diff0 = fabs(first1[0] - first2[0]);
|
||||
diff1 = fabs(first1[1] - first2[1]);
|
||||
diff2 = fabs(first1[2] - first2[2]);
|
||||
diff3 = fabs(first1[3] - first2[3]);
|
||||
distsq += diff0 + diff1 + diff2 + diff3;
|
||||
first1 += 4;
|
||||
first2 += 4;
|
||||
}
|
||||
/* Process last 0-3 pixels. Not needed for standard vector lengths. */
|
||||
while (first1 < last1) {
|
||||
diff0 = fabs(*first1++ - *first2++);
|
||||
distsq += diff0;
|
||||
}
|
||||
return distsq;
|
||||
}
|
||||
|
||||
|
||||
extern int flann_minkowski_order;
|
||||
/**
|
||||
* Compute the Minkowski (L_p) distance between two vectors.
|
||||
*
|
||||
* This is highly optimised, with loop unrolling, as it is one
|
||||
* of the most expensive inner loops.
|
||||
*
|
||||
* The computation of squared root at the end is omitted for
|
||||
* efficiency.
|
||||
*/
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
double minkowski_dist(Iterator1 first1, Iterator1 last1, Iterator2 first2, double acc = 0)
|
||||
{
|
||||
double distsq = acc;
|
||||
double diff0, diff1, diff2, diff3;
|
||||
Iterator1 lastgroup = last1 - 3;
|
||||
|
||||
int p = flann_minkowski_order;
|
||||
|
||||
/* Process 4 items with each loop for efficiency. */
|
||||
while (first1 < lastgroup) {
|
||||
diff0 = fabs(first1[0] - first2[0]);
|
||||
diff1 = fabs(first1[1] - first2[1]);
|
||||
diff2 = fabs(first1[2] - first2[2]);
|
||||
diff3 = fabs(first1[3] - first2[3]);
|
||||
distsq += pow(diff0,p) + pow(diff1,p) + pow(diff2,p) + pow(diff3,p);
|
||||
first1 += 4;
|
||||
first2 += 4;
|
||||
}
|
||||
/* Process last 0-3 pixels. Not needed for standard vector lengths. */
|
||||
while (first1 < last1) {
|
||||
diff0 = fabs(*first1++ - *first2++);
|
||||
distsq += pow(diff0,p);
|
||||
}
|
||||
return distsq;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern flann_distance_t flann_distance_type;
|
||||
/**
|
||||
* Custom distance function. The distance computed is dependent on the value
|
||||
* of the 'flann_distance_type' global variable.
|
||||
*
|
||||
* If the last argument 'acc' is passed, the result is accumulated to the value
|
||||
* of this argument.
|
||||
*/
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
float custom_dist(Iterator1 first1, Iterator1 last1, Iterator2 first2, double acc = 0)
|
||||
{
|
||||
switch (flann_distance_type) {
|
||||
case EUCLIDEAN:
|
||||
return (float)euclidean_dist(first1, last1, first2, acc);
|
||||
case MANHATTAN:
|
||||
return (float)manhattan_dist(first1, last1, first2, acc);
|
||||
case MINKOWSKI:
|
||||
return (float)minkowski_dist(first1, last1, first2, acc);
|
||||
default:
|
||||
return (float)euclidean_dist(first1, last1, first2, acc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a "zero iterator". It basically behaves like a zero filled
|
||||
* array to all algorithms that use arrays as iterators (STL style).
|
||||
* It's useful when there's a need to compute the distance between feature
|
||||
* and origin it and allows for better compiler optimisation than using a
|
||||
* zero-filled array.
|
||||
*/
|
||||
template <typename T>
|
||||
struct ZeroIterator {
|
||||
|
||||
T operator*() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
T operator[](int /*index*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZeroIterator<T>& operator ++(int) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZeroIterator<T>& operator+=(int) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
extern ZeroIterator<float> zero;
|
||||
|
||||
}
|
||||
|
||||
#endif //DIST_H
|
476
3rdparty/flann/flann.cpp
vendored
476
3rdparty/flann/flann.cpp
vendored
@@ -1,476 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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.
|
||||
*************************************************************************/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include "flann.h"
|
||||
#include "timer.h"
|
||||
#include "common.h"
|
||||
#include "logger.h"
|
||||
#include "index_testing.h"
|
||||
#include "saving.h"
|
||||
#include "object_factory.h"
|
||||
// index types
|
||||
#include "kdtree_index.h"
|
||||
#include "kmeans_index.h"
|
||||
#include "composite_index.h"
|
||||
#include "linear_index.h"
|
||||
#include "autotuned_index.h"
|
||||
|
||||
#include <typeinfo>
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
#include "flann.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define EXPORTED extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORTED extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
typedef ObjectFactory<IndexParams, flann_algorithm_t> ParamsFactory;
|
||||
|
||||
|
||||
IndexParams* IndexParams::createFromParameters(const FLANNParameters& p)
|
||||
{
|
||||
IndexParams* params = ParamsFactory::instance().create(p.algorithm);
|
||||
params->fromParameters(p);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
NNIndex* LinearIndexParams::createIndex(const Matrix<float>& dataset) const
|
||||
{
|
||||
return new LinearIndex(dataset, *this);
|
||||
}
|
||||
|
||||
|
||||
NNIndex* KDTreeIndexParams::createIndex(const Matrix<float>& dataset) const
|
||||
{
|
||||
return new KDTreeIndex(dataset, *this);
|
||||
}
|
||||
|
||||
NNIndex* KMeansIndexParams::createIndex(const Matrix<float>& dataset) const
|
||||
{
|
||||
return new KMeansIndex(dataset, *this);
|
||||
}
|
||||
|
||||
|
||||
NNIndex* CompositeIndexParams::createIndex(const Matrix<float>& dataset) const
|
||||
{
|
||||
return new CompositeIndex(dataset, *this);
|
||||
}
|
||||
|
||||
|
||||
NNIndex* AutotunedIndexParams::createIndex(const Matrix<float>& dataset) const
|
||||
{
|
||||
return new AutotunedIndex(dataset, *this);
|
||||
}
|
||||
|
||||
|
||||
NNIndex* SavedIndexParams::createIndex(const Matrix<float>& dataset) const
|
||||
{
|
||||
|
||||
FILE* fin = fopen(filename.c_str(), "rb");
|
||||
if (fin==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
IndexHeader header = load_header(fin);
|
||||
rewind(fin);
|
||||
IndexParams* params = ParamsFactory::instance().create(header.index_type);
|
||||
NNIndex* nnIndex = params->createIndex(dataset);
|
||||
nnIndex->loadIndex(fin);
|
||||
fclose(fin);
|
||||
delete params; //?
|
||||
|
||||
return nnIndex;
|
||||
|
||||
}
|
||||
|
||||
class StaticInit
|
||||
{
|
||||
public:
|
||||
StaticInit()
|
||||
{
|
||||
ParamsFactory::instance().register_<LinearIndexParams>(LINEAR);
|
||||
ParamsFactory::instance().register_<KDTreeIndexParams>(KDTREE);
|
||||
ParamsFactory::instance().register_<KMeansIndexParams>(KMEANS);
|
||||
ParamsFactory::instance().register_<CompositeIndexParams>(COMPOSITE);
|
||||
ParamsFactory::instance().register_<AutotunedIndexParams>(AUTOTUNED);
|
||||
ParamsFactory::instance().register_<SavedIndexParams>(SAVED);
|
||||
}
|
||||
};
|
||||
StaticInit __init;
|
||||
|
||||
|
||||
|
||||
Index::Index(const Matrix<float>& dataset, const IndexParams& params)
|
||||
{
|
||||
nnIndex = params.createIndex(dataset);
|
||||
nnIndex->buildIndex();
|
||||
}
|
||||
|
||||
Index::~Index()
|
||||
{
|
||||
delete nnIndex;
|
||||
}
|
||||
|
||||
|
||||
void Index::knnSearch(const Matrix<float>& queries, Matrix<int>& indices, Matrix<float>& dists, int knn, const SearchParams& searchParams)
|
||||
{
|
||||
assert(queries.cols==nnIndex->veclen());
|
||||
assert(indices.rows>=queries.rows);
|
||||
assert(dists.rows>=queries.rows);
|
||||
assert(indices.cols>=knn);
|
||||
assert(dists.cols>=knn);
|
||||
|
||||
|
||||
search_for_neighbors(*nnIndex, queries, indices, dists, searchParams);
|
||||
}
|
||||
|
||||
int Index::radiusSearch(const Matrix<float>& query, Matrix<int> indices, Matrix<float> dists, float radius, const SearchParams& searchParams)
|
||||
{
|
||||
if (query.rows!=1) {
|
||||
printf("I can only search one feature at a time for range search\n");
|
||||
return -1;
|
||||
}
|
||||
assert(query.cols==nnIndex->veclen());
|
||||
|
||||
RadiusResultSet resultSet(radius);
|
||||
resultSet.init(query.data, query.cols);
|
||||
nnIndex->findNeighbors(resultSet,query.data,searchParams);
|
||||
|
||||
// TODO: optimize here
|
||||
int* neighbors = resultSet.getNeighbors();
|
||||
float* distances = resultSet.getDistances();
|
||||
int count_nn = min((long)resultSet.size(), indices.cols);
|
||||
|
||||
assert (dists.cols>=count_nn);
|
||||
|
||||
for (int i=0;i<count_nn;++i) {
|
||||
indices[0][i] = neighbors[i];
|
||||
dists[0][i] = distances[i];
|
||||
}
|
||||
|
||||
return count_nn;
|
||||
}
|
||||
|
||||
|
||||
void Index::save(string filename)
|
||||
{
|
||||
FILE* fout = fopen(filename.c_str(), "wb");
|
||||
if (fout==NULL) {
|
||||
logger.error("Cannot open file: %s", filename.c_str());
|
||||
throw FLANNException("Cannot open file");
|
||||
}
|
||||
nnIndex->saveIndex(fout);
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
int Index::size() const
|
||||
{
|
||||
return nnIndex->size();
|
||||
}
|
||||
|
||||
int Index::veclen() const
|
||||
{
|
||||
return nnIndex->veclen();
|
||||
}
|
||||
|
||||
|
||||
int hierarchicalClustering(const Matrix<float>& features, Matrix<float>& centers, const KMeansIndexParams& params)
|
||||
{
|
||||
KMeansIndex kmeans(features, params);
|
||||
kmeans.buildIndex();
|
||||
|
||||
int clusterNum = kmeans.getClusterCenters(centers);
|
||||
return clusterNum;
|
||||
}
|
||||
|
||||
} // namespace FLANN
|
||||
|
||||
|
||||
|
||||
using namespace cvflann;
|
||||
|
||||
typedef NNIndex* NNIndexPtr;
|
||||
typedef Matrix<float>* MatrixPtr;
|
||||
|
||||
|
||||
|
||||
void init_flann_parameters(FLANNParameters* p)
|
||||
{
|
||||
if (p != NULL) {
|
||||
flann_log_verbosity(p->log_level);
|
||||
if (p->random_seed>0) {
|
||||
seed_random(p->random_seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORTED void flann_log_verbosity(int level)
|
||||
{
|
||||
if (level>=0) {
|
||||
logger.setLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORTED void flann_set_distance_type(flann_distance_t distance_type, int order)
|
||||
{
|
||||
flann_distance_type = distance_type;
|
||||
flann_minkowski_order = order;
|
||||
}
|
||||
|
||||
|
||||
EXPORTED flann_index_t flann_build_index(float* dataset, int rows, int cols, float* /*speedup*/, FLANNParameters* flann_params)
|
||||
{
|
||||
try {
|
||||
init_flann_parameters(flann_params);
|
||||
if (flann_params == NULL) {
|
||||
throw FLANNException("The flann_params argument must be non-null");
|
||||
}
|
||||
IndexParams* params = IndexParams::createFromParameters(*flann_params);
|
||||
Index* index = new Index(Matrix<float>(rows,cols,dataset), *params);
|
||||
|
||||
return index;
|
||||
}
|
||||
catch (runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
EXPORTED int flann_save_index(flann_index_t index_ptr, char* filename)
|
||||
{
|
||||
try {
|
||||
if (index_ptr==NULL) {
|
||||
throw FLANNException("Invalid index");
|
||||
}
|
||||
|
||||
Index* index = (Index*)index_ptr;
|
||||
index->save(filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch(runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORTED FLANN_INDEX flann_load_index(char* filename, float* dataset, int rows, int cols)
|
||||
{
|
||||
try {
|
||||
Index* index = new Index(Matrix<float>(rows,cols,dataset), SavedIndexParams(filename));
|
||||
return index;
|
||||
}
|
||||
catch(runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
EXPORTED int flann_find_nearest_neighbors(float* dataset, int rows, int cols, float* testset, int tcount, int* result, float* dists, int nn, FLANNParameters* flann_params)
|
||||
{
|
||||
int _result = 0;
|
||||
try {
|
||||
init_flann_parameters(flann_params);
|
||||
|
||||
IndexParams* params = IndexParams::createFromParameters(*flann_params);
|
||||
Index* index = new Index(Matrix<float>(rows,cols,dataset), *params);
|
||||
Matrix<int> m_indices(tcount, nn, result);
|
||||
Matrix<float> m_dists(tcount, nn, dists);
|
||||
index->knnSearch(Matrix<float>(tcount, index->veclen(), testset),
|
||||
m_indices,
|
||||
m_dists, nn, SearchParams(flann_params->checks) );
|
||||
}
|
||||
catch(runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
_result = -1;
|
||||
}
|
||||
|
||||
return _result;
|
||||
}
|
||||
|
||||
|
||||
EXPORTED int flann_find_nearest_neighbors_index(flann_index_t index_ptr, float* testset, int tcount, int* result, float* dists, int nn, int checks, FLANNParameters* flann_params)
|
||||
{
|
||||
try {
|
||||
init_flann_parameters(flann_params);
|
||||
if (index_ptr==NULL) {
|
||||
throw FLANNException("Invalid index");
|
||||
}
|
||||
Index* index = (Index*) index_ptr;
|
||||
|
||||
Matrix<int> m_indices(tcount, nn, result);
|
||||
Matrix<float> m_dists(tcount, nn, dists);
|
||||
index->knnSearch(Matrix<float>(tcount, index->veclen(), testset),
|
||||
m_indices,
|
||||
m_dists, nn, SearchParams(checks) );
|
||||
|
||||
}
|
||||
catch(runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
EXPORTED int flann_radius_search(FLANN_INDEX index_ptr,
|
||||
float* query,
|
||||
int* indices,
|
||||
float* dists,
|
||||
int max_nn,
|
||||
float radius,
|
||||
int checks,
|
||||
FLANNParameters* flann_params)
|
||||
{
|
||||
try {
|
||||
init_flann_parameters(flann_params);
|
||||
if (index_ptr==NULL) {
|
||||
throw FLANNException("Invalid index");
|
||||
}
|
||||
Index* index = (Index*) index_ptr;
|
||||
|
||||
Matrix<int> m_indices(1, max_nn, indices);
|
||||
Matrix<float> m_dists(1, max_nn, dists);
|
||||
int count = index->radiusSearch(Matrix<float>(1, index->veclen(), query),
|
||||
m_indices,
|
||||
m_dists, radius, SearchParams(checks) );
|
||||
|
||||
|
||||
return count;
|
||||
}
|
||||
catch(runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
EXPORTED int flann_free_index(FLANN_INDEX index_ptr, FLANNParameters* flann_params)
|
||||
{
|
||||
try {
|
||||
init_flann_parameters(flann_params);
|
||||
if (index_ptr==NULL) {
|
||||
throw FLANNException("Invalid index");
|
||||
}
|
||||
Index* index = (Index*) index_ptr;
|
||||
delete index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch(runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORTED int flann_compute_cluster_centers(float* dataset, int rows, int cols, int clusters, float* result, FLANNParameters* flann_params)
|
||||
{
|
||||
try {
|
||||
init_flann_parameters(flann_params);
|
||||
|
||||
MatrixPtr inputData = new Matrix<float>(rows,cols,dataset);
|
||||
KMeansIndexParams params(flann_params->branching, flann_params->iterations, flann_params->centers_init, flann_params->cb_index);
|
||||
Matrix<float> centers(clusters, cols, result);
|
||||
int clusterNum = hierarchicalClustering(*inputData,centers, params);
|
||||
|
||||
return clusterNum;
|
||||
} catch (runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORTED void compute_ground_truth_float(float* dataset, int dshape[], float* testset, int tshape[], int* match, int mshape[], int skip)
|
||||
{
|
||||
assert(dshape[1]==tshape[1]);
|
||||
assert(tshape[0]==mshape[0]);
|
||||
|
||||
Matrix<int> _match(mshape[0], mshape[1], match);
|
||||
compute_ground_truth(Matrix<float>(dshape[0], dshape[1], dataset), Matrix<float>(tshape[0], tshape[1], testset), _match, skip);
|
||||
}
|
||||
|
||||
|
||||
EXPORTED float test_with_precision(FLANN_INDEX index_ptr, float* dataset, int dshape[], float* testset, int tshape[], int* matches, int mshape[],
|
||||
int nn, float precision, int* checks, int skip = 0)
|
||||
{
|
||||
assert(dshape[1]==tshape[1]);
|
||||
assert(tshape[0]==mshape[0]);
|
||||
|
||||
try {
|
||||
if (index_ptr==NULL) {
|
||||
throw FLANNException("Invalid index");
|
||||
}
|
||||
NNIndexPtr index = (NNIndexPtr)index_ptr;
|
||||
return test_index_precision(*index, Matrix<float>(dshape[0], dshape[1],dataset), Matrix<float>(tshape[0], tshape[1], testset),
|
||||
Matrix<int>(mshape[0],mshape[1],matches), precision, *checks, nn, skip);
|
||||
} catch (runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORTED float test_with_checks(FLANN_INDEX index_ptr, float* dataset, int dshape[], float* testset, int tshape[], int* matches, int mshape[],
|
||||
int nn, int checks, float* precision, int skip = 0)
|
||||
{
|
||||
assert(dshape[1]==tshape[1]);
|
||||
assert(tshape[0]==mshape[0]);
|
||||
|
||||
try {
|
||||
if (index_ptr==NULL) {
|
||||
throw FLANNException("Invalid index");
|
||||
}
|
||||
NNIndexPtr index = (NNIndexPtr)index_ptr;
|
||||
return test_index_checks(*index, Matrix<float>(dshape[0], dshape[1],dataset), Matrix<float>(tshape[0], tshape[1], testset),
|
||||
Matrix<int>(mshape[0],mshape[1],matches), checks, *precision, nn, skip);
|
||||
} catch (runtime_error& e) {
|
||||
logger.error("Caught exception: %s\n",e.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
278
3rdparty/flann/flann.h
vendored
278
3rdparty/flann/flann.h
vendored
@@ -1,278 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 FLANN_H
|
||||
#define FLANN_H
|
||||
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
/* win32 dll export/import directives */
|
||||
#ifdef flann_EXPORTS
|
||||
#define LIBSPEC __declspec(dllexport)
|
||||
#else
|
||||
#define LIBSPEC __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
/* unix needs nothing */
|
||||
#define LIBSPEC
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct FLANNParameters {
|
||||
flann_algorithm_t algorithm; // the algorithm to use (see constants.h)
|
||||
|
||||
int checks; // how many leafs (features) to check in one search
|
||||
float cb_index; // cluster boundary index. Used when searching the kmeans tree
|
||||
int trees; // number of randomized trees to use (for kdtree)
|
||||
int branching; // branching factor (for kmeans tree)
|
||||
int iterations; // max iterations to perform in one kmeans cluetering (kmeans tree)
|
||||
flann_centers_init_t centers_init; // algorithm used for picking the initial cluetr centers for kmeans tree
|
||||
float target_precision; // precision desired (used for autotuning, -1 otherwise)
|
||||
float build_weight; // build tree time weighting factor
|
||||
float memory_weight; // index memory weigthing factor
|
||||
float sample_fraction; // what fraction of the dataset to use for autotuning
|
||||
|
||||
flann_log_level_t log_level; // determines the verbosity of each flann function
|
||||
char* log_destination; // file where the output should go, NULL for the console
|
||||
long random_seed; // random seed to use
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef void* FLANN_INDEX; // deprecated
|
||||
typedef void* flann_index_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Sets the log level used for all flann functions (unless
|
||||
specified in FLANNParameters for each call
|
||||
|
||||
Params:
|
||||
level = verbosity level (defined in constants.h)
|
||||
*/
|
||||
LIBSPEC void flann_log_verbosity(int level);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the distance type to use throughout FLANN.
|
||||
* If distance type specified is MINKOWSKI, the second argument
|
||||
* specifies which order the minkowski distance should have.
|
||||
*/
|
||||
LIBSPEC void flann_set_distance_type(flann_distance_t distance_type, int order);
|
||||
|
||||
|
||||
/**
|
||||
Builds and returns an index. It uses autotuning if the target_precision field of index_params
|
||||
is between 0 and 1, or the parameters specified if it's -1.
|
||||
|
||||
Params:
|
||||
dataset = pointer to a data set stored in row major order
|
||||
rows = number of rows (features) in the dataset
|
||||
cols = number of columns in the dataset (feature dimensionality)
|
||||
speedup = speedup over linear search, estimated if using autotuning, output parameter
|
||||
index_params = index related parameters
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: the newly created index or a number <0 for error
|
||||
*/
|
||||
LIBSPEC FLANN_INDEX flann_build_index(float* dataset,
|
||||
int rows,
|
||||
int cols,
|
||||
float* speedup,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Saves the index to a file. Only the index is saved into the file, the dataset corresponding to the index is not saved.
|
||||
*
|
||||
* @param index_id The index that should be saved
|
||||
* @param filename The filename the index should be saved to
|
||||
* @return Returns 0 on success, negative value on error.
|
||||
*/
|
||||
LIBSPEC int flann_save_index(FLANN_INDEX index_id,
|
||||
char* filename);
|
||||
|
||||
|
||||
/**
|
||||
* Loads an index from a file.
|
||||
*
|
||||
* @param filename File to load the index from.
|
||||
* @param dataset The dataset corresponding to the index.
|
||||
* @param rows Dataset tors
|
||||
* @param cols Dataset columns
|
||||
* @return
|
||||
*/
|
||||
LIBSPEC FLANN_INDEX flann_load_index(char* filename,
|
||||
float* dataset,
|
||||
int rows,
|
||||
int cols);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Builds an index and uses it to find nearest neighbors.
|
||||
|
||||
Params:
|
||||
dataset = pointer to a data set stored in row major order
|
||||
rows = number of rows (features) in the dataset
|
||||
cols = number of columns in the dataset (feature dimensionality)
|
||||
testset = pointer to a query set stored in row major order
|
||||
trows = number of rows (features) in the query dataset (same dimensionality as features in the dataset)
|
||||
indices = pointer to matrix for the indices of the nearest neighbors of the testset features in the dataset
|
||||
(must have trows number of rows and nn number of columns)
|
||||
nn = how many nearest neighbors to return
|
||||
index_params = index related parameters
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: zero or -1 for error
|
||||
*/
|
||||
LIBSPEC int flann_find_nearest_neighbors(float* dataset,
|
||||
int rows,
|
||||
int cols,
|
||||
float* testset,
|
||||
int trows,
|
||||
int* indices,
|
||||
float* dists,
|
||||
int nn,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Searches for nearest neighbors using the index provided
|
||||
|
||||
Params:
|
||||
index_id = the index (constructed previously using flann_build_index).
|
||||
testset = pointer to a query set stored in row major order
|
||||
trows = number of rows (features) in the query dataset (same dimensionality as features in the dataset)
|
||||
indices = pointer to matrix for the indices of the nearest neighbors of the testset features in the dataset
|
||||
(must have trows number of rows and nn number of columns)
|
||||
nn = how many nearest neighbors to return
|
||||
checks = number of checks to perform before the search is stopped
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: zero or a number <0 for error
|
||||
*/
|
||||
LIBSPEC int flann_find_nearest_neighbors_index(FLANN_INDEX index_id,
|
||||
float* testset,
|
||||
int trows,
|
||||
int* indices,
|
||||
float* dists,
|
||||
int nn,
|
||||
int checks,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Performs an radius search using an already constructed index.
|
||||
*
|
||||
* In case of radius search, instead of always returning a predetermined
|
||||
* number of nearest neighbours (for example the 10 nearest neighbours), the
|
||||
* search will return all the neighbours found within a search radius
|
||||
* of the query point.
|
||||
*
|
||||
* The check parameter in the function below sets the level of approximation
|
||||
* for the search by only visiting "checks" number of features in the index
|
||||
* (the same way as for the KNN search). A lower value for checks will give
|
||||
* a higher search speedup at the cost of potentially not returning all the
|
||||
* neighbours in the specified radius.
|
||||
*/
|
||||
LIBSPEC int flann_radius_search(FLANN_INDEX index_ptr, /* the index */
|
||||
float* query, /* query point */
|
||||
int* indices, /* array for storing the indices found (will be modified) */
|
||||
float* dists, /* similar, but for storing distances */
|
||||
int max_nn, /* size of arrays indices and dists */
|
||||
float radius, /* search radius (squared radius for euclidian metric) */
|
||||
int checks, /* number of features to check, sets the level of approximation */
|
||||
FLANNParameters* flann_params);
|
||||
|
||||
|
||||
/**
|
||||
Deletes an index and releases the memory used by it.
|
||||
|
||||
Params:
|
||||
index_id = the index (constructed previously using flann_build_index).
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: zero or a number <0 for error
|
||||
*/
|
||||
LIBSPEC int flann_free_index(FLANN_INDEX index_id,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
/**
|
||||
Clusters the features in the dataset using a hierarchical kmeans clustering approach.
|
||||
This is significantly faster than using a flat kmeans clustering for a large number
|
||||
of clusters.
|
||||
|
||||
Params:
|
||||
dataset = pointer to a data set stored in row major order
|
||||
rows = number of rows (features) in the dataset
|
||||
cols = number of columns in the dataset (feature dimensionality)
|
||||
clusters = number of cluster to compute
|
||||
result = memory buffer where the output cluster centers are storred
|
||||
index_params = used to specify the kmeans tree parameters (branching factor, max number of iterations to use)
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: number of clusters computed or a number <0 for error. This number can be different than the number of clusters requested, due to the
|
||||
way hierarchical clusters are computed. The number of clusters returned will be the highest number of the form
|
||||
(branch_size-1)*K+1 smaller than the number of clusters requested.
|
||||
*/
|
||||
|
||||
LIBSPEC int flann_compute_cluster_centers(float* dataset,
|
||||
int rows,
|
||||
int cols,
|
||||
int clusters,
|
||||
float* result,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
||||
|
||||
#include "flann.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*FLANN_H*/
|
247
3rdparty/flann/flann.hpp
vendored
247
3rdparty/flann/flann.hpp
vendored
@@ -1,247 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 FLANN_HPP_
|
||||
#define FLANN_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "constants.h"
|
||||
#include "common.h"
|
||||
#include "matrix.h"
|
||||
|
||||
#include "flann.h"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
class NNIndex;
|
||||
|
||||
class IndexFactory
|
||||
{
|
||||
public:
|
||||
virtual ~IndexFactory() {}
|
||||
virtual NNIndex* createIndex(const Matrix<float>& dataset) const = 0;
|
||||
};
|
||||
|
||||
struct IndexParams : public IndexFactory {
|
||||
protected:
|
||||
IndexParams() {};
|
||||
|
||||
public:
|
||||
|
||||
static IndexParams* createFromParameters(const FLANNParameters& p);
|
||||
|
||||
virtual void fromParameters(const FLANNParameters&) {};
|
||||
virtual void toParameters(FLANNParameters&) { };
|
||||
};
|
||||
|
||||
struct LinearIndexParams : public IndexParams {
|
||||
LinearIndexParams() {};
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct KDTreeIndexParams : public IndexParams {
|
||||
KDTreeIndexParams(int trees_ = 4) : trees(trees_) {};
|
||||
|
||||
int trees; // number of randomized trees to use (for kdtree)
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
|
||||
void fromParameters(const FLANNParameters& p)
|
||||
{
|
||||
trees = p.trees;
|
||||
}
|
||||
|
||||
void toParameters(FLANNParameters& p)
|
||||
{
|
||||
p.algorithm = KDTREE;
|
||||
p.trees = trees;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct KMeansIndexParams : public IndexParams {
|
||||
KMeansIndexParams(int branching_ = 32, int iterations_ = 11,
|
||||
flann_centers_init_t centers_init_ = CENTERS_RANDOM, float cb_index_ = 0.2 ) :
|
||||
branching(branching_),
|
||||
iterations(iterations_),
|
||||
centers_init(centers_init_),
|
||||
cb_index(cb_index_) {};
|
||||
|
||||
int branching; // branching factor (for kmeans tree)
|
||||
int iterations; // max iterations to perform in one kmeans clustering (kmeans tree)
|
||||
flann_centers_init_t centers_init; // algorithm used for picking the initial cluster centers for kmeans tree
|
||||
float cb_index; // cluster boundary index. Used when searching the kmeans tree
|
||||
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
|
||||
void fromParameters(const FLANNParameters& p)
|
||||
{
|
||||
branching = p.branching;
|
||||
iterations = p.iterations;
|
||||
centers_init = p.centers_init;
|
||||
cb_index = p.cb_index;
|
||||
}
|
||||
|
||||
void toParameters(FLANNParameters& p)
|
||||
{
|
||||
p.algorithm = KMEANS;
|
||||
p.branching = branching;
|
||||
p.iterations = iterations;
|
||||
p.centers_init = centers_init;
|
||||
p.cb_index = cb_index;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct CompositeIndexParams : public IndexParams {
|
||||
CompositeIndexParams(int trees_ = 4, int branching_ = 32, int iterations_ = 11,
|
||||
flann_centers_init_t centers_init_ = CENTERS_RANDOM, float cb_index_ = 0.2 ) :
|
||||
trees(trees_),
|
||||
branching(branching_),
|
||||
iterations(iterations_),
|
||||
centers_init(centers_init_),
|
||||
cb_index(cb_index_) {};
|
||||
|
||||
int trees; // number of randomized trees to use (for kdtree)
|
||||
int branching; // branching factor (for kmeans tree)
|
||||
int iterations; // max iterations to perform in one kmeans clustering (kmeans tree)
|
||||
flann_centers_init_t centers_init; // algorithm used for picking the initial cluster centers for kmeans tree
|
||||
float cb_index; // cluster boundary index. Used when searching the kmeans tree
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
|
||||
void fromParameters(const FLANNParameters& p)
|
||||
{
|
||||
trees = p.trees;
|
||||
branching = p.branching;
|
||||
iterations = p.iterations;
|
||||
centers_init = p.centers_init;
|
||||
cb_index = p.cb_index;
|
||||
}
|
||||
|
||||
void toParameters(FLANNParameters& p)
|
||||
{
|
||||
p.algorithm = COMPOSITE;
|
||||
p.trees = trees;
|
||||
p.branching = branching;
|
||||
p.iterations = iterations;
|
||||
p.centers_init = centers_init;
|
||||
p.cb_index = cb_index;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct AutotunedIndexParams : public IndexParams {
|
||||
AutotunedIndexParams( float target_precision_ = 0.9, float build_weight_ = 0.01,
|
||||
float memory_weight_ = 0, float sample_fraction_ = 0.1) :
|
||||
target_precision(target_precision_),
|
||||
build_weight(build_weight_),
|
||||
memory_weight(memory_weight_),
|
||||
sample_fraction(sample_fraction_) {};
|
||||
|
||||
float target_precision; // precision desired (used for autotuning, -1 otherwise)
|
||||
float build_weight; // build tree time weighting factor
|
||||
float memory_weight; // index memory weighting factor
|
||||
float sample_fraction; // what fraction of the dataset to use for autotuning
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
|
||||
void fromParameters(const FLANNParameters& p)
|
||||
{
|
||||
target_precision = p.target_precision;
|
||||
build_weight = p.build_weight;
|
||||
memory_weight = p.memory_weight;
|
||||
sample_fraction = p.sample_fraction;
|
||||
}
|
||||
|
||||
void toParameters(FLANNParameters& p)
|
||||
{
|
||||
p.algorithm = AUTOTUNED;
|
||||
p.target_precision = target_precision;
|
||||
p.build_weight = build_weight;
|
||||
p.memory_weight = memory_weight;
|
||||
p.sample_fraction = sample_fraction;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct SavedIndexParams : public IndexParams {
|
||||
SavedIndexParams() {
|
||||
throw FLANNException("I don't know which index to load");
|
||||
}
|
||||
SavedIndexParams(std::string filename_) : filename(filename_) {}
|
||||
|
||||
std::string filename; // filename of the stored index
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
};
|
||||
|
||||
|
||||
struct SearchParams {
|
||||
SearchParams(int checks_ = 32) :
|
||||
checks(checks_) {};
|
||||
|
||||
int checks;
|
||||
};
|
||||
|
||||
|
||||
class Index {
|
||||
NNIndex* nnIndex;
|
||||
|
||||
public:
|
||||
Index(const Matrix<float>& features, const IndexParams& params);
|
||||
|
||||
~Index();
|
||||
|
||||
void knnSearch(const Matrix<float>& queries, Matrix<int>& indices, Matrix<float>& dists, int knn, const SearchParams& params);
|
||||
|
||||
int radiusSearch(const Matrix<float>& query, Matrix<int> indices, Matrix<float> dists, float radius, const SearchParams& params);
|
||||
|
||||
void save(std::string filename);
|
||||
|
||||
int veclen() const;
|
||||
|
||||
int size() const;
|
||||
};
|
||||
|
||||
|
||||
int hierarchicalClustering(const Matrix<float>& features, Matrix<float>& centers, const KMeansIndexParams& params);
|
||||
|
||||
|
||||
}
|
||||
#endif /* FLANN_HPP_ */
|
95
3rdparty/flann/ground_truth.h
vendored
95
3rdparty/flann/ground_truth.h
vendored
@@ -1,95 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 GROUND_TRUTH_H
|
||||
#define GROUND_TRUTH_H
|
||||
|
||||
#include "matrix.h"
|
||||
#include "dist.h"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
void find_nearest(const Matrix<T>& dataset, T* query, int* matches, int nn, int skip = 0)
|
||||
{
|
||||
int n = nn + skip;
|
||||
|
||||
T* query_end = query + dataset.cols;
|
||||
|
||||
long* match = new long[n];
|
||||
T* dists = new T[n];
|
||||
|
||||
dists[0] = flann_dist(query, query_end, dataset[0]);
|
||||
match[0] = 0;
|
||||
int dcnt = 1;
|
||||
|
||||
for (int i=1;i<dataset.rows;++i) {
|
||||
T tmp = flann_dist(query, query_end, dataset[i]);
|
||||
|
||||
if (dcnt<n) {
|
||||
match[dcnt] = i;
|
||||
dists[dcnt++] = tmp;
|
||||
}
|
||||
else if (tmp < dists[dcnt-1]) {
|
||||
dists[dcnt-1] = tmp;
|
||||
match[dcnt-1] = i;
|
||||
}
|
||||
|
||||
int j = dcnt-1;
|
||||
// bubble up
|
||||
while (j>=1 && dists[j]<dists[j-1]) {
|
||||
swap(dists[j],dists[j-1]);
|
||||
swap(match[j],match[j-1]);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<nn;++i) {
|
||||
matches[i] = match[i+skip];
|
||||
}
|
||||
|
||||
delete[] match;
|
||||
delete[] dists;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void compute_ground_truth(const Matrix<T>& dataset, const Matrix<T>& testset, Matrix<int>& matches, int skip=0)
|
||||
{
|
||||
for (int i=0;i<testset.rows;++i) {
|
||||
find_nearest(dataset, testset[i], matches[i], matches.cols, skip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif //GROUND_TRUTH_H
|
209
3rdparty/flann/heap.h
vendored
209
3rdparty/flann/heap.h
vendored
@@ -1,209 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 HEAP_H
|
||||
#define HEAP_H
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/**
|
||||
* Priority Queue Implementation
|
||||
*
|
||||
* The priority queue is implemented with a heap. A heap is a complete
|
||||
* (full) binary tree in which each parent is less than both of its
|
||||
* children, but the order of the children is unspecified.
|
||||
* Note that a heap uses 1-based indexing to allow for power-of-2
|
||||
* location of parents and children. We ignore element 0 of Heap array.
|
||||
*/
|
||||
template <typename T>
|
||||
class Heap {
|
||||
|
||||
/**
|
||||
* Storage array for the heap.
|
||||
* Type T must be comparable.
|
||||
*/
|
||||
T* heap;
|
||||
int length;
|
||||
|
||||
/**
|
||||
* Number of element in the heap
|
||||
*/
|
||||
int count;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Params:
|
||||
* size = heap size
|
||||
*/
|
||||
|
||||
Heap(int size)
|
||||
{
|
||||
length = size+1;
|
||||
heap = new T[length]; // heap uses 1-based indexing
|
||||
count = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*
|
||||
*/
|
||||
~Heap()
|
||||
{
|
||||
delete[] heap;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns: heap size
|
||||
*/
|
||||
int size()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the heap is empty
|
||||
*
|
||||
* Returns: true is heap empty, false otherwise
|
||||
*/
|
||||
bool empty()
|
||||
{
|
||||
return size()==0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the heap.
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert a new element in the heap.
|
||||
*
|
||||
* We select the next empty leaf node, and then keep moving any larger
|
||||
* parents down until the right location is found to store this element.
|
||||
*
|
||||
* Params:
|
||||
* value = the new element to be inserted in the heap
|
||||
*/
|
||||
void insert(T value)
|
||||
{
|
||||
/* If heap is full, then return without adding this element. */
|
||||
if (count == length-1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int loc = ++(count); /* Remember 1-based indexing. */
|
||||
|
||||
/* Keep moving parents down until a place is found for this node. */
|
||||
int par = loc / 2; /* Location of parent. */
|
||||
while (par > 0 && value < heap[par]) {
|
||||
heap[loc] = heap[par]; /* Move parent down to loc. */
|
||||
loc = par;
|
||||
par = loc / 2;
|
||||
}
|
||||
/* Insert the element at the determined location. */
|
||||
heap[loc] = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the node of minimum value from the heap (top of the heap).
|
||||
*
|
||||
* Params:
|
||||
* value = out parameter used to return the min element
|
||||
* Returns: false if heap empty
|
||||
*/
|
||||
bool popMin(T& value)
|
||||
{
|
||||
if (count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Switch first node with last. */
|
||||
swap(heap[1],heap[count]);
|
||||
|
||||
count -= 1;
|
||||
heapify(1); /* Move new node 1 to right position. */
|
||||
|
||||
value = heap[count + 1];
|
||||
return true; /* Return old last node. */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reorganizes the heap (a parent is smaller than its children)
|
||||
* starting with a node.
|
||||
*
|
||||
* Params:
|
||||
* parent = node form which to start heap reorganization.
|
||||
*/
|
||||
void heapify(int parent)
|
||||
{
|
||||
int minloc = parent;
|
||||
|
||||
/* Check the left child */
|
||||
int left = 2 * parent;
|
||||
if (left <= count && heap[left] < heap[parent]) {
|
||||
minloc = left;
|
||||
}
|
||||
|
||||
/* Check the right child */
|
||||
int right = left + 1;
|
||||
if (right <= count && heap[right] < heap[minloc]) {
|
||||
minloc = right;
|
||||
}
|
||||
|
||||
/* If a child was smaller, than swap parent with it and Heapify. */
|
||||
if (minloc != parent) {
|
||||
swap(heap[parent],heap[minloc]);
|
||||
heapify(minloc);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //HEAP_H
|
314
3rdparty/flann/index_testing.cpp
vendored
314
3rdparty/flann/index_testing.cpp
vendored
@@ -1,314 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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.
|
||||
*************************************************************************/
|
||||
|
||||
#include "index_testing.h"
|
||||
#include "result_set.h"
|
||||
#include "timer.h"
|
||||
#include "logger.h"
|
||||
#include "dist.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
const float SEARCH_EPS = 0.001f;
|
||||
|
||||
int countCorrectMatches(int* neighbors, int* groundTruth, int n)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i=0;i<n;++i) {
|
||||
for (int k=0;k<n;++k) {
|
||||
if (neighbors[i]==groundTruth[k]) {
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
float computeDistanceRaport(const Matrix<float>& inputData, float* target, int* neighbors, int* groundTruth, int veclen, int n)
|
||||
{
|
||||
float* target_end = target + veclen;
|
||||
float ret = 0;
|
||||
for (int i=0;i<n;++i) {
|
||||
float den = (float)flann_dist(target,target_end, inputData[groundTruth[i]]);
|
||||
float num = (float)flann_dist(target,target_end, inputData[neighbors[i]]);
|
||||
|
||||
// printf("den=%g,num=%g\n",den,num);
|
||||
|
||||
if (den==0 && num==0) {
|
||||
ret += 1;
|
||||
} else {
|
||||
ret += num/den;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
float search_with_ground_truth(NNIndex& index, const Matrix<float>& inputData, const Matrix<float>& testData, const Matrix<int>& matches, int nn, int checks, float& time, float& dist, int skipMatches)
|
||||
{
|
||||
if (matches.cols<nn) {
|
||||
logger.info("matches.cols=%d, nn=%d\n",matches.cols,nn);
|
||||
|
||||
throw FLANNException("Ground truth is not computed for as many neighbors as requested");
|
||||
}
|
||||
|
||||
KNNResultSet resultSet(nn+skipMatches);
|
||||
SearchParams searchParams(checks);
|
||||
|
||||
int correct = 0;
|
||||
float distR = 0;
|
||||
StartStopTimer t;
|
||||
int repeats = 0;
|
||||
while (t.value<0.2) {
|
||||
repeats++;
|
||||
t.start();
|
||||
correct = 0;
|
||||
distR = 0;
|
||||
for (int i = 0; i < testData.rows; i++) {
|
||||
float* target = testData[i];
|
||||
resultSet.init(target, testData.cols);
|
||||
index.findNeighbors(resultSet,target, searchParams);
|
||||
int* neighbors = resultSet.getNeighbors();
|
||||
neighbors = neighbors+skipMatches;
|
||||
|
||||
correct += countCorrectMatches(neighbors,matches[i], nn);
|
||||
distR += computeDistanceRaport(inputData, target,neighbors,matches[i], testData.cols, nn);
|
||||
}
|
||||
t.stop();
|
||||
}
|
||||
time = (float)(t.value/repeats);
|
||||
|
||||
|
||||
float precicion = (float)correct/(nn*testData.rows);
|
||||
|
||||
dist = distR/(testData.rows*nn);
|
||||
|
||||
logger.info("%8d %10.4g %10.5g %10.5g %10.5g\n",
|
||||
checks, precicion, time, 1000.0 * time / testData.rows, dist);
|
||||
|
||||
return precicion;
|
||||
}
|
||||
|
||||
void search_for_neighbors(NNIndex& index, const Matrix<float>& testset, Matrix<int>& result, Matrix<float>& dists, const SearchParams& searchParams, int skip)
|
||||
{
|
||||
assert(testset.rows == result.rows);
|
||||
|
||||
int nn = result.cols;
|
||||
KNNResultSet resultSet(nn+skip);
|
||||
|
||||
|
||||
for (int i = 0; i < testset.rows; i++) {
|
||||
float* target = testset[i];
|
||||
resultSet.init(target, testset.cols);
|
||||
|
||||
index.findNeighbors(resultSet,target, searchParams);
|
||||
|
||||
int* neighbors = resultSet.getNeighbors();
|
||||
float* distances = resultSet.getDistances();
|
||||
memcpy(result[i], neighbors+skip, nn*sizeof(int));
|
||||
memcpy(dists[i], distances+skip, nn*sizeof(float));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float test_index_checks(NNIndex& index, const Matrix<float>& inputData, const Matrix<float>& testData, const Matrix<int>& matches, int checks, float& precision, int nn, int skipMatches)
|
||||
{
|
||||
logger.info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist\n");
|
||||
logger.info("---------------------------------------------------------\n");
|
||||
|
||||
float time = 0;
|
||||
float dist = 0;
|
||||
precision = search_with_ground_truth(index, inputData, testData, matches, nn, checks, time, dist, skipMatches);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
|
||||
float test_index_precision(NNIndex& index, const Matrix<float>& inputData, const Matrix<float>& testData, const Matrix<int>& matches,
|
||||
float precision, int& checks, int nn, int skipMatches)
|
||||
{
|
||||
logger.info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist\n");
|
||||
logger.info("---------------------------------------------------------\n");
|
||||
|
||||
int c2 = 1;
|
||||
float p2;
|
||||
int c1 = 1;
|
||||
float p1;
|
||||
float time;
|
||||
float dist;
|
||||
|
||||
p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, skipMatches);
|
||||
|
||||
if (p2>precision) {
|
||||
logger.info("Got as close as I can\n");
|
||||
checks = c2;
|
||||
return time;
|
||||
}
|
||||
|
||||
while (p2<precision) {
|
||||
c1 = c2;
|
||||
p1 = p2;
|
||||
c2 *=2;
|
||||
p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, skipMatches);
|
||||
}
|
||||
|
||||
int cx;
|
||||
float realPrecision;
|
||||
if (fabs(p2-precision)>SEARCH_EPS) {
|
||||
logger.info("Start linear estimation\n");
|
||||
// after we got to values in the vecinity of the desired precision
|
||||
// use linear approximation get a better estimation
|
||||
|
||||
cx = (c1+c2)/2;
|
||||
realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, skipMatches);
|
||||
while (fabs(realPrecision-precision)>SEARCH_EPS) {
|
||||
|
||||
if (realPrecision<precision) {
|
||||
c1 = cx;
|
||||
}
|
||||
else {
|
||||
c2 = cx;
|
||||
}
|
||||
cx = (c1+c2)/2;
|
||||
if (cx==c1) {
|
||||
logger.info("Got as close as I can\n");
|
||||
break;
|
||||
}
|
||||
realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, skipMatches);
|
||||
}
|
||||
|
||||
c2 = cx;
|
||||
p2 = realPrecision;
|
||||
|
||||
} else {
|
||||
logger.info("No need for linear estimation\n");
|
||||
cx = c2;
|
||||
realPrecision = p2;
|
||||
}
|
||||
|
||||
checks = cx;
|
||||
return time;
|
||||
}
|
||||
|
||||
|
||||
float test_index_precisions(NNIndex& index, const Matrix<float>& inputData, const Matrix<float>& testData, const Matrix<int>& matches,
|
||||
float* precisions, int precisions_length, int nn, int skipMatches, float maxTime)
|
||||
{
|
||||
// make sure precisions array is sorted
|
||||
sort(precisions, precisions+precisions_length);
|
||||
|
||||
int pindex = 0;
|
||||
float precision = precisions[pindex];
|
||||
|
||||
logger.info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist");
|
||||
logger.info("---------------------------------------------------------");
|
||||
|
||||
int c2 = 1;
|
||||
float p2;
|
||||
|
||||
int c1 = 1;
|
||||
float p1;
|
||||
|
||||
float time;
|
||||
float dist;
|
||||
|
||||
p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, skipMatches);
|
||||
|
||||
// if precision for 1 run down the tree is already
|
||||
// better then some of the requested precisions, then
|
||||
// skip those
|
||||
while (precisions[pindex]<p2 && pindex<precisions_length) {
|
||||
pindex++;
|
||||
}
|
||||
|
||||
if (pindex==precisions_length) {
|
||||
logger.info("Got as close as I can\n");
|
||||
return time;
|
||||
}
|
||||
|
||||
for (int i=pindex;i<precisions_length;++i) {
|
||||
|
||||
precision = precisions[i];
|
||||
while (p2<precision) {
|
||||
c1 = c2;
|
||||
p1 = p2;
|
||||
c2 *=2;
|
||||
p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, skipMatches);
|
||||
if (maxTime> 0 && time > maxTime && p2<precision) return time;
|
||||
}
|
||||
|
||||
int cx;
|
||||
float realPrecision;
|
||||
if (fabs(p2-precision)>SEARCH_EPS) {
|
||||
logger.info("Start linear estimation\n");
|
||||
// after we got to values in the vecinity of the desired precision
|
||||
// use linear approximation get a better estimation
|
||||
|
||||
cx = (c1+c2)/2;
|
||||
realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, skipMatches);
|
||||
while (fabs(realPrecision-precision)>SEARCH_EPS) {
|
||||
|
||||
if (realPrecision<precision) {
|
||||
c1 = cx;
|
||||
}
|
||||
else {
|
||||
c2 = cx;
|
||||
}
|
||||
cx = (c1+c2)/2;
|
||||
if (cx==c1) {
|
||||
logger.info("Got as close as I can\n");
|
||||
break;
|
||||
}
|
||||
realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, skipMatches);
|
||||
}
|
||||
|
||||
c2 = cx;
|
||||
p2 = realPrecision;
|
||||
|
||||
} else {
|
||||
logger.info("No need for linear estimation\n");
|
||||
cx = c2;
|
||||
realPrecision = p2;
|
||||
}
|
||||
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
}
|
57
3rdparty/flann/index_testing.h
vendored
57
3rdparty/flann/index_testing.h
vendored
@@ -1,57 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 TESTING_H
|
||||
#define TESTING_H
|
||||
|
||||
|
||||
#include "nn_index.h"
|
||||
#include "matrix.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
void search_for_neighbors(NNIndex& index, const Matrix<float>& testset, Matrix<int>& result, Matrix<float>& dists, const SearchParams &searchParams, int skip = 0);
|
||||
|
||||
float test_index_checks(NNIndex& index, const Matrix<float>& inputData, const Matrix<float>& testData, const Matrix<int>& matches,
|
||||
int checks, float& precision, int nn = 1, int skipMatches = 0);
|
||||
|
||||
float test_index_precision(NNIndex& index, const Matrix<float>& inputData, const Matrix<float>& testData, const Matrix<int>& matches,
|
||||
float precision, int& checks, int nn = 1, int skipMatches = 0);
|
||||
|
||||
float test_index_precisions(NNIndex& index, const Matrix<float>& inputData, const Matrix<float>& testData, const Matrix<int>& matches,
|
||||
float* precisions, int precisions_length, int nn = 1, int skipMatches = 0, float maxTime = 0);
|
||||
|
||||
}
|
||||
|
||||
#endif //TESTING_H
|
653
3rdparty/flann/kdtree_index.h
vendored
653
3rdparty/flann/kdtree_index.h
vendored
@@ -1,653 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 KDTREE_H
|
||||
#define KDTREE_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
|
||||
#include "heap.h"
|
||||
#include "common.h"
|
||||
#include "constants.h"
|
||||
#include "allocator.h"
|
||||
#include "matrix.h"
|
||||
#include "result_set.h"
|
||||
#include "random.h"
|
||||
#include "nn_index.h"
|
||||
#include "saving.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Randomized kd-tree index
|
||||
*
|
||||
* Contains the k-d trees and other information for indexing a set of points
|
||||
* for nearest-neighbor matching.
|
||||
*/
|
||||
class KDTreeIndex : public NNIndex
|
||||
{
|
||||
|
||||
enum {
|
||||
/**
|
||||
* To improve efficiency, only SAMPLE_MEAN random values are used to
|
||||
* compute the mean and variance at each level when building a tree.
|
||||
* A value of 100 seems to perform as well as using all values.
|
||||
*/
|
||||
SAMPLE_MEAN = 100,
|
||||
/**
|
||||
* Top random dimensions to consider
|
||||
*
|
||||
* When creating random trees, the dimension on which to subdivide is
|
||||
* selected at random from among the top RAND_DIM dimensions with the
|
||||
* highest variance. A value of 5 works well.
|
||||
*/
|
||||
RAND_DIM=5
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Number of randomized trees that are used
|
||||
*/
|
||||
int numTrees;
|
||||
|
||||
/**
|
||||
* Array of indices to vectors in the dataset. When doing lookup,
|
||||
* this is used instead to mark checkID.
|
||||
*/
|
||||
int* vind;
|
||||
|
||||
/**
|
||||
* An unique ID for each lookup.
|
||||
*/
|
||||
int checkID;
|
||||
|
||||
/**
|
||||
* The dataset used by this index
|
||||
*/
|
||||
const Matrix<float> dataset;
|
||||
|
||||
int size_;
|
||||
int veclen_;
|
||||
|
||||
|
||||
float* mean;
|
||||
float* var;
|
||||
|
||||
|
||||
/*--------------------- Internal Data Structures --------------------------*/
|
||||
|
||||
/**
|
||||
* A node of the binary k-d tree.
|
||||
*
|
||||
* This is All nodes that have vec[divfeat] < divval are placed in the
|
||||
* child1 subtree, else child2., A leaf node is indicated if both children are NULL.
|
||||
*/
|
||||
struct TreeSt {
|
||||
/**
|
||||
* Index of the vector feature used for subdivision.
|
||||
* If this is a leaf node (both children are NULL) then
|
||||
* this holds vector index for this leaf.
|
||||
*/
|
||||
int divfeat;
|
||||
/**
|
||||
* The value used for subdivision.
|
||||
*/
|
||||
float divval;
|
||||
/**
|
||||
* The child nodes.
|
||||
*/
|
||||
TreeSt *child1, *child2;
|
||||
};
|
||||
typedef TreeSt* Tree;
|
||||
|
||||
/**
|
||||
* Array of k-d trees used to find neighbors.
|
||||
*/
|
||||
Tree* trees;
|
||||
typedef BranchStruct<Tree> BranchSt;
|
||||
typedef BranchSt* Branch;
|
||||
/**
|
||||
* Priority queue storing intermediate branches in the best-bin-first search
|
||||
*/
|
||||
Heap<BranchSt>* heap;
|
||||
|
||||
|
||||
/**
|
||||
* Pooled memory allocator.
|
||||
*
|
||||
* Using a pooled memory allocator is more efficient
|
||||
* than allocating memory directly when there is a large
|
||||
* number small of memory allocations.
|
||||
*/
|
||||
PooledAllocator pool;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
flann_algorithm_t getType() const
|
||||
{
|
||||
return KDTREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* KDTree constructor
|
||||
*
|
||||
* Params:
|
||||
* inputData = dataset with the input features
|
||||
* params = parameters passed to the kdtree algorithm
|
||||
*/
|
||||
KDTreeIndex(const Matrix<float>& inputData, const KDTreeIndexParams& params = KDTreeIndexParams() ) : dataset(inputData)
|
||||
{
|
||||
size_ = dataset.rows;
|
||||
veclen_ = dataset.cols;
|
||||
|
||||
numTrees = params.trees;
|
||||
trees = new Tree[numTrees];
|
||||
|
||||
// get the parameters
|
||||
// if (params.find("trees") != params.end()) {
|
||||
// numTrees = (int)params["trees"];
|
||||
// trees = new Tree[numTrees];
|
||||
// }
|
||||
// else {
|
||||
// numTrees = -1;
|
||||
// trees = NULL;
|
||||
// }
|
||||
heap = new Heap<BranchSt>(size_);
|
||||
checkID = -1000;
|
||||
|
||||
// Create a permutable array of indices to the input vectors.
|
||||
vind = new int[size_];
|
||||
for (int i = 0; i < size_; i++) {
|
||||
vind[i] = i;
|
||||
}
|
||||
|
||||
mean = new float[veclen_];
|
||||
var = new float[veclen_];
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard destructor
|
||||
*/
|
||||
~KDTreeIndex()
|
||||
{
|
||||
delete[] vind;
|
||||
if (trees!=NULL) {
|
||||
delete[] trees;
|
||||
}
|
||||
delete heap;
|
||||
delete[] mean;
|
||||
delete[] var;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds the index
|
||||
*/
|
||||
void buildIndex()
|
||||
{
|
||||
/* Construct the randomized trees. */
|
||||
for (int i = 0; i < numTrees; i++) {
|
||||
/* Randomize the order of vectors to allow for unbiased sampling. */
|
||||
for (int j = size_; j > 0; --j) {
|
||||
// int rand = cast(int) (drand48() * size);
|
||||
int rnd = rand_int(j);
|
||||
assert(rnd >=0 && rnd < size_);
|
||||
swap(vind[j-1], vind[rnd]);
|
||||
}
|
||||
trees[i] = NULL;
|
||||
divideTree(&trees[i], 0, size_ - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void saveIndex(FILE* stream)
|
||||
{
|
||||
save_header(stream, *this);
|
||||
save_value(stream, numTrees);
|
||||
for (int i=0;i<numTrees;++i) {
|
||||
save_tree(stream, trees[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loadIndex(FILE* stream)
|
||||
{
|
||||
IndexHeader header = load_header(stream);
|
||||
|
||||
if (header.rows!=size() || header.cols!=veclen()) {
|
||||
throw FLANNException("The index saved belongs to a different dataset");
|
||||
}
|
||||
load_value(stream, numTrees);
|
||||
|
||||
if (trees!=NULL) {
|
||||
delete[] trees;
|
||||
}
|
||||
trees = new Tree[numTrees];
|
||||
for (int i=0;i<numTrees;++i) {
|
||||
load_tree(stream,trees[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns size of index.
|
||||
*/
|
||||
int size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of an index feature.
|
||||
*/
|
||||
int veclen() const
|
||||
{
|
||||
return veclen_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the inde memory usage
|
||||
* Returns: memory used by the index
|
||||
*/
|
||||
int usedMemory() const
|
||||
{
|
||||
return pool.usedMemory+pool.wastedMemory+dataset.rows*sizeof(int); // pool memory and vind array memory
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find set of nearest neighbors to vec. Their indices are stored inside
|
||||
* the result object.
|
||||
*
|
||||
* Params:
|
||||
* result = the result object in which the indices of the nearest-neighbors are stored
|
||||
* vec = the vector for which to search the nearest neighbors
|
||||
* maxCheck = the maximum number of restarts (in a best-bin-first manner)
|
||||
*/
|
||||
void findNeighbors(ResultSet& result, const float* vec, const SearchParams& searchParams)
|
||||
{
|
||||
int maxChecks = searchParams.checks;
|
||||
|
||||
if (maxChecks<0) {
|
||||
getExactNeighbors(result, vec);
|
||||
} else {
|
||||
getNeighbors(result, vec, maxChecks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void continueSearch(ResultSet& result, float* vec, int maxCheck)
|
||||
{
|
||||
BranchSt branch;
|
||||
|
||||
int checkCount = 0;
|
||||
|
||||
/* Keep searching other branches from heap until finished. */
|
||||
while ( heap->popMin(branch) && (checkCount < maxCheck || !result.full() )) {
|
||||
searchLevel(result, vec, branch.node,branch.mindistsq, checkCount, maxCheck);
|
||||
}
|
||||
|
||||
assert(result.full());
|
||||
}
|
||||
|
||||
|
||||
// Params estimateSearchParams(float precision, Dataset<float>* testset = NULL)
|
||||
// {
|
||||
// Params params;
|
||||
//
|
||||
// return params;
|
||||
// }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void save_tree(FILE* stream, Tree tree)
|
||||
{
|
||||
save_value(stream, *tree);
|
||||
if (tree->child1!=NULL) {
|
||||
save_tree(stream, tree->child1);
|
||||
}
|
||||
if (tree->child2!=NULL) {
|
||||
save_tree(stream, tree->child2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void load_tree(FILE* stream, Tree& tree)
|
||||
{
|
||||
tree = pool.allocate<TreeSt>();
|
||||
load_value(stream, *tree);
|
||||
if (tree->child1!=NULL) {
|
||||
load_tree(stream, tree->child1);
|
||||
}
|
||||
if (tree->child2!=NULL) {
|
||||
load_tree(stream, tree->child2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a tree node that subdivides the list of vecs from vind[first]
|
||||
* to vind[last]. The routine is called recursively on each sublist.
|
||||
* Place a pointer to this new tree node in the location pTree.
|
||||
*
|
||||
* Params: pTree = the new node to create
|
||||
* first = index of the first vector
|
||||
* last = index of the last vector
|
||||
*/
|
||||
void divideTree(Tree* pTree, int first, int last)
|
||||
{
|
||||
Tree node;
|
||||
|
||||
node = pool.allocate<TreeSt>(); // allocate memory
|
||||
*pTree = node;
|
||||
|
||||
/* If only one exemplar remains, then make this a leaf node. */
|
||||
if (first == last) {
|
||||
node->child1 = node->child2 = NULL; /* Mark as leaf node. */
|
||||
node->divfeat = vind[first]; /* Store index of this vec. */
|
||||
} else {
|
||||
chooseDivision(node, first, last);
|
||||
subdivide(node, first, last);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Choose which feature to use in order to subdivide this set of vectors.
|
||||
* Make a random choice among those with the highest variance, and use
|
||||
* its variance as the threshold value.
|
||||
*/
|
||||
void chooseDivision(Tree node, int first, int last)
|
||||
{
|
||||
memset(mean,0,veclen_*sizeof(float));
|
||||
memset(var,0,veclen_*sizeof(float));
|
||||
|
||||
/* Compute mean values. Only the first SAMPLE_MEAN values need to be
|
||||
sampled to get a good estimate.
|
||||
*/
|
||||
int end = min(first + SAMPLE_MEAN, last);
|
||||
int count = end - first + 1;
|
||||
for (int j = first; j <= end; ++j) {
|
||||
float* v = dataset[vind[j]];
|
||||
for (int k=0; k<veclen_; ++k) {
|
||||
mean[k] += v[k];
|
||||
}
|
||||
}
|
||||
for (int k=0; k<veclen_; ++k) {
|
||||
mean[k] /= count;
|
||||
}
|
||||
|
||||
/* Compute variances (no need to divide by count). */
|
||||
for (int j = first; j <= end; ++j) {
|
||||
float* v = dataset[vind[j]];
|
||||
for (int k=0; k<veclen_; ++k) {
|
||||
float dist = v[k] - mean[k];
|
||||
var[k] += dist * dist;
|
||||
}
|
||||
}
|
||||
/* Select one of the highest variance indices at random. */
|
||||
node->divfeat = selectDivision(var);
|
||||
node->divval = mean[node->divfeat];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Select the top RAND_DIM largest values from v and return the index of
|
||||
* one of these selected at random.
|
||||
*/
|
||||
int selectDivision(float* v)
|
||||
{
|
||||
int num = 0;
|
||||
int topind[RAND_DIM];
|
||||
|
||||
/* Create a list of the indices of the top RAND_DIM values. */
|
||||
for (int i = 0; i < veclen_; ++i) {
|
||||
if (num < RAND_DIM || v[i] > v[topind[num-1]]) {
|
||||
/* Put this element at end of topind. */
|
||||
if (num < RAND_DIM) {
|
||||
topind[num++] = i; /* Add to list. */
|
||||
}
|
||||
else {
|
||||
topind[num-1] = i; /* Replace last element. */
|
||||
}
|
||||
/* Bubble end value down to right location by repeated swapping. */
|
||||
int j = num - 1;
|
||||
while (j > 0 && v[topind[j]] > v[topind[j-1]]) {
|
||||
swap(topind[j], topind[j-1]);
|
||||
--j;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Select a random integer in range [0,num-1], and return that index. */
|
||||
// int rand = cast(int) (drand48() * num);
|
||||
int rnd = rand_int(num);
|
||||
assert(rnd >=0 && rnd < num);
|
||||
return topind[rnd];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Subdivide the list of exemplars using the feature and division
|
||||
* value given in this node. Call divideTree recursively on each list.
|
||||
*/
|
||||
void subdivide(Tree node, int first, int last)
|
||||
{
|
||||
/* Move vector indices for left subtree to front of list. */
|
||||
int i = first;
|
||||
int j = last;
|
||||
while (i <= j) {
|
||||
int ind = vind[i];
|
||||
float val = dataset[ind][node->divfeat];
|
||||
if (val < node->divval) {
|
||||
++i;
|
||||
} else {
|
||||
/* Move to end of list by swapping vind i and j. */
|
||||
swap(vind[i], vind[j]);
|
||||
--j;
|
||||
}
|
||||
}
|
||||
/* If either list is empty, it means we have hit the unlikely case
|
||||
in which all remaining features are identical. Split in the middle
|
||||
to maintain a balanced tree.
|
||||
*/
|
||||
if ( (i == first) || (i == last+1)) {
|
||||
i = (first+last+1)/2;
|
||||
}
|
||||
|
||||
divideTree(& node->child1, first, i - 1);
|
||||
divideTree(& node->child2, i, last);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Performs an exact nearest neighbor search. The exact search performs a full
|
||||
* traversal of the tree.
|
||||
*/
|
||||
void getExactNeighbors(ResultSet& result, const float* vec)
|
||||
{
|
||||
checkID -= 1; /* Set a different unique ID for each search. */
|
||||
|
||||
if (numTrees > 1) {
|
||||
fprintf(stderr,"It doesn't make any sense to use more than one tree for exact search");
|
||||
}
|
||||
if (numTrees>0) {
|
||||
searchLevelExact(result, vec, trees[0], 0.0);
|
||||
}
|
||||
assert(result.full());
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the approximate nearest-neighbor search. The search is approximate
|
||||
* because the tree traversal is abandoned after a given number of descends in
|
||||
* the tree.
|
||||
*/
|
||||
void getNeighbors(ResultSet& result, const float* vec, int maxCheck)
|
||||
{
|
||||
int i;
|
||||
BranchSt branch;
|
||||
|
||||
int checkCount = 0;
|
||||
heap->clear();
|
||||
checkID -= 1; /* Set a different unique ID for each search. */
|
||||
|
||||
/* Search once through each tree down to root. */
|
||||
for (i = 0; i < numTrees; ++i) {
|
||||
searchLevel(result, vec, trees[i], 0.0, checkCount, maxCheck);
|
||||
}
|
||||
|
||||
/* Keep searching other branches from heap until finished. */
|
||||
while ( heap->popMin(branch) && (checkCount < maxCheck || !result.full() )) {
|
||||
searchLevel(result, vec, branch.node,branch.mindistsq, checkCount, maxCheck);
|
||||
}
|
||||
|
||||
assert(result.full());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search starting from a given node of the tree. Based on any mismatches at
|
||||
* higher levels, all exemplars below this level must have a distance of
|
||||
* at least "mindistsq".
|
||||
*/
|
||||
void searchLevel(ResultSet& result, const float* vec, Tree node, float mindistsq, int& checkCount, int maxCheck)
|
||||
{
|
||||
if (result.worstDist()<mindistsq) {
|
||||
// printf("Ignoring branch, too far\n");
|
||||
return;
|
||||
}
|
||||
|
||||
float val, diff;
|
||||
Tree bestChild, otherChild;
|
||||
|
||||
/* If this is a leaf node, then do check and return. */
|
||||
if (node->child1 == NULL && node->child2 == NULL) {
|
||||
|
||||
/* Do not check same node more than once when searching multiple trees.
|
||||
Once a vector is checked, we set its location in vind to the
|
||||
current checkID.
|
||||
*/
|
||||
if (vind[node->divfeat] == checkID || checkCount>=maxCheck) {
|
||||
if (result.full()) return;
|
||||
}
|
||||
checkCount++;
|
||||
vind[node->divfeat] = checkID;
|
||||
|
||||
result.addPoint(dataset[node->divfeat],node->divfeat);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Which child branch should be taken first? */
|
||||
val = vec[node->divfeat];
|
||||
diff = val - node->divval;
|
||||
bestChild = (diff < 0) ? node->child1 : node->child2;
|
||||
otherChild = (diff < 0) ? node->child2 : node->child1;
|
||||
|
||||
/* Create a branch record for the branch not taken. Add distance
|
||||
of this feature boundary (we don't attempt to correct for any
|
||||
use of this feature in a parent node, which is unlikely to
|
||||
happen and would have only a small effect). Don't bother
|
||||
adding more branches to heap after halfway point, as cost of
|
||||
adding exceeds their value.
|
||||
*/
|
||||
|
||||
float new_distsq = flann_dist(&val, &val+1, &node->divval, mindistsq);
|
||||
// if (2 * checkCount < maxCheck || !result.full()) {
|
||||
if (new_distsq < result.worstDist() || !result.full()) {
|
||||
heap->insert( BranchSt::make_branch(otherChild, new_distsq) );
|
||||
}
|
||||
|
||||
/* Call recursively to search next level down. */
|
||||
searchLevel(result, vec, bestChild, mindistsq, checkCount, maxCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an exact search in the tree starting from a node.
|
||||
*/
|
||||
void searchLevelExact(ResultSet& result, const float* vec, Tree node, float mindistsq)
|
||||
{
|
||||
if (mindistsq>result.worstDist()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float val, diff;
|
||||
Tree bestChild, otherChild;
|
||||
|
||||
/* If this is a leaf node, then do check and return. */
|
||||
if (node->child1 == NULL && node->child2 == NULL) {
|
||||
|
||||
/* Do not check same node more than once when searching multiple trees.
|
||||
Once a vector is checked, we set its location in vind to the
|
||||
current checkID.
|
||||
*/
|
||||
if (vind[node->divfeat] == checkID)
|
||||
return;
|
||||
vind[node->divfeat] = checkID;
|
||||
|
||||
result.addPoint(dataset[node->divfeat],node->divfeat);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Which child branch should be taken first? */
|
||||
val = vec[node->divfeat];
|
||||
diff = val - node->divval;
|
||||
bestChild = (diff < 0) ? node->child1 : node->child2;
|
||||
otherChild = (diff < 0) ? node->child2 : node->child1;
|
||||
|
||||
|
||||
/* Call recursively to search next level down. */
|
||||
searchLevelExact(result, vec, bestChild, mindistsq);
|
||||
float new_distsq = flann_dist(&val, &val+1, &node->divval, mindistsq);
|
||||
searchLevelExact(result, vec, otherChild, new_distsq);
|
||||
}
|
||||
|
||||
}; // class KDTree
|
||||
|
||||
}
|
||||
|
||||
#endif //KDTREE_H
|
1119
3rdparty/flann/kmeans_index.h
vendored
1119
3rdparty/flann/kmeans_index.h
vendored
File diff suppressed because it is too large
Load Diff
105
3rdparty/flann/linear_index.h
vendored
105
3rdparty/flann/linear_index.h
vendored
@@ -1,105 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 LINEARSEARCH_H
|
||||
#define LINEARSEARCH_H
|
||||
|
||||
#include "constants.h"
|
||||
#include "nn_index.h"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
class LinearIndex : public NNIndex {
|
||||
|
||||
const Matrix<float> dataset;
|
||||
|
||||
public:
|
||||
|
||||
LinearIndex(const Matrix<float>& inputData, const LinearIndexParams& params = LinearIndexParams() ) : dataset(inputData)
|
||||
{
|
||||
}
|
||||
|
||||
flann_algorithm_t getType() const
|
||||
{
|
||||
return LINEAR;
|
||||
}
|
||||
|
||||
|
||||
int size() const
|
||||
{
|
||||
return dataset.rows;
|
||||
}
|
||||
|
||||
int veclen() const
|
||||
{
|
||||
return dataset.cols;
|
||||
}
|
||||
|
||||
|
||||
int usedMemory() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void buildIndex()
|
||||
{
|
||||
/* nothing to do here for linear search */
|
||||
}
|
||||
|
||||
void saveIndex(FILE* /*stream*/)
|
||||
{
|
||||
/* nothing to do here for linear search */
|
||||
}
|
||||
|
||||
|
||||
void loadIndex(FILE* /*stream*/)
|
||||
{
|
||||
/* nothing to do here for linear search */
|
||||
}
|
||||
|
||||
void findNeighbors(ResultSet& resultSet, const float* /*vec*/, const SearchParams& /*searchParams*/)
|
||||
{
|
||||
for (int i=0;i<dataset.rows;++i) {
|
||||
resultSet.addPoint(dataset[i],i);
|
||||
}
|
||||
}
|
||||
|
||||
// Params estimateSearchParams(float precision, Matrix<float>* testset = NULL)
|
||||
// {
|
||||
// Params params;
|
||||
// return params;
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LINEARSEARCH_H
|
85
3rdparty/flann/logger.cpp
vendored
85
3rdparty/flann/logger.cpp
vendored
@@ -1,85 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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.
|
||||
*************************************************************************/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
Logger logger;
|
||||
|
||||
int Logger::log(int level, const char* fmt, ...)
|
||||
{
|
||||
if (level > logLevel ) return -1;
|
||||
|
||||
int ret;
|
||||
va_list arglist;
|
||||
va_start(arglist, fmt);
|
||||
ret = vfprintf(stream, fmt, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Logger::log(int level, const char* fmt, va_list arglist)
|
||||
{
|
||||
if (level > logLevel ) return -1;
|
||||
|
||||
int ret;
|
||||
ret = vfprintf(stream, fmt, arglist);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define LOG_METHOD(NAME,LEVEL) \
|
||||
int Logger::NAME(const char* fmt, ...) \
|
||||
{ \
|
||||
int ret; \
|
||||
va_list ap; \
|
||||
va_start(ap, fmt); \
|
||||
ret = log(LEVEL, fmt, ap); \
|
||||
va_end(ap); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
|
||||
LOG_METHOD(fatal, LOG_FATAL)
|
||||
LOG_METHOD(error, LOG_ERROR)
|
||||
LOG_METHOD(warn, LOG_WARN)
|
||||
LOG_METHOD(info, LOG_INFO)
|
||||
|
||||
}
|
93
3rdparty/flann/logger.h
vendored
93
3rdparty/flann/logger.h
vendored
@@ -1,93 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdarg.h>
|
||||
#include "common.h"
|
||||
#include "flann.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
class Logger
|
||||
{
|
||||
FILE* stream;
|
||||
int logLevel;
|
||||
|
||||
public:
|
||||
|
||||
Logger() : stream(stdout), logLevel(LOG_WARN) {};
|
||||
|
||||
~Logger()
|
||||
{
|
||||
if (stream!=NULL && stream!=stdout) {
|
||||
fclose(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void setDestination(const char* name)
|
||||
{
|
||||
if (name==NULL) {
|
||||
stream = stdout;
|
||||
}
|
||||
else {
|
||||
stream = fopen(name,"w");
|
||||
if (stream == NULL) {
|
||||
stream = stdout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setLevel(int level) { logLevel = level; }
|
||||
|
||||
int log(int level, const char* fmt, ...);
|
||||
|
||||
int log(int level, const char* fmt, va_list arglist);
|
||||
|
||||
int fatal(const char* fmt, ...);
|
||||
|
||||
int error(const char* fmt, ...);
|
||||
|
||||
int warn(const char* fmt, ...);
|
||||
|
||||
int info(const char* fmt, ...);
|
||||
};
|
||||
|
||||
extern Logger logger;
|
||||
|
||||
}
|
||||
|
||||
#endif //LOGGER_H
|
163
3rdparty/flann/matrix.h
vendored
163
3rdparty/flann/matrix.h
vendored
@@ -1,163 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 DATASET_H
|
||||
#define DATASET_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <random.h>
|
||||
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
/**
|
||||
* Class implementing a generic rectangular dataset.
|
||||
*/
|
||||
template <typename T>
|
||||
class Matrix {
|
||||
|
||||
/**
|
||||
* Flag showing if the class owns its data storage.
|
||||
*/
|
||||
bool ownData;
|
||||
|
||||
void shallow_copy(const Matrix& rhs)
|
||||
{
|
||||
data = rhs.data;
|
||||
rows = rhs.rows;
|
||||
cols = rhs.cols;
|
||||
ownData = false;
|
||||
}
|
||||
|
||||
public:
|
||||
long rows;
|
||||
long cols;
|
||||
T* data;
|
||||
|
||||
|
||||
Matrix(long rows_, long cols_, T* data_ = NULL) :
|
||||
ownData(false), rows(rows_), cols(cols_), data(data_)
|
||||
{
|
||||
if (data_==NULL) {
|
||||
data = new T[rows*cols];
|
||||
ownData = true;
|
||||
}
|
||||
}
|
||||
|
||||
Matrix(const Matrix& d)
|
||||
{
|
||||
shallow_copy(d);
|
||||
}
|
||||
|
||||
const Matrix& operator=(const Matrix& rhs)
|
||||
{
|
||||
if (this!=&rhs) {
|
||||
shallow_copy(rhs);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Matrix()
|
||||
{
|
||||
if (ownData) {
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator that return a (pointer to a) row of the data.
|
||||
*/
|
||||
T* operator[](long index)
|
||||
{
|
||||
return data+index*cols;
|
||||
}
|
||||
|
||||
T* operator[](long index) const
|
||||
{
|
||||
return data+index*cols;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Matrix<T>* sample(long size, bool remove = false)
|
||||
{
|
||||
UniqueRandom rand(rows);
|
||||
Matrix<T> *newSet = new Matrix<T>(size,cols);
|
||||
|
||||
T *src,*dest;
|
||||
for (long i=0;i<size;++i) {
|
||||
long r = rand.next();
|
||||
dest = (*newSet)[i];
|
||||
src = (*this)[r];
|
||||
for (long j=0;j<cols;++j) {
|
||||
dest[j] = src[j];
|
||||
}
|
||||
if (remove) {
|
||||
dest = (*this)[rows-i-1];
|
||||
src = (*this)[r];
|
||||
for (long j=0;j<cols;++j) {
|
||||
swap(*src,*dest);
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remove) {
|
||||
rows -= size;
|
||||
}
|
||||
|
||||
return newSet;
|
||||
}
|
||||
|
||||
Matrix<T>* sample(long size) const
|
||||
{
|
||||
UniqueRandom rand(rows);
|
||||
Matrix<T> *newSet = new Matrix<T>(size,cols);
|
||||
|
||||
T *src,*dest;
|
||||
for (long i=0;i<size;++i) {
|
||||
long r = rand.next();
|
||||
dest = (*newSet)[i];
|
||||
src = (*this)[r];
|
||||
for (long j=0;j<cols;++j) {
|
||||
dest[j] = src[j];
|
||||
}
|
||||
}
|
||||
|
||||
return newSet;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif //DATASET_H
|
109
3rdparty/flann/nn_index.h
vendored
109
3rdparty/flann/nn_index.h
vendored
@@ -1,109 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 NNINDEX_H
|
||||
#define NNINDEX_H
|
||||
|
||||
#include "flann.hpp"
|
||||
#include "constants.h"
|
||||
#include "common.h"
|
||||
#include "matrix.h"
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
class ResultSet;
|
||||
|
||||
/**
|
||||
* Nearest-neighbor index base class
|
||||
*/
|
||||
class NNIndex
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~NNIndex() {};
|
||||
|
||||
/**
|
||||
Method responsible with building the index.
|
||||
*/
|
||||
virtual void buildIndex() = 0;
|
||||
|
||||
/**
|
||||
Saves the index to a stream
|
||||
*/
|
||||
virtual void saveIndex(FILE* stream) = 0;
|
||||
|
||||
/**
|
||||
Loads the index from a stream
|
||||
*/
|
||||
virtual void loadIndex(FILE* stream) = 0;
|
||||
|
||||
/**
|
||||
Method that searches for nearest-neighbors
|
||||
*/
|
||||
virtual void findNeighbors(ResultSet& result, const float* vec, const SearchParams& searchParams) = 0;
|
||||
|
||||
/**
|
||||
Number of features in this index.
|
||||
*/
|
||||
virtual int size() const = 0;
|
||||
|
||||
/**
|
||||
The length of each vector in this index.
|
||||
*/
|
||||
virtual int veclen() const = 0;
|
||||
|
||||
/**
|
||||
The amount of memory (in bytes) this index uses.
|
||||
*/
|
||||
virtual int usedMemory() const = 0;
|
||||
|
||||
/**
|
||||
* Algorithm name
|
||||
*/
|
||||
virtual flann_algorithm_t getType() const = 0;
|
||||
|
||||
/**
|
||||
Estimates the search parameters required in order to get a certain precision.
|
||||
If testset is not given it uses cross-validation.
|
||||
*/
|
||||
// virtual Params estimateSearchParams(float precision, Matrix<float>* testset = NULL) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif //NNINDEX_H
|
93
3rdparty/flann/object_factory.h
vendored
93
3rdparty/flann/object_factory.h
vendored
@@ -1,93 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 OBJECT_FACTORY_H_
|
||||
#define OBJECT_FACTORY_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
template<typename BaseClass, typename DerivedClass>
|
||||
BaseClass* createObject()
|
||||
{
|
||||
return new DerivedClass();
|
||||
}
|
||||
|
||||
template<typename BaseClass, typename UniqueIdType>
|
||||
class ObjectFactory
|
||||
{
|
||||
typedef BaseClass* (*CreateObjectFunc)();
|
||||
std::map<UniqueIdType, CreateObjectFunc> object_registry;
|
||||
|
||||
// singleton class, private constructor
|
||||
ObjectFactory() {};
|
||||
|
||||
public:
|
||||
typedef typename std::map<UniqueIdType, CreateObjectFunc>::iterator Iterator;
|
||||
|
||||
|
||||
template<typename DerivedClass>
|
||||
bool register_(UniqueIdType id)
|
||||
{
|
||||
if (object_registry.find(id) != object_registry.end())
|
||||
return false;
|
||||
|
||||
object_registry[id] = &createObject<BaseClass, DerivedClass>;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool unregister(UniqueIdType id)
|
||||
{
|
||||
return (object_registry.erase(id) == 1);
|
||||
}
|
||||
|
||||
BaseClass* create(UniqueIdType id)
|
||||
{
|
||||
Iterator iter = object_registry.find(id);
|
||||
|
||||
if (iter == object_registry.end())
|
||||
return NULL;
|
||||
|
||||
return ((*iter).second)();
|
||||
}
|
||||
|
||||
static ObjectFactory<BaseClass,UniqueIdType>& instance()
|
||||
{
|
||||
static ObjectFactory<BaseClass,UniqueIdType> the_factory;
|
||||
return the_factory;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* OBJECT_FACTORY_H_ */
|
53
3rdparty/flann/random.cpp
vendored
53
3rdparty/flann/random.cpp
vendored
@@ -1,53 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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.
|
||||
*************************************************************************/
|
||||
|
||||
#include "random.h"
|
||||
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
void seed_random(unsigned int seed)
|
||||
{
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
double rand_double(double high, double low)
|
||||
{
|
||||
return low + ((high-low) * (std::rand() / (RAND_MAX + 1.0)));
|
||||
}
|
||||
|
||||
|
||||
int rand_int(int high, int low)
|
||||
{
|
||||
return low + (int) ( double(high-low) * (std::rand() / (RAND_MAX + 1.0)));
|
||||
}
|
||||
|
||||
}
|
134
3rdparty/flann/random.h
vendored
134
3rdparty/flann/random.h
vendored
@@ -1,134 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/**
|
||||
* Seeds the random number generator
|
||||
*/
|
||||
void seed_random(unsigned int seed);
|
||||
|
||||
/*
|
||||
* Generates a random double value.
|
||||
*/
|
||||
double rand_double(double high = 1.0, double low=0);
|
||||
|
||||
/*
|
||||
* Generates a random integer value.
|
||||
*/
|
||||
int rand_int(int high = RAND_MAX, int low = 0);
|
||||
|
||||
|
||||
/**
|
||||
* Random number generator that returns a distinct number from
|
||||
* the [0,n) interval each time.
|
||||
*
|
||||
* TODO: improve on this to use a generator function instead of an
|
||||
* array of randomly permuted numbers
|
||||
*/
|
||||
class UniqueRandom
|
||||
{
|
||||
int* vals;
|
||||
int size;
|
||||
int counter;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Params:
|
||||
* n = the size of the interval from which to generate
|
||||
* random numbers.
|
||||
*/
|
||||
UniqueRandom(int n) : vals(NULL) {
|
||||
init(n);
|
||||
}
|
||||
|
||||
~UniqueRandom()
|
||||
{
|
||||
delete[] vals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the number generator.
|
||||
* Params:
|
||||
* n = the size of the interval from which to generate
|
||||
* random numbers.
|
||||
*/
|
||||
void init(int n)
|
||||
{
|
||||
// create and initialize an array of size n
|
||||
if (vals == NULL || n!=size) {
|
||||
delete[] vals;
|
||||
size = n;
|
||||
vals = new int[size];
|
||||
}
|
||||
for(int i=0;i<size;++i) {
|
||||
vals[i] = i;
|
||||
}
|
||||
|
||||
// shuffle the elements in the array
|
||||
// Fisher-Yates shuffle
|
||||
for (int i=size;i>0;--i) {
|
||||
// int rand = cast(int) (drand48() * n);
|
||||
int rnd = rand_int(i);
|
||||
assert(rnd >=0 && rnd < i);
|
||||
swap(vals[i-1], vals[rnd]);
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a distinct random integer in greater or equal to 0 and less
|
||||
* than 'n' on each call. It should be called maximum 'n' times.
|
||||
* Returns: a random integer
|
||||
*/
|
||||
int next() {
|
||||
if (counter==size) {
|
||||
return -1;
|
||||
} else {
|
||||
return vals[counter++];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //RANDOM_H
|
314
3rdparty/flann/result_set.h
vendored
314
3rdparty/flann/result_set.h
vendored
@@ -1,314 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 RESULTSET_H
|
||||
#define RESULTSET_H
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include "dist.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
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>
|
||||
struct BranchStruct {
|
||||
T node; /* Tree node at which search resumes */
|
||||
float mindistsq; /* Minimum distance to query for all nodes below. */
|
||||
|
||||
bool operator<(const BranchStruct<T>& rhs)
|
||||
{
|
||||
return mindistsq<rhs.mindistsq;
|
||||
}
|
||||
|
||||
static BranchStruct<T> make_branch(T aNode, float dist)
|
||||
{
|
||||
BranchStruct<T> branch;
|
||||
branch.node = aNode;
|
||||
branch.mindistsq = dist;
|
||||
return branch;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ResultSet
|
||||
{
|
||||
protected:
|
||||
const float* target;
|
||||
const float* target_end;
|
||||
int veclen;
|
||||
|
||||
public:
|
||||
|
||||
ResultSet(float* target_ = NULL, int veclen_ = 0) :
|
||||
target(target_), veclen(veclen_) { target_end = target + veclen;}
|
||||
|
||||
virtual ~ResultSet() {}
|
||||
|
||||
virtual void init(const float* target_, int veclen_) = 0;
|
||||
|
||||
virtual int* getNeighbors() = 0;
|
||||
|
||||
virtual float* getDistances() = 0;
|
||||
|
||||
virtual int size() const = 0;
|
||||
|
||||
virtual bool full() const = 0;
|
||||
|
||||
virtual bool addPoint(float* point, int index) = 0;
|
||||
|
||||
virtual float worstDist() const = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class KNNResultSet : public ResultSet
|
||||
{
|
||||
int* indices;
|
||||
float* dists;
|
||||
int capacity;
|
||||
|
||||
int count;
|
||||
|
||||
public:
|
||||
KNNResultSet(int capacity_, float* target_ = NULL, int veclen_ = 0 ) :
|
||||
ResultSet(target_, veclen_), capacity(capacity_), count(0)
|
||||
{
|
||||
indices = new int[capacity_];
|
||||
dists = new float[capacity_];
|
||||
}
|
||||
|
||||
~KNNResultSet()
|
||||
{
|
||||
delete[] indices;
|
||||
delete[] dists;
|
||||
}
|
||||
|
||||
void init(const float* target_, int veclen_)
|
||||
{
|
||||
target = target_;
|
||||
veclen = veclen_;
|
||||
target_end = target + veclen;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
|
||||
int* getNeighbors()
|
||||
{
|
||||
return indices;
|
||||
}
|
||||
|
||||
float* getDistances()
|
||||
{
|
||||
return dists;
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
bool full() const
|
||||
{
|
||||
return count == capacity;
|
||||
}
|
||||
|
||||
|
||||
bool addPoint(float* point, int index)
|
||||
{
|
||||
for (int i=0;i<count;++i) {
|
||||
if (indices[i]==index) return false;
|
||||
}
|
||||
float dist = (float)flann_dist(target, target_end, point);
|
||||
|
||||
if (count<capacity) {
|
||||
indices[count] = index;
|
||||
dists[count] = dist;
|
||||
++count;
|
||||
}
|
||||
else if (dist < dists[count-1] || (dist == dists[count-1] && index < indices[count-1])) {
|
||||
// else if (dist < dists[count-1]) {
|
||||
indices[count-1] = index;
|
||||
dists[count-1] = dist;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = count-1;
|
||||
// bubble up
|
||||
while (i>=1 && (dists[i]<dists[i-1] || (dists[i]==dists[i-1] && indices[i]<indices[i-1]) ) ) {
|
||||
// while (i>=1 && (dists[i]<dists[i-1]) ) {
|
||||
swap(indices[i],indices[i-1]);
|
||||
swap(dists[i],dists[i-1]);
|
||||
i--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float worstDist() const
|
||||
{
|
||||
return (count<capacity) ? numeric_limits<float>::max() : dists[count-1];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A result-set class used when performing a radius based search.
|
||||
*/
|
||||
class RadiusResultSet : public ResultSet
|
||||
{
|
||||
struct Item {
|
||||
int index;
|
||||
float dist;
|
||||
|
||||
bool operator<(Item rhs) {
|
||||
return dist<rhs.dist;
|
||||
}
|
||||
};
|
||||
|
||||
vector<Item> items;
|
||||
float radius;
|
||||
|
||||
bool sorted;
|
||||
int* indices;
|
||||
float* dists;
|
||||
size_t count;
|
||||
|
||||
private:
|
||||
void resize_vecs()
|
||||
{
|
||||
if (items.size()>count) {
|
||||
if (indices!=NULL) delete[] indices;
|
||||
if (dists!=NULL) delete[] dists;
|
||||
count = items.size();
|
||||
indices = new int[count];
|
||||
dists = new float[count];
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
RadiusResultSet(float radius_) :
|
||||
radius(radius_), indices(NULL), dists(NULL)
|
||||
{
|
||||
sorted = false;
|
||||
items.reserve(16);
|
||||
count = 0;
|
||||
}
|
||||
|
||||
~RadiusResultSet()
|
||||
{
|
||||
if (indices!=NULL) delete[] indices;
|
||||
if (dists!=NULL) delete[] dists;
|
||||
}
|
||||
|
||||
void init(const float* target_, int veclen_)
|
||||
{
|
||||
target = target_;
|
||||
veclen = veclen_;
|
||||
target_end = target + veclen;
|
||||
items.clear();
|
||||
sorted = false;
|
||||
}
|
||||
|
||||
int* getNeighbors()
|
||||
{
|
||||
if (!sorted) {
|
||||
sorted = true;
|
||||
sort_heap(items.begin(), items.end());
|
||||
}
|
||||
resize_vecs();
|
||||
for (size_t i=0;i<items.size();++i) {
|
||||
indices[i] = items[i].index;
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
||||
float* getDistances()
|
||||
{
|
||||
if (!sorted) {
|
||||
sorted = true;
|
||||
sort_heap(items.begin(), items.end());
|
||||
}
|
||||
resize_vecs();
|
||||
for (size_t i=0;i<items.size();++i) {
|
||||
dists[i] = items[i].dist;
|
||||
}
|
||||
return dists;
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return (int)items.size();
|
||||
}
|
||||
|
||||
bool full() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool addPoint(float* point, int index)
|
||||
{
|
||||
Item it;
|
||||
it.index = index;
|
||||
it.dist = (float)flann_dist(target, target_end, point);
|
||||
if (it.dist<=radius) {
|
||||
items.push_back(it);
|
||||
push_heap(items.begin(), items.end());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float worstDist() const
|
||||
{
|
||||
return radius;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //RESULTSET_H
|
73
3rdparty/flann/saving.cpp
vendored
73
3rdparty/flann/saving.cpp
vendored
@@ -1,73 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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.
|
||||
*************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "saving.h"
|
||||
#include "nn_index.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
const char FLANN_SIGNATURE[] = "FLANN_INDEX";
|
||||
|
||||
void save_header(FILE* stream, const NNIndex& index)
|
||||
{
|
||||
IndexHeader header;
|
||||
memset(header.signature, 0 , sizeof(header.signature));
|
||||
strcpy(header.signature, FLANN_SIGNATURE);
|
||||
header.flann_version = (int)FLANN_VERSION;
|
||||
header.index_type = index.getType();
|
||||
header.rows = index.size();
|
||||
header.cols = index.veclen();
|
||||
|
||||
std::fwrite(&header, sizeof(header),1,stream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
IndexHeader load_header(FILE* stream)
|
||||
{
|
||||
IndexHeader header;
|
||||
int read_size = (int)fread(&header,sizeof(header),1,stream);
|
||||
|
||||
if (read_size!=1) {
|
||||
throw FLANNException("Invalid index file, cannot read");
|
||||
}
|
||||
|
||||
if (strcmp(header.signature,FLANN_SIGNATURE)!=0) {
|
||||
throw FLANNException("Invalid index file, wrong signature");
|
||||
}
|
||||
|
||||
return header;
|
||||
|
||||
}
|
||||
|
||||
}
|
87
3rdparty/flann/saving.h
vendored
87
3rdparty/flann/saving.h
vendored
@@ -1,87 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 SAVING_H_
|
||||
#define SAVING_H_
|
||||
|
||||
#include "constants.h"
|
||||
#include "nn_index.h"
|
||||
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/**
|
||||
* Structure representing the index header.
|
||||
*/
|
||||
struct IndexHeader
|
||||
{
|
||||
char signature[16];
|
||||
int flann_version;
|
||||
flann_algorithm_t index_type;
|
||||
int rows;
|
||||
int cols;
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves index header to stream
|
||||
*
|
||||
* @param stream - Stream to save to
|
||||
* @param index - The index to save
|
||||
*/
|
||||
void save_header(FILE* stream, const NNIndex& index);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param stream - Stream to load from
|
||||
* @return Index header
|
||||
*/
|
||||
IndexHeader load_header(FILE* stream);
|
||||
|
||||
|
||||
template<typename T>
|
||||
void save_value(FILE* stream, const T& value, int count = 1)
|
||||
{
|
||||
fwrite(&value, sizeof(value),count, stream);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void load_value(FILE* stream, T& value, int count = 1)
|
||||
{
|
||||
int read_cnt = (int)fread(&value, sizeof(value),count, stream);
|
||||
if (read_cnt!=count) {
|
||||
throw FLANNException("Cannot read from file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SAVING_H_ */
|
186
3rdparty/flann/simplex_downhill.h
vendored
186
3rdparty/flann/simplex_downhill.h
vendored
@@ -1,186 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 SIMPLEX_DOWNHILL_H
|
||||
#define SIMPLEX_DOWNHILL_H
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/**
|
||||
Adds val to array vals (and point to array points) and keeping the arrays sorted by vals.
|
||||
*/
|
||||
template <typename T>
|
||||
void addValue(int pos, float val, float* vals, T* point, T* points, int n)
|
||||
{
|
||||
vals[pos] = val;
|
||||
for (int i=0;i<n;++i) {
|
||||
points[pos*n+i] = point[i];
|
||||
}
|
||||
|
||||
// bubble down
|
||||
int j=pos;
|
||||
while (j>0 && vals[j]<vals[j-1]) {
|
||||
swap(vals[j],vals[j-1]);
|
||||
for (int i=0;i<n;++i) {
|
||||
swap(points[j*n+i],points[(j-1)*n+i]);
|
||||
}
|
||||
--j;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Simplex downhill optimization function.
|
||||
Preconditions: points is a 2D mattrix of size (n+1) x n
|
||||
func is the cost function taking n an array of n params and returning float
|
||||
vals is the cost function in the n+1 simplex points, if NULL it will be computed
|
||||
|
||||
Postcondition: returns optimum value and points[0..n] are the optimum parameters
|
||||
*/
|
||||
template <typename T, typename F>
|
||||
float optimizeSimplexDownhill(T* points, int n, F func, float* vals = NULL )
|
||||
{
|
||||
const int MAX_ITERATIONS = 10;
|
||||
|
||||
assert(n>0);
|
||||
|
||||
T* p_o = new T[n];
|
||||
T* p_r = new T[n];
|
||||
T* p_e = new T[n];
|
||||
|
||||
int alpha = 1;
|
||||
|
||||
int iterations = 0;
|
||||
|
||||
bool ownVals = false;
|
||||
if (vals == NULL) {
|
||||
ownVals = true;
|
||||
vals = new float[n+1];
|
||||
for (int i=0;i<n+1;++i) {
|
||||
float val = func(points+i*n);
|
||||
addValue(i, val, vals, points+i*n, points, n);
|
||||
}
|
||||
}
|
||||
int nn = n*n;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (iterations++ > MAX_ITERATIONS) break;
|
||||
|
||||
// compute average of simplex points (except the highest point)
|
||||
for (int j=0;j<n;++j) {
|
||||
p_o[j] = 0;
|
||||
for (int i=0;i<n;++i) {
|
||||
p_o[i] += points[j*n+i];
|
||||
}
|
||||
}
|
||||
for (int i=0;i<n;++i) {
|
||||
p_o[i] /= n;
|
||||
}
|
||||
|
||||
bool converged = true;
|
||||
for (int i=0;i<n;++i) {
|
||||
if (p_o[i] != points[nn+i]) {
|
||||
converged = false;
|
||||
}
|
||||
}
|
||||
if (converged) break;
|
||||
|
||||
// trying a reflection
|
||||
for (int i=0;i<n;++i) {
|
||||
p_r[i] = p_o[i] + alpha*(p_o[i]-points[nn+i]);
|
||||
}
|
||||
float val_r = func(p_r);
|
||||
|
||||
if (val_r>=vals[0] && val_r<vals[n]) {
|
||||
// reflection between second highest and lowest
|
||||
// add it to the simplex
|
||||
logger.info("Choosing reflection\n");
|
||||
addValue(n, val_r,vals, p_r, points, n);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (val_r<vals[0]) {
|
||||
// value is smaller than smalest in simplex
|
||||
|
||||
// expand some more to see if it drops further
|
||||
for (int i=0;i<n;++i) {
|
||||
p_e[i] = 2*p_r[i]-p_o[i];
|
||||
}
|
||||
float val_e = func(p_e);
|
||||
|
||||
if (val_e<val_r) {
|
||||
logger.info("Choosing reflection and expansion\n");
|
||||
addValue(n, val_e,vals,p_e,points,n);
|
||||
}
|
||||
else {
|
||||
logger.info("Choosing reflection\n");
|
||||
addValue(n, val_r,vals,p_r,points,n);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (val_r>=vals[n]) {
|
||||
for (int i=0;i<n;++i) {
|
||||
p_e[i] = (p_o[i]+points[nn+i])/2;
|
||||
}
|
||||
float val_e = func(p_e);
|
||||
|
||||
if (val_e<vals[n]) {
|
||||
logger.info("Choosing contraction\n");
|
||||
addValue(n,val_e,vals,p_e,points,n);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
{
|
||||
logger.info("Full contraction\n");
|
||||
for (int j=1;j<=n;++j) {
|
||||
for (int i=0;i<n;++i) {
|
||||
points[j*n+i] = (points[j*n+i]+points[i])/2;
|
||||
}
|
||||
float val = func(points+j*n);
|
||||
addValue(j,val,vals,points+j*n,points,n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float bestVal = vals[0];
|
||||
|
||||
delete[] p_r;
|
||||
delete[] p_o;
|
||||
delete[] p_e;
|
||||
if (ownVals) delete[] vals;
|
||||
|
||||
return bestVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //SIMPLEX_DOWNHILL_H
|
90
3rdparty/flann/timer.h
vendored
90
3rdparty/flann/timer.h
vendored
@@ -1,90 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/**
|
||||
* A start-stop timer class.
|
||||
*
|
||||
* Can be used to time portions of code.
|
||||
*/
|
||||
class StartStopTimer
|
||||
{
|
||||
clock_t startTime;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Value of the timer.
|
||||
*/
|
||||
double value;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
StartStopTimer()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the timer.
|
||||
*/
|
||||
void start() {
|
||||
startTime = clock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the timer and updates timer value.
|
||||
*/
|
||||
void stop() {
|
||||
clock_t stopTime = clock();
|
||||
value += ( (double)stopTime - startTime) / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the timer value to 0.
|
||||
*/
|
||||
void reset() {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TIMER_H
|
48
3rdparty/include/flann/common.h
vendored
48
3rdparty/include/flann/common.h
vendored
@@ -1,48 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 COMMOM_H
|
||||
#define COMMOM_H
|
||||
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
class FLANNException : public std::runtime_error {
|
||||
public:
|
||||
FLANNException(const char* message) : std::runtime_error(message) { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //COMMOM_H
|
68
3rdparty/include/flann/constants.h
vendored
68
3rdparty/include/flann/constants.h
vendored
@@ -1,68 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
|
||||
|
||||
const double FLANN_VERSION = 1.20;
|
||||
|
||||
/* Nearest neighbor index algorithms */
|
||||
enum flann_algorithm_t {
|
||||
LINEAR = 0,
|
||||
KDTREE = 1,
|
||||
KMEANS = 2,
|
||||
COMPOSITE = 3,
|
||||
SAVED = 254,
|
||||
AUTOTUNED = 255,
|
||||
};
|
||||
|
||||
enum flann_centers_init_t {
|
||||
CENTERS_RANDOM = 0,
|
||||
CENTERS_GONZALES = 1,
|
||||
CENTERS_KMEANSPP = 2
|
||||
};
|
||||
|
||||
|
||||
enum flann_log_level_t {
|
||||
LOG_NONE = 0,
|
||||
LOG_FATAL = 1,
|
||||
LOG_ERROR = 2,
|
||||
LOG_WARN = 3,
|
||||
LOG_INFO = 4
|
||||
};
|
||||
|
||||
enum flann_distance_t {
|
||||
EUCLIDEAN = 1,
|
||||
MANHATTAN = 2,
|
||||
MINKOWSKI = 3
|
||||
};
|
||||
|
||||
#endif // CONSTANTS_H
|
278
3rdparty/include/flann/flann.h
vendored
278
3rdparty/include/flann/flann.h
vendored
@@ -1,278 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 FLANN_H
|
||||
#define FLANN_H
|
||||
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
/* win32 dll export/import directives */
|
||||
#ifdef flann_EXPORTS
|
||||
#define LIBSPEC __declspec(dllexport)
|
||||
#else
|
||||
#define LIBSPEC __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
/* unix needs nothing */
|
||||
#define LIBSPEC
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct FLANNParameters {
|
||||
flann_algorithm_t algorithm; // the algorithm to use (see constants.h)
|
||||
|
||||
int checks; // how many leafs (features) to check in one search
|
||||
float cb_index; // cluster boundary index. Used when searching the kmeans tree
|
||||
int trees; // number of randomized trees to use (for kdtree)
|
||||
int branching; // branching factor (for kmeans tree)
|
||||
int iterations; // max iterations to perform in one kmeans cluetering (kmeans tree)
|
||||
flann_centers_init_t centers_init; // algorithm used for picking the initial cluetr centers for kmeans tree
|
||||
float target_precision; // precision desired (used for autotuning, -1 otherwise)
|
||||
float build_weight; // build tree time weighting factor
|
||||
float memory_weight; // index memory weigthing factor
|
||||
float sample_fraction; // what fraction of the dataset to use for autotuning
|
||||
|
||||
flann_log_level_t log_level; // determines the verbosity of each flann function
|
||||
char* log_destination; // file where the output should go, NULL for the console
|
||||
long random_seed; // random seed to use
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef void* FLANN_INDEX; // deprecated
|
||||
typedef void* flann_index_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Sets the log level used for all flann functions (unless
|
||||
specified in FLANNParameters for each call
|
||||
|
||||
Params:
|
||||
level = verbosity level (defined in constants.h)
|
||||
*/
|
||||
LIBSPEC void flann_log_verbosity(int level);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the distance type to use throughout FLANN.
|
||||
* If distance type specified is MINKOWSKI, the second argument
|
||||
* specifies which order the minkowski distance should have.
|
||||
*/
|
||||
LIBSPEC void flann_set_distance_type(flann_distance_t distance_type, int order);
|
||||
|
||||
|
||||
/**
|
||||
Builds and returns an index. It uses autotuning if the target_precision field of index_params
|
||||
is between 0 and 1, or the parameters specified if it's -1.
|
||||
|
||||
Params:
|
||||
dataset = pointer to a data set stored in row major order
|
||||
rows = number of rows (features) in the dataset
|
||||
cols = number of columns in the dataset (feature dimensionality)
|
||||
speedup = speedup over linear search, estimated if using autotuning, output parameter
|
||||
index_params = index related parameters
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: the newly created index or a number <0 for error
|
||||
*/
|
||||
LIBSPEC FLANN_INDEX flann_build_index(float* dataset,
|
||||
int rows,
|
||||
int cols,
|
||||
float* speedup,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Saves the index to a file. Only the index is saved into the file, the dataset corresponding to the index is not saved.
|
||||
*
|
||||
* @param index_id The index that should be saved
|
||||
* @param filename The filename the index should be saved to
|
||||
* @return Returns 0 on success, negative value on error.
|
||||
*/
|
||||
LIBSPEC int flann_save_index(FLANN_INDEX index_id,
|
||||
char* filename);
|
||||
|
||||
|
||||
/**
|
||||
* Loads an index from a file.
|
||||
*
|
||||
* @param filename File to load the index from.
|
||||
* @param dataset The dataset corresponding to the index.
|
||||
* @param rows Dataset tors
|
||||
* @param cols Dataset columns
|
||||
* @return
|
||||
*/
|
||||
LIBSPEC FLANN_INDEX flann_load_index(char* filename,
|
||||
float* dataset,
|
||||
int rows,
|
||||
int cols);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Builds an index and uses it to find nearest neighbors.
|
||||
|
||||
Params:
|
||||
dataset = pointer to a data set stored in row major order
|
||||
rows = number of rows (features) in the dataset
|
||||
cols = number of columns in the dataset (feature dimensionality)
|
||||
testset = pointer to a query set stored in row major order
|
||||
trows = number of rows (features) in the query dataset (same dimensionality as features in the dataset)
|
||||
indices = pointer to matrix for the indices of the nearest neighbors of the testset features in the dataset
|
||||
(must have trows number of rows and nn number of columns)
|
||||
nn = how many nearest neighbors to return
|
||||
index_params = index related parameters
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: zero or -1 for error
|
||||
*/
|
||||
LIBSPEC int flann_find_nearest_neighbors(float* dataset,
|
||||
int rows,
|
||||
int cols,
|
||||
float* testset,
|
||||
int trows,
|
||||
int* indices,
|
||||
float* dists,
|
||||
int nn,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Searches for nearest neighbors using the index provided
|
||||
|
||||
Params:
|
||||
index_id = the index (constructed previously using flann_build_index).
|
||||
testset = pointer to a query set stored in row major order
|
||||
trows = number of rows (features) in the query dataset (same dimensionality as features in the dataset)
|
||||
indices = pointer to matrix for the indices of the nearest neighbors of the testset features in the dataset
|
||||
(must have trows number of rows and nn number of columns)
|
||||
nn = how many nearest neighbors to return
|
||||
checks = number of checks to perform before the search is stopped
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: zero or a number <0 for error
|
||||
*/
|
||||
LIBSPEC int flann_find_nearest_neighbors_index(FLANN_INDEX index_id,
|
||||
float* testset,
|
||||
int trows,
|
||||
int* indices,
|
||||
float* dists,
|
||||
int nn,
|
||||
int checks,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Performs an radius search using an already constructed index.
|
||||
*
|
||||
* In case of radius search, instead of always returning a predetermined
|
||||
* number of nearest neighbours (for example the 10 nearest neighbours), the
|
||||
* search will return all the neighbours found within a search radius
|
||||
* of the query point.
|
||||
*
|
||||
* The check parameter in the function below sets the level of approximation
|
||||
* for the search by only visiting "checks" number of features in the index
|
||||
* (the same way as for the KNN search). A lower value for checks will give
|
||||
* a higher search speedup at the cost of potentially not returning all the
|
||||
* neighbours in the specified radius.
|
||||
*/
|
||||
LIBSPEC int flann_radius_search(FLANN_INDEX index_ptr, /* the index */
|
||||
float* query, /* query point */
|
||||
int* indices, /* array for storing the indices found (will be modified) */
|
||||
float* dists, /* similar, but for storing distances */
|
||||
int max_nn, /* size of arrays indices and dists */
|
||||
float radius, /* search radius (squared radius for euclidian metric) */
|
||||
int checks, /* number of features to check, sets the level of approximation */
|
||||
FLANNParameters* flann_params);
|
||||
|
||||
|
||||
/**
|
||||
Deletes an index and releases the memory used by it.
|
||||
|
||||
Params:
|
||||
index_id = the index (constructed previously using flann_build_index).
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: zero or a number <0 for error
|
||||
*/
|
||||
LIBSPEC int flann_free_index(FLANN_INDEX index_id,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
/**
|
||||
Clusters the features in the dataset using a hierarchical kmeans clustering approach.
|
||||
This is significantly faster than using a flat kmeans clustering for a large number
|
||||
of clusters.
|
||||
|
||||
Params:
|
||||
dataset = pointer to a data set stored in row major order
|
||||
rows = number of rows (features) in the dataset
|
||||
cols = number of columns in the dataset (feature dimensionality)
|
||||
clusters = number of cluster to compute
|
||||
result = memory buffer where the output cluster centers are storred
|
||||
index_params = used to specify the kmeans tree parameters (branching factor, max number of iterations to use)
|
||||
flann_params = generic flann parameters
|
||||
|
||||
Returns: number of clusters computed or a number <0 for error. This number can be different than the number of clusters requested, due to the
|
||||
way hierarchical clusters are computed. The number of clusters returned will be the highest number of the form
|
||||
(branch_size-1)*K+1 smaller than the number of clusters requested.
|
||||
*/
|
||||
|
||||
LIBSPEC int flann_compute_cluster_centers(float* dataset,
|
||||
int rows,
|
||||
int cols,
|
||||
int clusters,
|
||||
float* result,
|
||||
struct FLANNParameters* flann_params);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
||||
|
||||
#include "flann.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*FLANN_H*/
|
246
3rdparty/include/flann/flann.hpp
vendored
246
3rdparty/include/flann/flann.hpp
vendored
@@ -1,246 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 FLANN_HPP_
|
||||
#define FLANN_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "constants.h"
|
||||
#include "common.h"
|
||||
#include "matrix.h"
|
||||
|
||||
#include "flann.h"
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
class NNIndex;
|
||||
|
||||
class IndexFactory
|
||||
{
|
||||
public:
|
||||
virtual ~IndexFactory() {}
|
||||
virtual NNIndex* createIndex(const Matrix<float>& dataset) const = 0;
|
||||
};
|
||||
|
||||
struct IndexParams : public IndexFactory {
|
||||
protected:
|
||||
IndexParams() {};
|
||||
public:
|
||||
|
||||
static IndexParams* createFromParameters(const FLANNParameters& p);
|
||||
|
||||
void fromParameters(const FLANNParameters&) {};
|
||||
void toParameters(FLANNParameters&) { };
|
||||
};
|
||||
|
||||
struct LinearIndexParams : public IndexParams {
|
||||
LinearIndexParams() {};
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct KDTreeIndexParams : public IndexParams {
|
||||
KDTreeIndexParams(int trees_ = 4) : trees(trees_) {};
|
||||
|
||||
int trees; // number of randomized trees to use (for kdtree)
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
|
||||
void fromParameters(const FLANNParameters& p)
|
||||
{
|
||||
trees = p.trees;
|
||||
}
|
||||
|
||||
void toParameters(FLANNParameters& p)
|
||||
{
|
||||
p.algorithm = KDTREE;
|
||||
p.trees = trees;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct KMeansIndexParams : public IndexParams {
|
||||
KMeansIndexParams(int branching_ = 32, int iterations_ = 11,
|
||||
flann_centers_init_t centers_init_ = CENTERS_RANDOM, float cb_index_ = 0.2 ) :
|
||||
branching(branching_),
|
||||
iterations(iterations_),
|
||||
centers_init(centers_init_),
|
||||
cb_index(cb_index_) {};
|
||||
|
||||
int branching; // branching factor (for kmeans tree)
|
||||
int iterations; // max iterations to perform in one kmeans clustering (kmeans tree)
|
||||
flann_centers_init_t centers_init; // algorithm used for picking the initial cluster centers for kmeans tree
|
||||
float cb_index; // cluster boundary index. Used when searching the kmeans tree
|
||||
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
|
||||
void fromParameters(const FLANNParameters& p)
|
||||
{
|
||||
branching = p.branching;
|
||||
iterations = p.iterations;
|
||||
centers_init = p.centers_init;
|
||||
cb_index = p.cb_index;
|
||||
}
|
||||
|
||||
void toParameters(FLANNParameters& p)
|
||||
{
|
||||
p.algorithm = KMEANS;
|
||||
p.branching = branching;
|
||||
p.iterations = iterations;
|
||||
p.centers_init = centers_init;
|
||||
p.cb_index = cb_index;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct CompositeIndexParams : public IndexParams {
|
||||
CompositeIndexParams(int trees_ = 4, int branching_ = 32, int iterations_ = 11,
|
||||
flann_centers_init_t centers_init_ = CENTERS_RANDOM, float cb_index_ = 0.2 ) :
|
||||
trees(trees_),
|
||||
branching(branching_),
|
||||
iterations(iterations_),
|
||||
centers_init(centers_init_),
|
||||
cb_index(cb_index_) {};
|
||||
|
||||
int trees; // number of randomized trees to use (for kdtree)
|
||||
int branching; // branching factor (for kmeans tree)
|
||||
int iterations; // max iterations to perform in one kmeans clustering (kmeans tree)
|
||||
flann_centers_init_t centers_init; // algorithm used for picking the initial cluster centers for kmeans tree
|
||||
float cb_index; // cluster boundary index. Used when searching the kmeans tree
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
|
||||
void fromParameters(const FLANNParameters& p)
|
||||
{
|
||||
trees = p.trees;
|
||||
branching = p.branching;
|
||||
iterations = p.iterations;
|
||||
centers_init = p.centers_init;
|
||||
cb_index = p.cb_index;
|
||||
}
|
||||
|
||||
void toParameters(FLANNParameters& p)
|
||||
{
|
||||
p.algorithm = COMPOSITE;
|
||||
p.trees = trees;
|
||||
p.branching = branching;
|
||||
p.iterations = iterations;
|
||||
p.centers_init = centers_init;
|
||||
p.cb_index = cb_index;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct AutotunedIndexParams : public IndexParams {
|
||||
AutotunedIndexParams( float target_precision_ = 0.9, float build_weight_ = 0.01,
|
||||
float memory_weight_ = 0, float sample_fraction_ = 0.1) :
|
||||
target_precision(target_precision_),
|
||||
build_weight(build_weight_),
|
||||
memory_weight(memory_weight_),
|
||||
sample_fraction(sample_fraction_) {};
|
||||
|
||||
float target_precision; // precision desired (used for autotuning, -1 otherwise)
|
||||
float build_weight; // build tree time weighting factor
|
||||
float memory_weight; // index memory weighting factor
|
||||
float sample_fraction; // what fraction of the dataset to use for autotuning
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
|
||||
void fromParameters(const FLANNParameters& p)
|
||||
{
|
||||
target_precision = p.target_precision;
|
||||
build_weight = p.build_weight;
|
||||
memory_weight = p.memory_weight;
|
||||
sample_fraction = p.sample_fraction;
|
||||
}
|
||||
|
||||
void toParameters(FLANNParameters& p)
|
||||
{
|
||||
p.algorithm = AUTOTUNED;
|
||||
p.target_precision = target_precision;
|
||||
p.build_weight = build_weight;
|
||||
p.memory_weight = memory_weight;
|
||||
p.sample_fraction = sample_fraction;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct SavedIndexParams : public IndexParams {
|
||||
SavedIndexParams() {
|
||||
throw FLANNException("I don't know which index to load");
|
||||
}
|
||||
SavedIndexParams(std::string filename_) : filename(filename_) {}
|
||||
|
||||
std::string filename; // filename of the stored index
|
||||
|
||||
NNIndex* createIndex(const Matrix<float>& dataset) const;
|
||||
};
|
||||
|
||||
|
||||
struct SearchParams {
|
||||
SearchParams(int checks_ = 32) :
|
||||
checks(checks_) {};
|
||||
|
||||
int checks;
|
||||
};
|
||||
|
||||
|
||||
class Index {
|
||||
NNIndex* nnIndex;
|
||||
|
||||
public:
|
||||
Index(const Matrix<float>& features, const IndexParams& params);
|
||||
|
||||
~Index();
|
||||
|
||||
void knnSearch(const Matrix<float>& queries, Matrix<int>& indices, Matrix<float>& dists, int knn, const SearchParams& params);
|
||||
|
||||
int radiusSearch(const Matrix<float>& query, Matrix<int> indices, Matrix<float> dists, float radius, const SearchParams& params);
|
||||
|
||||
void save(std::string filename);
|
||||
|
||||
int veclen() const;
|
||||
|
||||
int size() const;
|
||||
};
|
||||
|
||||
|
||||
int hierarchicalClustering(const Matrix<float>& features, Matrix<float>& centers, const KMeansIndexParams& params);
|
||||
|
||||
|
||||
}
|
||||
#endif /* FLANN_HPP_ */
|
163
3rdparty/include/flann/matrix.h
vendored
163
3rdparty/include/flann/matrix.h
vendored
@@ -1,163 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 DATASET_H
|
||||
#define DATASET_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "random.h"
|
||||
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
/**
|
||||
* Class implementing a generic rectangular dataset.
|
||||
*/
|
||||
template <typename T>
|
||||
class Matrix {
|
||||
|
||||
/**
|
||||
* Flag showing if the class owns its data storage.
|
||||
*/
|
||||
bool ownData;
|
||||
|
||||
void shallow_copy(const Matrix& rhs)
|
||||
{
|
||||
data = rhs.data;
|
||||
rows = rhs.rows;
|
||||
cols = rhs.cols;
|
||||
ownData = false;
|
||||
}
|
||||
|
||||
public:
|
||||
long rows;
|
||||
long cols;
|
||||
T* data;
|
||||
|
||||
|
||||
Matrix(long rows_, long cols_, T* data_ = NULL) :
|
||||
ownData(false), rows(rows_), cols(cols_), data(data_)
|
||||
{
|
||||
if (data_==NULL) {
|
||||
data = new T[rows*cols];
|
||||
ownData = true;
|
||||
}
|
||||
}
|
||||
|
||||
Matrix(const Matrix& d)
|
||||
{
|
||||
shallow_copy(d);
|
||||
}
|
||||
|
||||
const Matrix& operator=(const Matrix& rhs)
|
||||
{
|
||||
if (this!=&rhs) {
|
||||
shallow_copy(rhs);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Matrix()
|
||||
{
|
||||
if (ownData) {
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator that return a (pointer to a) row of the data.
|
||||
*/
|
||||
T* operator[](long index)
|
||||
{
|
||||
return data+index*cols;
|
||||
}
|
||||
|
||||
T* operator[](long index) const
|
||||
{
|
||||
return data+index*cols;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Matrix<T>* sample(long size, bool remove = false)
|
||||
{
|
||||
UniqueRandom rand(rows);
|
||||
Matrix<T> *newSet = new Matrix<T>(size,cols);
|
||||
|
||||
T *src,*dest;
|
||||
for (long i=0;i<size;++i) {
|
||||
long r = rand.next();
|
||||
dest = (*newSet)[i];
|
||||
src = (*this)[r];
|
||||
for (long j=0;j<cols;++j) {
|
||||
dest[j] = src[j];
|
||||
}
|
||||
if (remove) {
|
||||
dest = (*this)[rows-i-1];
|
||||
src = (*this)[r];
|
||||
for (long j=0;j<cols;++j) {
|
||||
swap(*src,*dest);
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remove) {
|
||||
rows -= size;
|
||||
}
|
||||
|
||||
return newSet;
|
||||
}
|
||||
|
||||
Matrix<T>* sample(long size) const
|
||||
{
|
||||
UniqueRandom rand(rows);
|
||||
Matrix<T> *newSet = new Matrix<T>(size,cols);
|
||||
|
||||
T *src,*dest;
|
||||
for (long i=0;i<size;++i) {
|
||||
long r = rand.next();
|
||||
dest = (*newSet)[i];
|
||||
src = (*this)[r];
|
||||
for (long j=0;j<cols;++j) {
|
||||
dest[j] = src[j];
|
||||
}
|
||||
}
|
||||
|
||||
return newSet;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif //DATASET_H
|
134
3rdparty/include/flann/random.h
vendored
134
3rdparty/include/flann/random.h
vendored
@@ -1,134 +0,0 @@
|
||||
/***********************************************************************
|
||||
* 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 RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
|
||||
/**
|
||||
* Seeds the random number generator
|
||||
*/
|
||||
void seed_random(unsigned int seed);
|
||||
|
||||
/*
|
||||
* Generates a random double value.
|
||||
*/
|
||||
double rand_double(double high = 1.0, double low=0);
|
||||
|
||||
/*
|
||||
* Generates a random integer value.
|
||||
*/
|
||||
int rand_int(int high = RAND_MAX, int low = 0);
|
||||
|
||||
|
||||
/**
|
||||
* Random number generator that returns a distinct number from
|
||||
* the [0,n) interval each time.
|
||||
*
|
||||
* TODO: improve on this to use a generator function instead of an
|
||||
* array of randomly permuted numbers
|
||||
*/
|
||||
class UniqueRandom
|
||||
{
|
||||
int* vals;
|
||||
int size;
|
||||
int counter;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Params:
|
||||
* n = the size of the interval from which to generate
|
||||
* random numbers.
|
||||
*/
|
||||
UniqueRandom(int n) : vals(NULL) {
|
||||
init(n);
|
||||
}
|
||||
|
||||
~UniqueRandom()
|
||||
{
|
||||
delete[] vals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the number generator.
|
||||
* Params:
|
||||
* n = the size of the interval from which to generate
|
||||
* random numbers.
|
||||
*/
|
||||
void init(int n)
|
||||
{
|
||||
// create and initialize an array of size n
|
||||
if (vals == NULL || n!=size) {
|
||||
delete[] vals;
|
||||
size = n;
|
||||
vals = new int[size];
|
||||
}
|
||||
for(int i=0;i<size;++i) {
|
||||
vals[i] = i;
|
||||
}
|
||||
|
||||
// shuffle the elements in the array
|
||||
// Fisher-Yates shuffle
|
||||
for (int i=size;i>0;--i) {
|
||||
// int rand = cast(int) (drand48() * n);
|
||||
int rnd = rand_int(i);
|
||||
assert(rnd >=0 && rnd < i);
|
||||
swap(vals[i-1], vals[rnd]);
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a distinct random integer in greater or equal to 0 and less
|
||||
* than 'n' on each call. It should be called maximum 'n' times.
|
||||
* Returns: a random integer
|
||||
*/
|
||||
int next() {
|
||||
if (counter==size) {
|
||||
return -1;
|
||||
} else {
|
||||
return vals[counter++];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //RANDOM_H
|
Reference in New Issue
Block a user