mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2024-11-24 02:59:07 +08:00
doxygen classify/kdtree.cpp
This commit is contained in:
parent
5668a52670
commit
84788d49a0
@ -48,7 +48,7 @@ static int NextLevel(KDTREE *tree, int level) {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Store the k smallest-keyed key-value pairs.
|
||||
/** Store the k smallest-keyed key-value pairs. */
|
||||
template<typename Key, typename Value>
|
||||
class MinK {
|
||||
public:
|
||||
@ -70,11 +70,11 @@ class MinK {
|
||||
const Element* elements() { return elements_; }
|
||||
|
||||
private:
|
||||
const Key max_key_; // the maximum possible Key
|
||||
Element* elements_; // unsorted array of elements
|
||||
int elements_count_; // the number of results collected so far
|
||||
int k_; // the number of results we want from the search
|
||||
int max_index_; // the index of the result with the largest key
|
||||
const Key max_key_; //< the maximum possible Key
|
||||
Element* elements_; //< unsorted array of elements
|
||||
int elements_count_; //< the number of results collected so far
|
||||
int k_; //< the number of results we want from the search
|
||||
int max_index_; //< the index of the result with the largest key
|
||||
};
|
||||
|
||||
template<typename Key, typename Value>
|
||||
@ -117,13 +117,13 @@ bool MinK<Key, Value>::insert(Key key, Value value) {
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper class for searching for the k closest points to query_point in tree.
|
||||
/** Helper class for searching for the k closest points to query_point in tree. */
|
||||
class KDTreeSearch {
|
||||
public:
|
||||
KDTreeSearch(KDTREE* tree, FLOAT32 *query_point, int k_closest);
|
||||
~KDTreeSearch();
|
||||
|
||||
// Return the k nearest points' data.
|
||||
/** Return the k nearest points' data. */
|
||||
void Search(int *result_count, FLOAT32 *distances, void **results);
|
||||
|
||||
private:
|
||||
@ -133,8 +133,8 @@ class KDTreeSearch {
|
||||
KDTREE *tree_;
|
||||
FLOAT32 *query_point_;
|
||||
MinK<FLOAT32, void *>* results_;
|
||||
FLOAT32 *sb_min_; // search box minimum
|
||||
FLOAT32 *sb_max_; // search box maximum
|
||||
FLOAT32 *sb_min_; //< search box minimum
|
||||
FLOAT32 *sb_max_; //< search box maximum
|
||||
};
|
||||
|
||||
KDTreeSearch::KDTreeSearch(KDTREE* tree, FLOAT32 *query_point, int k_closest) :
|
||||
@ -151,8 +151,8 @@ KDTreeSearch::~KDTreeSearch() {
|
||||
delete[] sb_max_;
|
||||
}
|
||||
|
||||
// Locate the k_closest points to query_point_, and return their distances and
|
||||
// data into the given buffers.
|
||||
/// Locate the k_closest points to query_point_, and return their distances and
|
||||
/// data into the given buffers.
|
||||
void KDTreeSearch::Search(int *result_count,
|
||||
FLOAT32 *distances,
|
||||
void **results) {
|
||||
@ -176,11 +176,9 @@ void KDTreeSearch::Search(int *result_count,
|
||||
/*-----------------------------------------------------------------------------
|
||||
Public Code
|
||||
-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/// Return a new KDTREE based on the specified parameters.
|
||||
/// Parameters:
|
||||
/// KeySize # of dimensions in the K-D tree
|
||||
/// KeyDesc array of params to describe key dimensions
|
||||
/// @return a new KDTREE based on the specified parameters.
|
||||
/// @param KeySize # of dimensions in the K-D tree
|
||||
/// @param KeyDesc array of params to describe key dimensions
|
||||
KDTREE *MakeKDTree(inT16 KeySize, const PARAM_DESC KeyDesc[]) {
|
||||
KDTREE *KDTree = (KDTREE *) Emalloc(
|
||||
sizeof(KDTREE) + (KeySize - 1) * sizeof(PARAM_DESC));
|
||||
@ -205,8 +203,6 @@ KDTREE *MakeKDTree(inT16 KeySize, const PARAM_DESC KeyDesc[]) {
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
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.
|
||||
@ -219,6 +215,7 @@ void KDStore(KDTREE *Tree, FLOAT32 *Key, void *Data) {
|
||||
* @note History: 3/10/89, DSJ, Created.
|
||||
* 7/13/89, DSJ, Changed return to void.
|
||||
*/
|
||||
void KDStore(KDTREE *Tree, FLOAT32 *Key, void *Data) {
|
||||
int Level;
|
||||
KDNODE *Node;
|
||||
KDNODE **PtrToNode;
|
||||
@ -245,7 +242,6 @@ void KDStore(KDTREE *Tree, FLOAT32 *Key, void *Data) {
|
||||
} /* KDStore */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* This routine deletes a node from Tree. The node to be
|
||||
* deleted is specified by the Key for the node and the Data
|
||||
@ -303,39 +299,36 @@ KDDelete (KDTREE * Tree, FLOAT32 Key[], void *Data) {
|
||||
} /* KDDelete */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* 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.
|
||||
* @param Tree ptr to K-D tree to be searched
|
||||
* @param Query ptr to query key (point in D-space)
|
||||
* @param QuerySize number of nearest neighbors to be found
|
||||
* @param MaxDistance all neighbors must be within this distance
|
||||
* @param NBuffer ptr to QuerySize buffer to hold nearest neighbors
|
||||
* @param DBuffer ptr to QuerySize buffer to hold distances
|
||||
* from nearest neighbor to query point
|
||||
* @return Number of nearest neighbors actually found
|
||||
* @note Exceptions: none
|
||||
* @note History:
|
||||
* - 3/10/89, DSJ, Created.
|
||||
* - 7/13/89, DSJ, Return contents of node instead of node itself.
|
||||
*/
|
||||
void KDNearestNeighborSearch(
|
||||
KDTREE *Tree, FLOAT32 Query[], int QuerySize, FLOAT32 MaxDistance,
|
||||
int *NumberOfResults, void **NBuffer, FLOAT32 DBuffer[]) {
|
||||
/*
|
||||
** Parameters:
|
||||
** Tree ptr to K-D tree to be searched
|
||||
** Query ptr to query key (point in D-space)
|
||||
** QuerySize number of nearest neighbors to be found
|
||||
** MaxDistance all neighbors must be within this distance
|
||||
** NBuffer ptr to QuerySize buffer to hold nearest neighbors
|
||||
** DBuffer ptr to QuerySize buffer to hold distances
|
||||
** from nearest neighbor to query point
|
||||
** Operation:
|
||||
** 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.
|
||||
** Return: Number of nearest neighbors actually found
|
||||
** Exceptions: none
|
||||
** History:
|
||||
** 3/10/89, DSJ, Created.
|
||||
** 7/13/89, DSJ, Return contents of node instead of node itself.
|
||||
*/
|
||||
KDTreeSearch search(Tree, Query, QuerySize);
|
||||
search.Search(NumberOfResults, DBuffer, NBuffer);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Walk a given Tree with action.
|
||||
/** Walk a given Tree with action. */
|
||||
void KDWalk(KDTREE *Tree, void_proc action, void *context) {
|
||||
if (Tree->Root.Left != NULL)
|
||||
Walk(Tree, action, context, Tree->Root.Left, NextLevel(Tree, -1));
|
||||
@ -343,22 +336,19 @@ void KDWalk(KDTREE *Tree, void_proc action, void *context) {
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void FreeKDTree(KDTREE *Tree) {
|
||||
/*
|
||||
** Parameters:
|
||||
** Tree tree data structure to be released
|
||||
** Operation:
|
||||
** 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.
|
||||
** Return: none
|
||||
** Exceptions: none
|
||||
** History:
|
||||
** 5/26/89, DSJ, Created.
|
||||
/**
|
||||
* 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.
|
||||
* @param Tree tree data structure to be released
|
||||
* @return none
|
||||
* @note Exceptions: none
|
||||
* @note History: 5/26/89, DSJ, Created.
|
||||
*/
|
||||
void FreeKDTree(KDTREE *Tree) {
|
||||
FreeSubTree(Tree->Root.Left);
|
||||
memfree(Tree);
|
||||
} /* FreeKDTree */
|
||||
@ -368,25 +358,20 @@ void FreeKDTree(KDTREE *Tree) {
|
||||
Private Code
|
||||
-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
KDNODE *MakeKDNode(KDTREE *tree, FLOAT32 Key[], void *Data, int Index) {
|
||||
/*
|
||||
** Parameters:
|
||||
** tree The tree to create the node for
|
||||
** Key Access key for new node in KD tree
|
||||
** Data ptr to data to be stored in new node
|
||||
** Index index of Key to branch on
|
||||
** Operation:
|
||||
** 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.
|
||||
** Return:
|
||||
** pointer to new K-D tree node
|
||||
** Exceptions:
|
||||
** None
|
||||
** History:
|
||||
** 3/11/89, DSJ, Created.
|
||||
/**
|
||||
* 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.
|
||||
* @param tree The tree to create the node for
|
||||
* @param Key Access key for new node in KD tree
|
||||
* @param Data ptr to data to be stored in new node
|
||||
* @param Index index of Key to branch on
|
||||
* @return pointer to new K-D tree node
|
||||
* @note Exceptions: None
|
||||
* @note History: 3/11/89, DSJ, Created.
|
||||
*/
|
||||
KDNODE *MakeKDNode(KDTREE *tree, FLOAT32 Key[], void *Data, int Index) {
|
||||
KDNODE *NewNode;
|
||||
|
||||
NewNode = (KDNODE *) Emalloc (sizeof (KDNODE));
|
||||
@ -410,10 +395,11 @@ void FreeKDNode(KDNODE *Node) {
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Recursively accumulate the k_closest points to query_point_ into results_.
|
||||
// Parameters:
|
||||
// Level level in tree of sub-tree to be searched
|
||||
// SubTree sub-tree to be searched
|
||||
/**
|
||||
* Recursively accumulate the k_closest points to query_point_ into results_.
|
||||
* @param Level level in tree of sub-tree to be searched
|
||||
* @param SubTree sub-tree to be searched
|
||||
*/
|
||||
void KDTreeSearch::SearchRec(int level, KDNODE *sub_tree) {
|
||||
if (level >= tree_->KeySize)
|
||||
level = 0;
|
||||
@ -456,12 +442,13 @@ void KDTreeSearch::SearchRec(int level, KDNODE *sub_tree) {
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Returns the Euclidean distance squared between p1 and p2 for all essential
|
||||
// dimensions.
|
||||
// Parameters:
|
||||
// k keys are in k-space
|
||||
// dim dimension descriptions (essential, circular, etc)
|
||||
// p1,p2 two different points in K-D space
|
||||
/**
|
||||
*Returns the Euclidean distance squared between p1 and p2 for all essential
|
||||
* dimensions.
|
||||
* @param k keys are in k-space
|
||||
* @param dim dimension descriptions (essential, circular, etc)
|
||||
* @param p1,p2 two different points in K-D space
|
||||
*/
|
||||
FLOAT32 DistanceSquared(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[]) {
|
||||
FLOAT32 total_distance = 0;
|
||||
|
||||
@ -488,10 +475,10 @@ FLOAT32 ComputeDistance(int k, PARAM_DESC *dim, FLOAT32 p1[], FLOAT32 p2[]) {
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Return whether the query region (the smallest known circle about
|
||||
// query_point_ containing results->k_ points) intersects the box specified
|
||||
// between lower and upper. For circular dimensions, we also check the point
|
||||
// one wrap distance away from the query.
|
||||
/// Return whether the query region (the smallest known circle about
|
||||
/// query_point_ containing results->k_ points) intersects the box specified
|
||||
/// between lower and upper. For circular dimensions, we also check the point
|
||||
/// one wrap distance away from the query.
|
||||
bool KDTreeSearch::BoxIntersectsSearch(FLOAT32 *lower, FLOAT32 *upper) {
|
||||
FLOAT32 *query = query_point_;
|
||||
FLOAT64 total_distance = 0.0;
|
||||
@ -530,20 +517,21 @@ bool KDTreeSearch::BoxIntersectsSearch(FLOAT32 *lower, FLOAT32 *upper) {
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Walk a tree, calling action once on each node.
|
||||
//
|
||||
// Parameters:
|
||||
// tree root of the tree being walked.
|
||||
// action action to be performed at every node
|
||||
// context action's context
|
||||
// sub_tree ptr to root of subtree to be walked
|
||||
// level current level in the tree for this node
|
||||
// Operation:
|
||||
// This routine walks thru 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.
|
||||
/**
|
||||
* Walk a tree, calling action once on each node.
|
||||
*
|
||||
* Operation:
|
||||
* This routine walks thru 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.
|
||||
* @param tree root of the tree being walked.
|
||||
* @param action action to be performed at every node
|
||||
* @param context action's context
|
||||
* @param sub_tree ptr to root of subtree to be walked
|
||||
* @param level current level in the tree for this node
|
||||
*/
|
||||
void Walk(KDTREE *tree, void_proc action, void *context,
|
||||
KDNODE *sub_tree, inT32 level) {
|
||||
(*action)(context, sub_tree->Data, level);
|
||||
@ -554,7 +542,7 @@ void Walk(KDTREE *tree, void_proc action, void *context,
|
||||
}
|
||||
|
||||
|
||||
// Given a subtree nodes, insert all of its elements into tree.
|
||||
/** Given a subtree nodes, insert all of its elements into tree. */
|
||||
void InsertNodes(KDTREE *tree, KDNODE *nodes) {
|
||||
if (nodes == NULL)
|
||||
return;
|
||||
@ -564,11 +552,11 @@ void InsertNodes(KDTREE *tree, KDNODE *nodes) {
|
||||
InsertNodes(tree, nodes->Right);
|
||||
}
|
||||
|
||||
// Free all of the nodes of a sub tree.
|
||||
/** Free all of the nodes of a sub tree. */
|
||||
void FreeSubTree(KDNODE *sub_tree) {
|
||||
if (sub_tree != NULL) {
|
||||
FreeSubTree(sub_tree->Left);
|
||||
FreeSubTree(sub_tree->Right);
|
||||
memfree(sub_tree);
|
||||
}
|
||||
} /* FreeSubTree */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user