当前位置: 首页>>代码示例>>C++>>正文


C++ TBLOB::bounding_box方法代码示例

本文整理汇总了C++中TBLOB::bounding_box方法的典型用法代码示例。如果您正苦于以下问题:C++ TBLOB::bounding_box方法的具体用法?C++ TBLOB::bounding_box怎么用?C++ TBLOB::bounding_box使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在TBLOB的用法示例。


在下文中一共展示了TBLOB::bounding_box方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: CountMisfitTops

// Returns the number of misfit blob tops in this word.
int Tesseract::CountMisfitTops(WERD_RES *word_res) {
  int bad_blobs = 0;
  TBLOB* blob = word_res->rebuild_word->blobs;
  int blob_id = 0;
  for (; blob != NULL; blob = blob->next, ++blob_id) {
    UNICHAR_ID class_id = word_res->best_choice->unichar_id(blob_id);
    if (unicharset.get_isalpha(class_id) || unicharset.get_isdigit(class_id)) {
      int top = blob->bounding_box().top();
      if (top >= INT_FEAT_RANGE)
        top = INT_FEAT_RANGE - 1;
      int min_bottom, max_bottom, min_top, max_top;
      unicharset.get_top_bottom(class_id, &min_bottom, &max_bottom,
                                &min_top, &max_top);
      if (max_top - min_top > kMaxCharTopRange)
        continue;
      bool bad =  top < min_top - x_ht_acceptance_tolerance ||
                  top > max_top + x_ht_acceptance_tolerance;
      if (bad)
        ++bad_blobs;
      if (debug_x_ht_level >= 1) {
        tprintf("Class %s is %s with top %d vs limits of %d->%d, +/-%d\n",
                unicharset.id_to_unichar(class_id),
                bad ? "Misfit" : "OK", top, min_top, max_top,
                static_cast<int>(x_ht_acceptance_tolerance));
      }
    }
  }
  return bad_blobs;
}
开发者ID:ErwcPKerr,项目名称:node-dv,代码行数:30,代码来源:fixxht.cpp

示例2: memalloc

/**********************************************************************
 * blobs_widths
 *
 * Compute the widths of a list of blobs. Return an array of the widths
 * and gaps.
 **********************************************************************/
WIDTH_RECORD *blobs_widths(TBLOB *blobs) {  /*blob to compute on */
  WIDTH_RECORD *width_record;
  TPOINT topleft;                /*bounding box */
  TPOINT botright;
  int i = 0;
  int blob_end;
  int num_blobs = count_blobs (blobs);

  /* Get memory */
  width_record = (WIDTH_RECORD *) memalloc (sizeof (int) * num_blobs * 2);
  width_record->num_chars = num_blobs;

  TBOX bbox = blobs->bounding_box();
  width_record->widths[i++] = bbox.width();
  /* First width */
  blob_end = bbox.right();

  for (TBLOB* blob = blobs->next; blob != NULL; blob = blob->next) {
    TBOX curbox = blob->bounding_box();
    width_record->widths[i++] = curbox.left() - blob_end;
    width_record->widths[i++] = curbox.width();
    blob_end = curbox.right();
  }
  return width_record;
}
开发者ID:ErwcPKerr,项目名称:node-dv,代码行数:31,代码来源:blobs.cpp

示例3: render_segmentation

/**********************************************************************
 * render_segmentation
 *
 * Create a list of line segments that represent the list of chunks
 * using the correct segmentation that was supplied as input.
 **********************************************************************/
void render_segmentation(ScrollView *window,
                         TBLOB *chunks,
                         SEARCH_STATE segmentation) {
  TBLOB *blob;
  C_COL color = Black;
  int char_num = -1;
  int chunks_left = 0;

  TBOX bbox;
  if (chunks) bbox = chunks->bounding_box();

  for (blob = chunks; blob != NULL; blob = blob->next) {
    bbox += blob->bounding_box();
    if (chunks_left-- == 0) {
      color = color_list[++char_num % NUM_COLORS];

      if (char_num < segmentation[0])
        chunks_left = segmentation[char_num + 1];
      else
        chunks_left = MAX_INT32;
    }
    render_outline(window, blob->outlines, color);
  }
  window->ZoomToRectangle(bbox.left(), bbox.top(),
                          bbox.right(), bbox.bottom());
}
开发者ID:slohman,项目名称:October2012Workspace,代码行数:32,代码来源:plotseg.cpp

