tesseract  4.00.00dev
kdtree.cpp File Reference
#include "kdtree.h"
#include "const.h"
#include "emalloc.h"
#include <stdio.h>
#include <math.h>

Go to the source code of this file.

Classes

class  MinK< Key, Value >
 
struct  MinK< Key, Value >::Element
 
class  KDTreeSearch
 

Macros

#define Magnitude(X)   ((X) < 0 ? -(X) : (X))
 
#define NodeFound(N, K, D)   (( (N)->Key == (K) ) && ( (N)->Data == (D) ))
 
#define MINSEARCH   -MAX_FLOAT32
 
#define MAXSEARCH   MAX_FLOAT32
 

Functions

KDTREEMakeKDTree (inT16 KeySize, const PARAM_DESC KeyDesc[])
 
void KDStore (KDTREE *Tree, FLOAT32 *Key, void *Data)
 
void KDDelete (KDTREE *Tree, FLOAT32 Key[], void *Data)
 
void KDNearestNeighborSearch (KDTREE *Tree, FLOAT32 Query[], int QuerySize, FLOAT32 MaxDistance, int *NumberOfResults, void **NBuffer, FLOAT32 DBuffer[])
 
void KDWalk (KDTREE *Tree, void_proc action, void *context)
 
void FreeKDTree (KDTREE *Tree)
 
KDNODEMakeKDNode (KDTREE *tree, FLOAT32 Key[], void *Data, int Index)
 
void FreeKDNode (KDNODE *Node)
 
FLOAT32 DistanceSquared (int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[])
 
FLOAT32 ComputeDistance (int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[])
 
void Walk (KDTREE *tree, void_proc action, void *context, KDNODE *sub_tree, inT32 level)
 
void InsertNodes (KDTREE *tree, KDNODE *nodes)
 
void FreeSubTree (KDNODE *sub_tree)
 

Macro Definition Documentation

◆ Magnitude

#define Magnitude (   X)    ((X) < 0 ? -(X) : (X))

Definition at line 30 of file kdtree.cpp.

◆ MAXSEARCH

#define MAXSEARCH   MAX_FLOAT32

Definition at line 37 of file kdtree.cpp.

◆ MINSEARCH

#define MINSEARCH   -MAX_FLOAT32

Definition at line 36 of file kdtree.cpp.

◆ NodeFound

#define NodeFound (   N,
  K,
 
)    (( (N)->Key == (K) ) && ( (N)->Data == (D) ))

Definition at line 31 of file kdtree.cpp.

Function Documentation

◆ ComputeDistance()

FLOAT32 ComputeDistance ( int  k,
PARAM_DESC dim,
FLOAT32  p1[],
FLOAT32  p2[] 
)

Definition at line 471 of file kdtree.cpp.

471  {
472  return sqrt(DistanceSquared(k, dim, p1, p2));
473 }
FLOAT32 DistanceSquared(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[])
Definition: kdtree.cpp:450

◆ DistanceSquared()

FLOAT32 DistanceSquared ( int  k,
PARAM_DESC dim,
FLOAT32  p1[],
FLOAT32  p2[] 
)

Returns the Euclidean distance squared between p1 and p2 for all essential dimensions.

Parameters
kkeys are in k-space
dimdimension descriptions (essential, circular, etc)
p1,p2two different points in K-D space

Definition at line 450 of file kdtree.cpp.

450  {
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 }
#define Magnitude(X)
Definition: kdtree.cpp:30
inT8 Circular
Definition: ocrfeatures.h:47
FLOAT32 Min
Definition: ocrfeatures.h:49
inT8 NonEssential
Definition: ocrfeatures.h:48
float FLOAT32
Definition: host.h:42
#define MIN(x, y)
Definition: ndminx.h:28
FLOAT32 Max
Definition: ocrfeatures.h:50

◆ FreeKDNode()

void FreeKDNode ( KDNODE Node)

Definition at line 390 of file kdtree.cpp.

390  {
391  free(Node);
392 }

◆ FreeKDTree()

void FreeKDTree ( KDTREE Tree)

This routine frees all memory which is allocated to the specified KD-tree. This includes the data structure for the kd-tree itself plus the data structures for each node in the tree. It does not include the Key and Data items which are pointed to by the nodes. This memory is left untouched.

Parameters
Treetree data structure to be released
Returns
none
Note
Exceptions: none
History: 5/26/89, DSJ, Created.

Definition at line 349 of file kdtree.cpp.

