upgraded to FLANN 1.6. Added miniflann interface, which is now used in the rest of OpenCV. Added Python bindings for FLANN.

This commit is contained in:
Vadim Pisarevsky
2011-07-13 23:04:39 +00:00
parent 4e42bf6308
commit 562914e33b
48 changed files with 8503 additions and 3606 deletions

View File

@@ -27,199 +27,31 @@
*************************************************************************/
#include "precomp.hpp"
#include "opencv2/flann/flann.hpp"
namespace cvflann
{
// ----------------------- dist.cpp ---------------------------
/** Global variable indicating the distance metric
* to be used.
*/
flann_distance_t flann_distance_type_ = FLANN_DIST_EUCLIDEAN;
flann_distance_t flann_distance_type() { return flann_distance_type_; }
/**
* Zero iterator that emulates a zero feature.
*/
ZeroIterator<float> zero_;
ZeroIterator<float>& zero() { return zero_; }
/**
* Order of Minkowski distance to use.
*/
int flann_minkowski_order_;
int flann_minkowski_order() { return 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;
}
/** Global variable indicating the distance metric to be used.
* \deprecated Provided for backward compatibility
*/
flann_distance_t flann_distance_type_ = FLANN_DIST_L2;
flann_distance_t flann_distance_type() { return flann_distance_type_; }
/**
* Set distance type to used
* \deprecated
*/
void set_distance_type(flann_distance_t distance_type, int /*order*/)
{
printf("[WARNING] The cvflann::set_distance_type function is deperecated, "
"use cv::flann::GenericIndex<Distance> instead.\n");
if (distance_type != FLANN_DIST_L1 && distance_type != FLANN_DIST_L2) {
printf("[ERROR] cvflann::set_distance_type only provides backwards compatibility "
"for the L1 and L2 distances. "
"For other distance types you must use cv::flann::GenericIndex<Distance>\n");
}
flann_distance_type_ = distance_type;
}
return count;
}
// ----------------------- logger.cpp ---------------------------
Logger logger_;
Logger& logger() { return 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, FLANN_LOG_FATAL)
LOG_METHOD(error, FLANN_LOG_ERROR)
LOG_METHOD(warn, FLANN_LOG_WARN)
LOG_METHOD(info, FLANN_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";
const char* FLANN_SIGNATURE() { return FLANN_SIGNATURE_; }
const char* FLANN_VERSION() { return FLANN_VERSION_; }
IndexHeader load_header(FILE* stream)
{
IndexHeader header;
size_t 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;
}
static ParamsFactory the_factory;
ParamsFactory& ParamsFactory_instance()
{
return the_factory;
}
class StaticInit
{
public:
StaticInit()
{
ParamsFactory_instance().register_<LinearIndexParams>(FLANN_INDEX_LINEAR);
ParamsFactory_instance().register_<KDTreeIndexParams>(FLANN_INDEX_KDTREE);
ParamsFactory_instance().register_<KMeansIndexParams>(FLANN_INDEX_KMEANS);
ParamsFactory_instance().register_<CompositeIndexParams>(FLANN_INDEX_COMPOSITE);
ParamsFactory_instance().register_<AutotunedIndexParams>(FLANN_INDEX_AUTOTUNED);
// ParamsFactory::instance().register_<SavedIndexParams>(FLANN_INDEX_SAVED);
}
};
StaticInit __init;
} // namespace cvflann
void dummyfunc() {}
}