Tesseract  3.02
tesseract-ocr/ccstruct/blobs.cpp File Reference
#include "mfcpch.h"
#include "blobs.h"
#include "ccstruct.h"
#include "clst.h"
#include "cutil.h"
#include "emalloc.h"
#include "helpers.h"
#include "ndminx.h"
#include "normalis.h"
#include "ocrblock.h"
#include "ocrrow.h"
#include "points.h"
#include "polyaprx.h"
#include "structures.h"
#include "werd.h"

Go to the source code of this file.

Functions

 CLISTIZE (EDGEPT)
void blob_origin (TBLOB *blob, TPOINT *origin)
WIDTH_RECORDblobs_widths (TBLOB *blobs)
int count_blobs (TBLOB *blobs)
bool divisible_blob (TBLOB *blob, bool italic_blob, TPOINT *location)
void divide_blobs (TBLOB *blob, TBLOB *other_blob, bool italic_blob, const TPOINT &location)

Variables

const TPOINT kDivisibleVerticalUpright (0, 1)
const TPOINT kDivisibleVerticalItalic (1, 5)

Function Documentation

void blob_origin ( TBLOB blob,
TPOINT origin 
)

Definition at line 528 of file blobs.cpp.

                                 {  /*return value */
  TBOX bbox = blob->bounding_box();
  *origin = (bbox.topleft() + bbox.botright()) / 2;
}
WIDTH_RECORD* blobs_widths ( TBLOB blobs)

Definition at line 540 of file blobs.cpp.

                                         {  /*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;
}
CLISTIZE ( EDGEPT  )
int count_blobs ( TBLOB blobs)

Definition at line 572 of file blobs.cpp.

                              { 
  int x = 0;

  for (TBLOB* b = blobs; b != NULL; b = b->next)
    x++;
  return x;
}
void divide_blobs ( TBLOB blob,
TBLOB other_blob,
bool  italic_blob,
const TPOINT location 
)

Definition at line 636 of file blobs.cpp.

                                          {
  TPOINT vertical = italic_blob ? kDivisibleVerticalItalic
                                : kDivisibleVerticalUpright;
  TESSLINE *outline1 = NULL;
  TESSLINE *outline2 = NULL;

  TESSLINE *outline = blob->outlines;
  blob->outlines = NULL;
  int location_prod = CROSS(location, vertical);

  while (outline != NULL) {
    TPOINT mid_pt(
      static_cast<inT16>((outline->topleft.x + outline->botright.x) / 2),
      static_cast<inT16>((outline->topleft.y + outline->botright.y) / 2));
    int mid_prod = CROSS(mid_pt, vertical);
    if (mid_prod < location_prod) {
      // Outline is in left blob.
      if (outline1)
        outline1->next = outline;
      else
        blob->outlines = outline;
      outline1 = outline;
    } else {
      // Outline is in right blob.
      if (outline2)
        outline2->next = outline;
      else
        other_blob->outlines = outline;
      outline2 = outline;
    }
    outline = outline->next;
  }

  if (outline1)
    outline1->next = NULL;
  if (outline2)
    outline2->next = NULL;
}
bool divisible_blob ( TBLOB blob,
bool  italic_blob,
TPOINT location 
)

Definition at line 587 of file blobs.cpp.

                                                                     {
  if (blob->outlines == NULL || blob->outlines->next == NULL)
    return false;  // Need at least 2 outlines for it to be possible.
  int max_gap = 0;
  TPOINT vertical = italic_blob ? kDivisibleVerticalItalic
                                : kDivisibleVerticalUpright;
  for (TESSLINE* outline1 = blob->outlines; outline1 != NULL;
       outline1 = outline1->next) {
    if (outline1->is_hole)
      continue;  // Holes do not count as separable.
    TPOINT mid_pt1(
      static_cast<inT16>((outline1->topleft.x + outline1->botright.x) / 2),
      static_cast<inT16>((outline1->topleft.y + outline1->botright.y) / 2));
    int mid_prod1 = CROSS(mid_pt1, vertical);
    int min_prod1, max_prod1;
    outline1->MinMaxCrossProduct(vertical, &min_prod1, &max_prod1);
    for (TESSLINE* outline2 = outline1->next; outline2 != NULL;
         outline2 = outline2->next) {
      if (outline2->is_hole)
        continue;  // Holes do not count as separable.
      TPOINT mid_pt2(
        static_cast<inT16>((outline2->topleft.x + outline2->botright.x) / 2),
        static_cast<inT16>((outline2->topleft.y + outline2->botright.y) / 2));
      int mid_prod2 = CROSS(mid_pt2, vertical);
      int min_prod2, max_prod2;
      outline2->MinMaxCrossProduct(vertical, &min_prod2, &max_prod2);
      int mid_gap = abs(mid_prod2 - mid_prod1);
      int overlap = MIN(max_prod1, max_prod2) - MAX(min_prod1, min_prod2);
      if (mid_gap - overlap / 4 > max_gap) {
        max_gap = mid_gap - overlap / 4;
        *location = mid_pt1;
        *location += mid_pt2;
        *location /= 2;
      }
    }
  }
  // Use the y component of the vertical vector as an approximation to its
  // length.
  return max_gap > vertical.y;
}

Variable Documentation