tesseract  4.00.00dev
kdtree.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  ** Filename: kdtree.cpp
3  ** Purpose: Routines for managing K-D search trees
4  ** Author: Dan Johnson
5  ** History: 3/10/89, DSJ, Created.
6  ** 5/23/89, DSJ, Added circular feature capability.
7  ** 7/13/89, DSJ, Made tree nodes invisible to outside.
8  **
9  ** (c) Copyright Hewlett-Packard Company, 1988.
10  ** Licensed under the Apache License, Version 2.0 (the "License");
11  ** you may not use this file except in compliance with the License.
12  ** You may obtain a copy of the License at
13  ** http://www.apache.org/licenses/LICENSE-2.0
14  ** Unless required by applicable law or agreed to in writing, software
15  ** distributed under the License is distributed on an "AS IS" BASIS,
16  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  ** See the License for the specific language governing permissions and
18  ** limitations under the License.
19  ******************************************************************************/
20 
21 /*-----------------------------------------------------------------------------
22  Include Files and Type Defines
23 -----------------------------------------------------------------------------*/
24 #include "kdtree.h"
25 #include "const.h"
26 #include "emalloc.h"
27 #include <stdio.h>
28 #include <math.h>
29 
30 #define Magnitude(X) ((X) < 0 ? -(X) : (X))
31 #define NodeFound(N,K,D) (( (N)->Key == (K) ) && ( (N)->Data == (D) ))
32 
33 /*-----------------------------------------------------------------------------
34  Global Data Definitions and Declarations
35 -----------------------------------------------------------------------------*/
36 #define MINSEARCH -MAX_FLOAT32
37 #define MAXSEARCH MAX_FLOAT32
38 
39 // Helper function to find the next essential dimension in a cycle.
40 static int NextLevel(KDTREE *tree, int level) {
41  do {
42  ++level;
43  if (level >= tree->KeySize)
44  level = 0;
45  } while (tree->KeyDesc[level].NonEssential);
46  return level;
47 }
48 
49 //-----------------------------------------------------------------------------
51 template<typename Key, typename Value>
52 class MinK {
53  public:
54  MinK(Key max_key, int k);
55  ~MinK();
56 
57  struct Element {
58  Element() {}
59  Element(const Key& k, const Value& v) : key(k), value(v) {}
60 
61  Key key;
62  Value value;
63  };
64 
65  bool insert(Key k, Value v);
66  const Key& max_insertable_key();
67 
68  int elements_count() { return elements_count_; }
69  const Element* elements() { return elements_; }
70 
71  private:
72  const Key max_key_; //< the maximum possible Key
73  Element *elements_; //< unsorted array of elements
74  int elements_count_; //< the number of results collected so far
75  int k_; //< the number of results we want from the search
76  int max_index_; //< the index of the result with the largest key
77 };
78 
79 template<typename Key, typename Value>
80 MinK<Key, Value>::MinK(Key max_key, int k) :
81  max_key_(max_key), elements_count_(0), k_(k < 1 ? 1 : k), max_index_(0) {
82  elements_ = new Element[k_];
83 }
84 
85 template<typename Key, typename Value>
87  delete []elements_;
88 }
89 
90 template<typename Key, typename Value>
92  if (elements_count_ < k_)
93  return max_key_;
94  return elements_[max_index_].key;
95 }
96 
97 template<typename Key, typename Value>
98 bool MinK<Key, Value>::insert(Key key, Value value) {
99  if (elements_count_ < k_) {
100  elements_[elements_count_++] = Element(key, value);
101  if (key > elements_[max_index_].key)
102  max_index_ = elements_count_ - 1;
103  return true;
104  } else if (key < elements_[max_index_].key) {
105  // evict the largest element.
106  elements_[max_index_] = Element(key, value);
107  // recompute max_index_
108  for (int i = 0; i < elements_count_; i++) {
109  if (elements_[i].key > elements_[max_index_].key)
110  max_index_ = i;
111  }
112  return true;
113  }
114  return false;
115 }
116 
117 
118 //-----------------------------------------------------------------------------
122  public:
123  KDTreeSearch(KDTREE* tree, FLOAT32 *query_point, int k_closest);
124  ~KDTreeSearch();
125 
127  void Search(int *result_count, FLOAT32 *distances, void **results);
128 
129  private:
130  void SearchRec(int Level, KDNODE *SubTree);
131  bool BoxIntersectsSearch(FLOAT32 *lower, FLOAT32 *upper);
132 
133  KDTREE *tree_;
134  FLOAT32 *query_point_;
135  FLOAT32 *sb_min_; //< search box minimum
136  FLOAT32 *sb_max_; //< search box maximum
137  MinK<FLOAT32, void *> results_;
138 };
139 
140 KDTreeSearch::KDTreeSearch(KDTREE* tree, FLOAT32 *query_point, int k_closest) :
141  tree_(tree),
142  query_point_(query_point),
143  results_(MAXSEARCH, k_closest) {
144  sb_min_ = new FLOAT32[tree->KeySize];
145  sb_max_ = new FLOAT32[tree->KeySize];
146 }
147 
149  delete[] sb_min_;
150  delete[] sb_max_;
151 }
152 
155 void KDTreeSearch::Search(int *result_count,
156  FLOAT32 *distances,
157  void **results) {
158  if (tree_->Root.Left == NULL) {
159  *result_count = 0;
160  } else {
161  for (int i = 0; i < tree_->KeySize; i++) {
162  sb_min_[i] = tree_->KeyDesc[i].Min;
163  sb_max_[i] = tree_->KeyDesc[i].Max;
164  }
165  SearchRec(0, tree_->Root.Left);
166  int count = results_.elements_count();
167  *result_count = count;
168  for (int j = 0; j < count; j++) {
169  // TODO: why FLOAT64 here?
170  distances[j] = (FLOAT32) sqrt((FLOAT64)results_.elements()[j].key);
171  results[j] = results_.elements()[j].value;
172  }
173  }
174 }
175 
176 /*-----------------------------------------------------------------------------
177  Public Code
178 -----------------------------------------------------------------------------*/
182 KDTREE *MakeKDTree(inT16 KeySize, const PARAM_DESC KeyDesc[]) {
183  KDTREE *KDTree = (KDTREE *) Emalloc(
184  sizeof(KDTREE) + (KeySize - 1) * sizeof(PARAM_DESC));
185  for (int i = 0; i < KeySize; i++) {
186  KDTree->KeyDesc[i].NonEssential = KeyDesc[i].NonEssential;
187  KDTree->KeyDesc[i].Circular = KeyDesc[i].Circular;
188  if (KeyDesc[i].Circular) {
189  KDTree->KeyDesc[i].Min = KeyDesc[i].Min;
190  KDTree->KeyDesc[i].Max = KeyDesc[i].Max;
191  KDTree->KeyDesc[i].Range = KeyDesc[i].Max - KeyDesc[i].Min;
192  KDTree->KeyDesc[i].HalfRange = KDTree->KeyDesc[i].Range / 2;
193  KDTree->KeyDesc[i].MidRange = (KeyDesc[i].Max + KeyDesc[i].Min) / 2;
194  } else {
195  KDTree->KeyDesc[i].Min = MINSEARCH;
196  KDTree->KeyDesc[i].Max = MAXSEARCH;
197  }
198  }
199  KDTree->KeySize = KeySize;
200  KDTree->Root.Left = NULL;
201  KDTree->Root.Right = NULL;
202  return KDTree;
203 }
204 
205 
218 void KDStore(KDTREE *Tree, FLOAT32 *Key, void *Data) {
219  int Level;
220  KDNODE *Node;
221  KDNODE **PtrToNode;
222 
223  PtrToNode = &(Tree->Root.Left);
224  Node = *PtrToNode;
225  Level = NextLevel(Tree, -1);
226  while (Node != NULL) {
227  if (Key[Level] < Node->BranchPoint) {
228  PtrToNode = &(Node->Left);
229  if (Key[Level] > Node->LeftBranch)
230  Node->LeftBranch = Key[Level];
231  }
232  else {
233  PtrToNode = &(Node->Right);
234  if (Key[Level] < Node->RightBranch)
235  Node->RightBranch = Key[Level];
236  }
237  Level = NextLevel(Tree, Level);
238  Node = *PtrToNode;
239  }
240 
241  *PtrToNode = MakeKDNode(Tree, Key, (void *) Data, Level);
242 } /* KDStore */
243 
263 void
264 KDDelete (KDTREE * Tree, FLOAT32 Key[], void *Data) {
265  int Level;
266  KDNODE *Current;
267  KDNODE *Father;
268 
269  /* initialize search at root of tree */
270  Father = &(Tree->Root);
271  Current = Father->Left;
272  Level = NextLevel(Tree, -1);
273 
274  /* search tree for node to be deleted */
275  while ((Current != NULL) && (!NodeFound (Current, Key, Data))) {
276  Father = Current;
277  if (Key[Level] < Current->BranchPoint)
278  Current = Current->Left;
279  else
280  Current = Current->Right;
281 
282  Level = NextLevel(Tree, Level);
283  }
284 
285  if (Current != NULL) { /* if node to be deleted was found */
286  if (Current == Father->Left) {
287  Father->Left = NULL;
288  Father->LeftBranch = Tree->KeyDesc[Level].Min;
289  } else {
290  Father->Right = NULL;
291  Father->RightBranch = Tree->KeyDesc[Level].Max;
292  }
293 
294  InsertNodes(Tree, Current->Left);
295  InsertNodes(Tree, Current->Right);
296  FreeSubTree(Current);
297  }
298 } /* KDDelete */
299 
321  KDTREE *Tree, FLOAT32 Query[], int QuerySize, FLOAT32 MaxDistance,
322  int *NumberOfResults, void **NBuffer, FLOAT32 DBuffer[]) {
323  KDTreeSearch search(Tree, Query, QuerySize);
324  search.Search(NumberOfResults, DBuffer, NBuffer);
325 }
326 
327 
328 /*---------------------------------------------------------------------------*/
330 void KDWalk(KDTREE *Tree, void_proc action, void *context) {
331  if (Tree->Root.Left != NULL)
332  Walk(Tree, action, context, Tree->Root.Left, NextLevel(Tree, -1));
333 }
334 
335 
336 /*---------------------------------------------------------------------------*/
349 void FreeKDTree(KDTREE *Tree) {
350  FreeSubTree(Tree->Root.Left);
351  free(Tree);
352 } /* FreeKDTree */
353 
354 
355 /*-----------------------------------------------------------------------------
356  Private Code
357 -----------------------------------------------------------------------------*/
358 /*---------------------------------------------------------------------------*/
372 KDNODE *MakeKDNode(KDTREE *tree, FLOAT32 Key[], void *Data, int Index) {
373  KDNODE *NewNode;
374 
375  NewNode = (KDNODE *) Emalloc (sizeof (KDNODE));
376 
377  NewNode->Key = Key;
378  NewNode->Data = Data;
379  NewNode->BranchPoint = Key[Index];
380  NewNode->LeftBranch = tree->KeyDesc[Index].Min;
381  NewNode->RightBranch = tree->KeyDesc[Index].Max;
382  NewNode->Left = NULL;
383  NewNode->Right = NULL;
384 
385  return NewNode;
386 } /* MakeKDNode */
387 
388 
389 /*---------------------------------------------------------------------------*/
390 void FreeKDNode(KDNODE *Node) {
391  free(Node);
392 }
393 
394 
395 /*---------------------------------------------------------------------------*/
401 void KDTreeSearch::SearchRec(int level, KDNODE *sub_tree) {
402  if (level >= tree_->KeySize)
403  level = 0;
404 
405  if (!BoxIntersectsSearch(sb_min_, sb_max_))
406  return;
407 
408  results_.insert(DistanceSquared(tree_->KeySize, tree_->KeyDesc,
409  query_point_, sub_tree->Key),
410  sub_tree->Data);
411 
412  if (query_point_[level] < sub_tree->BranchPoint) {
413  if (sub_tree->Left != NULL) {
414  FLOAT32 tmp = sb_max_[level];
415  sb_max_[level] = sub_tree->LeftBranch;
416  SearchRec(NextLevel(tree_, level), sub_tree->Left);
417  sb_max_[level] = tmp;
418  }
419  if (sub_tree->Right != NULL) {
420  FLOAT32 tmp = sb_min_[level];
421  sb_min_[level] = sub_tree->RightBranch;
422  SearchRec(NextLevel(tree_, level), sub_tree->Right);
423  sb_min_[level] = tmp;
424  }
425  } else {
426  if (sub_tree->Right != NULL) {
427  FLOAT32 tmp = sb_min_[level];
428  sb_min_[level] = sub_tree->RightBranch;
429  SearchRec(NextLevel(tree_, level), sub_tree->Right);
430  sb_min_[level] = tmp;
431  }
432  if (sub_tree->Left != NULL) {
433  FLOAT32 tmp = sb_max_[level];
434  sb_max_[level] = sub_tree->LeftBranch;
435  SearchRec(NextLevel(tree_, level), sub_tree->Left);
436  sb_max_[level] = tmp;
437  }
438  }
439 }
440 
441 
442 /*---------------------------------------------------------------------------*/
451  FLOAT32 total_distance = 0;
452 
453  for (; k > 0; k--, p1++, p2++, dim++) {
454  if (dim->NonEssential)
455  continue;
456 
457  FLOAT32 dimension_distance = *p1 - *p2;
458 
459  /* if this dimension is circular - check wraparound distance */
460  if (dim->Circular) {
461  dimension_distance = Magnitude(dimension_distance);
462  FLOAT32 wrap_distance = dim->Max - dim->Min - dimension_distance;
463  dimension_distance = MIN(dimension_distance, wrap_distance);
464  }
465 
466  total_distance += dimension_distance * dimension_distance;
467  }
468  return total_distance;
469 }
470 
472  return sqrt(DistanceSquared(k, dim, p1, p2));
473 }
474 
475 /*---------------------------------------------------------------------------*/
480 bool KDTreeSearch::BoxIntersectsSearch(FLOAT32 *lower, FLOAT32 *upper) {
481  FLOAT32 *query = query_point_;
482  // Why FLOAT64?
483  FLOAT64 total_distance = 0.0;
484  FLOAT64 radius_squared =
485  results_.max_insertable_key() * results_.max_insertable_key();
486  PARAM_DESC *dim = tree_->KeyDesc;
487 
488  for (int i = tree_->KeySize; i > 0; i--, dim++, query++, lower++, upper++) {
489  if (dim->NonEssential)
490  continue;
491 
492  FLOAT32 dimension_distance;
493  if (*query < *lower)
494  dimension_distance = *lower - *query;
495  else if (*query > *upper)
496  dimension_distance = *query - *upper;
497  else
498  dimension_distance = 0;
499 
500  /* if this dimension is circular - check wraparound distance */
501  if (dim->Circular) {
502  FLOAT32 wrap_distance = MAX_FLOAT32;
503  if (*query < *lower)
504  wrap_distance = *query + dim->Max - dim->Min - *upper;
505  else if (*query > *upper)
506  wrap_distance = *lower - (*query - (dim->Max - dim->Min));
507  dimension_distance = MIN(dimension_distance, wrap_distance);
508  }
509 
510  total_distance += dimension_distance * dimension_distance;
511  if (total_distance >= radius_squared)
512  return FALSE;
513  }
514  return TRUE;
515 }
516 
517 
518 /*---------------------------------------------------------------------------*/
534 void Walk(KDTREE *tree, void_proc action, void *context,
535  KDNODE *sub_tree, inT32 level) {
536  (*action)(context, sub_tree->Data, level);
537  if (sub_tree->Left != NULL)
538  Walk(tree, action, context, sub_tree->Left, NextLevel(tree, level));
539  if (sub_tree->Right != NULL)
540  Walk(tree, action, context, sub_tree->Right, NextLevel(tree, level));
541 }
542 
544 void InsertNodes(KDTREE *tree, KDNODE *nodes) {
545  if (nodes == NULL)
546  return;
547 
548  KDStore(tree, nodes->Key, nodes->Data);
549  InsertNodes(tree, nodes->Left);
550  InsertNodes(tree, nodes->Right);
551 }
552 
554 void FreeSubTree(KDNODE *sub_tree) {
555  if (sub_tree != NULL) {
556  FreeSubTree(sub_tree->Left);
557  FreeSubTree(sub_tree->Right);
558  free(sub_tree);
559  }
560 }
FLOAT32 BranchPoint
Definition: kdtree.h:42
void KDWalk(KDTREE *Tree, void_proc action, void *context)
Definition: kdtree.cpp:330
Definition: kdtree.h:49
void KDStore(KDTREE *Tree, FLOAT32 *Key, void *Data)
Definition: kdtree.cpp:218
#define TRUE
Definition: capi.h:45
int32_t inT32
Definition: host.h:38
void Search(int *result_count, FLOAT32 *distances, void **results)
Definition: kdtree.cpp:155
#define Magnitude(X)
Definition: kdtree.cpp:30
KDTREE * MakeKDTree(inT16 KeySize, const PARAM_DESC KeyDesc[])
Definition: kdtree.cpp:182
KDTreeSearch(KDTREE *tree, FLOAT32 *query_point, int k_closest)
Definition: kdtree.cpp:140
const Element * elements()
Definition: kdtree.cpp:69
void * Data
Definition: kdtree.h:41
FLOAT32 * Key
Definition: kdtree.h:40
FLOAT32 MidRange
Definition: ocrfeatures.h:53
void * Emalloc(int Size)
Definition: emalloc.cpp:47
FLOAT32 Range
Definition: ocrfeatures.h:51
PARAM_DESC KeyDesc[1]
Definition: kdtree.h:52
#define NodeFound(N, K, D)
Definition: kdtree.cpp:31
void KDNearestNeighborSearch(KDTREE *Tree, FLOAT32 Query[], int QuerySize, FLOAT32 MaxDistance, int *NumberOfResults, void **NBuffer, FLOAT32 DBuffer[])
Definition: kdtree.cpp:320
inT8 Circular
Definition: ocrfeatures.h:47
Value value
Definition: kdtree.cpp:62
FLOAT32 Min
Definition: ocrfeatures.h:49
int16_t inT16
Definition: host.h:36
const Key & max_insertable_key()
Definition: kdtree.cpp:91
bool insert(Key k, Value v)
Definition: kdtree.cpp:98
Element(const Key &k, const Value &v)
Definition: kdtree.cpp:59
struct KDNODE * Right
Definition: kdtree.h:46
LIST search(LIST list, void *key, int_compare is_equal)
Definition: oldlist.cpp:406
inT8 NonEssential
Definition: ocrfeatures.h:48
#define MAXSEARCH
Definition: kdtree.cpp:37
void FreeKDNode(KDNODE *Node)
Definition: kdtree.cpp:390
FLOAT32 LeftBranch
Definition: kdtree.h:43
#define FALSE
Definition: capi.h:46
struct KDNODE * Left
Definition: kdtree.h:45
void Walk(KDTREE *tree, void_proc action, void *context, KDNODE *sub_tree, inT32 level)
Definition: kdtree.cpp:534
~MinK()
Definition: kdtree.cpp:86
#define MAX_FLOAT32
Definition: host.h:66
void InsertNodes(KDTREE *tree, KDNODE *nodes)
Definition: kdtree.cpp:544
MinK(Key max_key, int k)
Definition: kdtree.cpp:80
void FreeSubTree(KDNODE *sub_tree)
Definition: kdtree.cpp:554
float FLOAT32
Definition: host.h:42
#define MIN(x, y)
Definition: ndminx.h:28
FLOAT32 ComputeDistance(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[])
Definition: kdtree.cpp:471
void KDDelete(KDTREE *Tree, FLOAT32 Key[], void *Data)
Definition: kdtree.cpp:264
FLOAT32 Max
Definition: ocrfeatures.h:50
#define MINSEARCH
Definition: kdtree.cpp:36
void FreeKDTree(KDTREE *Tree)
Definition: kdtree.cpp:349
FLOAT32 DistanceSquared(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[])
Definition: kdtree.cpp:450
int elements_count()
Definition: kdtree.cpp:68
KDNODE * MakeKDNode(KDTREE *tree, FLOAT32 Key[], void *Data, int Index)
Definition: kdtree.cpp:372
Definition: kdtree.h:39
Definition: kdtree.cpp:52
FLOAT32 RightBranch
Definition: kdtree.h:44
double v[max]
int count(LIST var_list)
Definition: oldlist.cpp:103
void(* void_proc)(...)
Definition: cutil.h:66
double FLOAT64
Definition: host.h:43
inT16 KeySize
Definition: kdtree.h:50
FLOAT32 HalfRange
Definition: ocrfeatures.h:52
KDNODE Root
Definition: kdtree.h:51