diff --git a/modules/features2d/misc/java/test/FlannBasedDescriptorMatcherTest.java b/modules/features2d/misc/java/test/FlannBasedDescriptorMatcherTest.java
index 2b1aa7a97b..72947a85cd 100644
--- a/modules/features2d/misc/java/test/FlannBasedDescriptorMatcherTest.java
+++ b/modules/features2d/misc/java/test/FlannBasedDescriptorMatcherTest.java
@@ -43,6 +43,10 @@ public class FlannBasedDescriptorMatcherTest extends OpenCVTestCase {
+ " 5\n"
+ " 0.\n"
+ " <_>\n"
+ + " explore_all_trees\n"
+ + " 8\n"
+ + " 0\n"
+ + " <_>\n"
+ " sorted\n"
+ " 8\n" // FLANN_INDEX_TYPE_BOOL
+ " 1\n"
@@ -68,6 +72,10 @@ public class FlannBasedDescriptorMatcherTest extends OpenCVTestCase {
+ " type: 5\n"
+ " value: 0.\n"
+ " -\n"
+ + " name: explore_all_trees\n"
+ + " type: 8\n"
+ + " value: 0\n"
+ + " -\n"
+ " name: sorted\n"
+ " type: 8\n" // FLANN_INDEX_TYPE_BOOL
+ " value: 1\n";
@@ -92,6 +100,10 @@ public class FlannBasedDescriptorMatcherTest extends OpenCVTestCase {
+ " type: 5\n"
+ " value: 4.\n"// this line is changed!
+ " -\n"
+ + " name: explore_all_trees\n"
+ + " type: 8\n"
+ + " value: 1\n"// this line is changed!
+ + " -\n"
+ " name: sorted\n"
+ " type: 8\n" // FLANN_INDEX_TYPE_BOOL
+ " value: 1\n";
diff --git a/modules/features2d/test/test_matchers_algorithmic.cpp b/modules/features2d/test/test_matchers_algorithmic.cpp
index 6af6f5ffc7..203b640209 100644
--- a/modules/features2d/test/test_matchers_algorithmic.cpp
+++ b/modules/features2d/test/test_matchers_algorithmic.cpp
@@ -582,6 +582,10 @@ TEST( Features2d_FlannBasedMatcher, read_write )
" type: 5\n"
" value: 4.\n"// this line is changed!
" -\n"
+ " name: explore_all_trees\n"
+ " type: 8\n"
+ " value: 0\n"
+ " -\n"
" name: sorted\n"
" type: 8\n" // FLANN_INDEX_TYPE_BOOL
" value: 1\n";
diff --git a/modules/flann/include/opencv2/flann/hierarchical_clustering_index.h b/modules/flann/include/opencv2/flann/hierarchical_clustering_index.h
index c068e184bb..9d01644aad 100644
--- a/modules/flann/include/opencv2/flann/hierarchical_clustering_index.h
+++ b/modules/flann/include/opencv2/flann/hierarchical_clustering_index.h
@@ -548,6 +548,7 @@ public:
{
const int maxChecks = get_param(searchParams,"checks",32);
+ const bool explore_all_trees = get_param(searchParams,"explore_all_trees",false);
// Priority queue storing intermediate branches in the best-bin-first search
Heap* heap = new Heap((int)size_);
@@ -555,15 +556,15 @@ public:
std::vector checked(size_,false);
int checks = 0;
for (int i=0; i= maxChecks) && result.full())
+ findNN(root[i], result, vec, checks, maxChecks, heap, checked, explore_all_trees);
+ if (!explore_all_trees && (checks >= maxChecks) && result.full())
break;
}
BranchSt branch;
while (heap->popMin(branch) && (checks& result, const ElementType* vec, int& checks, int maxChecks,
- Heap* heap, std::vector& checked)
+ Heap* heap, std::vector& checked, bool explore_all_trees = false)
{
if (node->childs==NULL) {
- if ((checks>=maxChecks) && result.full()) {
+ if (!explore_all_trees && (checks>=maxChecks) && result.full()) {
return;
}
for (int i=0; isize; ++i) {
@@ -778,7 +779,7 @@ private:
}
}
delete[] domain_distances;
- findNN(node->childs[best_index],result,vec, checks, maxChecks, heap, checked);
+ findNN(node->childs[best_index],result,vec, checks, maxChecks, heap, checked, explore_all_trees);
}
}
diff --git a/modules/flann/include/opencv2/flann/kdtree_index.h b/modules/flann/include/opencv2/flann/kdtree_index.h
index acc87a3198..5a3d9d7fe0 100644
--- a/modules/flann/include/opencv2/flann/kdtree_index.h
+++ b/modules/flann/include/opencv2/flann/kdtree_index.h
@@ -204,14 +204,15 @@ public:
*/
void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE
{
- int maxChecks = get_param(searchParams,"checks", 32);
- float epsError = 1+get_param(searchParams,"eps",0.0f);
+ const int maxChecks = get_param(searchParams,"checks", 32);
+ const float epsError = 1+get_param(searchParams,"eps",0.0f);
+ const bool explore_all_trees = get_param(searchParams,"explore_all_trees",false);
if (maxChecks==FLANN_CHECKS_UNLIMITED) {
getExactNeighbors(result, vec, epsError);
}
else {
- getNeighbors(result, vec, maxChecks, epsError);
+ getNeighbors(result, vec, maxChecks, epsError, explore_all_trees);
}
}
@@ -440,7 +441,8 @@ private:
* because the tree traversal is abandoned after a given number of descends in
* the tree.
*/
- void getNeighbors(ResultSet& result, const ElementType* vec, int maxCheck, float epsError)
+ void getNeighbors(ResultSet& result, const ElementType* vec,
+ int maxCheck, float epsError, bool explore_all_trees = false)
{
int i;
BranchSt branch;
@@ -451,12 +453,16 @@ private:
/* Search once through each tree down to root. */
for (i = 0; i < trees_; ++i) {
- searchLevel(result, vec, tree_roots_[i], 0, checkCount, maxCheck, epsError, heap, checked);
+ searchLevel(result, vec, tree_roots_[i], 0, checkCount, maxCheck,
+ epsError, heap, checked, explore_all_trees);
+ if (!explore_all_trees && (checkCount >= maxCheck) && result.full())
+ break;
}
/* Keep searching other branches from heap until finished. */
while ( heap->popMin(branch) && (checkCount < maxCheck || !result.full() )) {
- searchLevel(result, vec, branch.node, branch.mindist, checkCount, maxCheck, epsError, heap, checked);
+ searchLevel(result, vec, branch.node, branch.mindist, checkCount, maxCheck,
+ epsError, heap, checked, false);
}
delete heap;
@@ -471,7 +477,7 @@ private:
* at least "mindistsq".
*/
void searchLevel(ResultSet& result_set, const ElementType* vec, NodePtr node, DistanceType mindist, int& checkCount, int maxCheck,
- float epsError, Heap* heap, DynamicBitset& checked)
+ float epsError, Heap* heap, DynamicBitset& checked, bool explore_all_trees = false)
{
if (result_set.worstDist()divfeat;
- if ( checked.test(index) || ((checkCount>=maxCheck)&& result_set.full()) ) return;
+ if ( checked.test(index) ||
+ (!explore_all_trees && (checkCount>=maxCheck) && result_set.full()) ) {
+ return;
+ }
checked.set(index);
checkCount++;
diff --git a/modules/flann/include/opencv2/flann/miniflann.hpp b/modules/flann/include/opencv2/flann/miniflann.hpp
index 253290790e..093646254c 100644
--- a/modules/flann/include/opencv2/flann/miniflann.hpp
+++ b/modules/flann/include/opencv2/flann/miniflann.hpp
@@ -143,6 +143,7 @@ struct CV_EXPORTS SavedIndexParams : public IndexParams
struct CV_EXPORTS SearchParams : public IndexParams
{
+ SearchParams( int checks, float eps, bool sorted, bool explore_all_trees );
SearchParams( int checks = 32, float eps = 0, bool sorted = true );
};
diff --git a/modules/flann/include/opencv2/flann/params.h b/modules/flann/include/opencv2/flann/params.h
index b8f7331905..dd3092f065 100644
--- a/modules/flann/include/opencv2/flann/params.h
+++ b/modules/flann/include/opencv2/flann/params.h
@@ -46,6 +46,16 @@ typedef std::map IndexParams;
struct SearchParams : public IndexParams
{
SearchParams(int checks = 32, float eps = 0, bool sorted = true )
+ {
+ init(checks, eps, sorted, false);
+ }
+
+ SearchParams(int checks, float eps, bool sorted, bool explore_all_trees )
+ {
+ init(checks, eps, sorted, explore_all_trees);
+ }
+
+ void init(int checks = 32, float eps = 0, bool sorted = true, bool explore_all_trees = false )
{
// how many leafs to visit when searching for neighbours (-1 for unlimited)
(*this)["checks"] = checks;
@@ -53,6 +63,10 @@ struct SearchParams : public IndexParams
(*this)["eps"] = eps;
// only for radius search, require neighbours sorted by distance (default: true)
(*this)["sorted"] = sorted;
+ // if false, search stops at the tree reaching the number of max checks (original behavior).
+ // When true, we do a descent in each tree and. Like before the alternative paths
+ // stored in the heap are not be processed further when max checks is reached.
+ (*this)["explore_all_trees"] = explore_all_trees;
}
};
diff --git a/modules/flann/src/miniflann.cpp b/modules/flann/src/miniflann.cpp
index 6cb99564e5..5d2d655feb 100644
--- a/modules/flann/src/miniflann.cpp
+++ b/modules/flann/src/miniflann.cpp
@@ -294,6 +294,23 @@ SavedIndexParams::SavedIndexParams(const String& _filename)
p["filename"] = filename;
}
+SearchParams::SearchParams( int checks, float eps, bool sorted, bool explore_all_trees )
+{
+ ::cvflann::IndexParams& p = get_params(*this);
+
+ // how many leafs to visit when searching for neighbours (-1 for unlimited)
+ p["checks"] = checks;
+ // search for eps-approximate neighbours (default: 0)
+ p["eps"] = eps;
+ // only for radius search, require neighbours sorted by distance (default: true)
+ p["sorted"] = sorted;
+ // if false, search stops at the tree reaching the number of max checks (original behavior).
+ // When true, we do a descent in each tree and. Like before the alternative paths
+ // stored in the heap are not be processed further when max checks is reached.
+ p["explore_all_trees"] = explore_all_trees;
+}
+
+
SearchParams::SearchParams( int checks, float eps, bool sorted )
{
::cvflann::IndexParams& p = get_params(*this);
@@ -304,6 +321,10 @@ SearchParams::SearchParams( int checks, float eps, bool sorted )
p["eps"] = eps;
// only for radius search, require neighbours sorted by distance (default: true)
p["sorted"] = sorted;
+ // if false, search stops at the tree reaching the number of max checks (original behavior).
+ // When true, we do a descent in each tree and. Like before the alternative paths
+ // stored in the heap are not be processed further when max checks is reached.
+ p["explore_all_trees"] = false;
}