349  {
350  FreeSubTree(Tree->Root.Left);
351  free(Tree);
352 } /* FreeKDTree */
struct KDNODE * Left
Definition: kdtree.h:45
void FreeSubTree(KDNODE *sub_tree)
Definition: kdtree.cpp:554
KDNODE Root
Definition: kdtree.h:51

◆ FreeSubTree()

void FreeSubTree ( KDNODE sub_tree)

Free all of the nodes of a sub tree.

Definition at line 554 of file kdtree.cpp.

554  {
555  if (sub_tree != NULL) {
556  FreeSubTree(sub_tree->Left);
557  FreeSubTree(sub_tree->Right);
558  free(sub_tree);
559  }
560 }
struct KDNODE * Right
Definition: kdtree.h:46
struct KDNODE * Left
Definition: kdtree.h:45
void FreeSubTree(KDNODE *sub_tree)
Definition: kdtree.cpp:554

◆ InsertNodes()

void InsertNodes ( KDTREE tree,
KDNODE nodes 
)

Given a subtree nodes, insert all of its elements into tree.

Definition at line 544 of file kdtree.cpp.

544  {
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 }
void KDStore(KDTREE *Tree, FLOAT32 *Key, void *Data)
Definition: kdtree.cpp:218
void * Data
Definition: kdtree.h:41
FLOAT32 * Key
Definition: kdtree.h:40
struct KDNODE * Right
Definition: kdtree.h:46
struct KDNODE * Left
Definition: kdtree.h:45
void InsertNodes(KDTREE *tree, KDNODE *nodes)
Definition: kdtree.cpp:544

◆ KDDelete()

void KDDelete ( KDTREE Tree,
FLOAT32  Key[],
void *  Data 
)

This routine deletes a node from Tree. The node to be deleted is specified by the Key for the node and the Data contents of the node. These two pointers must be identical to the pointers that were used for the node when it was originally stored in the tree. A node will be deleted from the tree only if its key and data pointers are identical to Key and Data respectively. The tree is re-formed by removing the affected subtree and inserting all elements but the root.

Parameters
TreeK-D tree to delete node from
Keykey of node to be deleted
Datadata contents of node to be deleted
Note
Exceptions: none
History: 3/13/89, DSJ, Created. 7/13/89, DSJ, Specify node indirectly by key and data.

Definition at line 264 of file kdtree.cpp.