示例4: chop_one_blob

/**
 * @name chop_one_blob
 *
 * Start with the current one-blob word and its classification.  Find
 * the worst blobs and try to divide it up to improve the ratings.
 * Used for testing chopper.
 */
bool Wordrec::chop_one_blob(TWERD *word,
                               BLOB_CHOICE_LIST_VECTOR *char_choices,
                               inT32 *blob_number,
                               SEAMS *seam_list,
                               int *right_chop_index) {
  TBLOB *blob;
  inT16 x = 0;
  float rating_ceiling = MAX_FLOAT32;
  BLOB_CHOICE_LIST *answer;
  BLOB_CHOICE_IT answer_it;
  SEAM *seam;
  UNICHAR_ID unichar_id = 0;
  int left_chop_index = 0;

  do {
    *blob_number = select_blob_to_split(*char_choices, rating_ceiling, false);
    if (chop_debug)
      cprintf("blob_number = %d\n", *blob_number);
    if (*blob_number == -1)
      return false;
    seam = attempt_blob_chop(word, *blob_number, true, *seam_list);
    if (seam != NULL)
      break;
    /* Must split null blobs */
    answer = char_choices->get(*blob_number);
    if (answer == NULL)
      return false;
    answer_it.set_to_list(answer);
    rating_ceiling = answer_it.data()->rating();  // try a different blob
  } while (true);
  /* Split OK */
  for (blob = word->blobs; x < *blob_number; x++) {
    blob = blob->next;
  }
  if (chop_debug) {
    tprintf("Chop made blob1:");
    blob->bounding_box().print();
    tprintf("and blob2:");
    blob->next->bounding_box().print();
  }
  *seam_list = insert_seam(*seam_list, *blob_number, seam, blob, word->blobs);

  answer = char_choices->get(*blob_number);
  answer_it.set_to_list(answer);
  unichar_id = answer_it.data()->unichar_id();
  float rating = answer_it.data()->rating() / exp(1.0);
  left_chop_index = atoi(unicharset.id_to_unichar(unichar_id));

  delete char_choices->get(*blob_number);
  // combine confidence w/ serial #
  answer = fake_classify_blob(0, rating, -rating);
  modify_blob_choice(answer, left_chop_index);
  char_choices->insert(answer, *blob_number);

  answer = fake_classify_blob(0, rating - 0.125f, -rating);
  modify_blob_choice(answer, ++*right_chop_index);
  char_choices->set(answer, *blob_number + 1);
  return true;
}
开发者ID:0359xiaodong,项目名称:tess-two,代码行数:66,代码来源:chopper.cpp

示例5: bounding_box

TBOX TWERD::bounding_box() const {
  TBOX result;
  for (TBLOB* blob = blobs; blob != NULL; blob = blob->next) {
    TBOX box = blob->bounding_box();
    result += box;
  }
  return result;
}
开发者ID:coffeesam,项目名称:tesseract-ocr,代码行数:8,代码来源:blobs.cpp

示例6: ExtractFeatures

