Tesseract
3.02
|
00001 /********************************************************************** 00002 * File: search_node.h 00003 * Description: Declaration of the Beam Search Node Class 00004 * Author: Ahmad Abdulkader 00005 * Created: 2008 00006 * 00007 * (C) Copyright 2008, Google Inc. 00008 ** Licensed under the Apache License, Version 2.0 (the "License"); 00009 ** you may not use this file except in compliance with the License. 00010 ** You may obtain a copy of the License at 00011 ** http://www.apache.org/licenses/LICENSE-2.0 00012 ** Unless required by applicable law or agreed to in writing, software 00013 ** distributed under the License is distributed on an "AS IS" BASIS, 00014 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 ** See the License for the specific language governing permissions and 00016 ** limitations under the License. 00017 * 00018 **********************************************************************/ 00019 00020 // The SearchNode class abstracts the search lattice node in the lattice 00021 // generated by the BeamSearch class 00022 // The SearchNode class holds the lang_mod_edge associated with the lattice 00023 // node. It also holds a pointer to the parent SearchNode in the search path 00024 // In addition it holds the recognition and the language model costs of the 00025 // node and the path leading to this node 00026 00027 #ifndef SEARCH_NODE_H 00028 #define SEARCH_NODE_H 00029 00030 #include "lang_mod_edge.h" 00031 #include "cube_reco_context.h" 00032 00033 namespace tesseract { 00034 00035 class SearchNode { 00036 public: 00037 SearchNode(CubeRecoContext *cntxt, SearchNode *parent_node, 00038 int char_reco_cost, LangModEdge *edge, int col_idx); 00039 00040 ~SearchNode(); 00041 00042 // Updates the parent of the current node if the specified path yields 00043 // a better path cost 00044 bool UpdateParent(SearchNode *new_parent, int new_reco_cost, 00045 LangModEdge *new_edge); 00046 // returns the 32-bit string corresponding to the path leading to this node 00047 char_32 *PathString(); 00048 // True if the two input nodes correspond to the same path 00049 static bool IdenticalPath(SearchNode *node1, SearchNode *node2); 00050 00051 inline const char_32 *NodeString() { return str_; } 00052 inline void SetString(char_32 *str) { str_ = str; } 00053 00054 // This node's character recognition cost. 00055 inline int CharRecoCost() { return char_reco_cost_; } 00056 // Total character recognition cost of the nodes in the best path, 00057 // excluding this node. 00058 inline int BestPathRecoCost() { return best_path_reco_cost_; } 00059 // Number of nodes in best path. 00060 inline int BestPathLength() { return best_path_len_; } 00061 // Mean mixed cost, i.e., mean character recognition cost + 00062 // current language model cost, all weighted by the RecoWgt parameter 00063 inline int BestCost() { return best_cost_; } 00064 // Mean character recognition cost of the nodes on the best path, 00065 // including this node. 00066 inline int BestRecoCost() { return mean_char_reco_cost_ ; } 00067 00068 inline int ColIdx() { return col_idx_; } 00069 inline SearchNode *ParentNode() { return parent_node_; } 00070 inline LangModEdge *LangModelEdge() { return lang_mod_edge_;} 00071 inline int LangModCost() { return LangModCost(lang_mod_edge_, parent_node_); } 00072 00073 // A comparer function that allows the SearchColumn class to sort the 00074 // nodes based on the path cost 00075 inline static int SearchNodeComparer(const void *node1, const void *node2) { 00076 return (*(reinterpret_cast<SearchNode * const *>(node1)))->best_cost_ - 00077 (*(reinterpret_cast<SearchNode * const *>(node2)))->best_cost_; 00078 } 00079 00080 private: 00081 CubeRecoContext *cntxt_; 00082 // Character code 00083 const char_32 *str_; 00084 // Recognition cost of most recent character 00085 int char_reco_cost_; 00086 // Mean mixed cost, i.e., mean character recognition cost + 00087 // current language model cost, all weighted by the RecoWgt parameter 00088 int best_cost_; 00089 // Mean character recognition cost of the nodes on the best path, 00090 // including this node. 00091 int mean_char_reco_cost_ ; 00092 // Total character recognition cost of the nodes in the best path, 00093 // excluding this node. 00094 int best_path_reco_cost_; 00095 // Number of nodes in best path. 00096 int best_path_len_; 00097 // Column index 00098 int col_idx_; 00099 // Parent Node 00100 SearchNode *parent_node_; 00101 // Language model edge 00102 LangModEdge *lang_mod_edge_; 00103 static int LangModCost(LangModEdge *lang_mod_edge, SearchNode *parent_node); 00104 }; 00105 00106 // Implments a SearchNode hash table used to detect if a Search Node exists 00107 // or not. This is needed to make sure that identical paths in the BeamSearch 00108 // converge 00109 class SearchNodeHashTable { 00110 public: 00111 SearchNodeHashTable() { 00112 memset(bin_size_array_, 0, sizeof(bin_size_array_)); 00113 } 00114 00115 ~SearchNodeHashTable() { 00116 } 00117 00118 // inserts an entry in the hash table 00119 inline bool Insert(LangModEdge *lang_mod_edge, SearchNode *srch_node) { 00120 // compute hash based on the edge and its parent node edge 00121 unsigned int edge_hash = lang_mod_edge->Hash(); 00122 unsigned int parent_hash = (srch_node->ParentNode() == NULL ? 00123 0 : srch_node->ParentNode()->LangModelEdge()->Hash()); 00124 unsigned int hash_bin = (edge_hash + parent_hash) % kSearchNodeHashBins; 00125 00126 // already maxed out, just fail 00127 if (bin_size_array_[hash_bin] >= kMaxSearchNodePerBin) { 00128 return false; 00129 } 00130 00131 bin_array_[hash_bin][bin_size_array_[hash_bin]++] = srch_node; 00132 00133 return true; 00134 } 00135 00136 // Looks up an entry in the hash table 00137 inline SearchNode *Lookup(LangModEdge *lang_mod_edge, 00138 SearchNode *parent_node) { 00139 // compute hash based on the edge and its parent node edge 00140 unsigned int edge_hash = lang_mod_edge->Hash(); 00141 unsigned int parent_hash = (parent_node == NULL ? 00142 0 : parent_node->LangModelEdge()->Hash()); 00143 unsigned int hash_bin = (edge_hash + parent_hash) % kSearchNodeHashBins; 00144 00145 // lookup the entries in the hash bin 00146 for (int node_idx = 0; node_idx < bin_size_array_[hash_bin]; node_idx++) { 00147 if (lang_mod_edge->IsIdentical( 00148 bin_array_[hash_bin][node_idx]->LangModelEdge()) == true && 00149 SearchNode::IdenticalPath( 00150 bin_array_[hash_bin][node_idx]->ParentNode(), parent_node) == true) { 00151 return bin_array_[hash_bin][node_idx]; 00152 } 00153 } 00154 00155 return NULL; 00156 } 00157 00158 private: 00159 // Hash bin size parameters. These were determined emperically. These affect 00160 // the speed of the beam search but have no impact on accuracy 00161 static const int kSearchNodeHashBins = 4096; 00162 static const int kMaxSearchNodePerBin = 512; 00163 int bin_size_array_[kSearchNodeHashBins]; 00164 SearchNode *bin_array_[kSearchNodeHashBins][kMaxSearchNodePerBin]; 00165 }; 00166 } 00167 00168 #endif // SEARCH_NODE_H