Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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