// Extracts sets of 3-D features of length kStandardFeatureLength (=12.8), as
// (x,y) position and angle as measured counterclockwise from the vector
// <-1, 0>, from blob using two normalizations defined by bl_denorm and
// cn_denorm. See SetpuBLCNDenorms for definitions.
// If outline_cn_counts is not nullptr, on return it contains the cumulative
// number of cn features generated for each outline in the blob (in order).
// Thus after the first outline, there were (*outline_cn_counts)[0] features,
// after the second outline, there were (*outline_cn_counts)[1] features etc.
void Classify::ExtractFeatures(const TBLOB& blob,
                               bool nonlinear_norm,
                               GenericVector<INT_FEATURE_STRUCT>* bl_features,
                               GenericVector<INT_FEATURE_STRUCT>* cn_features,
                               INT_FX_RESULT_STRUCT* results,
                               GenericVector<int>* outline_cn_counts) {
  DENORM bl_denorm, cn_denorm;
  tesseract::Classify::SetupBLCNDenorms(blob, nonlinear_norm,
                                        &bl_denorm, &cn_denorm, results);
  if (outline_cn_counts != nullptr)
    outline_cn_counts->truncate(0);
  // Iterate the outlines.
  for (TESSLINE* ol = blob.outlines; ol != nullptr; ol = ol->next) {
    // Iterate the polygon.
    EDGEPT* loop_pt = ol->FindBestStartPt();
    EDGEPT* pt = loop_pt;
    if (pt == nullptr) continue;
    do {
      if (pt->IsHidden()) continue;
      // Find a run of equal src_outline.
      EDGEPT* last_pt = pt;
      do {
        last_pt = last_pt->next;
      } while (last_pt != loop_pt && !last_pt->IsHidden() &&
               last_pt->src_outline == pt->src_outline);
      last_pt = last_pt->prev;
      // Until the adaptive classifier can be weaned off polygon segments,
      // we have to force extraction from the polygon for the bl_features.
      ExtractFeaturesFromRun(pt, last_pt, bl_denorm, kStandardFeatureLength,
                             true, bl_features);
      ExtractFeaturesFromRun(pt, last_pt, cn_denorm, kStandardFeatureLength,
                             false, cn_features);
      pt = last_pt;
    } while ((pt = pt->next) != loop_pt);
    if (outline_cn_counts != nullptr)
      outline_cn_counts->push_back(cn_features->size());
  }
  results->NumBL = bl_features->size();
  results->NumCN = cn_features->size();
  results->YBottom = blob.bounding_box().bottom();
  results->YTop = blob.bounding_box().top();
  results->Width = blob.bounding_box().width();
}
开发者ID:dqsoft,项目名称:tesseract,代码行数:51,代码来源:intfx.cpp

示例7:

/**********************************************************************
 * record_blob_bounds
 *
 * Set up and initialize an array that holds the bounds of a set of
 * blobs.  Caller should delete[] the array.
 **********************************************************************/
TBOX *Wordrec::record_blob_bounds(TBLOB *blobs) {
  int nblobs = count_blobs(blobs);
  TBOX *bboxes = new TBOX[nblobs];

  inT16 x = 0;
  for (TBLOB* blob = blobs; blob != NULL; blob = blob->next) {
    bboxes[x] = blob->bounding_box();
    x++;
  }
  return bboxes;
}
开发者ID:ErfanHasmin,项目名称:scope-ocr,代码行数:17,代码来源:pieces.cpp

示例8: TBOX

SEAM *Wordrec::chop_overlapping_blob(const GenericVector<TBOX>& boxes,
                                     bool italic_blob, WERD_RES *word_res,
                                     int *blob_number) {
  TWERD *word = word_res->chopped_word;
  for (*blob_number = 0; *blob_number < word->NumBlobs(); ++*blob_number) {
    TBLOB *blob = word->blobs[*blob_number];
    TPOINT topleft, botright;
    topleft.x = blob->bounding_box().left();
    topleft.y = blob->bounding_box().top();
    botright.x = blob->bounding_box().right();
    botright.y = blob->bounding_box().bottom();

    TPOINT original_topleft, original_botright;
    word_res->denorm.DenormTransform(NULL, topleft, &original_topleft);
    word_res->denorm.DenormTransform(NULL, botright, &original_botright);

    TBOX original_box = TBOX(original_topleft.x, original_botright.y,
                             original_botright.x, original_topleft.y);

    bool almost_equal_box = false;
    int num_overlap = 0;
    for (int i = 0; i < boxes.size(); i++) {
      if (original_box.overlap_fraction(boxes[i]) > 0.125)
        num_overlap++;
      if (original_box.almost_equal(boxes[i], 3))
        almost_equal_box = true;
    }

    TPOINT location;
    if (divisible_blob(blob, italic_blob, &location) ||
        (!almost_equal_box && num_overlap > 1)) {
      SEAM *seam = attempt_blob_chop(word, blob, *blob_number,
                                     italic_blob, word_res->seam_array);
      if (seam != NULL)
        return seam;
    }
  }

  *blob_number = -1;
  return NULL;
}
开发者ID:ManishKSharma,项目名称:tess-two,代码行数:41,代码来源:chopper.cpp

