makerow.cpp
来自「一个google的OCR源码」· C++ 代码 · 共 1,682 行 · 第 1/5 页
CPP
1,682 行
inT32 row_offset; //from current row inT32 abs_dist; //absolute distance inT8 row_inc; //increment to row_index TO_ROW *next_row; //nextious row if (testing_on) tprintf ("Row at %g(%g), dropout dist=%d,", row->intercept (), row->parallel_c (), distance); if (distance < 0) { row_inc = 1; abs_dist = -distance; } else { row_inc = -1; abs_dist = distance; } if (abs_dist > dist_limit) { if (testing_on) { tprintf (" too far - deleting\n"); } return TRUE; } if ((distance < 0 && !row_it->at_last ()) || (distance >= 0 && !row_it->at_first ())) { row_offset = row_inc; do { next_row = row_it->data_relative (row_offset); next_index = (inT32) floor (next_row->intercept ()); if ((distance < 0 && next_index < line_index && next_index > line_index + distance + distance) || (distance >= 0 && next_index > line_index && next_index < line_index + distance + distance)) { if (testing_on) { tprintf (" nearer neighbour (%d) at %g\n", line_index + distance - next_index, next_row->intercept ()); } return TRUE; //other is nearer } else if (next_index == line_index || next_index == line_index + distance + distance) { if (row->believability () <= next_row->believability ()) { if (testing_on) { tprintf (" equal but more believable at %g (%g/%g)\n", next_row->intercept (), row->believability (), next_row->believability ()); } return TRUE; //other is more believable } } row_offset += row_inc; } while ((next_index == line_index || next_index == line_index + distance + distance) && row_offset < row_it->length ()); if (testing_on) tprintf (" keeping\n"); } return FALSE;}/********************************************************************** * deskew_block_coords * * Compute the bounding box of all the blobs in the block * if they were deskewed without actually doing it. **********************************************************************/TBOX deskew_block_coords( //block box TO_BLOCK *block, //block to do float gradient //global skew ) { TBOX result; //block bounds TBOX blob_box; //of block FCOORD rotation; //deskew vector float length; //of gradient vector TO_ROW_IT row_it = block->get_rows (); TO_ROW *row; //current row BLOBNBOX *blob; //current blob BLOBNBOX_IT blob_it; //iterator length = sqrt (gradient * gradient + 1); rotation = FCOORD (1 / length, -gradient / length); for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) { row = row_it.data (); blob_it.set_to_list (row->blob_list ()); for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) { blob = blob_it.data (); blob_box = blob->bounding_box (); blob_box.rotate (rotation);//de-skew it result += blob_box; } } return result;}/********************************************************************** * compute_line_occupation * * Compute the pixel projection back on the y axis given the global * skew. Also compute the 1st derivative. **********************************************************************/void compute_line_occupation( //project blobs TO_BLOCK *block, //block to do float gradient, //global skew inT32 min_y, //min coord in block inT32 max_y, //in block inT32 *occupation, //output projection inT32 *deltas //derivative ) { inT32 line_count; //maxy-miny+1 inT32 line_index; //of scan line int index; //array index for daft compilers float top, bottom; //coords of blob inT32 width; //of blob TO_ROW *row; //current row TO_ROW_IT row_it = block->get_rows (); BLOBNBOX *blob; //current blob BLOBNBOX_IT blob_it; //iterator float length; //of skew vector TBOX blob_box; //bounding box FCOORD rotation; //inverse of skew line_count = max_y - min_y + 1; length = sqrt (gradient * gradient + 1); rotation = FCOORD (1 / length, -gradient / length); for (line_index = 0; line_index < line_count; line_index++) deltas[line_index] = 0; for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) { row = row_it.data (); blob_it.set_to_list (row->blob_list ()); for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) { blob = blob_it.data (); blob_box = blob->bounding_box (); blob_box.rotate (rotation);//de-skew it top = blob_box.top (); bottom = blob_box.bottom (); width = (inT32) floor ((FLOAT32) (blob_box.right () - blob_box.left ())); if ((inT32) floor (bottom) < min_y || (inT32) floor (bottom) - min_y >= line_count) fprintf (stderr, "Bad y coord of bottom, " INT32FORMAT "(" INT32FORMAT "," INT32FORMAT ")\n", (inT32) floor (bottom), min_y, max_y); //count transitions index = (inT32) floor (bottom) - min_y; deltas[index] += width; if ((inT32) floor (top) < min_y || (inT32) floor (top) - min_y >= line_count) fprintf (stderr, "Bad y coord of top, " INT32FORMAT "(" INT32FORMAT "," INT32FORMAT ")\n", (inT32) floor (top), min_y, max_y); index = (inT32) floor (top) - min_y; deltas[index] -= width; } } occupation[0] = deltas[0]; for (line_index = 1; line_index < line_count; line_index++) occupation[line_index] = occupation[line_index - 1] + deltas[line_index];}/********************************************************************** * compute_occupation_threshold * * Compute thresholds for textline or not for the occupation array. **********************************************************************/void compute_occupation_threshold( //project blobs inT32 low_window, //below result point inT32 high_window, //above result point inT32 line_count, //array sizes inT32 *occupation, //input projection inT32 *thresholds //output thresholds ) { inT32 line_index; //of thresholds line inT32 low_index; //in occupation inT32 high_index; //in occupation inT32 sum; //current average inT32 divisor; //to get thresholds inT32 min_index; //of min occ inT32 min_occ; //min in locality inT32 test_index; //for finding min divisor = (inT32) ceil ((low_window + high_window) / textord_occupancy_threshold); if (low_window + high_window < line_count) { for (sum = 0, high_index = 0; high_index < low_window; high_index++) sum += occupation[high_index]; for (low_index = 0; low_index < high_window; low_index++, high_index++) sum += occupation[high_index]; min_occ = occupation[0]; min_index = 0; for (test_index = 1; test_index < high_index; test_index++) { if (occupation[test_index] <= min_occ) { min_occ = occupation[test_index]; min_index = test_index; //find min in region } } for (line_index = 0; line_index < low_window; line_index++) thresholds[line_index] = (sum - min_occ) / divisor + min_occ; //same out to end for (low_index = 0; high_index < line_count; low_index++, high_index++) { sum -= occupation[low_index]; sum += occupation[high_index]; if (occupation[high_index] <= min_occ) { //find min in region min_occ = occupation[high_index]; min_index = high_index; } //lost min from region if (min_index <= low_index) { min_occ = occupation[low_index + 1]; min_index = low_index + 1; for (test_index = low_index + 2; test_index <= high_index; test_index++) { if (occupation[test_index] <= min_occ) { min_occ = occupation[test_index]; //find min in region min_index = test_index; } } } thresholds[line_index++] = (sum - min_occ) / divisor + min_occ; } } else { min_occ = occupation[0]; min_index = 0; for (sum = 0, low_index = 0; low_index < line_count; low_index++) { if (occupation[low_index] < min_occ) { min_occ = occupation[low_index]; min_index = low_index; } sum += occupation[low_index]; } line_index = 0; } for (; line_index < line_count; line_index++) thresholds[line_index] = (sum - min_occ) / divisor + min_occ; //same out to end}/********************************************************************** * compute_dropout_distances * * Compute the distance from each coordinate to the nearest dropout. **********************************************************************/void compute_dropout_distances( //project blobs inT32 *occupation, //input projection inT32 *thresholds, //output thresholds inT32 line_count //array sizes ) { inT32 line_index; //of thresholds line inT32 distance; //from prev dropout inT32 next_dist; //to next dropout inT32 back_index; //for back filling inT32 prev_threshold; //before overwrite distance = -line_count; line_index = 0; do { do { distance--; prev_threshold = thresholds[line_index]; //distance from prev thresholds[line_index] = distance; line_index++; } while (line_index < line_count && (occupation[line_index] < thresholds[line_index] || occupation[line_index - 1] >= prev_threshold)); if (line_index < line_count) { back_index = line_index - 1; next_dist = 1; while (next_dist < -distance && back_index >= 0) { thresholds[back_index] = next_dist; back_index--; next_dist++; distance++; } distance = 1; } } while (line_index < line_count);}/********************************************************************** * expand_rows * * Expand each row to the least of its allowed size and touching its * neighbours. If the expansion would entirely swallow a neighbouring row * then do so. **********************************************************************/void expand_rows( //find lines ICOORD page_tr, //top right TO_BLOCK *block, //block to do float gradient, //gradient to fit FCOORD rotation, //for drawing inT32 block_edge, //edge of block BOOL8 testing_on //correct orientation ) { BOOL8 swallowed_row; //eaten a neighbour float y_max, y_min; //new row limits float y_bottom, y_top; //allowed limits TO_ROW *test_row; //next row TO_ROW *row; //current row //iterators BLOBNBOX_IT blob_it = &block->blobs; TO_ROW_IT row_it = block->get_rows ();#ifndef GRAPHICS_DISABLED if (textord_show_expanded_rows && testing_on) { if (to_win == NULL) create_to_win(page_tr); }#endif adjust_row_limits(block); //shift min,max. if (textord_new_initial_xheight) { if (block->get_rows ()->length () == 0) return; compute_row_stats(block, textord_show_expanded_rows &&testing_on); } assign_blobs_to_rows (block, &gradient, 4, TRUE, FALSE, FALSE);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?