264  {
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 */
FLOAT32 BranchPoint
Definition: kdtree.h:42
PARAM_DESC KeyDesc[1]
Definition: kdtree.h:52
#define NodeFound(N, K, D)
Definition: kdtree.cpp:31
FLOAT32 Min
Definition: ocrfeatures.h:49
struct KDNODE * Right
Definition: kdtree.h:46
FLOAT32 LeftBranch
Definition: kdtree.h:43
struct KDNODE * Left
Definition: kdtree.h:45
void InsertNodes(KDTREE *tree, KDNODE *nodes)
Definition: kdtree.cpp:544
void FreeSubTree(KDNODE *sub_tree)
Definition: kdtree.cpp:554
FLOAT32 Max
Definition: ocrfeatures.h:50
Definition: kdtree.h:39
FLOAT32 RightBranch
Definition: kdtree.h:44
KDNODE Root
Definition: kdtree.h:51

◆ KDNearestNeighborSearch()

void KDNearestNeighborSearch ( KDTREE Tree,
FLOAT32  Query[],
int  QuerySize,
FLOAT32  MaxDistance,
int NumberOfResults,
void **  NBuffer,
FLOAT32  DBuffer[] 
)

This routine searches the K-D tree specified by Tree and finds the QuerySize nearest neighbors of Query. All neighbors must be within MaxDistance of Query. The data contents of the nearest neighbors are placed in NBuffer and their distances from Query are placed in DBuffer.

Parameters
Treeptr to K-D tree to be searched
Queryptr to query key (point in D-space)
QuerySizenumber of nearest neighbors to be found
MaxDistanceall neighbors must be within this distance
NBufferptr to QuerySize buffer to hold nearest neighbors
DBufferptr to QuerySize buffer to hold distances from nearest neighbor to query point
NumberOfResults[out] Number of nearest neighbors actually found
Note
Exceptions: none
History:
  • 3/10/89, DSJ, Created.
  • 7/13/89, DSJ, Return contents of node instead of node itself.

Definition at line 320 of file kdtree.cpp.

322  {
323  KDTreeSearch search(Tree, Query, QuerySize);
324  search.Search(NumberOfResults, DBuffer, NBuffer);
325 }
LIST search(LIST list, void *key, int_compare is_equal)
Definition: oldlist.cpp:406

◆ KDStore()

void KDStore ( KDTREE Tree,
FLOAT32 Key,
void *  Data 
)

This routine stores Data in the K-D tree specified by Tree using Key as an access key.

Parameters
TreeK-D tree in which data is to be stored
Keyptr to key by which data can be retrieved
Dataptr to data to be stored in the tree
Note
Exceptions: none
History: 3/10/89, DSJ, Created. 7/13/89, DSJ, Changed return to void.

Definition at line 218 of file kdtree.cpp.

218  {
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 */
FLOAT32 BranchPoint
Definition: kdtree.h:42
struct KDNODE * Right
Definition: kdtree.h:46
FLOAT32 LeftBranch
Definition: kdtree.h:43
struct KDNODE * Left
Definition: kdtree.h:45
KDNODE * MakeKDNode(KDTREE *tree, FLOAT32 Key[], void *Data, int Index)
Definition: kdtree.cpp:372
Definition: kdtree.h:39
FLOAT32 RightBranch
Definition: kdtree.h:44
KDNODE Root
Definition: kdtree.h:51

◆ KDWalk()

void KDWalk ( KDTREE Tree,
void_proc  action,
void *  context 
)

Walk a given Tree with action.

Definition at line 330 of file kdtree.cpp.

330  {
331  if (Tree->Root.Left != NULL)
332  Walk(Tree, action, context, Tree->Root.Left, NextLevel(Tree, -1));
333 }
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
KDNODE Root
Definition: kdtree.h:51

◆ MakeKDNode()

KDNODE* MakeKDNode ( KDTREE tree,
FLOAT32  Key[],
void *  Data,
int  Index 
)

This routine allocates memory for a new K-D tree node and places the specified Key and Data into it. The left and right subtree pointers for the node are initialized to empty subtrees.

Parameters
treeThe tree to create the node for
KeyAccess key for new node in KD tree
Dataptr to data to be stored in new node
Indexindex of Key to branch on
Returns
pointer to new K-D tree node
Note
Exceptions: None
History: 3/11/89, DSJ, Created.

Definition at line 372 of file kdtree.cpp.

372  {
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 */
FLOAT32 BranchPoint
Definition: kdtree.h:42
void * Data
Definition: kdtree.h:41
FLOAT32 * Key
Definition: kdtree.h:40
void * Emalloc(int Size)
Definition: emalloc.cpp:47
PARAM_DESC KeyDesc[1]
Definition: kdtree.h:52
FLOAT32 Min
Definition: ocrfeatures.h:49
struct KDNODE * Right
Definition: kdtree.h:46
FLOAT32 LeftBranch
Definition: kdtree.h:43
struct KDNODE * Left
Definition: kdtree.h:45
FLOAT32 Max
Definition: ocrfeatures.h:50
Definition: kdtree.h:39
FLOAT32 RightBranch
Definition: kdtree.h:44

◆ MakeKDTree()

KDTREE* MakeKDTree ( inT16  KeySize,
const PARAM_DESC  KeyDesc[] 
)
Returns
a new KDTREE based on the specified parameters.
Parameters
KeySize# of dimensions in the K-D tree
KeyDescarray of params to describe key dimensions

Definition at line 182 of file kdtree.cpp.

182  {
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 }
Definition: kdtree.h:49
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
inT8 Circular
Definition: ocrfeatures.h:47
FLOAT32 Min
Definition: ocrfeatures.h:49
struct KDNODE * Right
Definition: kdtree.h:46
inT8 NonEssential
Definition: ocrfeatures.h:48
#define MAXSEARCH
Definition: kdtree.cpp:37
struct KDNODE * Left
Definition: kdtree.h:45
FLOAT32 Max
Definition: ocrfeatures.h:50
#define MINSEARCH
Definition: kdtree.cpp:36
inT16 KeySize
Definition: kdtree.h:50
FLOAT32 HalfRange
Definition: ocrfeatures.h:52
KDNODE Root
Definition: kdtree.h:51

◆ Walk()

void Walk ( KDTREE tree,
void_proc  action,
void *  context,
KDNODE sub_tree,
inT32  level 
)

Walk a tree, calling action once on each node.

Operation: This routine walks through the specified sub_tree and invokes action action at each node as follows: action(context, data, level) data the data contents of the node being visited, level is the level of the node in the tree with the root being level 0.

Parameters
treeroot of the tree being walked.
actionaction to be performed at every node
contextaction's context
sub_treeptr to root of subtree to be walked
levelcurrent level in the tree for this node

Definition at line 534 of file kdtree.cpp.

535  {
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 }
void * Data
Definition: kdtree.h:41
struct KDNODE * Right
Definition: kdtree.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