示例9: flip_hyphens

// Note: After running this function word_res->ratings
// might not contain the right BLOB_CHOICE corresponding to each character
// in word_res->best_choice.
void Tesseract::flip_hyphens(WERD_RES *word_res) {
  WERD_CHOICE *best_choice = word_res->best_choice;
  int i;
  int prev_right = -9999;
  int next_left;
  TBOX out_box;
  float aspect_ratio;

  if (tessedit_lower_flip_hyphen <= 1)
    return;

  int num_blobs = word_res->rebuild_word->NumBlobs();
  UNICHAR_ID unichar_dash = word_res->uch_set->unichar_to_id("-");
  for (i = 0; i < best_choice->length() && i < num_blobs; ++i) {
    TBLOB* blob = word_res->rebuild_word->blobs[i];
    out_box = blob->bounding_box();
    if (i + 1 == num_blobs)
      next_left = 9999;
    else
      next_left = word_res->rebuild_word->blobs[i + 1]->bounding_box().left();
    // Dont touch small or touching blobs - it is too dangerous.
    if ((out_box.width() > 8 * word_res->denorm.x_scale()) &&
        (out_box.left() > prev_right) && (out_box.right() < next_left)) {
      aspect_ratio = out_box.width() / (float) out_box.height();
      if (word_res->uch_set->eq(best_choice->unichar_id(i), ".")) {
        if (aspect_ratio >= tessedit_upper_flip_hyphen &&
            word_res->uch_set->contains_unichar_id(unichar_dash) &&
            word_res->uch_set->get_enabled(unichar_dash)) {
          /* Certain HYPHEN */
          best_choice->set_unichar_id(unichar_dash, i);
          if (word_res->reject_map[i].rejected())
            word_res->reject_map[i].setrej_hyphen_accept();
        }
        if ((aspect_ratio > tessedit_lower_flip_hyphen) &&
          word_res->reject_map[i].accepted())
                                 //Suspected HYPHEN
          word_res->reject_map[i].setrej_hyphen ();
      }
      else if (best_choice->unichar_id(i) == unichar_dash) {
        if ((aspect_ratio >= tessedit_upper_flip_hyphen) &&
          (word_res->reject_map[i].rejected()))
          word_res->reject_map[i].setrej_hyphen_accept();
        //Certain HYPHEN

        if ((aspect_ratio <= tessedit_lower_flip_hyphen) &&
          (word_res->reject_map[i].accepted()))
                                 //Suspected HYPHEN
          word_res->reject_map[i].setrej_hyphen();
      }
    }
    prev_right = out_box.right();
  }
}
开发者ID:xmarston,项目名称:BillRecognizer,代码行数:56,代码来源:reject.cpp

示例10: Normalize

// Normalize in-place and record the normalization in the DENORM.
void TWERD::Normalize(ROW* row, float x_height, bool numeric_mode,
                      DENORM* denorm) {
  TBOX word_box = bounding_box();
  DENORM antidote((word_box.left() + word_box.right()) / 2.0,
                  kBlnXHeight / x_height, row);
  if (row == NULL) {
    antidote = DENORM(antidote.origin(), antidote.scale(), 0.0,
                      word_box.bottom(), 0, NULL, false, NULL);
  }
  int num_segments = 0;
  DENORM_SEG *segs = new DENORM_SEG[NumBlobs()];
  for (TBLOB* blob = blobs; blob != NULL; blob = blob->next) {
    TBOX blob_box = blob->bounding_box();
    ICOORD translation(-static_cast<int>(floor(antidote.origin() + 0.5)),
                       -blob_box.bottom());
    float factor = antidote.scale();
    if (numeric_mode) {
      factor = ClipToRange(kBlnXHeight * 4.0f / (3 * blob_box.height()),
                           factor, factor * 1.5f);
      segs[num_segments].xstart = blob->bounding_box().left();
      segs[num_segments].ycoord = blob_box.bottom();
      segs[num_segments++].scale_factor = factor;
    } else {
      float blob_x_center = (blob_box.left() + blob_box.right()) / 2.0;
      float y_shift = antidote.yshift_at_orig_x(blob_x_center);
      translation.set_y(-static_cast<int>(floor(y_shift + 0.5)));
    }
    blob->Move(translation);
    blob->Scale(factor);
    blob->Move(ICOORD(0, kBlnBaselineOffset));
  }
  if (num_segments > 0) {
    antidote.set_segments(segs, num_segments);
  }
  delete [] segs;
  if (denorm != NULL)
    *denorm = antidote;
}
开发者ID:coffeesam,项目名称:tesseract-ocr,代码行数:39,代码来源:blobs.cpp

