Exposed HierarchicalClusteringIndex in OpenCV wrapper

pull/33/head
Marius Muja 12 years ago
parent 56200dbd37
commit 7236858bea
  1. 1
      modules/flann/include/opencv2/flann/defines.h
  2. 2
      modules/flann/include/opencv2/flann/hierarchical_clustering_index.h
  3. 6
      modules/flann/include/opencv2/flann/miniflann.hpp
  4. 149
      modules/flann/src/miniflann.cpp

@ -137,6 +137,7 @@ enum flann_distance_t
FLANN_DIST_CS = 7, FLANN_DIST_CS = 7,
FLANN_DIST_KULLBACK_LEIBLER = 8, FLANN_DIST_KULLBACK_LEIBLER = 8,
FLANN_DIST_KL = 8, FLANN_DIST_KL = 8,
FLANN_DIST_HAMMING = 9,
// deprecated constants, should use the FLANN_DIST_* ones instead // deprecated constants, should use the FLANN_DIST_* ones instead
EUCLIDEAN = 1, EUCLIDEAN = 1,

@ -619,13 +619,13 @@ private:
if (checks>=maxChecks) { if (checks>=maxChecks) {
if (result.full()) return; if (result.full()) return;
} }
checks += node->size;
for (int i=0; i<node->size; ++i) { for (int i=0; i<node->size; ++i) {
int index = node->indices[i]; int index = node->indices[i];
if (!checked[index]) { if (!checked[index]) {
DistanceType dist = distance(dataset[index], vec, veclen_); DistanceType dist = distance(dataset[index], vec, veclen_);
result.addPoint(dist, index); result.addPoint(dist, index);
checked[index] = true; checked[index] = true;
++checks;
} }
} }
} }

