⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 topitch.cpp

📁 一OCR的相关资料。.希望对研究OCR的朋友有所帮助.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                       INT32 &corr_prop,                       INT32 &dunno) {  TO_ROW *row;                   //current 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 ();    switch (row->pitch_decision) {      case PITCH_DUNNO:        dunno++;        break;      case PITCH_DEF_PROP:        def_prop++;        break;      case PITCH_MAYBE_PROP:        maybe_prop++;        break;      case PITCH_DEF_FIXED:        def_fixed++;        break;      case PITCH_MAYBE_FIXED:        maybe_fixed++;        break;      case PITCH_CORR_PROP:        corr_prop++;        break;      case PITCH_CORR_FIXED:        corr_fixed++;        break;    }  }}/********************************************************************** * row_pitch_stats * * Decide whether each row is fixed pitch individually. **********************************************************************/BOOL8 row_pitch_stats(                  //find line stats                      TO_ROW *row,      //current row                      INT32 maxwidth,   //of spaces                      BOOL8 testing_on  //correct orientation                     ) {  BLOBNBOX *blob;                //current blob  int gap_index;                 //current gap  INT32 prev_x;                  //end of prev blob  INT32 cluster_count;           //no of clusters  INT32 prev_count;              //of clusters  INT32 smooth_factor;           //for smoothing stats  BOX blob_box;                  //bounding box  float lower, upper;            //cluster thresholds                                 //gap sizes  float gaps[BLOCK_STATS_CLUSTERS];                                 //blobs  BLOBNBOX_IT blob_it = row->blob_list ();  STATS gap_stats (0, maxwidth);  STATS cluster_stats[BLOCK_STATS_CLUSTERS + 1];  //clusters  smooth_factor =    (INT32) (row->xheight * textord_wordstats_smooth_factor + 1.5);  if (!blob_it.empty ()) {    prev_x = blob_it.data ()->bounding_box ().right ();    blob_it.forward ();    while (!blob_it.at_first ()) {      blob = blob_it.data ();      if (!blob->joined_to_prev ()) {        blob_box = blob->bounding_box ();        if (blob_box.left () - prev_x < maxwidth)          gap_stats.add (blob_box.left () - prev_x, 1);        prev_x = blob_box.right ();      }      blob_it.forward ();    }  }  if (gap_stats.get_total () == 0) {    return FALSE;  }  cluster_count = 0;  lower = row->xheight * words_initial_lower;  upper = row->xheight * words_initial_upper;  gap_stats.smooth (smooth_factor);  do {    prev_count = cluster_count;    cluster_count = gap_stats.cluster (lower, upper,      textord_spacesize_ratioprop,      BLOCK_STATS_CLUSTERS, cluster_stats);  }  while (cluster_count > prev_count && cluster_count < BLOCK_STATS_CLUSTERS);  if (cluster_count < 1) {    return FALSE;  }  for (gap_index = 0; gap_index < cluster_count; gap_index++)    gaps[gap_index] = cluster_stats[gap_index + 1].ile (0.5);  //get medians  if (testing_on) {    tprintf ("cluster_count=%d:", cluster_count);    for (gap_index = 0; gap_index < cluster_count; gap_index++)      tprintf (" %g(%d)", gaps[gap_index],        cluster_stats[gap_index + 1].get_total ());    tprintf ("\n");  }  qsort (gaps, cluster_count, sizeof (float), sort_floats2);  //Try to find proportional non-space and space for row.  lower = row->xheight * words_default_prop_nonspace;  upper = row->xheight * textord_words_min_minspace;  for (gap_index = 0; gap_index < cluster_count    && gaps[gap_index] < lower; gap_index++);  if (gap_index == 0) {    if (testing_on)      tprintf ("No clusters below nonspace threshold!!\n");    if (cluster_count > 1) {      row->pr_nonsp = gaps[0];      row->pr_space = gaps[1];    }    else {      row->pr_nonsp = lower;      row->pr_space = gaps[0];    }  }  else {    row->pr_nonsp = gaps[gap_index - 1];    while (gap_index < cluster_count && gaps[gap_index] < upper)      gap_index++;    if (gap_index == cluster_count) {      if (testing_on)        tprintf ("No clusters above nonspace threshold!!\n");      row->pr_space = lower * textord_spacesize_ratioprop;    }    else      row->pr_space = gaps[gap_index];  }  //Now try to find the fixed pitch space and non-space.  upper = row->xheight * words_default_fixed_space;  for (gap_index = 0; gap_index < cluster_count    && gaps[gap_index] < upper; gap_index++);  if (gap_index == 0) {    if (testing_on)      tprintf ("No clusters below space threshold!!\n");    row->fp_nonsp = upper;    row->fp_space = gaps[0];  }  else {    row->fp_nonsp = gaps[gap_index - 1];    if (gap_index == cluster_count) {      if (testing_on)        tprintf ("No clusters above space threshold!!\n");      row->fp_space = row->xheight;    }    else      row->fp_space = gaps[gap_index];  }  if (testing_on) {    tprintf      ("Initial estimates:pr_nonsp=%g, pr_space=%g, fp_nonsp=%g, fp_space=%g\n",      row->pr_nonsp, row->pr_space, row->fp_nonsp, row->fp_space);  }  return TRUE;                   //computed some stats}/********************************************************************** * find_row_pitch * * Check to see if this row could be fixed pitch using the given spacings. * Blobs with gaps smaller than the lower threshold are assumed to be one. * The larger threshold is the word gap threshold. **********************************************************************/BOOL8 find_row_pitch(                    //find lines                     TO_ROW *row,        //row to do                     INT32 maxwidth,     //max permitted space                     INT32 dm_gap,       //ignorable gaps                     TO_BLOCK *block,    //block of row                     INT32 block_index,  //block_number                     INT32 row_index,    //number of row                     BOOL8 testing_on    //correct orientation                    ) {  BOOL8 used_dm_model;           //looks lik dot matrix  float min_space;               //estimate threshold  float non_space;               //gap size  float gap_iqr;                 //interquartile range  float pitch_iqr;  float dm_gap_iqr;              //interquartile range  float dm_pitch_iqr;  float dm_pitch;                //pitch with dm on  float pitch;                   //revised estimate  float initial_pitch;           //guess at pitch  STATS gap_stats (0, maxwidth);                                 //centre-centre  STATS pitch_stats (0, maxwidth);  row->fixed_pitch = 0.0f;  initial_pitch = row->fp_space;  if (initial_pitch > row->xheight * (1 + words_default_fixed_limit))    initial_pitch = row->xheight;//keep pitch decent  non_space = row->fp_nonsp;  if (non_space > initial_pitch)    non_space = initial_pitch;  min_space = (initial_pitch + non_space) / 2;  if (!count_pitch_stats (row, &gap_stats, &pitch_stats,  initial_pitch, min_space, TRUE, FALSE, dm_gap)) {    dm_gap_iqr = 0.0001;    dm_pitch_iqr = maxwidth * 2.0f;    dm_pitch = initial_pitch;  }  else {    dm_gap_iqr = gap_stats.ile (0.75) - gap_stats.ile (0.25);    dm_pitch_iqr = pitch_stats.ile (0.75) - pitch_stats.ile (0.25);    dm_pitch = pitch_stats.ile (0.5);  }  gap_stats.clear ();  pitch_stats.clear ();  if (!count_pitch_stats (row, &gap_stats, &pitch_stats,  initial_pitch, min_space, TRUE, FALSE, 0)) {    gap_iqr = 0.0001;    pitch_iqr = maxwidth * 3.0f;  }  else {    gap_iqr = gap_stats.ile (0.75) - gap_stats.ile (0.25);    pitch_iqr = pitch_stats.ile (0.75) - pitch_stats.ile (0.25);    if (testing_on)      tprintf        ("First fp iteration:initial_pitch=%g, gap_iqr=%g, pitch_iqr=%g, pitch=%g\n",        initial_pitch, gap_iqr, pitch_iqr, pitch_stats.ile (0.5));    initial_pitch = pitch_stats.ile (0.5);    if (min_space > initial_pitch      && count_pitch_stats (row, &gap_stats, &pitch_stats,    initial_pitch, initial_pitch, TRUE, FALSE, 0)) {      min_space = initial_pitch;      gap_iqr = gap_stats.ile (0.75) - gap_stats.ile (0.25);      pitch_iqr = pitch_stats.ile (0.75) - pitch_stats.ile (0.25);      if (testing_on)        tprintf          ("Revised fp iteration:initial_pitch=%g, gap_iqr=%g, pitch_iqr=%g, pitch=%g\n",          initial_pitch, gap_iqr, pitch_iqr, pitch_stats.ile (0.5));      initial_pitch = pitch_stats.ile (0.5);    }  }  if (textord_debug_pitch_metric)    tprintf ("Blk=%d:Row=%d:%c:p_iqr=%g:g_iqr=%g:dm_p_iqr=%g:dm_g_iqr=%g:%c:",      block_index, row_index,      block->block->text_region () != NULL ?      (block->block->text_region ()->is_prop ()? 'P' : 'F') : 'X',    pitch_iqr, gap_iqr, dm_pitch_iqr, dm_gap_iqr,    pitch_iqr > maxwidth && dm_pitch_iqr > maxwidth ? 'D'    : (pitch_iqr * dm_gap_iqr <=    dm_pitch_iqr * gap_iqr ? 'S' : 'M'));  if (pitch_iqr > maxwidth && dm_pitch_iqr > maxwidth) {    row->pitch_decision = PITCH_DUNNO;    if (textord_debug_pitch_metric)      tprintf ("\n");    return FALSE;                //insufficient data  }  if (pitch_iqr * dm_gap_iqr <= dm_pitch_iqr * gap_iqr) {    if (testing_on)      tprintf        ("Choosing non dm version:pitch_iqr=%g, gap_iqr=%g, dm_pitch_iqr=%g, dm_gap_iqr=%g\n",        pitch_iqr, gap_iqr, dm_pitch_iqr, dm_gap_iqr);    gap_iqr = gap_stats.ile (0.75) - gap_stats.ile (0.25);    pitch_iqr = pitch_stats.ile (0.75) - pitch_stats.ile (0.25);    pitch = pitch_stats.ile (0.5);    used_dm_model = FALSE;  }  else {    if (testing_on)      tprintf        ("Choosing dm version:pitch_iqr=%g, gap_iqr=%g, dm_pitch_iqr=%g, dm_gap_iqr=%g\n",        pitch_iqr, gap_iqr, dm_pitch_iqr, dm_gap_iqr);    gap_iqr = dm_gap_iqr;    pitch_iqr = dm_pitch_iqr;    pitch = dm_pitch;    used_dm_model = TRUE;  }  if (textord_debug_pitch_metric) {    tprintf ("rev_p_iqr=%g:rev_g_iqr=%g:pitch=%g:",      pitch_iqr, gap_iqr, pitch);    tprintf ("p_iqr/g=%g:p_iqr/x=%g:iqr_res=%c:",      pitch_iqr / gap_iqr, pitch_iqr / block->xheight,      pitch_iqr < gap_iqr * textord_fpiqr_ratio      && pitch_iqr < block->xheight * textord_max_pitch_iqr      && pitch < block->xheight * textord_words_default_maxspace      ? 'F' : 'P');  }  if (pitch_iqr < gap_iqr * textord_fpiqr_ratio    && pitch_iqr < block->xheight * textord_max_pitch_iqr    && pitch < block->xheight * textord_words_default_maxspace)    row->pitch_decision = PITCH_MAYBE_FIXED;  else    row->pitch_decision = PITCH_MAYBE_PROP;  row->fixed_pitch = pitch;  row->kern_size = gap_stats.ile (0.5);  row->min_space = (INT32) (row->fixed_pitch + non_space) / 2;  if (row->min_space > row->fixed_pitch)    row->min_space = (INT32) row->fixed_pitch;  row->max_nonspace = row->min_space;  row->space_size = row->fixed_pitch;  row->space_threshold = (row->max_nonspace + row->min_space) / 2;  row->used_dm_model = used_dm_model;  return TRUE;}/********************************************************************** * fixed_pitch_row * * Check to see if this row could be fixed pitch using the given spacings. * Blobs with gaps smaller than the lower threshold are assumed to be one. * The larger threshold is the word gap threshold. **********************************************************************/BOOL8 fixed_pitch_row(                   //find lines                      TO_ROW *row,       //row to do                      INT32 block_index  //block_number                     ) {  const char *res_string;        //pitch result  INT16 mid_cuts;                //no of cheap cuts  float non_space;               //gap size  float pitch_sd;                //error on pitch  float sp_sd;                   //space sd  non_space = row->fp_nonsp;  if (non_space > row->fixed_pitch)    non_space = row->fixed_pitch;  if (textord_all_prop) {    // Set the decision to definitely proportional.    pitch_sd = textord_words_def_prop * row->fixed_pitch;    row->pitch_decision = PITCH_DEF_PROP;  } else {    pitch_sd = tune_row_pitch (row, &row->projection, row->projection_left,                               row->projection_right,                               (row->fixed_pitch + non_space * 3) / 4,                               row->fixed_pitch, sp_sd, mid_cuts,                               &row->char_cells,                               block_index == textord_debug_block);    if (pitch_sd < textord_words_pitchsd_threshold * row->fixed_pitch      && ((pitsync_linear_version & 3) < 3      || (pitsync_linear_version & 3) >= 3 && (row->used_dm_model      || sp_sd > 20      || pitch_sd == 0    && sp_sd > 10))) {      if (pitch_sd < textord_words_def_fixed * row->fixed_pitch        && !row->all_caps        && ((pitsync_linear_version & 3) < 3 || sp_sd > 20))        row->pitch_decision = PITCH_DEF_FIXED;      else        row->pitch_decision = PITCH_MAYBE_FIXED;    }

⌨️ 快捷键说明

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