Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Macros | Typedefs | Functions
blobs.h File Reference
`#include "clst.h"`
`#include "rect.h"`
`#include "vecfuncs.h"`

Go to the source code of this file.

## Classes
struct | WIDTH_RECORD
struct | TPOINT
struct | EDGEPT
struct | TESSLINE
struct | TBLOB
struct | TWERD

## Macros
#define | EDGEPTFLAGS 4 /*concavity,length etc. */
#define | free_widths(w) if (w) memfree (w)

## Typedefs
typedef TPOINT | VECTOR

## Functions
| CLISTIZEH (EDGEPT)
int | count_blobs (TBLOB *blobs)
void | blob_origin (TBLOB *blob, TPOINT *origin)
WIDTH_RECORD * | blobs_widths (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)

## Macro Definition Documentation

#define EDGEPTFLAGS 4 /*concavity,length etc. */

Definition at line 45 of file blobs.h.

#define free_widths | ( |  | w | ) | if (w) memfree (w)

Definition at line 287 of file blobs.h.

## Typedef Documentation

typedef TPOINT VECTOR

Definition at line 70 of file blobs.h.

## Function Documentation

void blob_origin | ( | TBLOB * | blob,
|  | TPOINT * | origin
| ) |  |

Definition at line 537 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 549 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;
}

CLISTIZEH | ( | EDGEPT |  | ) |

int count_blobs | ( | TBLOB * | blobs | ) |

Definition at line 581 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 645 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 596 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;
}