示例#1
0
/**********************************************************************
 * choose_best_seam
 *
 * Choose the best seam that can be created by assembling this a
 * collection of splits.  A queue of all the possible seams is
 * maintained.  Each new split received is placed in that queue with
 * its partial priority value.  These values in the seam queue are
 * evaluated and combined until a good enough seam is found.  If no
 * further good seams are being found then this function returns to the
 * caller, who will send more splits.  If this function is called with
 * a split of NULL, then no further splits can be supplied by the
 * caller.
 **********************************************************************/
void Wordrec::choose_best_seam(SeamQueue *seam_queue, const SPLIT *split,
                               PRIORITY priority, SEAM **seam_result,
                               TBLOB *blob, SeamPile *seam_pile) {
  SEAM *seam;
  char str[80];
  float my_priority;
  /* Add seam of split */
  my_priority = priority;
  if (split != NULL) {
    TPOINT split_point = split->point1->pos;
    split_point += split->point2->pos;
    split_point /= 2;
    seam = new SEAM(my_priority, split_point, *split);
    if (chop_debug > 1) seam->Print("Partial priority    ");
    add_seam_to_queue(my_priority, seam, seam_queue);

    if (my_priority > chop_good_split)
      return;
  }

  TBOX bbox = blob->bounding_box();
  /* Queue loop */
  while (!seam_queue->empty()) {
    SeamPair seam_pair;
    seam_queue->Pop(&seam_pair);
    seam = seam_pair.extract_data();
    /* Set full priority */
    my_priority = seam->FullPriority(bbox.left(), bbox.right(),
                                     chop_overlap_knob, chop_centered_maxwidth,
                                     chop_center_knob, chop_width_change_knob);
    if (chop_debug) {
      sprintf (str, "Full my_priority %0.0f,  ", my_priority);
      seam->Print(str);
    }

    if ((*seam_result == NULL || (*seam_result)->priority() > my_priority) &&
        my_priority < chop_ok_split) {
      /* No crossing */
      if (seam->IsHealthy(*blob, chop_min_outline_points,
                          chop_min_outline_area)) {
        delete *seam_result;
        *seam_result = new SEAM(*seam);
        (*seam_result)->set_priority(my_priority);
      } else {
        delete seam;
        seam = NULL;
        my_priority = BAD_PRIORITY;
      }
    }

    if (my_priority < chop_good_split) {
      if (seam)
        delete seam;
      return;                    /* Made good answer */
    }

    if (seam) {
      /* Combine with others */
      if (seam_pile->size() < chop_seam_pile_size) {
        combine_seam(*seam_pile, seam, seam_queue);
        SeamDecPair pair(seam_pair.key(), seam);
        seam_pile->Push(&pair);
      } else if (chop_new_seam_pile &&
                 seam_pile->size() == chop_seam_pile_size &&
                 seam_pile->PeekTop().key() > seam_pair.key()) {
        combine_seam(*seam_pile, seam, seam_queue);
        SeamDecPair pair;
        seam_pile->Pop(&pair);  // pop the worst.
        // Replace the seam in pair (deleting the old one) with
        // the new seam and score, then push back into the heap.
        pair.set_key(seam_pair.key());
        pair.set_data(seam);
        seam_pile->Push(&pair);
      } else {
        delete seam;
      }
    }

    my_priority = seam_queue->empty() ? NO_FULL_PRIORITY
                                      : seam_queue->PeekTop().key();
    if ((my_priority > chop_ok_split) ||
      (my_priority > chop_good_split && split))
      return;
  }
}
/**********************************************************************
 * choose_best_seam
 *
 * Choose the best seam that can be created by assembling this a
 * collection of splits.  A queue of all the possible seams is
 * maintained.  Each new split received is placed in that queue with
 * its partial priority value.  These values in the seam queue are
 * evaluated and combined until a good enough seam is found.  If no
 * further good seams are being found then this function returns to the
 * caller, who will send more splits.  If this function is called with
 * a split of NULL, then no further splits can be supplied by the
 * caller.
 **********************************************************************/
void choose_best_seam(SEAM_QUEUE seam_queue,
                      SEAM_PILE *seam_pile,
                      SPLIT *split,
                      PRIORITY priority,
                      SEAM **seam_result,
                      TBLOB *blob) {
  SEAM *seam;
  TPOINT topleft;
  TPOINT botright;
  char str[80];
  float my_priority;
  /* Add seam of split */
  my_priority = priority;
  if (split != NULL) {
    seam = new_seam (my_priority,
      (split->point1->pos.x + split->point1->pos.x) / 2,
      split, NULL, NULL);
    if (chop_debug > 1)
      print_seam ("Partial priority    ", seam);
    add_seam_to_queue (seam_queue, seam, (float) my_priority);

    if (my_priority > chop_good_split)
      return;
  }

  blob_bounding_box(blob, &topleft, &botright);
  /* Queue loop */
  while (pop_next_seam (seam_queue, seam, my_priority)) {
    /* Set full priority */
    my_priority = seam_priority (seam, topleft.x, botright.x);
    if (chop_debug) {
      sprintf (str, "Full my_priority %0.0f,  ", my_priority);
      print_seam(str, seam);
    }

    if ((*seam_result == NULL || /* Replace answer */
    (*seam_result)->priority > my_priority) && my_priority < chop_ok_split) {
      /* No crossing */
      if (constrained_split (seam->split1, blob)) {
        delete_seam(*seam_result);
        clone_seam(*seam_result, seam);
        (*seam_result)->priority = my_priority;
      }
      else {
        delete_seam(seam);
        seam = NULL;
        my_priority = BAD_PRIORITY;
      }
    }

    if (my_priority < chop_good_split) {
      if (seam)
        delete_seam(seam);
      return;                    /* Made good answer */
    }

    if (seam) {
                                 /* Combine with others */
      if (array_count (*seam_pile) < MAX_NUM_SEAMS
      /*|| tessedit_truncate_chopper==0 */ ) {
        combine_seam(seam_queue, *seam_pile, seam);
        *seam_pile = array_push (*seam_pile, seam);
      }
      else
        delete_seam(seam);
    }

    my_priority = best_seam_priority (seam_queue);
    if ((my_priority > chop_ok_split) ||
      (my_priority > chop_good_split && split))
      return;
  }
}