parent
3230073b9b
commit
16b1f61c83
60 changed files with 2127 additions and 3678 deletions
@ -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 |
|
@ -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
|
|
@ -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; |
|
||||||
|
|
||||||
} |
|
@ -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; |
|
||||||
} |
|
||||||
} |
|
@ -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*/ |
|
@ -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_ */ |
|
@ -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
|
|
@ -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
|
|
@ -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))); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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*/ |
|
@ -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_ */ |
|
@ -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
|
|
@ -1 +1 @@ |
|||||||
define_opencv_module(contrib opencv_core opencv_imgproc opencv_calib3d opencv_features2d opencv_highgui opencv_ml opencv_video opencv_objdetect) |
define_opencv_module(contrib opencv_core opencv_imgproc opencv_calib3d opencv_features2d opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_flann) |
||||||
|
@ -1,3 +1,3 @@ |
|||||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/include") |
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/include") |
||||||
set(deps opencv_lapack zlib flann) |
set(deps opencv_lapack zlib) |
||||||
define_opencv_module(core ${deps}) |
define_opencv_module(core ${deps}) |
||||||
|
@ -1,220 +0,0 @@ |
|||||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
|
||||||
//
|
|
||||||
// By downloading, copying, installing or using the software you agree to this license.
|
|
||||||
// If you do not agree to this license, do not download, install,
|
|
||||||
// copy or use the software.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// License Agreement
|
|
||||||
// For Open Source Computer Vision Library
|
|
||||||
//
|
|
||||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
|
||||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
|
||||||
// Third party copyrights are property of their respective owners.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
// are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistribution's of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// * Redistribution's 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.
|
|
||||||
//
|
|
||||||
// * The name of the copyright holders may not be used to endorse or promote products
|
|
||||||
// derived from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// This software is provided by the copyright holders and contributors "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 Intel Corporation or contributors 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.
|
|
||||||
//
|
|
||||||
//M*/
|
|
||||||
|
|
||||||
#ifndef __OPENCV_CORE_FLANN_HPP__ |
|
||||||
#define __OPENCV_CORE_FLANN_HPP__ |
|
||||||
|
|
||||||
#ifdef __cplusplus |
|
||||||
|
|
||||||
namespace cvflann |
|
||||||
{ |
|
||||||
class Index; |
|
||||||
} |
|
||||||
|
|
||||||
namespace cv { |
|
||||||
|
|
||||||
namespace flann { |
|
||||||
|
|
||||||
/* 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 |
|
||||||
}; |
|
||||||
|
|
||||||
class CV_EXPORTS IndexFactory |
|
||||||
{ |
|
||||||
public: |
|
||||||
virtual ~IndexFactory() {} |
|
||||||
virtual ::cvflann::Index* createIndex(const Mat& dataset) const = 0; |
|
||||||
}; |
|
||||||
|
|
||||||
struct CV_EXPORTS IndexParams : public IndexFactory { |
|
||||||
protected: |
|
||||||
IndexParams() {}; |
|
||||||
|
|
||||||
}; |
|
||||||
|
|
||||||
struct CV_EXPORTS LinearIndexParams : public IndexParams { |
|
||||||
LinearIndexParams() {}; |
|
||||||
|
|
||||||
::cvflann::Index* createIndex(const Mat& dataset) const; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct CV_EXPORTS KDTreeIndexParams : public IndexParams { |
|
||||||
KDTreeIndexParams(int trees_ = 4) : trees(trees_) {}; |
|
||||||
|
|
||||||
int trees; // number of randomized trees to use (for kdtree)
|
|
||||||
|
|
||||||
::cvflann::Index* createIndex(const Mat& dataset) const; |
|
||||||
}; |
|
||||||
|
|
||||||
struct CV_EXPORTS 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
|
|
||||||
|
|
||||||
::cvflann::Index* createIndex(const Mat& dataset) const; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
struct CV_EXPORTS 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
|
|
||||||
|
|
||||||
::cvflann::Index* createIndex(const Mat& dataset) const; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
struct CV_EXPORTS 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
|
|
||||||
|
|
||||||
::cvflann::Index* createIndex(const Mat& dataset) const; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
struct CV_EXPORTS SavedIndexParams : public IndexParams { |
|
||||||
SavedIndexParams() {} |
|
||||||
SavedIndexParams(std::string filename_) : filename(filename_) {} |
|
||||||
|
|
||||||
std::string filename; // filename of the stored index
|
|
||||||
|
|
||||||
::cvflann::Index* createIndex(const Mat& dataset) const; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
struct CV_EXPORTS SearchParams { |
|
||||||
SearchParams(int checks_ = 32) : |
|
||||||
checks(checks_) {}; |
|
||||||
|
|
||||||
int checks; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CV_EXPORTS Index { |
|
||||||
::cvflann::Index* nnIndex; |
|
||||||
|
|
||||||
public: |
|
||||||
Index(const Mat& features, const IndexParams& params); |
|
||||||
|
|
||||||
~Index(); |
|
||||||
|
|
||||||
void knnSearch(const vector<float>& queries, vector<int>& indices, vector<float>& dists, int knn, const SearchParams& params); |
|
||||||
void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const SearchParams& params); |
|
||||||
|
|
||||||
int radiusSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, float radius, const SearchParams& params); |
|
||||||
int radiusSearch(const Mat& query, Mat& indices, Mat& dists, float radius, const SearchParams& params); |
|
||||||
|
|
||||||
void save(std::string filename); |
|
||||||
|
|
||||||
int veclen() const; |
|
||||||
|
|
||||||
int size() const; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
CV_EXPORTS int hierarchicalClustering(const Mat& features, Mat& centers, |
|
||||||
const KMeansIndexParams& params); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#endif |
|
@ -1,211 +0,0 @@ |
|||||||
/*********************************************************************
|
|
||||||
* Software License Agreement (BSD License) |
|
||||||
* |
|
||||||
* Copyright (c) 2009, Willow Garage, Inc. |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions |
|
||||||
* are met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* * 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. |
|
||||||
* * Neither the name of the Willow Garage nor the names of its |
|
||||||
* contributors may be used to endorse or promote products derived |
|
||||||
* from this software without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "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 |
|
||||||
* COPYRIGHT OWNER OR CONTRIBUTORS 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 "precomp.hpp" |
|
||||||
#include "flann/flann.hpp" |
|
||||||
|
|
||||||
namespace cv |
|
||||||
{ |
|
||||||
|
|
||||||
namespace flann { |
|
||||||
|
|
||||||
::cvflann::Index* LinearIndexParams::createIndex(const Mat& dataset) const |
|
||||||
{ |
|
||||||
CV_Assert(dataset.type() == CV_32F); |
|
||||||
CV_Assert(dataset.isContinuous()); |
|
||||||
|
|
||||||
// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
|
|
||||||
::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0)); |
|
||||||
|
|
||||||
return new ::cvflann::Index(mat, ::cvflann::LinearIndexParams()); |
|
||||||
} |
|
||||||
|
|
||||||
::cvflann::Index* KDTreeIndexParams::createIndex(const Mat& dataset) const |
|
||||||
{ |
|
||||||
CV_Assert(dataset.type() == CV_32F); |
|
||||||
CV_Assert(dataset.isContinuous()); |
|
||||||
|
|
||||||
// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
|
|
||||||
::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0)); |
|
||||||
|
|
||||||
return new ::cvflann::Index(mat, ::cvflann::KDTreeIndexParams(trees)); |
|
||||||
} |
|
||||||
|
|
||||||
::cvflann::Index* KMeansIndexParams::createIndex(const Mat& dataset) const |
|
||||||
{ |
|
||||||
CV_Assert(dataset.type() == CV_32F); |
|
||||||
CV_Assert(dataset.isContinuous()); |
|
||||||
|
|
||||||
// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
|
|
||||||
::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0)); |
|
||||||
|
|
||||||
return new ::cvflann::Index(mat, ::cvflann::KMeansIndexParams(branching,iterations, (::flann_centers_init_t)centers_init, cb_index)); |
|
||||||
} |
|
||||||
|
|
||||||
::cvflann::Index* CompositeIndexParams::createIndex(const Mat& dataset) const |
|
||||||
{ |
|
||||||
CV_Assert(dataset.type() == CV_32F); |
|
||||||
CV_Assert(dataset.isContinuous()); |
|
||||||
|
|
||||||
// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
|
|
||||||
::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0)); |
|
||||||
|
|
||||||
return new ::cvflann::Index(mat, ::cvflann::CompositeIndexParams(trees, branching, iterations, (::flann_centers_init_t)centers_init, cb_index)); |
|
||||||
} |
|
||||||
|
|
||||||
::cvflann::Index* AutotunedIndexParams::createIndex(const Mat& dataset) const |
|
||||||
{ |
|
||||||
CV_Assert(dataset.type() == CV_32F); |
|
||||||
CV_Assert(dataset.isContinuous()); |
|
||||||
|
|
||||||
// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
|
|
||||||
::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0)); |
|
||||||
|
|
||||||
return new ::cvflann::Index(mat, ::cvflann::AutotunedIndexParams(target_precision, build_weight, memory_weight, sample_fraction)); |
|
||||||
} |
|
||||||
|
|
||||||
::cvflann::Index* SavedIndexParams::createIndex(const Mat& dataset) const |
|
||||||
{ |
|
||||||
CV_Assert(dataset.type() == CV_32F); |
|
||||||
CV_Assert(dataset.isContinuous()); |
|
||||||
|
|
||||||
// TODO: fix ::cvflann::Matrix class so it can be constructed with a const float*
|
|
||||||
::cvflann::Matrix<float> mat(dataset.rows, dataset.cols, (float*)dataset.ptr<float>(0)); |
|
||||||
|
|
||||||
return new ::cvflann::Index(mat, ::cvflann::SavedIndexParams(filename)); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Index::Index(const Mat& dataset, const IndexParams& params) |
|
||||||
{ |
|
||||||
nnIndex = params.createIndex(dataset); |
|
||||||
} |
|
||||||
|
|
||||||
Index::~Index() |
|
||||||
{ |
|
||||||
delete nnIndex; |
|
||||||
} |
|
||||||
|
|
||||||
void Index::knnSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, int knn, const SearchParams& searchParams) |
|
||||||
{ |
|
||||||
|
|
||||||
::cvflann::Matrix<float> m_query(1, (int)query.size(), (float*)&query[0]); |
|
||||||
::cvflann::Matrix<int> m_indices(1, (int)indices.size(), &indices[0]); |
|
||||||
::cvflann::Matrix<float> m_dists(1, (int)dists.size(), &dists[0]); |
|
||||||
|
|
||||||
nnIndex->knnSearch(m_query,m_indices,m_dists,knn,::cvflann::SearchParams(searchParams.checks)); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
void Index::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const SearchParams& searchParams) |
|
||||||
{ |
|
||||||
|
|
||||||
CV_Assert(queries.type() == CV_32F); |
|
||||||
CV_Assert(queries.isContinuous()); |
|
||||||
::cvflann::Matrix<float> m_queries(queries.rows, queries.cols, (float*)queries.ptr<float>(0)); |
|
||||||
|
|
||||||
CV_Assert(indices.type() == CV_32S); |
|
||||||
CV_Assert(indices.isContinuous()); |
|
||||||
::cvflann::Matrix<int> m_indices(indices.rows, indices.cols, (int*)indices.ptr<int>(0)); |
|
||||||
|
|
||||||
CV_Assert(dists.type() == CV_32F); |
|
||||||
CV_Assert(dists.isContinuous()); |
|
||||||
::cvflann::Matrix<float> m_dists(dists.rows, dists.cols, (float*)dists.ptr<float>(0)); |
|
||||||
|
|
||||||
nnIndex->knnSearch(m_queries,m_indices,m_dists,knn,::cvflann::SearchParams(searchParams.checks)); |
|
||||||
} |
|
||||||
|
|
||||||
int Index::radiusSearch(const vector<float>& query, vector<int>& indices, vector<float>& dists, float radius, const SearchParams& searchParams) |
|
||||||
{ |
|
||||||
::cvflann::Matrix<float> m_query(1, (int)query.size(), (float*)&query[0]); |
|
||||||
::cvflann::Matrix<int> m_indices(1, (int)indices.size(), &indices[0]); |
|
||||||
::cvflann::Matrix<float> m_dists(1, (int)dists.size(), &dists[0]); |
|
||||||
|
|
||||||
return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,::cvflann::SearchParams(searchParams.checks)); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
int Index::radiusSearch(const Mat& query, Mat& indices, Mat& dists, float radius, const SearchParams& searchParams) |
|
||||||
{ |
|
||||||
CV_Assert(query.type() == CV_32F); |
|
||||||
CV_Assert(query.isContinuous()); |
|
||||||
::cvflann::Matrix<float> m_query(query.rows, query.cols, (float*)query.ptr<float>(0)); |
|
||||||
|
|
||||||
CV_Assert(indices.type() == CV_32S); |
|
||||||
CV_Assert(indices.isContinuous()); |
|
||||||
::cvflann::Matrix<int> m_indices(indices.rows, indices.cols, (int*)indices.ptr<int>(0)); |
|
||||||
|
|
||||||
CV_Assert(dists.type() == CV_32F); |
|
||||||
CV_Assert(dists.isContinuous()); |
|
||||||
::cvflann::Matrix<float> m_dists(dists.rows, dists.cols, (float*)dists.ptr<float>(0)); |
|
||||||
|
|
||||||
return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,::cvflann::SearchParams(searchParams.checks)); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
void Index::save(string filename) |
|
||||||
{ |
|
||||||
nnIndex->save(filename); |
|
||||||
} |
|
||||||
|
|
||||||
int Index::size() const |
|
||||||
{ |
|
||||||
return nnIndex->size(); |
|
||||||
} |
|
||||||
|
|
||||||
int Index::veclen() const |
|
||||||
{ |
|
||||||
return nnIndex->veclen(); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
int hierarchicalClustering(const Mat& features, Mat& centers, const KMeansIndexParams& params) |
|
||||||
{ |
|
||||||
CV_Assert(features.type() == CV_32F); |
|
||||||
CV_Assert(features.isContinuous()); |
|
||||||
::cvflann::Matrix<float> m_features(features.rows, features.cols, (float*)features.ptr<float>(0)); |
|
||||||
|
|
||||||
CV_Assert(features.type() == CV_32F); |
|
||||||
CV_Assert(features.isContinuous()); |
|
||||||
::cvflann::Matrix<float> m_centers(centers.rows, centers.cols, (float*)centers.ptr<float>(0)); |
|
||||||
|
|
||||||
return ::cvflann::hierarchicalClustering(m_features, m_centers, ::cvflann::KMeansIndexParams(params.branching, params.iterations, |
|
||||||
(::flann_centers_init_t)params.centers_init, params.cb_index)); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,2 +1,2 @@ |
|||||||
define_opencv_module(features2d opencv_core opencv_imgproc opencv_calib3d opencv_highgui) |
define_opencv_module(features2d opencv_core opencv_imgproc opencv_calib3d opencv_highgui opencv_flann) |
||||||
|
|
||||||
|
@ -0,0 +1,2 @@ |
|||||||
|
define_opencv_module(flann opencv_core) |
||||||
|
|
@ -0,0 +1,196 @@ |
|||||||
|
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||||
|
//
|
||||||
|
// By downloading, copying, installing or using the software you agree to this license.
|
||||||
|
// If you do not agree to this license, do not download, install,
|
||||||
|
// copy or use the software.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// License Agreement
|
||||||
|
// For Open Source Computer Vision Library
|
||||||
|
//
|
||||||
|
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||||
|
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||||
|
// Third party copyrights are property of their respective owners.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistribution's of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistribution's 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.
|
||||||
|
//
|
||||||
|
// * The name of the copyright holders may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// This software is provided by the copyright holders and contributors "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 Intel Corporation or contributors 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.
|
||||||
|
//
|
||||||
|
//M*/
|
||||||
|
|
||||||
|
#ifndef __OPENCV_FLANN_HPP__ |
||||||
|
#define __OPENCV_FLANN_HPP__ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
|
||||||
|
#include "opencv2/flann/flann_base.hpp" |
||||||
|
|
||||||
|
namespace cv |
||||||
|
{ |
||||||
|
namespace flann |
||||||
|
{ |
||||||
|
|
||||||
|
template <typename T> struct CvType {}; |
||||||
|
template <> struct CvType<unsigned char> { static int type() { return CV_8U; } }; |
||||||
|
template <> struct CvType<char> { static int type() { return CV_8S; } }; |
||||||
|
template <> struct CvType<unsigned short> { static int type() { return CV_16U; } }; |
||||||
|
template <> struct CvType<short> { static int type() { return CV_16S; } }; |
||||||
|
template <> struct CvType<int> { static int type() { return CV_32S; } }; |
||||||
|
template <> struct CvType<float> { static int type() { return CV_32F; } }; |
||||||
|
template <> struct CvType<double> { static int type() { return CV_64F; } }; |
||||||
|
|
||||||
|
|
||||||
|
using ::cvflann::IndexParams; |
||||||
|
using ::cvflann::LinearIndexParams; |
||||||
|
using ::cvflann::KDTreeIndexParams; |
||||||
|
using ::cvflann::KMeansIndexParams; |
||||||
|
using ::cvflann::CompositeIndexParams; |
||||||
|
using ::cvflann::AutotunedIndexParams; |
||||||
|
using ::cvflann::SavedIndexParams; |
||||||
|
|
||||||
|
using ::cvflann::SearchParams; |
||||||
|
|
||||||
|
|
||||||
|
template <typename T> |
||||||
|
class Index_ { |
||||||
|
::cvflann::Index<T>* nnIndex; |
||||||
|
|
||||||
|
public: |
||||||
|
Index_(const Mat& features, const IndexParams& params); |
||||||
|
|
||||||
|
~Index_(); |
||||||
|
|
||||||
|
void knnSearch(const vector<T>& query, vector<int>& indices, vector<float>& dists, int knn, const SearchParams& params); |
||||||
|
void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const SearchParams& params); |
||||||
|
|
||||||
|
int radiusSearch(const vector<T>& query, vector<int>& indices, vector<float>& dists, float radius, const SearchParams& params); |
||||||
|
int radiusSearch(const Mat& query, Mat& indices, Mat& dists, float radius, const SearchParams& params); |
||||||
|
|
||||||
|
void save(std::string filename) { nnIndex->save(filename); } |
||||||
|
|
||||||
|
int veclen() const { return nnIndex->veclen(); } |
||||||
|
|
||||||
|
int size() const { return nnIndex->size(); } |
||||||
|
|
||||||
|
const IndexParams* getIndexParameters() { return nnIndex->getParameters(); } |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
template <typename T> |
||||||
|
Index_<T>::Index_(const Mat& dataset, const IndexParams& params) |
||||||
|
{ |
||||||
|
CV_Assert(dataset.type() == CvType<T>::type()); |
||||||
|
CV_Assert(dataset.isContinuous()); |
||||||
|
::cvflann::Matrix<float> m_dataset((T*)dataset.ptr<T>(0), dataset.rows, dataset.cols); |
||||||
|
|
||||||
|
nnIndex = new ::cvflann::Index<T>(m_dataset, params); |
||||||
|
nnIndex->buildIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
template <typename T> |
||||||
|
Index_<T>::~Index_() |
||||||
|
{ |
||||||
|
delete nnIndex; |
||||||
|
} |
||||||
|
|
||||||
|
template <typename T> |
||||||
|
void Index_<T>::knnSearch(const vector<T>& query, vector<int>& indices, vector<float>& dists, int knn, const SearchParams& searchParams) |
||||||
|
{ |
||||||
|
::cvflann::Matrix<T> m_query((T*)&query[0], 1, (int)query.size()); |
||||||
|
::cvflann::Matrix<int> m_indices(&indices[0], 1, (int)indices.size()); |
||||||
|
::cvflann::Matrix<float> m_dists(&dists[0], 1, (int)dists.size()); |
||||||
|
|
||||||
|
nnIndex->knnSearch(m_query,m_indices,m_dists,knn,searchParams); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
template <typename T> |
||||||
|
void Index_<T>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const SearchParams& searchParams) |
||||||
|
{ |
||||||
|
CV_Assert(queries.type() == CvType<T>::type()); |
||||||
|
CV_Assert(queries.isContinuous()); |
||||||
|
::cvflann::Matrix<T> m_queries((T*)queries.ptr<T>(0), queries.rows, queries.cols); |
||||||
|
|
||||||
|
CV_Assert(indices.type() == CV_32S); |
||||||
|
CV_Assert(indices.isContinuous()); |
||||||
|
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols); |
||||||
|
|
||||||
|
CV_Assert(dists.type() == CV_32F); |
||||||
|
CV_Assert(dists.isContinuous()); |
||||||
|
::cvflann::Matrix<float> m_dists((float*)dists.ptr<float>(0), dists.rows, dists.cols); |
||||||
|
|
||||||
|
nnIndex->knnSearch(m_queries,m_indices,m_dists,knn, searchParams); |
||||||
|
} |
||||||
|
|
||||||
|
template <typename T> |
||||||
|
int Index_<T>::radiusSearch(const vector<T>& query, vector<int>& indices, vector<float>& dists, float radius, const SearchParams& searchParams) |
||||||
|
{ |
||||||
|
::cvflann::Matrix<T> m_query((T*)&query[0], 1, (int)query.size()); |
||||||
|
::cvflann::Matrix<int> m_indices(&indices[0], 1, (int)indices.size()); |
||||||
|
::cvflann::Matrix<float> m_dists(&dists[0], 1, (int)dists.size()); |
||||||
|
|
||||||
|
return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); |
||||||
|
} |
||||||
|
|
||||||
|
template <typename T> |
||||||
|
int Index_<T>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, float radius, const SearchParams& searchParams) |
||||||
|
{ |
||||||
|
CV_Assert(query.type() == CvType<T>::type()); |
||||||
|
CV_Assert(query.isContinuous()); |
||||||
|
::cvflann::Matrix<T> m_query((T*)query.ptr<T>(0), query.rows, query.cols); |
||||||
|
|
||||||
|
CV_Assert(indices.type() == CV_32S); |
||||||
|
CV_Assert(indices.isContinuous()); |
||||||
|
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols); |
||||||
|
|
||||||
|
CV_Assert(dists.type() == CV_32F); |
||||||
|
CV_Assert(dists.isContinuous()); |
||||||
|
::cvflann::Matrix<float> m_dists((float*)dists.ptr<float>(0), dists.rows, dists.cols); |
||||||
|
|
||||||
|
return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); |
||||||
|
} |
||||||
|
|
||||||
|
typedef Index_<float> Index; |
||||||
|
|
||||||
|
template <typename ELEM_TYPE, typename DIST_TYPE> |
||||||
|
int hierarchicalClustering(const Mat& features, Mat& centers, const KMeansIndexParams& params) |
||||||
|
{ |
||||||
|
CV_Assert(features.type() == CvType<ELEM_TYPE>::type()); |
||||||
|
CV_Assert(features.isContinuous()); |
||||||
|
::cvflann::Matrix<ELEM_TYPE> m_features((ELEM_TYPE*)features.ptr<ELEM_TYPE>(0), features.rows, features.cols); |
||||||
|
|
||||||
|
CV_Assert(centers.type() == CvType<DIST_TYPE>::type()); |
||||||
|
CV_Assert(centers.isContinuous()); |
||||||
|
::cvflann::Matrix<DIST_TYPE> m_centers((DIST_TYPE*)centers.ptr<DIST_TYPE>(0), centers.rows, centers.cols); |
||||||
|
|
||||||
|
return ::cvflann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE>(m_features, m_centers, params); |
||||||
|
} |
||||||
|
|
||||||
|
} } // namespace cv::flann
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,261 @@ |
|||||||
|
/***********************************************************************
|
||||||
|
* 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 <cassert> |
||||||
|
#include <cstdio> |
||||||
|
|
||||||
|
#include "opencv2/flann/general.h" |
||||||
|
#include "opencv2/flann/matrix.h" |
||||||
|
#include "opencv2/flann/result_set.h" |
||||||
|
#include "opencv2/flann/index_testing.h" |
||||||
|
#include "opencv2/flann/object_factory.h" |
||||||
|
#include "opencv2/flann/saving.h" |
||||||
|
|
||||||
|
#include "opencv2/flann/all_indices.h" |
||||||
|
|
||||||
|
namespace cvflann |
||||||
|
{ |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the log level used for all flann functions |
||||||
|
|
||||||
|
Params: |
||||||
|
level = verbosity level |
||||||
|
*/ |
||||||
|
void 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. |
||||||
|
*/ |
||||||
|
void set_distance_type(flann_distance_t distance_type, int order); |
||||||
|
|
||||||
|
|
||||||
|
struct SavedIndexParams : public IndexParams { |
||||||
|
SavedIndexParams(std::string filename_) : IndexParams(SAVED), filename(filename_) {} |
||||||
|
|
||||||
|
std::string filename; // filename of the stored index
|
||||||
|
|
||||||
|
flann_algorithm_t getIndexType() const { return algorithm; } |
||||||
|
|
||||||
|
void print() const |
||||||
|
{ |
||||||
|
logger.info("Index type: %d\n",(int)algorithm); |
||||||
|
logger.info("Filename: %s\n", filename.c_str()); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
template<typename T> |
||||||
|
class Index { |
||||||
|
NNIndex<T>* nnIndex; |
||||||
|
bool built; |
||||||
|
|
||||||
|
public: |
||||||
|
Index(const Matrix<T>& features, const IndexParams& params); |
||||||
|
|
||||||
|
~Index(); |
||||||
|
|
||||||
|
void buildIndex(); |
||||||
|
|
||||||
|
void knnSearch(const Matrix<T>& queries, Matrix<int>& indices, Matrix<float>& dists, int knn, const SearchParams& params); |
||||||
|
|
||||||
|
int radiusSearch(const Matrix<T>& query, Matrix<int>& indices, Matrix<float>& dists, float radius, const SearchParams& params); |
||||||
|
|
||||||
|
void save(std::string filename); |
||||||
|
|
||||||
|
int veclen() const; |
||||||
|
|
||||||
|
int size() const; |
||||||
|
|
||||||
|
NNIndex<T>* getIndex() { return nnIndex; } |
||||||
|
|
||||||
|
const IndexParams* getIndexParameters() { return nnIndex->getParameters(); } |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
template<typename T> |
||||||
|
NNIndex<T>* load_saved_index(const Matrix<T>& dataset, const string& filename) |
||||||
|
{ |
||||||
|
FILE* fin = fopen(filename.c_str(), "rb"); |
||||||
|
if (fin==NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
IndexHeader header = load_header(fin); |
||||||
|
if (header.data_type!=Datatype<T>::type()) { |
||||||
|
throw FLANNException("Datatype of saved index is different than of the one to be created."); |
||||||
|
} |
||||||
|
if (size_t(header.rows)!=dataset.rows || size_t(header.cols)!=dataset.cols) { |
||||||
|
throw FLANNException("The index saved belongs to a different dataset"); |
||||||
|
} |
||||||
|
|
||||||
|
IndexParams* params = ParamsFactory::instance().create(header.index_type); |
||||||
|
NNIndex<T>* nnIndex = create_index_by_type(dataset, *params); |
||||||
|
nnIndex->loadIndex(fin); |
||||||
|
fclose(fin); |
||||||
|
|
||||||
|
return nnIndex; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
template<typename T> |
||||||
|
Index<T>::Index(const Matrix<T>& dataset, const IndexParams& params) |
||||||
|
{ |
||||||
|
flann_algorithm_t index_type = params.getIndexType(); |
||||||
|
built = false; |
||||||
|
|
||||||
|
if (index_type==SAVED) { |
||||||
|
nnIndex = load_saved_index(dataset, ((const SavedIndexParams&)params).filename); |
||||||
|
built = true; |
||||||
|
} |
||||||
|
else { |
||||||
|
nnIndex = create_index_by_type(dataset, params); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template<typename T> |
||||||
|
Index<T>::~Index() |
||||||
|
{ |
||||||
|
delete nnIndex; |
||||||
|
} |
||||||
|
|
||||||
|
template<typename T> |
||||||
|
void Index<T>::buildIndex() |
||||||
|
{ |
||||||
|
if (!built) { |
||||||
|
nnIndex->buildIndex(); |
||||||
|
built = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template<typename T> |
||||||
|
void Index<T>::knnSearch(const Matrix<T>& queries, Matrix<int>& indices, Matrix<float>& dists, int knn, const SearchParams& searchParams) |
||||||
|
{ |
||||||
|
if (!built) { |
||||||
|
throw FLANNException("You must build the index before searching."); |
||||||
|
} |
||||||
|
assert(queries.cols==nnIndex->veclen()); |
||||||
|
assert(indices.rows>=queries.rows); |
||||||
|
assert(dists.rows>=queries.rows); |
||||||
|
assert(int(indices.cols)>=knn); |
||||||
|
assert(int(dists.cols)>=knn); |
||||||
|
|
||||||
|
KNNResultSet<T> resultSet(knn); |
||||||
|
|
||||||
|
for (size_t i = 0; i < queries.rows; i++) { |
||||||
|
T* target = queries[i]; |
||||||
|
resultSet.init(target, queries.cols); |
||||||
|
|
||||||
|
nnIndex->findNeighbors(resultSet, target, searchParams); |
||||||
|
|
||||||
|
int* neighbors = resultSet.getNeighbors(); |
||||||
|
float* distances = resultSet.getDistances(); |
||||||
|
memcpy(indices[i], neighbors, knn*sizeof(int)); |
||||||
|
memcpy(dists[i], distances, knn*sizeof(float)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template<typename T> |
||||||
|
int Index<T>::radiusSearch(const Matrix<T>& query, Matrix<int>& indices, Matrix<float>& dists, float radius, const SearchParams& searchParams) |
||||||
|
{ |
||||||
|
if (!built) { |
||||||
|
throw FLANNException("You must build the index before searching."); |
||||||
|
} |
||||||
|
if (query.rows!=1) { |
||||||
|
fprintf(stderr, "I can only search one feature at a time for range search\n"); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
assert(query.cols==nnIndex->veclen()); |
||||||
|
|
||||||
|
RadiusResultSet<T> resultSet(radius); |
||||||
|
resultSet.init(query.data, query.cols); |
||||||
|
nnIndex->findNeighbors(resultSet,query.data,searchParams); |
||||||
|
|
||||||
|
// TODO: optimise here
|
||||||
|
int* neighbors = resultSet.getNeighbors(); |
||||||
|
float* distances = resultSet.getDistances(); |
||||||
|
size_t count_nn = min(resultSet.size(), indices.cols); |
||||||
|
|
||||||
|
assert (dists.cols>=count_nn); |
||||||
|
|
||||||
|
for (size_t i=0;i<count_nn;++i) { |
||||||
|
indices[0][i] = neighbors[i]; |
||||||
|
dists[0][i] = distances[i]; |
||||||
|
} |
||||||
|
|
||||||
|
return count_nn; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
template<typename T> |
||||||
|
void Index<T>::save(string filename) |
||||||
|
{ |
||||||
|
FILE* fout = fopen(filename.c_str(), "wb"); |
||||||
|
if (fout==NULL) { |
||||||
|
throw FLANNException("Cannot open file"); |
||||||
|
} |
||||||
|
save_header(fout, *nnIndex); |
||||||
|
nnIndex->saveIndex(fout); |
||||||
|
fclose(fout); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
template<typename T> |
||||||
|
int Index<T>::size() const |
||||||
|
{ |
||||||
|
return nnIndex->size(); |
||||||
|
} |
||||||
|
|
||||||
|
template<typename T> |
||||||
|
int Index<T>::veclen() const |
||||||
|
{ |
||||||
|
return nnIndex->veclen(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
template <typename ELEM_TYPE, typename DIST_TYPE> |
||||||
|
int hierarchicalClustering(const Matrix<ELEM_TYPE>& features, Matrix<DIST_TYPE>& centers, const KMeansIndexParams& params) |
||||||
|
{ |
||||||
|
KMeansIndex<ELEM_TYPE, DIST_TYPE> kmeans(features, params); |
||||||
|
kmeans.buildIndex(); |
||||||
|
|
||||||
|
int clusterNum = kmeans.getClusterCenters(centers); |
||||||
|
return clusterNum; |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace cvflann
|
||||||
|
#endif /* FLANN_HPP_ */ |
@ -0,0 +1,163 @@ |
|||||||
|
/***********************************************************************
|
||||||
|
* 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. |
||||||
|
* |
||||||
|
* 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 IO_H_ |
||||||
|
#define IO_H_ |
||||||
|
|
||||||
|
#include <H5Cpp.h> |
||||||
|
|
||||||
|
#include "opencv2/flann/matrix.h" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef H5_NO_NAMESPACE |
||||||
|
using namespace H5; |
||||||
|
#endif |
||||||
|
|
||||||
|
namespace cvflann
|
||||||
|
{ |
||||||
|
|
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
template<typename T> |
||||||
|
PredType get_hdf5_type() |
||||||
|
{ |
||||||
|
throw FLANNException("Unsupported type for IO operations"); |
||||||
|
} |
||||||
|
|
||||||
|
template<> PredType get_hdf5_type<char>() { return PredType::NATIVE_CHAR; } |
||||||
|
template<> PredType get_hdf5_type<unsigned char>() { return PredType::NATIVE_UCHAR; } |
||||||
|
template<> PredType get_hdf5_type<short int>() { return PredType::NATIVE_SHORT; } |
||||||
|
template<> PredType get_hdf5_type<unsigned short int>() { return PredType::NATIVE_USHORT; } |
||||||
|
template<> PredType get_hdf5_type<int>() { return PredType::NATIVE_INT; } |
||||||
|
template<> PredType get_hdf5_type<unsigned int>() { return PredType::NATIVE_UINT; } |
||||||
|
template<> PredType get_hdf5_type<long>() { return PredType::NATIVE_LONG; } |
||||||
|
template<> PredType get_hdf5_type<unsigned long>() { return PredType::NATIVE_ULONG; } |
||||||
|
template<> PredType get_hdf5_type<float>() { return PredType::NATIVE_FLOAT; } |
||||||
|
template<> PredType get_hdf5_type<double>() { return PredType::NATIVE_DOUBLE; } |
||||||
|
template<> PredType get_hdf5_type<long double>() { return PredType::NATIVE_LDOUBLE; } |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
template<typename T> |
||||||
|
void save_to_file(const cvflann::Matrix<T>& flann_dataset, const std::string& filename, const std::string& name) |
||||||
|
{ |
||||||
|
// Try block to detect exceptions raised by any of the calls inside it
|
||||||
|
try |
||||||
|
{ |
||||||
|
/*
|
||||||
|
* Turn off the auto-printing when failure occurs so that we can |
||||||
|
* handle the errors appropriately |
||||||
|
*/ |
||||||
|
Exception::dontPrint(); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a new file using H5F_ACC_TRUNC access, |
||||||
|
* default file creation properties, and default file |
||||||
|
* access properties. |
||||||
|
*/ |
||||||
|
H5File file( filename, H5F_ACC_TRUNC ); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the size of the array and create the data space for fixed |
||||||
|
* size dataset. |
||||||
|
*/ |
||||||
|
hsize_t dimsf[2]; // dataset dimensions
|
||||||
|
dimsf[0] = flann_dataset.rows; |
||||||
|
dimsf[1] = flann_dataset.cols; |
||||||
|
DataSpace dataspace( 2, dimsf ); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a new dataset within the file using defined dataspace and |
||||||
|
* datatype and default dataset creation properties. |
||||||
|
*/ |
||||||
|
DataSet dataset = file.createDataSet( name, get_hdf5_type<T>(), dataspace ); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Write the data to the dataset using default memory space, file |
||||||
|
* space, and transfer properties. |
||||||
|
*/ |
||||||
|
dataset.write( flann_dataset.data, get_hdf5_type<T>() ); |
||||||
|
} // end of try block
|
||||||
|
catch( H5::Exception& error ) |
||||||
|
{ |
||||||
|
error.printError(); |
||||||
|
throw FLANNException(error.getDetailMsg()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
template<typename T> |
||||||
|
void load_from_file(cvflann::Matrix<T>& flann_dataset, const std::string& filename, const std::string& name) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
Exception::dontPrint(); |
||||||
|
|
||||||
|
H5File file( filename, H5F_ACC_RDONLY ); |
||||||
|
DataSet dataset = file.openDataSet( name ); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the type used by the dataset matches |
||||||
|
*/ |
||||||
|
if ( !(dataset.getDataType()==get_hdf5_type<T>())) { |
||||||
|
throw FLANNException("Dataset matrix type does not match the type to be read."); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Get dataspace of the dataset. |
||||||
|
*/ |
||||||
|
DataSpace dataspace = dataset.getSpace(); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the dimension size of each dimension in the dataspace and |
||||||
|
* display them. |
||||||
|
*/ |
||||||
|
hsize_t dims_out[2]; |
||||||
|
dataspace.getSimpleExtentDims( dims_out, NULL); |
||||||
|
|
||||||
|
flann_dataset.rows = dims_out[0]; |
||||||
|
flann_dataset.cols = dims_out[1]; |
||||||
|
flann_dataset.data = new T[flann_dataset.rows*flann_dataset.cols]; |
||||||
|
|
||||||
|
dataset.read( flann_dataset.data, get_hdf5_type<T>() ); |
||||||
|
} // end of try block
|
||||||
|
catch( H5::Exception &error ) |
||||||
|
{ |
||||||
|
error.printError(); |
||||||
|
throw FLANNException(error.getDetailMsg()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} // namespace cvflann
|
||||||
|
|
||||||
|
#endif /* IO_H_ */ |
@ -0,0 +1,115 @@ |
|||||||
|
/***********************************************************************
|
||||||
|
* 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. |
||||||
|
* |
||||||
|
* 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 NNIndexGOODS 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 "opencv2/flann/general.h" |
||||||
|
#include "opencv2/flann/nn_index.h" |
||||||
|
#include <cstdio> |
||||||
|
#include <cstring> |
||||||
|
|
||||||
|
namespace cvflann |
||||||
|
{ |
||||||
|
template <typename T> struct Datatype {}; |
||||||
|
template<> struct Datatype<char> { static flann_datatype_t type() { return INT8; } }; |
||||||
|
template<> struct Datatype<short> { static flann_datatype_t type() { return INT16; } }; |
||||||
|
template<> struct Datatype<int> { static flann_datatype_t type() { return INT32; } }; |
||||||
|
template<> struct Datatype<unsigned char> { static flann_datatype_t type() { return UINT8; } }; |
||||||
|
template<> struct Datatype<unsigned short> { static flann_datatype_t type() { return UINT16; } }; |
||||||
|
template<> struct Datatype<unsigned int> { static flann_datatype_t type() { return UINT32; } }; |
||||||
|
template<> struct Datatype<float> { static flann_datatype_t type() { return FLOAT32; } }; |
||||||
|
template<> struct Datatype<double> { static flann_datatype_t type() { return FLOAT64; } }; |
||||||
|
|
||||||
|
|
||||||
|
extern const char FLANN_SIGNATURE[]; |
||||||
|
extern const char FLANN_VERSION[]; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure representing the index header. |
||||||
|
*/ |
||||||
|
struct IndexHeader |
||||||
|
{ |
||||||
|
char signature[16]; |
||||||
|
char version[16]; |
||||||
|
flann_datatype_t data_type; |
||||||
|
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 |
||||||
|
*/ |
||||||
|
template<typename ELEM_TYPE> |
||||||
|
void save_header(FILE* stream, const NNIndex<ELEM_TYPE>& index) |
||||||
|
{ |
||||||
|
IndexHeader header; |
||||||
|
memset(header.signature, 0 , sizeof(header.signature)); |
||||||
|
strcpy(header.signature, FLANN_SIGNATURE); |
||||||
|
memset(header.version, 0 , sizeof(header.version)); |
||||||
|
strcpy(header.version, FLANN_VERSION); |
||||||
|
header.data_type = Datatype<ELEM_TYPE>::type(); |
||||||
|
header.index_type = index.getType(); |
||||||
|
header.rows = index.size(); |
||||||
|
header.cols = index.veclen(); |
||||||
|
|
||||||
|
std::fwrite(&header, sizeof(header),1,stream); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* |
||||||
|
* @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 = fread(&value, sizeof(value),count, stream); |
||||||
|
if (read_cnt!=count) { |
||||||
|
throw FLANNException("Cannot read from file"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace cvflann
|
||||||
|
|
||||||
|
#endif /* SAVING_H_ */ |
@ -0,0 +1,222 @@ |
|||||||
|
/***********************************************************************
|
||||||
|
* 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. |
||||||
|
* |
||||||
|
* 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 <cstdio> |
||||||
|
#include <cstdarg> |
||||||
|
#include <sstream> |
||||||
|
|
||||||
|
#include "opencv2/flann/dist.h" |
||||||
|
#include "opencv2/flann/index_testing.h" |
||||||
|
#include "opencv2/flann/logger.h" |
||||||
|
#include "opencv2/flann/logger.h" |
||||||
|
#include "opencv2/flann/saving.h" |
||||||
|
#include "opencv2/flann/general.h" |
||||||
|
|
||||||
|
// index types
|
||||||
|
#include "opencv2/flann/all_indices.h" |
||||||
|
|
||||||
|
namespace cvflann |
||||||
|
{ |
||||||
|
// ----------------------- dist.cpp ---------------------------
|
||||||
|
|
||||||
|
/** 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; |
||||||
|
|
||||||
|
|
||||||
|
double euclidean_dist(const unsigned char* first1, const unsigned char* last1, unsigned char* first2, double acc) |
||||||
|
{ |
||||||
|
double distsq = acc; |
||||||
|
double diff0, diff1, diff2, diff3; |
||||||
|
const unsigned char* lastgroup = last1 - 3; |
||||||
|
|
||||||
|
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; |
||||||
|
} |
||||||
|
while (first1 < last1) { |
||||||
|
diff0 = *first1++ - *first2++; |
||||||
|
distsq += diff0 * diff0; |
||||||
|
} |
||||||
|
return distsq; |
||||||
|
} |
||||||
|
|
||||||
|
// ----------------------- index_testing.cpp ---------------------------
|
||||||
|
|
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
// ----------------------- logger.cpp ---------------------------
|
||||||
|
|
||||||
|
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) |
||||||
|
|
||||||
|
// ----------------------- random.cpp ---------------------------
|
||||||
|
|
||||||
|
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))); |
||||||
|
} |
||||||
|
|
||||||
|
// ----------------------- saving.cpp ---------------------------
|
||||||
|
|
||||||
|
const char FLANN_SIGNATURE[] = "FLANN_INDEX"; |
||||||
|
const char FLANN_VERSION[] = "1.5.0"; |
||||||
|
|
||||||
|
|
||||||
|
IndexHeader load_header(FILE* stream) |
||||||
|
{ |
||||||
|
IndexHeader header; |
||||||
|
int read_size = 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; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// ----------------------- flann.cpp ---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void log_verbosity(int level) |
||||||
|
{ |
||||||
|
if (level>=0) { |
||||||
|
logger.setLevel(level); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void set_distance_type(flann_distance_t distance_type, int order) |
||||||
|
{ |
||||||
|
flann_distance_type = distance_type; |
||||||
|
flann_minkowski_order = order; |
||||||
|
} |
||||||
|
|
||||||
|
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; |
||||||
|
|
||||||
|
|
||||||
|
} // namespace cvflann
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1 +1 @@ |
|||||||
define_opencv_module(legacy opencv_core opencv_imgproc opencv_calib3d opencv_features2d opencv_highgui opencv_video) |
define_opencv_module(legacy opencv_core opencv_imgproc opencv_calib3d opencv_features2d opencv_highgui opencv_video opencv_flann) |
||||||
|
Loading…
Reference in new issue