MCPcopy Create free account
hub / github.com/creatale/node-dv / FindVerticalAlignment

Method FindVerticalAlignment

deps/tesseract/textord/alignedblob.cpp:243–329  ·  view source on GitHub ↗

Finds a vector corresponding to a set of vertically aligned blob edges running through the given box. The type of vector returned and the search parameters are determined by the AlignedBlobParams. vertical_x and y are updated with an estimate of the real vertical direction. (skew finding.) Returns NULL if no decent vector can be found.

Source from the content-addressed store, hash-verified

241// vertical direction. (skew finding.)
242// Returns NULL if no decent vector can be found.
243TabVector* AlignedBlob::FindVerticalAlignment(AlignedBlobParams align_params,
244 BLOBNBOX* bbox,
245 int* vertical_x,
246 int* vertical_y) {
247 int ext_start_y, ext_end_y;
248 BLOBNBOX_CLIST good_points;
249 // Search up and then down from the starting bbox.
250 TBOX box = bbox->bounding_box();
251 bool debug = WithinTestRegion(2, box.left(), box.bottom());
252 int pt_count = AlignTabs(align_params, false, bbox, &good_points, &ext_end_y);
253 pt_count += AlignTabs(align_params, true, bbox, &good_points, &ext_start_y);
254 BLOBNBOX_C_IT it(&good_points);
255 it.move_to_last();
256 box = it.data()->bounding_box();
257 int end_y = box.top();
258 int end_x = align_params.right_tab ? box.right() : box.left();
259 it.move_to_first();
260 box = it.data()->bounding_box();
261 int start_x = align_params.right_tab ? box.right() : box.left();
262 int start_y = box.bottom();
263 // Acceptable tab vectors must have a mininum number of points,
264 // have a minimum acceptable length, and have a minimum gradient.
265 // The gradient corresponds to the skew angle.
266 // Ragged tabs don't need to satisfy the gradient condition, as they
267 // will always end up parallel to the vertical direction.
268 bool at_least_2_crossings = AtLeast2LineCrossings(&good_points);
269 if ((pt_count >= align_params.min_points &&
270 end_y - start_y >= align_params.min_length &&
271 (align_params.ragged ||
272 end_y - start_y >= abs(end_x - start_x) * kMinTabGradient)) ||
273 at_least_2_crossings) {
274 int confirmed_points = 0;
275 // Count existing confirmed points to see if vector is acceptable.
276 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
277 bbox = it.data();
278 if (align_params.right_tab) {
279 if (bbox->right_tab_type() == align_params.confirmed_type)
280 ++confirmed_points;
281 } else {
282 if (bbox->left_tab_type() == align_params.confirmed_type)
283 ++confirmed_points;
284 }
285 }
286 // Ragged vectors are not allowed to use too many already used points.
287 if (!align_params.ragged ||
288 confirmed_points + confirmed_points < pt_count) {
289 const TBOX& box = bbox->bounding_box();
290 if (debug) {
291 tprintf("Confirming tab vector of %d pts starting at %d,%d\n",
292 pt_count, box.left(), box.bottom());
293 }
294 // Flag all the aligned neighbours as confirmed .
295 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
296 bbox = it.data();
297 if (align_params.right_tab) {
298 bbox->set_right_tab_type(align_params.confirmed_type);
299 } else {
300 bbox->set_left_tab_type(align_params.confirmed_type);

Callers 1

FindLineVectorsMethod · 0.80

Calls 15

AtLeast2LineCrossingsFunction · 0.85
dataMethod · 0.80
right_tab_typeMethod · 0.80
left_tab_typeMethod · 0.80
set_right_tab_typeMethod · 0.80
set_left_tab_typeMethod · 0.80
absFunction · 0.50
bounding_boxMethod · 0.45
move_to_lastMethod · 0.45
move_to_firstMethod · 0.45
mark_cycle_ptMethod · 0.45

Tested by

no test coverage detected