makerow.cpp

来自「一OCR的相关资料。.希望对研究OCR的朋友有所帮助.」· C++ 代码 · 共 1,691 行 · 第 1/5 页

CPP
1,691
字号
      * (textord_merge_x + textord_merge_asc);    if (y_min > y_bottom) {      //expansion allowed                                 //expandable      swallowed_row = TRUE;      while (swallowed_row && !row_it.at_last ()) {        swallowed_row = FALSE;                                 //get next one        test_row = row_it.data_relative (1);                                 //overlaps space        if (test_row->max_y () > y_bottom) {          if (test_row->min_y () > y_bottom) {            row_it.forward ();#ifndef GRAPHICS_DISABLED            if (textord_show_expanded_rows && testing_on)              plot_parallel_row(test_row,                                gradient,                                block_edge,                                WHITE,                                rotation);#endif            blob_it.set_to_list (row->blob_list ());            blob_it.add_list_after (test_row->blob_list ());                                 //swallow complete row            delete row_it.extract ();            row_it.backward ();            swallowed_row = TRUE;          }          else if (test_row->max_y () < y_min)                                 //shorter limit            y_bottom = test_row->max_y ();          else            y_bottom = y_min;    //can't expand it        }      }      y_min = y_bottom;          //expand it    }    if (y_max < y_top) {         //expansion allowed      swallowed_row = TRUE;      while (swallowed_row && !row_it.at_first ()) {        swallowed_row = FALSE;                                 //get one above        test_row = row_it.data_relative (-1);        if (test_row->min_y () < y_top) {          if (test_row->max_y () < y_top) {            row_it.backward ();            blob_it.set_to_list (row->blob_list ());#ifndef GRAPHICS_DISABLED            if (textord_show_expanded_rows && testing_on)              plot_parallel_row(test_row,                                gradient,                                block_edge,                                WHITE,                                rotation);#endif            blob_it.add_list_after (test_row->blob_list ());                                 //swallow complete row            delete row_it.extract ();            row_it.forward ();            swallowed_row = TRUE;          }          else if (test_row->min_y () < y_max)                                 //shorter limit            y_top = test_row->min_y ();          else            y_top = y_max;       //can't expand it        }      }      y_max = y_top;    }                                 //new limits    row->set_limits (y_min, y_max);    row_it.backward ();  }  while (!row_it.at_last ());}/********************************************************************** * adjust_row_limits * * Change the limits of rows to suit the default fractions. **********************************************************************/void adjust_row_limits(                 //tidy limits                       TO_BLOCK *block  //block to do                      ) {  TO_ROW *row;                   //current row  float size;                    //size of row  float ymax;                    //top of row  float ymin;                    //bottom of row  TO_ROW_IT row_it = block->get_rows ();  for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {    row = row_it.data ();    size = row->max_y () - row->min_y ();    size /= textord_merge_x + textord_merge_asc + textord_merge_desc;    ymax = size * (textord_merge_x + textord_merge_asc);    ymin = -size * textord_merge_desc;    row->set_limits (row->intercept () + ymin, row->intercept () + ymax);    row->merged = FALSE;  }}/********************************************************************** * compute_row_stats * * Compute the linespacing and offset. **********************************************************************/void compute_row_stats(                  //find lines                       TO_BLOCK *block,  //block to do                       BOOL8 testing_on  //correct orientation                      ) {  INT32 row_index;               //of median  TO_ROW *row;                   //current row  TO_ROW *prev_row;              //previous row  float iqr;                     //inter quartile range  TO_ROW_IT row_it = block->get_rows ();                                 //number of rows  INT16 rowcount = row_it.length ();  TO_ROW **rows;                 //for choose nth  rows = (TO_ROW **) alloc_mem (rowcount * sizeof (TO_ROW *));  if (rows == NULL)    MEMORY_OUT.error ("compute_row_stats", ABORT, NULL);  rowcount = 0;  prev_row = NULL;  row_it.move_to_last ();        //start at bottom  do {    row = row_it.data ();    if (prev_row != NULL) {      rows[rowcount++] = prev_row;      prev_row->spacing = row->intercept () - prev_row->intercept ();      if (testing_on)        tprintf ("Row at %g yields spacing of %g\n",          row->intercept (), prev_row->spacing);    }    prev_row = row;    row_it.backward ();  }  while (!row_it.at_last ());  block->key_row = prev_row;  block->baseline_offset =    fmod (prev_row->parallel_c (), block->line_spacing);  if (testing_on)    tprintf ("Blob based spacing=(%g,%g), offset=%g",      block->line_size, block->line_spacing, block->baseline_offset);  if (rowcount > 0) {    row_index = choose_nth_item (rowcount * 3 / 4, rows, rowcount,      sizeof (TO_ROW *), row_spacing_order);    iqr = rows[row_index]->spacing;    row_index = choose_nth_item (rowcount / 4, rows, rowcount,      sizeof (TO_ROW *), row_spacing_order);    iqr -= rows[row_index]->spacing;    row_index = choose_nth_item (rowcount / 2, rows, rowcount,      sizeof (TO_ROW *), row_spacing_order);    block->key_row = rows[row_index];    if (testing_on)      tprintf (" row based=%g(%g)", rows[row_index]->spacing, iqr);    if (rowcount > 2    && iqr < rows[row_index]->spacing * textord_linespace_iqrlimit) {      if (!textord_new_initial_xheight) {        if (rows[row_index]->spacing < block->line_spacing          && rows[row_index]->spacing > block->line_size)          //within range          block->line_size = rows[row_index]->spacing;        //spacing=size        else if (rows[row_index]->spacing > block->line_spacing)          block->line_size = block->line_spacing;        //too big so use max      }      else {        if (rows[row_index]->spacing < block->line_spacing)          block->line_size = rows[row_index]->spacing;        else          block->line_size = block->line_spacing;        //too big so use max      }      if (block->line_size < textord_min_xheight)        block->line_size = (float) textord_min_xheight;      block->line_spacing = rows[row_index]->spacing;      block->max_blob_size =        block->line_spacing * textord_excess_blobsize;    }    block->baseline_offset = fmod (rows[row_index]->intercept (),      block->line_spacing);  }  if (testing_on)    tprintf ("\nEstimate line size=%g, spacing=%g, offset=%g\n",      block->line_size, block->line_spacing, block->baseline_offset);  free_mem(rows);}/********************************************************************** * compute_block_xheight * * Compute the xheight of the individual rows, then correlate them * and interpret ascenderless lines, correcting xheights. **********************************************************************/void compute_block_xheight(                  //find lines                           TO_BLOCK *block,  //block to do                           float gradient    //global skew                          ) {  TO_ROW *row;                   //current row  int xh_count, desc_count;      //no of samples  float block_median;            //median blob size  int asc_count, cap_count;  INT32 min_size, max_size;      //limits on xheight  INT32 evidence;                //no of samples on row  float xh_sum, desc_sum;        //for averages  float asc_sum, cap_sum;  TO_ROW_IT row_it = block->get_rows ();  STATS row_heights;             //block evidence  if (row_it.empty ())    return;                      //no rows  block_median = median_block_xheight (block, gradient);  block_median *= 2;  if (block_median < block->line_size)    block_median = block->line_size;  //      tprintf("Block median=%g, linesize=%g\n",  //              block_median,block->line_size);  max_size = (INT32) ceil (block_median);  min_size = (INT32) floor (block_median * textord_minxh);  row_heights.set_range (min_size, max_size + 1);  xh_count = desc_count = asc_count = cap_count = 0;  xh_sum = desc_sum = asc_sum = cap_sum = 0.0f;  for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {    row = row_it.data ();    evidence = compute_row_xheight (row, min_size, max_size, gradient);    if (row->xheight > 0 && row->ascrise > 0) {      row_heights.add ((INT32) row->xheight, evidence);      xh_count += evidence;      asc_sum += row->ascrise;      asc_count++;    }    else if (row->xheight > 0) {      cap_sum += row->xheight;   //assume just caps      cap_count++;    }    if (row->descdrop != 0) {      desc_sum += row->descdrop;      desc_count++;    }  }  if (xh_count > 0) {                                 //median    xh_sum = row_heights.ile (0.5);    asc_sum /= asc_count;  }  else if (cap_count > 0) {    cap_sum /= cap_count;        //must assume caps    xh_sum =      cap_sum * textord_merge_x / (textord_merge_x + textord_merge_asc);    asc_sum =      cap_sum * textord_merge_asc / (textord_merge_x + textord_merge_asc);  }  else {                                 //default sizes    xh_sum = block_median * textord_merge_x;    asc_sum = block_median * textord_merge_asc;  }  if (desc_count > 0) {    desc_sum /= desc_count;  }  else {    desc_sum = xh_sum * textord_merge_desc / textord_merge_x;  }  //      tprintf("Block average x height=%g, count=%d, asc=%g/%d, desc=%g/%d,cap=%g/%d\n",  //              xh_sum,xh_count,asc_sum,asc_count,desc_sum,desc_count,  //              cap_sum,cap_count);  if (xh_sum < textord_min_xheight)    xh_sum = (float) textord_min_xheight;  block->xheight = xh_sum;  for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {    correct_row_xheight (row_it.data (), xh_sum, asc_sum, desc_sum);  }}/********************************************************************** * median_block_xheight * * Compute the linespacing and offset. **********************************************************************/float median_block_xheight(                  //find lines                           TO_BLOCK *block,  //block to do                           float gradient    //global skew                          ) {  TO_ROW *row;                   //current row  float result;                  //output size  float xcentre;                 //centre of blob  TO_ROW_IT row_it = block->get_rows ();  BLOBNBOX_IT blob_it;  BLOBNBOX *blob;                //current blob  float *heights;                //for choose nth  INT32 blob_count;              //blobs in block  INT32 blob_index;              //current blob  blob_count = 0;  for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ())    blob_count += row_it.data ()->blob_list ()->length ();  heights = (float *) alloc_mem (blob_count * sizeof (float));  if (heights == NULL)    MEMORY_OUT.error ("compute_row_stats", ABORT, NULL);  blob_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 ();      if (!blob->joined_to_prev ()) {        xcentre =          (blob->bounding_box ().left () +          blob->bounding_box ().right ()) / 2.0f;        heights[blob_index] =          blob->bounding_box ().top () - gradient * xcentre -          row->parallel_c ();        if (heights[blob_index] > 0)          blob_index++;      }    }  }  ASSERT_HOST (blob_index > 0);  //dont expect 0  blob_count = blob_index;  blob_index = choose_nth_item (blob_count / 2, heights, blob_count);  result = heights[blob_index];  free_mem(heights);  return result;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?