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") |
||||
set(deps opencv_lapack zlib flann) |
||||
set(deps opencv_lapack zlib) |
||||
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