+ " <type>5</type>\n"
+ " <value>0.</value></_>\n"
+ " <_>\n"
+ + " <name>explore_all_trees</name>\n"
+ + " <type>8</type>\n"
+ + " <value>0</value></_>\n"
+ + " <_>\n"
+ " <name>sorted</name>\n"
+ " <type>8</type>\n" // FLANN_INDEX_TYPE_BOOL
+ " <value>1</value></_></searchParams>\n"
+ " 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";
+ " 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";
" 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";
{
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<BranchSt>* heap = new Heap<BranchSt>((int)size_);
std::vector<bool> checked(size_,false);
int checks = 0;
for (int i=0; i<trees_; ++i) {
- findNN(root[i], result, vec, checks, maxChecks, heap, checked);
- if ((checks >= 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<maxChecks || !result.full())) {
NodePtr node = branch.node;
- findNN(node, result, vec, checks, maxChecks, heap, checked);
+ findNN(node, result, vec, checks, maxChecks, heap, checked, false);
}
delete heap;
void findNN(NodePtr node, ResultSet<DistanceType>& result, const ElementType* vec, int& checks, int maxChecks,
- Heap<BranchSt>* heap, std::vector<bool>& checked)
+ Heap<BranchSt>* heap, std::vector<bool>& 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; i<node->size; ++i) {
}
}
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);
}
}
*/
void findNeighbors(ResultSet<DistanceType>& 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);
}
}
* because the tree traversal is abandoned after a given number of descends in
* the tree.
*/
- void getNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, int maxCheck, float epsError)
+ void getNeighbors(ResultSet<DistanceType>& result, const ElementType* vec,
+ int maxCheck, float epsError, bool explore_all_trees = false)
{
int i;
BranchSt branch;
/* 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;
* at least "mindistsq".
*/
void searchLevel(ResultSet<DistanceType>& result_set, const ElementType* vec, NodePtr node, DistanceType mindist, int& checkCount, int maxCheck,
- float epsError, Heap<BranchSt>* heap, DynamicBitset& checked)
+ float epsError, Heap<BranchSt>* heap, DynamicBitset& checked, bool explore_all_trees = false)
{
if (result_set.worstDist()<mindist) {
// printf("Ignoring branch, too far\n");
current checkID.
*/
int index = node->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++;
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 );
};
{
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;
// search for eps-approximate neighbours (default: 0)
(*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;
}
};
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);
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;
}