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 + -
显示快捷键?