示例11: BLNormalize

// Baseline normalizes the blobs in-place, recording the normalization in the
// DENORMs in the blobs.
void TWERD::BLNormalize(const BLOCK* block, const ROW* row, Pix* pix,
                        bool inverse, float x_height, bool numeric_mode,
                        tesseract::OcrEngineMode hint,
                        const TBOX* norm_box,
                        DENORM* word_denorm) {
  TBOX word_box = bounding_box();
  if (norm_box != NULL) word_box = *norm_box;
  float word_middle = (word_box.left() + word_box.right()) / 2.0f;
  float input_y_offset = 0.0f;
  float final_y_offset = static_cast<float>(kBlnBaselineOffset);
  float scale = kBlnXHeight / x_height;
  if (hint == tesseract::OEM_CUBE_ONLY || row == NULL) {
    word_middle = word_box.left();
    input_y_offset = word_box.bottom();
    final_y_offset = 0.0f;
    if (hint == tesseract::OEM_CUBE_ONLY)
      scale = 1.0f;
  } else {
    input_y_offset = row->base_line(word_middle);
  }
  for (int b = 0; b < blobs.size(); ++b) {
    TBLOB* blob = blobs[b];
    TBOX blob_box = blob->bounding_box();
    float mid_x = (blob_box.left() + blob_box.right()) / 2.0f;
    float baseline = input_y_offset;
    float blob_scale = scale;
    if (numeric_mode) {
      baseline = blob_box.bottom();
      blob_scale = ClipToRange(kBlnXHeight * 4.0f / (3 * blob_box.height()),
                               scale, scale * 1.5f);
    } else if (row != NULL && hint != tesseract::OEM_CUBE_ONLY) {
      baseline = row->base_line(mid_x);
    }
    // The image will be 8-bit grey if the input was grey or color. Note that in
    // a grey image 0 is black and 255 is white. If the input was binary, then
    // the pix will be binary and 0 is white, with 1 being black.
    // To tell the difference pixGetDepth() will return 8 or 1.
    // The inverse flag will be true iff the word has been determined to be
    // white on black, and is independent of whether the pix is 8 bit or 1 bit.
    blob->Normalize(block, NULL, NULL, word_middle, baseline, blob_scale,
                    blob_scale, 0.0f, final_y_offset, inverse, pix);
  }
  if (word_denorm != NULL) {
    word_denorm->SetupNormalization(block, NULL, NULL, word_middle,
                                    input_y_offset, scale, scale,
                                    0.0f, final_y_offset);
    word_denorm->set_inverse(inverse);
    word_denorm->set_pix(pix);
  }
}
开发者ID:11110101,项目名称:tess-two,代码行数:52,代码来源:blobs.cpp

示例12: DisplaySegmentation

