tesseract  4.0.0-1-g2a2b
equationdetect.h
Go to the documentation of this file.
1 // File: equationdetect.h
3 // Description: The equation detection class that inherits equationdetectbase.
4 // Author: Zongyi (Joe) Liu (joeliu@google.com)
5 // Created: Fri Aug 31 11:13:01 PST 2011
6 //
7 // (C) Copyright 2011, Google Inc.
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17 //
19 
20 #ifndef TESSERACT_CCMAIN_EQUATIONDETECT_H_
21 #define TESSERACT_CCMAIN_EQUATIONDETECT_H_
22 
23 #include "blobbox.h" // for BLOBNBOX (ptr only), BlobSpecialText...
24 #include "equationdetectbase.h" // for EquationDetectBase
25 #include "genericvector.h" // for GenericVector
26 #include "tesseractclass.h" // for Tesseract
27 #include "unichar.h" // for UNICHAR_ID
28 
29 class TBOX;
30 class UNICHARSET;
31 
32 namespace tesseract {
33 
34 class Tesseract;
35 class ColPartition;
36 class ColPartitionGrid;
37 class ColPartitionSet;
38 
40  public:
41  EquationDetect(const char* equ_datapath,
42  const char* equ_language);
44 
45  enum IndentType {
51  };
52 
53  // Reset the lang_tesseract_ pointer. This function should be called before we
54  // do any detector work.
55  void SetLangTesseract(Tesseract* lang_tesseract);
56 
57  // Iterate over the blobs inside to_block, and set the blobs that we want to
58  // process to BSTT_NONE. (By default, they should be BSTT_SKIP). The function
59  // returns 0 upon success.
60  int LabelSpecialText(TO_BLOCK* to_block);
61 
62  // Find possible equation partitions from part_grid. Should be called
63  // after the special_text_type of blobs are set.
64  // It returns 0 upon success.
65  int FindEquationParts(ColPartitionGrid* part_grid,
66  ColPartitionSet** best_columns);
67 
68  // Reset the resolution of the processing image. TEST only function.
69  void SetResolution(const int resolution);
70 
71  protected:
72  // Identify the special text type for one blob, and update its field. When
73  // height_th is set (> 0), we will label the blob as BSTT_NONE if its height
74  // is less than height_th.
75  void IdentifySpecialText(BLOBNBOX *blob, const int height_th);
76 
77  // Estimate the type for one unichar.
79  const UNICHARSET& unicharset, const UNICHAR_ID id) const;
80 
81  // Compute special text type for each blobs in part_grid_.
82  void IdentifySpecialText();
83 
84  // Identify blobs that we want to skip during special blob type
85  // classification.
87 
88  // The ColPartitions in part_grid_ maybe over-segmented, particularly in the
89  // block equation regions. So we like to identify these partitions and merge
90  // them before we do the searching.
91  void MergePartsByLocation();
92 
93  // Staring from the seed center, we do radius search. And for partitions that
94  // have large overlaps with seed, we remove them from part_grid_ and add into
95  // parts_overlap. Note: this function may update the part_grid_, so if the
96  // caller is also running ColPartitionGridSearch, use the RepositionIterator
97  // to continue.
98  void SearchByOverlap(ColPartition* seed,
99  GenericVector<ColPartition*>* parts_overlap);
100 
101  // Insert part back into part_grid_, after it absorbs some other parts.
103 
104  // Identify the colparitions in part_grid_, label them as PT_EQUATION, and
105  // save them into cp_seeds_.
106  void IdentifySeedParts();
107 
108  // Check the blobs count for a seed region candidate.
109  bool CheckSeedBlobsCount(ColPartition* part);
110 
111  // Compute the foreground pixel density for a tbox area.
112  float ComputeForegroundDensity(const TBOX& tbox);
113 
114  // Check if part from seed2 label: with low math density and left indented. We
115  // are using two checks:
116  // 1. If its left is aligned with any coordinates in indented_texts_left,
117  // which we assume have been sorted.
118  // 2. If its foreground density is over foreground_density_th.
119  bool CheckForSeed2(
120  const GenericVector<int>& indented_texts_left,
121  const float foreground_density_th,
122  ColPartition* part);
123 
124  // Count the number of values in sorted_vec that is close to val, used to
125  // check if a partition is aligned with text partitions.
126  int CountAlignment(
127  const GenericVector<int>& sorted_vec, const int val) const;
128 
129  // Check for a seed candidate using the foreground pixel density. And we
130  // return true if the density is below a certain threshold, because characters
131  // in equation regions usually are apart with more white spaces.
132  bool CheckSeedFgDensity(const float density_th, ColPartition* part);
133 
134  // A light version of SplitCPHor: instead of really doing the part split, we
135  // simply compute the union bounding box of each split part.
136  void SplitCPHorLite(ColPartition* part, GenericVector<TBOX>* splitted_boxes);
137 
138  // Split the part (horizontally), and save the split result into
139  // parts_splitted. Note that it is caller's responsibility to release the
140  // memory owns by parts_splitted. On the other hand, the part is unchanged
141  // during this process and still owns the blobs, so do NOT call DeleteBoxes
142  // when freeing the colpartitions in parts_splitted.
143  void SplitCPHor(ColPartition* part,
144  GenericVector<ColPartition*>* parts_splitted);
145 
146  // Check the density for a seed candidate (part) using its math density and
147  // italic density, returns true if the check passed.
148  bool CheckSeedDensity(const float math_density_high,
149  const float math_density_low,
150  const ColPartition* part) const;
151 
152  // Check if part is indented.
154 
155  // Identify inline partitions from cp_seeds_, and re-label them.
156  void IdentifyInlineParts();
157 
158  // Compute the super bounding box for all colpartitions inside part_grid_.
159  void ComputeCPsSuperBBox();
160 
161  // Identify inline partitions from cp_seeds_ using the horizontal search.
163 
164  // Estimate the line spacing between two text partitions. Returns -1 if not
165  // enough data.
167 
168  // Identify inline partitions from cp_seeds_ using vertical search.
169  void IdentifyInlinePartsVertical(const bool top_to_bottom,
170  const int textPartsLineSpacing);
171 
172  // Check if part is an inline equation zone. This should be called after we
173  // identified the seed regions.
174  bool IsInline(const bool search_bottom,
175  const int textPartsLineSpacing,
176  ColPartition* part);
177 
178  // For a given seed partition, we search the part_grid_ and see if there is
179  // any partition can be merged with it. It returns true if the seed has been
180  // expanded.
181  bool ExpandSeed(ColPartition* seed);
182 
183  // Starting from the seed position, we search the part_grid_
184  // horizontally/vertically, find all parititions that can be
185  // merged with seed, remove them from part_grid_, and put them into
186  // parts_to_merge.
187  void ExpandSeedHorizontal(const bool search_left,
188  ColPartition* seed,
189  GenericVector<ColPartition*>* parts_to_merge);
190  void ExpandSeedVertical(const bool search_bottom,
191  ColPartition* seed,
192  GenericVector<ColPartition*>* parts_to_merge);
193 
194  // Check if a part_box is the small neighbor of seed_box.
195  bool IsNearSmallNeighbor(const TBOX& seed_box,
196  const TBOX& part_box) const;
197 
198  // Perform the density check for part, which we assume is nearing a seed
199  // partition. It returns true if the check passed.
200  bool CheckSeedNeighborDensity(const ColPartition* part) const;
201 
202  // After identify the math blocks, we do one more scanning on all text
203  // partitions, and check if any of them is the satellite of:
204  // math blocks: here a p is the satellite of q if:
205  // 1. q is the nearest vertical neighbor of p, and
206  // 2. y_gap(p, q) is less than a threshold, and
207  // 3. x_overlap(p, q) is over a threshold.
208  // Note that p can be the satellites of two blocks: its top neighbor and
209  // bottom neighbor.
211 
212  // Check if part is the satellite of one/two math blocks. If it is, we return
213  // true, and save the blocks into math_blocks.
215  ColPartition* part, GenericVector<ColPartition*>* math_blocks);
216 
217  // Search the nearest neighbor of part in one vertical direction as defined in
218  // search_bottom. It returns the neighbor found that major x overlap with it,
219  // or nullptr when not found.
220  ColPartition* SearchNNVertical(const bool search_bottom,
221  const ColPartition* part);
222 
223  // Check if the neighbor with vertical distance of y_gap is a near and math
224  // block partition.
225  bool IsNearMathNeighbor(const int y_gap, const ColPartition *neighbor) const;
226 
227  // Generate the tiff file name for output/debug file.
228  void GetOutputTiffName(const char* name, STRING* image_name) const;
229 
230  // Debugger function that renders ColPartitions on the input image, where:
231  // parts labeled as PT_EQUATION will be painted in red, PT_INLINE_EQUATION
232  // will be painted in green, and other parts will be painted in blue.
233  void PaintColParts(const STRING& outfile) const;
234 
235  // Debugger function that renders the blobs in part_grid_ over the input
236  // image.
237  void PaintSpecialTexts(const STRING& outfile) const;
238 
239  // Debugger function that print the math blobs density values for a
240  // ColPartition object.
241  void PrintSpecialBlobsDensity(const ColPartition* part) const;
242 
243  // The tesseract engine initialized from equation training data.
245 
246  // The tesseract engine used for OCR. This pointer is passed in by the caller,
247  // so do NOT destroy it in this class.
249 
250  // The ColPartitionGrid that we are processing. This pointer is passed in from
251  // the caller, so do NOT destroy it in the class.
253 
254  // A simple array of pointers to the best assigned column division at
255  // each grid y coordinate. This pointer is passed in from the caller, so do
256  // NOT destroy it in the class.
258 
259  // The super bounding box of all cps in the part_grid_.
261 
262  // The seed ColPartition for equation region.
264 
265  // The resolution (dpi) of the processing image.
267 
268  // The number of pages we have processed.
270 };
271 
272 } // namespace tesseract
273 
274 #endif // TESSERACT_CCMAIN_EQUATIONDETECT_H_
int CountAlignment(const GenericVector< int > &sorted_vec, const int val) const
void SplitCPHor(ColPartition *part, GenericVector< ColPartition *> *parts_splitted)
int UNICHAR_ID
Definition: unichar.h:35
void GetOutputTiffName(const char *name, STRING *image_name) const
void IdentifyBlobsToSkip(ColPartition *part)
float ComputeForegroundDensity(const TBOX &tbox)
int LabelSpecialText(TO_BLOCK *to_block)
void SetLangTesseract(Tesseract *lang_tesseract)
bool IsInline(const bool search_bottom, const int textPartsLineSpacing, ColPartition *part)
Definition: rect.h:34
bool CheckForSeed2(const GenericVector< int > &indented_texts_left, const float foreground_density_th, ColPartition *part)
BlobSpecialTextType
Definition: blobbox.h:97
bool IsNearMathNeighbor(const int y_gap, const ColPartition *neighbor) const
void SearchByOverlap(ColPartition *seed, GenericVector< ColPartition *> *parts_overlap)
void SetResolution(const int resolution)
ColPartition * SearchNNVertical(const bool search_bottom, const ColPartition *part)
IndentType IsIndented(ColPartition *part)
BlobSpecialTextType EstimateTypeForUnichar(const UNICHARSET &unicharset, const UNICHAR_ID id) const
void IdentifyInlinePartsVertical(const bool top_to_bottom, const int textPartsLineSpacing)
void PaintColParts(const STRING &outfile) const
bool CheckSeedFgDensity(const float density_th, ColPartition *part)
int FindEquationParts(ColPartitionGrid *part_grid, ColPartitionSet **best_columns)
bool ExpandSeed(ColPartition *seed)
void InsertPartAfterAbsorb(ColPartition *part)
ColPartitionGrid * part_grid_
GenericVector< ColPartition * > cp_seeds_
Definition: strngs.h:45
bool CheckSeedBlobsCount(ColPartition *part)
bool IsMathBlockSatellite(ColPartition *part, GenericVector< ColPartition *> *math_blocks)
void ExpandSeedVertical(const bool search_bottom, ColPartition *seed, GenericVector< ColPartition *> *parts_to_merge)
bool CheckSeedNeighborDensity(const ColPartition *part) const
void SplitCPHorLite(ColPartition *part, GenericVector< TBOX > *splitted_boxes)
bool CheckSeedDensity(const float math_density_high, const float math_density_low, const ColPartition *part) const
void PaintSpecialTexts(const STRING &outfile) const
ColPartitionSet ** best_columns_
EquationDetect(const char *equ_datapath, const char *equ_language)
bool IsNearSmallNeighbor(const TBOX &seed_box, const TBOX &part_box) const
void ExpandSeedHorizontal(const bool search_left, ColPartition *seed, GenericVector< ColPartition *> *parts_to_merge)
void PrintSpecialBlobsDensity(const ColPartition *part) const