@ -100,6 +100,12 @@ struct CV_EXPORTS AutotunedIndexParams : public IndexParams
float memory_weight = 0, float sample_fraction = 0.1); float memory_weight = 0, float sample_fraction = 0.1);
}; };
struct CV_EXPORTS HierarchicalClusteringIndexParams : public IndexParams
{
HierarchicalClusteringIndexParams(int branching = 32,
cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, int trees = 4, int leaf_size = 100 );
};
struct CV_EXPORTS KMeansIndexParams : public IndexParams struct CV_EXPORTS KMeansIndexParams : public IndexParams
{ {
KMeansIndexParams(int branching = 32, int iterations = 11, KMeansIndexParams(int branching = 32, int iterations = 11,

@ -256,17 +256,33 @@ KMeansIndexParams::KMeansIndexParams(int branching, int iterations,
// cluster boundary index. Used when searching the kmeans tree // cluster boundary index. Used when searching the kmeans tree
p["cb_index"] = cb_index; p["cb_index"] = cb_index;
} }
HierarchicalClusteringIndexParams::HierarchicalClusteringIndexParams(int branching ,
flann_centers_init_t centers_init,
int trees, int leaf_size)
{
::cvflann::IndexParams& p = get_params(*this);
p["algorithm"] = FLANN_INDEX_HIERARCHICAL;
// The branching factor used in the hierarchical clustering
p["branching"] = branching;
// Algorithm used for picking the initial cluster centers
p["centers_init"] = centers_init;
// number of parallel trees to build
p["trees"] = trees;
// maximum leaf size
p["leaf_size"] = leaf_size;
}
LshIndexParams::LshIndexParams(int table_number, int key_size, int multi_probe_level) LshIndexParams::LshIndexParams(int table_number, int key_size, int multi_probe_level)
{ {
::cvflann::IndexParams& p = get_params(*this); ::cvflann::IndexParams& p = get_params(*this);
p["algorithm"] = FLANN_INDEX_LSH; p["algorithm"] = FLANN_INDEX_LSH;
// The number of hash tables to use // The number of hash tables to use
p["table_number"] = (unsigned)table_number; p["table_number"] = table_number;
// The length of the key in the hash tables // The length of the key in the hash tables
p["key_size"] = (unsigned)key_size; p["key_size"] = key_size;
// Number of levels to use in multi-probe (0 for standard LSH) // Number of levels to use in multi-probe (0 for standard LSH)
p["multi_probe_level"] = (unsigned)multi_probe_level; p["multi_probe_level"] = multi_probe_level;
} }
SavedIndexParams::SavedIndexParams(const std::string& _filename) SavedIndexParams::SavedIndexParams(const std::string& _filename)
@ -317,7 +333,6 @@ typedef ::cvflann::Hamming<uchar> HammingDistance;
#else #else
typedef ::cvflann::HammingLUT HammingDistance; typedef ::cvflann::HammingLUT HammingDistance;
#endif #endif
typedef ::cvflann::LshIndex<HammingDistance> LshIndex;
Index::Index() Index::Index()
{ {
@ -351,14 +366,11 @@ void Index::build(InputArray _data, const IndexParams& params, flann_distance_t
featureType = data.type(); featureType = data.type();
distType = _distType; distType = _distType;
if( algo == FLANN_INDEX_LSH )
{
buildIndex_<HammingDistance, LshIndex>(index, data, params);
return;
}
switch( distType ) switch( distType )
{ {
case FLANN_DIST_HAMMING:
buildIndex< HammingDistance >(index, data, params);
break;
case FLANN_DIST_L2: case FLANN_DIST_L2:
buildIndex< ::cvflann::L2<float> >(index, data, params); buildIndex< ::cvflann::L2<float> >(index, data, params);
break; break;
@ -406,15 +418,12 @@ void Index::release()
{ {
if( !index ) if( !index )
return; return;
if( algo == FLANN_INDEX_LSH )
{ switch( distType )
deleteIndex_<LshIndex>(index);
}
else
{ {
CV_Assert( featureType == CV_32F ); case FLANN_DIST_HAMMING:
switch( distType ) deleteIndex< HammingDistance >(index);
{ break;
case FLANN_DIST_L2: case FLANN_DIST_L2:
deleteIndex< ::cvflann::L2<float> >(index); deleteIndex< ::cvflann::L2<float> >(index);
break; break;
@ -440,7 +449,6 @@ void Index::release()
#endif #endif
default: default:
CV_Error(CV_StsBadArg, "Unknown/unsupported distance type"); CV_Error(CV_StsBadArg, "Unknown/unsupported distance type");
}
} }
index = 0; index = 0;
} }
@ -539,18 +547,15 @@ void Index::knnSearch(InputArray _query, OutputArray _indices,
OutputArray _dists, int knn, const SearchParams& params) OutputArray _dists, int knn, const SearchParams& params)
{ {
Mat query = _query.getMat(), indices, dists; Mat query = _query.getMat(), indices, dists;
int dtype = algo == FLANN_INDEX_LSH ? CV_32S : CV_32F; int dtype = distType == FLANN_DIST_HAMMING ? CV_32S : CV_32F;
createIndicesDists( _indices, _dists, indices, dists, query.rows, knn, knn, dtype ); createIndicesDists( _indices, _dists, indices, dists, query.rows, knn, knn, dtype );
if( algo == FLANN_INDEX_LSH )
{
runKnnSearch_<HammingDistance, LshIndex>(index, query, indices, dists, knn, params);
return;
}
switch( distType ) switch( distType )
{ {
case FLANN_DIST_HAMMING:
runKnnSearch<HammingDistance>(index, query, indices, dists, knn, params);
break;
case FLANN_DIST_L2: case FLANN_DIST_L2:
runKnnSearch< ::cvflann::L2<float> >(index, query, indices, dists, knn, params); runKnnSearch< ::cvflann::L2<float> >(index, query, indices, dists, knn, params);
break; break;
@ -584,7 +589,7 @@ int Index::radiusSearch(InputArray _query, OutputArray _indices,
const SearchParams& params) const SearchParams& params)
{ {
Mat query = _query.getMat(), indices, dists; Mat query = _query.getMat(), indices, dists;
int dtype = algo == FLANN_INDEX_LSH ? CV_32S : CV_32F; int dtype = distType == FLANN_DIST_HAMMING ? CV_32S : CV_32F;
CV_Assert( maxResults > 0 ); CV_Assert( maxResults > 0 );
createIndicesDists( _indices, _dists, indices, dists, query.rows, maxResults, INT_MAX, dtype ); createIndicesDists( _indices, _dists, indices, dists, query.rows, maxResults, INT_MAX, dtype );
@ -593,6 +598,9 @@ int Index::radiusSearch(InputArray _query, OutputArray _indices,
switch( distType ) switch( distType )
{ {
case FLANN_DIST_HAMMING:
return runRadiusSearch< HammingDistance >(index, query, indices, dists, radius, params);
case FLANN_DIST_L2: case FLANN_DIST_L2:
return runRadiusSearch< ::cvflann::L2<float> >(index, query, indices, dists, radius, params); return runRadiusSearch< ::cvflann::L2<float> >(index, query, indices, dists, radius, params);
case FLANN_DIST_L1: case FLANN_DIST_L1:
@ -647,15 +655,11 @@ void Index::save(const std::string& filename) const
if (fout == NULL) if (fout == NULL)
CV_Error_( CV_StsError, ("Can not open file %s for writing FLANN index\n", filename.c_str()) ); CV_Error_( CV_StsError, ("Can not open file %s for writing FLANN index\n", filename.c_str()) );
if( algo == FLANN_INDEX_LSH )
{
saveIndex_<LshIndex>(this, index, fout);
fclose(fout);
return;
}
switch( distType ) switch( distType )
{ {
case FLANN_DIST_HAMMING:
saveIndex< HammingDistance >(this, index, fout);
break;
case FLANN_DIST_L2: case FLANN_DIST_L2:
saveIndex< ::cvflann::L2<float> >(this, index, fout); saveIndex< ::cvflann::L2<float> >(this, index, fout);
break; break;
@ -739,54 +743,51 @@ bool Index::load(InputArray _data, const std::string& filename)
return false; return false;
} }
if( !((algo == FLANN_INDEX_LSH && featureType == CV_8U) || int idistType = 0;
(algo != FLANN_INDEX_LSH && featureType == CV_32F)) ) ::cvflann::load_value(fin, idistType);
distType = (flann_distance_t)idistType;
if( !((distType == FLANN_DIST_HAMMING && featureType == CV_8U) ||
(distType != FLANN_DIST_HAMMING && featureType == CV_32F)) )
{ {
fprintf(stderr, "Reading FLANN index error: unsupported feature type %d for the index type %d\n", featureType, algo); fprintf(stderr, "Reading FLANN index error: unsupported feature type %d for the index type %d\n", featureType, algo);
fclose(fin); fclose(fin);
return false; return false;
} }
int idistType = 0;
::cvflann::load_value(fin, idistType);
distType = (flann_distance_t)idistType;
if( algo == FLANN_INDEX_LSH ) switch( distType )
{
loadIndex_<HammingDistance, LshIndex>(this, index, data, fin);
}
else
{ {
switch( distType ) case FLANN_DIST_HAMMING:
{ loadIndex< HammingDistance >(this, index, data, fin);
case FLANN_DIST_L2: break;
loadIndex< ::cvflann::L2<float> >(this, index, data, fin); case FLANN_DIST_L2:
break; loadIndex< ::cvflann::L2<float> >(this, index, data, fin);
case FLANN_DIST_L1: break;
loadIndex< ::cvflann::L1<float> >(this, index, data, fin); case FLANN_DIST_L1:
break; loadIndex< ::cvflann::L1<float> >(this, index, data, fin);
#if MINIFLANN_SUPPORT_EXOTIC_DISTANCE_TYPES break;
case FLANN_DIST_MAX: #if MINIFLANN_SUPPORT_EXOTIC_DISTANCE_TYPES
loadIndex< ::cvflann::MaxDistance<float> >(this, index, data, fin); case FLANN_DIST_MAX:
break; loadIndex< ::cvflann::MaxDistance<float> >(this, index, data, fin);
case FLANN_DIST_HIST_INTERSECT: break;
loadIndex< ::cvflann::HistIntersectionDistance<float> >(index, data, fin); case FLANN_DIST_HIST_INTERSECT:
break; loadIndex< ::cvflann::HistIntersectionDistance<float> >(index, data, fin);
case FLANN_DIST_HELLINGER: break;
loadIndex< ::cvflann::HellingerDistance<float> >(this, index, data, fin); case FLANN_DIST_HELLINGER:
break; loadIndex< ::cvflann::HellingerDistance<float> >(this, index, data, fin);
case FLANN_DIST_CHI_SQUARE: break;
loadIndex< ::cvflann::ChiSquareDistance<float> >(this, index, data, fin); case FLANN_DIST_CHI_SQUARE:
break; loadIndex< ::cvflann::ChiSquareDistance<float> >(this, index, data, fin);
case FLANN_DIST_KL: break;
loadIndex< ::cvflann::KL_Divergence<float> >(this, index, data, fin); case FLANN_DIST_KL:
break; loadIndex< ::cvflann::KL_Divergence<float> >(this, index, data, fin);
#endif break;
default: #endif
fprintf(stderr, "Reading FLANN index error: unsupported distance type %d\n", distType); default:
ok = false; fprintf(stderr, "Reading FLANN index error: unsupported distance type %d\n", distType);
} ok = false;
} }
if( fin ) if( fin )
fclose(fin); fclose(fin);
return ok; return ok;

Loading…
Cancel
Save