// Displays the segmentation state of *this (if not the same as the last
// one displayed) and waits for a click in the window.
void WERD_CHOICE::DisplaySegmentation(TWERD* word) {
#ifndef GRAPHICS_DISABLED
  // Number of different colors to draw with.
  const int kNumColors = 6;
  static ScrollView *segm_window = NULL;
  // Check the state against the static prev_drawn_state.
  static GenericVector<int> prev_drawn_state;
  bool already_done = prev_drawn_state.size() == length_;
  if (!already_done) prev_drawn_state.init_to_size(length_, 0);
  for (int i = 0; i < length_; ++i) {
    if (prev_drawn_state[i] != state_[i]) {
      already_done = false;
    }
    prev_drawn_state[i] = state_[i];
  }
  if (already_done || word->blobs.empty()) return;

  // Create the window if needed.
  if (segm_window == NULL) {
    segm_window = new ScrollView("Segmentation", 5, 10, 500, 256,
                                 2000.0, 256.0, true);
  } else {
    segm_window->Clear();
  }

  TBOX bbox;
  int blob_index = 0;
  for (int c = 0; c < length_; ++c) {
    ScrollView::Color color =
        static_cast<ScrollView::Color>(c % kNumColors + 3);
    for (int i = 0; i < state_[c]; ++i, ++blob_index) {
      TBLOB* blob = word->blobs[blob_index];
      bbox += blob->bounding_box();
      blob->plot(segm_window, color, color);
    }
  }
  segm_window->ZoomToRectangle(bbox.left(), bbox.top(),
                               bbox.right(), bbox.bottom());
  segm_window->Update();
  window_wait(segm_window);
#endif
}
开发者ID:11110101,项目名称:tess-two,代码行数:44,代码来源:ratngs.cpp

示例13: SetupBLNormalize

// Normalize in-place and record the normalization in the DENORM.
void TWERD::SetupBLNormalize(const BLOCK* block, const ROW* row,
                             float x_height, bool numeric_mode,
                             DENORM* denorm) const {
  int num_segments = 0;
  DENORM_SEG* segs = NULL;
  if (numeric_mode) {
    segs = new DENORM_SEG[NumBlobs()];
    for (TBLOB* blob = blobs; blob != NULL; blob = blob->next) {
      TBOX blob_box = blob->bounding_box();
      float factor = kBlnXHeight / x_height;
      factor = ClipToRange(kBlnXHeight * 4.0f / (3 * blob_box.height()),
                           factor, factor * 1.5f);
      segs[num_segments].xstart = blob_box.left();
      segs[num_segments].ycoord = blob_box.bottom();
      segs[num_segments++].scale_factor = factor;
    }
  }
  denorm->SetupBLNormalize(block, row, x_height, bounding_box(),
                           num_segments, segs);
  delete [] segs;
}
开发者ID:ErwcPKerr,项目名称:node-dv,代码行数:22,代码来源:blobs.cpp

示例14: runBlobOCR

BLOB_CHOICE* M_Utils::runBlobOCR(BLOBNBOX* blob, Tesseract* ocrengine) {
  // * Normalize blob height to x-height (current OSD):
  // SetupNormalization(NULL, NULL, &rotation, NULL, NULL, 0,
  //                    box.rotational_x_middle(rotation),
  //                    box.rotational_y_middle(rotation),
  //                    kBlnXHeight / box.rotational_height(rotation),
  //                    kBlnXHeight / box.rotational_height(rotation),
  //                    0, kBlnBaselineOffset);
  BLOB_CHOICE_LIST ratings_lang;
  C_BLOB* cblob = blob->cblob();
  TBLOB* tblob = TBLOB::PolygonalCopy(cblob);
  const TBOX& box = tblob->bounding_box();

  // Normalize the blob. Set the origin to the place we want to be the
  // bottom-middle, and scaling is to mpx, box_, NULL);
  float scaling = static_cast<float>(kBlnXHeight) / box.height();
  DENORM denorm;
  float x_orig = (box.left() + box.right()) / 2.0f, y_orig = box.bottom();
  denorm.SetupNormalization(NULL, NULL, NULL, NULL, NULL, 0,
                            x_orig, y_orig, scaling, scaling,
                            0.0f, static_cast<float>(kBlnBaselineOffset));
  TBLOB* normed_blob = new TBLOB(*tblob);
  normed_blob->Normalize(denorm);
  ocrengine->AdaptiveClassifier(normed_blob, denorm, &ratings_lang, NULL);
  delete normed_blob;
  delete tblob;

  // Get the best choice from ratings_lang and rating_equ. As the choice in the
  // list has already been sorted by the certainty, we simply use the first
  // choice.
  BLOB_CHOICE *lang_choice = NULL;
  if (ratings_lang.length() > 0) {
    BLOB_CHOICE_IT choice_it(&ratings_lang);
    lang_choice = choice_it.data();
  }
  return lang_choice;
}
开发者ID:Andy0898,项目名称:Project_Isagoge,代码行数:37,代码来源:M_Utils.cpp

