|
tesseract 3.04.01
|
00001 /****************************************************************************** 00002 ** Filename: kdtree.cpp 00003 ** Purpose: Routines for managing K-D search trees 00004 ** Author: Dan Johnson 00005 ** History: 3/10/89, DSJ, Created. 00006 ** 5/23/89, DSJ, Added circular feature capability. 00007 ** 7/13/89, DSJ, Made tree nodes invisible to outside. 00008 ** 00009 ** (c) Copyright Hewlett-Packard Company, 1988. 00010 ** Licensed under the Apache License, Version 2.0 (the "License"); 00011 ** you may not use this file except in compliance with the License. 00012 ** You may obtain a copy of the License at 00013 ** http://www.apache.org/licenses/LICENSE-2.0 00014 ** Unless required by applicable law or agreed to in writing, software 00015 ** distributed under the License is distributed on an "AS IS" BASIS, 00016 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00017 ** See the License for the specific language governing permissions and 00018 ** limitations under the License. 00019 ******************************************************************************/ 00020 00021 /*----------------------------------------------------------------------------- 00022 Include Files and Type Defines 00023 -----------------------------------------------------------------------------*/ 00024 #include "kdtree.h" 00025 #include "const.h" 00026 #include "emalloc.h" 00027 #include "freelist.h" 00028 #include <stdio.h> 00029 #include <math.h> 00030 00031 #define Magnitude(X) ((X) < 0 ? -(X) : (X)) 00032 #define NodeFound(N,K,D) (( (N)->Key == (K) ) && ( (N)->Data == (D) )) 00033 00034 /*----------------------------------------------------------------------------- 00035 Global Data Definitions and Declarations 00036 -----------------------------------------------------------------------------*/ 00037 #define MINSEARCH -MAX_FLOAT32 00038 #define MAXSEARCH MAX_FLOAT32 00039 00040 // Helper function to find the next essential dimension in a cycle. 00041 static int NextLevel(KDTREE *tree, int level) { 00042 do { 00043 ++level; 00044 if (level >= tree->KeySize) 00045 level = 0; 00046 } while (tree->KeyDesc[level].NonEssential); 00047 return level; 00048 } 00049 00050 //----------------------------------------------------------------------------- 00052 template<typename Key, typename Value> 00053 class MinK { 00054 public: 00055 MinK(Key max_key, int k); 00056 ~MinK(); 00057 00058 struct Element { 00059 Element() {} 00060 Element(const Key& k, const Value& v) : key(k), value(v) {} 00061 00062 Key key; 00063 Value value; 00064 }; 00065 00066 bool insert(Key k, Value v); 00067 const Key& max_insertable_key(); 00068 00069 int elements_count() { return elements_count_; } 00070 const Element* elements() { return elements_; } 00071 00072 private: 00073 const Key max_key_; //< the maximum possible Key 00074 Element* elements_; //< unsorted array of elements 00075 int elements_count_; //< the number of results collected so far 00076 int k_; //< the number of results we want from the search 00077 int max_index_; //< the index of the result with the largest key 00078 }; 00079 00080 template<typename Key, typename Value> 00081 MinK<Key, Value>::MinK(Key max_key, int k) : 00082 max_key_(max_key), elements_count_(0), k_(k < 1 ? 1 : k), max_index_(0) { 00083 elements_ = new Element[k_]; 00084 } 00085 00086 template<typename Key, typename Value> 00087 MinK<Key, Value>::~MinK() { 00088 delete []elements_; 00089 } 00090 00091 template<typename Key, typename Value> 00092 const Key& MinK<Key, Value>::max_insertable_key() { 00093 if (elements_count_ < k_) 00094 return max_key_; 00095 return elements_[max_index_].key; 00096 } 00097 00098 template<typename Key, typename Value> 00099 bool MinK<Key, Value>::insert(Key key, Value value) { 00100 if (elements_count_ < k_) { 00101 elements_[elements_count_++] = Element(key, value); 00102 if (key > elements_[max_index_].key) 00103 max_index_ = elements_count_ - 1; 00104 return true; 00105 } else if (key < elements_[max_index_].key) { 00106 // evict the largest element. 00107 elements_[max_index_] = Element(key, value); 00108 // recompute max_index_ 00109 for (int i = 0; i < elements_count_; i++) { 00110 if (elements_[i].key > elements_[max_index_].key) 00111 max_index_ = i; 00112 } 00113 return true; 00114 } 00115 return false; 00116 } 00117 00118 00119 //----------------------------------------------------------------------------- 00121 class KDTreeSearch { 00122 public: 00123 KDTreeSearch(KDTREE* tree, FLOAT32 *query_point, int k_closest); 00124 ~KDTreeSearch(); 00125 00127 void Search(int *result_count, FLOAT32 *distances, void **results); 00128 00129 private: 00130 void SearchRec(int Level, KDNODE *SubTree); 00131 bool BoxIntersectsSearch(FLOAT32 *lower, FLOAT32 *upper); 00132 00133 KDTREE *tree_; 00134 FLOAT32 *query_point_; 00135 MinK<FLOAT32, void *>* results_; 00136 FLOAT32 *sb_min_; //< search box minimum 00137 FLOAT32 *sb_max_; //< search box maximum 00138 }; 00139 00140 KDTreeSearch::KDTreeSearch(KDTREE* tree, FLOAT32 *query_point, int k_closest) : 00141 tree_(tree), 00142 query_point_(query_point) { 00143 results_ = new MinK<FLOAT32, void *>(MAXSEARCH, k_closest); 00144 sb_min_ = new FLOAT32[tree->KeySize]; 00145 sb_max_ = new FLOAT32[tree->KeySize]; 00146 } 00147 00148 KDTreeSearch::~KDTreeSearch() { 00149 delete results_; 00150 delete[] sb_min_; 00151 delete[] sb_max_; 00152 } 00153 00156 void KDTreeSearch::Search(int *result_count, 00157 FLOAT32 *distances, 00158 void **results) { 00159 if (tree_->Root.Left == NULL) { 00160 *result_count = 0; 00161 } else { 00162 for (int i = 0; i < tree_->KeySize; i++) { 00163 sb_min_[i] = tree_->KeyDesc[i].Min; 00164 sb_max_[i] = tree_->KeyDesc[i].Max; 00165 } 00166 SearchRec(0, tree_->Root.Left); 00167 int count = results_->elements_count(); 00168 *result_count = count; 00169 for (int j = 0; j < count; j++) { 00170 distances[j] = (FLOAT32) sqrt((FLOAT64)results_->elements()[j].key); 00171 results[j] = results_->elements()[j].value; 00172 } 00173 } 00174 } 00175 00176 /*----------------------------------------------------------------------------- 00177 Public Code 00178 -----------------------------------------------------------------------------*/ 00182 KDTREE *MakeKDTree(inT16 KeySize, const PARAM_DESC KeyDesc[]) { 00183 KDTREE *KDTree = (KDTREE *) Emalloc( 00184 sizeof(KDTREE) + (KeySize - 1) * sizeof(PARAM_DESC)); 00185 for (int i = 0; i < KeySize; i++) { 00186 KDTree->KeyDesc[i].NonEssential = KeyDesc[i].NonEssential; 00187 KDTree->KeyDesc[i].Circular = KeyDesc[i].Circular; 00188 if (KeyDesc[i].Circular) { 00189 KDTree->KeyDesc[i].Min = KeyDesc[i].Min; 00190 KDTree->KeyDesc[i].Max = KeyDesc[i].Max; 00191 KDTree->KeyDesc[i].Range = KeyDesc[i].Max - KeyDesc[i].Min; 00192 KDTree->KeyDesc[i].HalfRange = KDTree->KeyDesc[i].Range / 2; 00193 KDTree->KeyDesc[i].MidRange = (KeyDesc[i].Max + KeyDesc[i].Min) / 2; 00194 } else { 00195 KDTree->KeyDesc[i].Min = MINSEARCH; 00196 KDTree->KeyDesc[i].Max = MAXSEARCH; 00197 } 00198 } 00199 KDTree->KeySize = KeySize; 00200 KDTree->Root.Left = NULL; 00201 KDTree->Root.Right = NULL; 00202 return KDTree; 00203 } 00204 00205 00218 void KDStore(KDTREE *Tree, FLOAT32 *Key, void *Data) { 00219 int Level; 00220 KDNODE *Node; 00221 KDNODE **PtrToNode; 00222 00223 PtrToNode = &(Tree->Root.Left); 00224 Node = *PtrToNode; 00225 Level = NextLevel(Tree, -1); 00226 while (Node != NULL) { 00227 if (Key[Level] < Node->BranchPoint) { 00228 PtrToNode = &(Node->Left); 00229 if (Key[Level] > Node->LeftBranch) 00230 Node->LeftBranch = Key[Level]; 00231 } 00232 else { 00233 PtrToNode = &(Node->Right); 00234 if (Key[Level] < Node->RightBranch) 00235 Node->RightBranch = Key[Level]; 00236 } 00237 Level = NextLevel(Tree, Level); 00238 Node = *PtrToNode; 00239 } 00240 00241 *PtrToNode = MakeKDNode(Tree, Key, (void *) Data, Level); 00242 } /* KDStore */ 00243 00244 00264 void 00265 KDDelete (KDTREE * Tree, FLOAT32 Key[], void *Data) { 00266 int Level; 00267 KDNODE *Current; 00268 KDNODE *Father; 00269 00270 /* initialize search at root of tree */ 00271 Father = &(Tree->Root); 00272 Current = Father->Left; 00273 Level = NextLevel(Tree, -1); 00274 00275 /* search tree for node to be deleted */ 00276 while ((Current != NULL) && (!NodeFound (Current, Key, Data))) { 00277 Father = Current; 00278 if (Key[Level] < Current->BranchPoint) 00279 Current = Current->Left; 00280 else 00281 Current = Current->Right; 00282 00283 Level = NextLevel(Tree, Level); 00284 } 00285 00286 if (Current != NULL) { /* if node to be deleted was found */ 00287 if (Current == Father->Left) { 00288 Father->Left = NULL; 00289 Father->LeftBranch = Tree->KeyDesc[Level].Min; 00290 } else { 00291 Father->Right = NULL; 00292 Father->RightBranch = Tree->KeyDesc[Level].Max; 00293 } 00294 00295 InsertNodes(Tree, Current->Left); 00296 InsertNodes(Tree, Current->Right); 00297 FreeSubTree(Current); 00298 } 00299 } /* KDDelete */ 00300 00301 00322 void KDNearestNeighborSearch( 00323 KDTREE *Tree, FLOAT32 Query[], int QuerySize, FLOAT32 MaxDistance, 00324 int *NumberOfResults, void **NBuffer, FLOAT32 DBuffer[]) { 00325 KDTreeSearch search(Tree, Query, QuerySize); 00326 search.Search(NumberOfResults, DBuffer, NBuffer); 00327 } 00328 00329 00330 /*---------------------------------------------------------------------------*/ 00332 void KDWalk(KDTREE *Tree, void_proc action, void *context) { 00333 if (Tree->Root.Left != NULL) 00334 Walk(Tree, action, context, Tree->Root.Left, NextLevel(Tree, -1)); 00335 } 00336 00337 00338 /*---------------------------------------------------------------------------*/ 00351 void FreeKDTree(KDTREE *Tree) { 00352 FreeSubTree(Tree->Root.Left); 00353 memfree(Tree); 00354 } /* FreeKDTree */ 00355 00356 00357 /*----------------------------------------------------------------------------- 00358 Private Code 00359 -----------------------------------------------------------------------------*/ 00360 /*---------------------------------------------------------------------------*/ 00374 KDNODE *MakeKDNode(KDTREE *tree, FLOAT32 Key[], void *Data, int Index) { 00375 KDNODE *NewNode; 00376 00377 NewNode = (KDNODE *) Emalloc (sizeof (KDNODE)); 00378 00379 NewNode->Key = Key; 00380 NewNode->Data = Data; 00381 NewNode->BranchPoint = Key[Index]; 00382 NewNode->LeftBranch = tree->KeyDesc[Index].Min; 00383 NewNode->RightBranch = tree->KeyDesc[Index].Max; 00384 NewNode->Left = NULL; 00385 NewNode->Right = NULL; 00386 00387 return NewNode; 00388 } /* MakeKDNode */ 00389 00390 00391 /*---------------------------------------------------------------------------*/ 00392 void FreeKDNode(KDNODE *Node) { 00393 memfree ((char *)Node); 00394 } 00395 00396 00397 /*---------------------------------------------------------------------------*/ 00403 void KDTreeSearch::SearchRec(int level, KDNODE *sub_tree) { 00404 if (level >= tree_->KeySize) 00405 level = 0; 00406 00407 if (!BoxIntersectsSearch(sb_min_, sb_max_)) 00408 return; 00409 00410 results_->insert(DistanceSquared(tree_->KeySize, tree_->KeyDesc, 00411 query_point_, sub_tree->Key), 00412 sub_tree->Data); 00413 00414 if (query_point_[level] < sub_tree->BranchPoint) { 00415 if (sub_tree->Left != NULL) { 00416 FLOAT32 tmp = sb_max_[level]; 00417 sb_max_[level] = sub_tree->LeftBranch; 00418 SearchRec(NextLevel(tree_, level), sub_tree->Left); 00419 sb_max_[level] = tmp; 00420 } 00421 if (sub_tree->Right != NULL) { 00422 FLOAT32 tmp = sb_min_[level]; 00423 sb_min_[level] = sub_tree->RightBranch; 00424 SearchRec(NextLevel(tree_, level), sub_tree->Right); 00425 sb_min_[level] = tmp; 00426 } 00427 } else { 00428 if (sub_tree->Right != NULL) { 00429 FLOAT32 tmp = sb_min_[level]; 00430 sb_min_[level] = sub_tree->RightBranch; 00431 SearchRec(NextLevel(tree_, level), sub_tree->Right); 00432 sb_min_[level] = tmp; 00433 } 00434 if (sub_tree->Left != NULL) { 00435 FLOAT32 tmp = sb_max_[level]; 00436 sb_max_[level] = sub_tree->LeftBranch; 00437 SearchRec(NextLevel(tree_, level), sub_tree->Left); 00438 sb_max_[level] = tmp; 00439 } 00440 } 00441 } 00442 00443 00444 /*---------------------------------------------------------------------------*/ 00452 FLOAT32 DistanceSquared(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[]) { 00453 FLOAT32 total_distance = 0; 00454 00455 for (; k > 0; k--, p1++, p2++, dim++) { 00456 if (dim->NonEssential) 00457 continue; 00458 00459 FLOAT32 dimension_distance = *p1 - *p2; 00460 00461 /* if this dimension is circular - check wraparound distance */ 00462 if (dim->Circular) { 00463 dimension_distance = Magnitude(dimension_distance); 00464 FLOAT32 wrap_distance = dim->Max - dim->Min - dimension_distance; 00465 dimension_distance = MIN(dimension_distance, wrap_distance); 00466 } 00467 00468 total_distance += dimension_distance * dimension_distance; 00469 } 00470 return total_distance; 00471 } 00472 00473 FLOAT32 ComputeDistance(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[]) { 00474 return sqrt(DistanceSquared(k, dim, p1, p2)); 00475 } 00476 00477 /*---------------------------------------------------------------------------*/ 00482 bool KDTreeSearch::BoxIntersectsSearch(FLOAT32 *lower, FLOAT32 *upper) { 00483 FLOAT32 *query = query_point_; 00484 FLOAT64 total_distance = 0.0; 00485 FLOAT64 radius_squared = 00486 results_->max_insertable_key() * results_->max_insertable_key(); 00487 PARAM_DESC *dim = tree_->KeyDesc; 00488 00489 for (int i = tree_->KeySize; i > 0; i--, dim++, query++, lower++, upper++) { 00490 if (dim->NonEssential) 00491 continue; 00492 00493 FLOAT32 dimension_distance; 00494 if (*query < *lower) 00495 dimension_distance = *lower - *query; 00496 else if (*query > *upper) 00497 dimension_distance = *query - *upper; 00498 else 00499 dimension_distance = 0; 00500 00501 /* if this dimension is circular - check wraparound distance */ 00502 if (dim->Circular) { 00503 FLOAT32 wrap_distance = MAX_FLOAT32; 00504 if (*query < *lower) 00505 wrap_distance = *query + dim->Max - dim->Min - *upper; 00506 else if (*query > *upper) 00507 wrap_distance = *lower - (*query - (dim->Max - dim->Min)); 00508 dimension_distance = MIN(dimension_distance, wrap_distance); 00509 } 00510 00511 total_distance += dimension_distance * dimension_distance; 00512 if (total_distance >= radius_squared) 00513 return FALSE; 00514 } 00515 return TRUE; 00516 } 00517 00518 00519 /*---------------------------------------------------------------------------*/ 00535 void Walk(KDTREE *tree, void_proc action, void *context, 00536 KDNODE *sub_tree, inT32 level) { 00537 (*action)(context, sub_tree->Data, level); 00538 if (sub_tree->Left != NULL) 00539 Walk(tree, action, context, sub_tree->Left, NextLevel(tree, level)); 00540 if (sub_tree->Right != NULL) 00541 Walk(tree, action, context, sub_tree->Right, NextLevel(tree, level)); 00542 } 00543 00544 00546 void InsertNodes(KDTREE *tree, KDNODE *nodes) { 00547 if (nodes == NULL) 00548 return; 00549 00550 KDStore(tree, nodes->Key, nodes->Data); 00551 InsertNodes(tree, nodes->Left); 00552 InsertNodes(tree, nodes->Right); 00553 } 00554 00556 void FreeSubTree(KDNODE *sub_tree) { 00557 if (sub_tree != NULL) { 00558 FreeSubTree(sub_tree->Left); 00559 FreeSubTree(sub_tree->Right); 00560 memfree(sub_tree); 00561 } 00562 }