示例15: ComputeCompatibleXheight

// Returns a new x-height maximally compatible with the result in word_res.
// See comment above for overall algorithm.
float Tesseract::ComputeCompatibleXheight(WERD_RES *word_res) {
  STATS top_stats(0, MAX_UINT8);
  TBLOB* blob = word_res->rebuild_word->blobs;
  int blob_id = 0;
  for (; blob != NULL; blob = blob->next, ++blob_id) {
    UNICHAR_ID class_id = word_res->best_choice->unichar_id(blob_id);
    if (unicharset.get_isalpha(class_id) || unicharset.get_isdigit(class_id)) {
      int top = blob->bounding_box().top();
      // Clip the top to the limit of normalized feature space.
      if (top >= INT_FEAT_RANGE)
        top = INT_FEAT_RANGE - 1;
      int bottom = blob->bounding_box().bottom();
      int min_bottom, max_bottom, min_top, max_top;
      unicharset.get_top_bottom(class_id, &min_bottom, &max_bottom,
                                &min_top, &max_top);
      // Chars with a wild top range would mess up the result so ignore them.
      if (max_top - min_top > kMaxCharTopRange)
        continue;
      int misfit_dist = MAX((min_top - x_ht_acceptance_tolerance) - top,
                          top - (max_top + x_ht_acceptance_tolerance));
      int height = top - kBlnBaselineOffset;
      if (debug_x_ht_level >= 20) {
        tprintf("Class %s: height=%d, bottom=%d,%d top=%d,%d, actual=%d,%d : ",
                unicharset.id_to_unichar(class_id),
                height, min_bottom, max_bottom, min_top, max_top,
                bottom, top);
      }
      // Use only chars that fit in the expected bottom range, and where
      // the range of tops is sensibly near the xheight.
      if (min_bottom <= bottom + x_ht_acceptance_tolerance &&
          bottom - x_ht_acceptance_tolerance <= max_bottom &&
          min_top > kBlnBaselineOffset &&
          max_top - kBlnBaselineOffset >= kBlnXHeight &&
          misfit_dist > 0) {
        // Compute the x-height position using proportionality between the
        // actual height and expected height.
        int min_xht = DivRounded(height * kBlnXHeight,
                                 max_top - kBlnBaselineOffset);
        int max_xht = DivRounded(height * kBlnXHeight,
                                 min_top - kBlnBaselineOffset);
        if (debug_x_ht_level >= 20) {
          tprintf(" xht range min=%d, max=%d\n",
                  min_xht, max_xht);
        }
        // The range of expected heights gets a vote equal to the distance
        // of the actual top from the expected top.
        for (int y = min_xht; y <= max_xht; ++y)
          top_stats.add(y, misfit_dist);
      } else if (debug_x_ht_level >= 20) {
        tprintf(" already OK\n");
      }
    }
  }
  if (top_stats.get_total() == 0)
    return 0.0f;
  // The new xheight is just the median vote, which is then scaled out
  // of BLN space back to pixel space to get the x-height in pixel space.
  float new_xht = top_stats.median();
  if (debug_x_ht_level >= 20) {
    tprintf("Median xht=%f\n", new_xht);
    tprintf("Mode20:A: New x-height = %f (norm), %f (orig)\n",
            new_xht, new_xht / word_res->denorm.y_scale());
  }
  // The xheight must change by at least x_ht_min_change to be used.
  if (fabs(new_xht - kBlnXHeight) >= x_ht_min_change)
    return new_xht / word_res->denorm.y_scale();
  else
    return 0.0f;
}
开发者ID:ErwcPKerr,项目名称:node-dv,代码行数:71,代码来源:fixxht.cpp


注:本文中的TBLOB::bounding_box方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。