tesseract  3.03
/usr/local/google/home/jbreiden/tesseract-ocr-read-only/ccstruct/seam.cpp File Reference
#include "seam.h"
#include "blobs.h"
#include "freelist.h"
#include "tprintf.h"

Go to the source code of this file.

Defines

#define NUM_STARTING_SEAMS   20

Functions

point_in_split

Check to see if either of these points are present in the current split.

Returns:
TRUE if one of them is split.
bool point_in_split (SPLIT *split, EDGEPT *point1, EDGEPT *point2)
point_in_seam

Check to see if either of these points are present in the current seam.

Returns:
TRUE if one of them is.
bool point_in_seam (const SEAM *seam, SPLIT *split)
point_used_by_split

Return whether this particular EDGEPT * is used in a given split.

Returns:
TRUE if the edgept is used by the split.
bool point_used_by_split (SPLIT *split, EDGEPT *point)
point_used_by_seam

Return whether this particular EDGEPT * is used in a given seam.

Returns:
TRUE if the edgept is used by the seam.
bool point_used_by_seam (SEAM *seam, EDGEPT *point)
combine_seam

Combine two seam records into a single seam. Move the split references from the second seam to the first one. The argument convention is patterned after strcpy.

void combine_seams (SEAM *dest_seam, SEAM *source_seam)
start_seam_list

Initialize a list of seams that match the original number of blobs present in the starting segmentation. Each of the seams created by this routine have location information only.

void start_seam_list (TWERD *word, GenericVector< SEAM * > *seam_array)
test_insert_seam
Returns:
true if insert_seam will succeed.
bool test_insert_seam (const GenericVector< SEAM * > &seam_array, TWERD *word, int index)
insert_seam

Add another seam to a collection of seams at a particular location in the seam array.

void insert_seam (const TWERD *word, int index, SEAM *seam, GenericVector< SEAM * > *seam_array)
account_splits

Account for all the splits by looking to the right (blob_direction == 1), or to the left (blob_direction == -1) in the word.

int account_splits (const SEAM *seam, const TWERD *word, int blob_index, int blob_direction)
find_split_in_blob
Returns:
TRUE if the split is somewhere in this blob.
bool find_split_in_blob (SPLIT *split, TBLOB *blob)
join_two_seams

Merge these two seams into a new seam. Duplicate the split records in both of the input seams. Return the resultant seam.

SEAMjoin_two_seams (const SEAM *seam1, const SEAM *seam2)
print_seam

Print a list of splits. Show the coordinates of both points in each split.

void print_seam (const char *label, SEAM *seam)
print_seams

Print a list of splits. Show the coordinates of both points in each split.

void print_seams (const char *label, const GenericVector< SEAM * > &seams)
shared_split_points

Check these two seams to make sure that neither of them have two points in common. Return TRUE if any of the same points are present in any of the splits of both seams.

int shared_split_points (const SEAM *seam1, const SEAM *seam2)
void break_pieces (const GenericVector< SEAM * > &seams, int first, int last, TWERD *word)
void join_pieces (const GenericVector< SEAM * > &seams, int first, int last, TWERD *word)
void hide_seam (SEAM *seam)
void hide_edge_pair (EDGEPT *pt1, EDGEPT *pt2)
void reveal_seam (SEAM *seam)
void reveal_edge_pair (EDGEPT *pt1, EDGEPT *pt2)

Define Documentation

#define NUM_STARTING_SEAMS   20

Definition at line 40 of file seam.cpp.


Function Documentation

int account_splits ( const SEAM seam,
const TWERD word,
int  blob_index,
int  blob_direction 
)

Definition at line 233 of file seam.cpp.

                                       {
  inT8 found_em[3];
  inT8 width;

  found_em[0] = seam->split1 == NULL;
  found_em[1] = seam->split2 == NULL;
  found_em[2] = seam->split3 == NULL;
  if (found_em[0] && found_em[1] && found_em[2])
    return 0;
  width = 0;
  do {
    TBLOB* blob = word->blobs[blob_index];
    if (!found_em[0])
      found_em[0] = find_split_in_blob(seam->split1, blob);
    if (!found_em[1])
      found_em[1] = find_split_in_blob(seam->split2, blob);
    if (!found_em[2])
      found_em[2] = find_split_in_blob(seam->split3, blob);
    if (found_em[0] && found_em[1] && found_em[2]) {
      return width;
    }
    width++;
    blob_index += blob_direction;
  } while (0 <= blob_index && blob_index < word->NumBlobs());
  return -1;
}
void break_pieces ( const GenericVector< SEAM * > &  seams,
int  first,
int  last,
TWERD word 
)

Definition at line 387 of file seam.cpp.

                               {
  for (int x = first; x < last; ++x)
    reveal_seam(seams[x]);

  TESSLINE *outline = word->blobs[first]->outlines;
  int next_blob = first + 1;

  while (outline != NULL && next_blob <= last) {
    if (outline->next == word->blobs[next_blob]->outlines) {
      outline->next = NULL;
      outline = word->blobs[next_blob]->outlines;
      ++next_blob;
    } else {
      outline = outline->next;
    }
  }
}
void combine_seams ( SEAM dest_seam,
SEAM source_seam 
)

Definition at line 105 of file seam.cpp.

                                                       {
  dest_seam->priority += source_seam->priority;
  dest_seam->location += source_seam->location;
  dest_seam->location /= 2;

  if (source_seam->split1) {
    if (!dest_seam->split1)
      dest_seam->split1 = source_seam->split1;
    else if (!dest_seam->split2)
      dest_seam->split2 = source_seam->split1;
    else if (!dest_seam->split3)
      dest_seam->split3 = source_seam->split1;
    else
      delete source_seam->split1;  // Wouldn't have fitted.
    source_seam->split1 = NULL;
  }
  if (source_seam->split2) {
    if (!dest_seam->split2)
      dest_seam->split2 = source_seam->split2;
    else if (!dest_seam->split3)
      dest_seam->split3 = source_seam->split2;
    else
      delete source_seam->split2;  // Wouldn't have fitted.
    source_seam->split2 = NULL;
  }
  if (source_seam->split3) {
    if (!dest_seam->split3)
      dest_seam->split3 = source_seam->split3;
    else
      delete source_seam->split3;  // Wouldn't have fitted.
    source_seam->split3 = NULL;
  }
  delete source_seam;
}
bool find_split_in_blob ( SPLIT split,
TBLOB blob 
)

Definition at line 267 of file seam.cpp.

                                                   {
  TESSLINE *outline;

  for (outline = blob->outlines; outline != NULL; outline = outline->next)
    if (outline->Contains(split->point1->pos))
      break;
  if (outline == NULL)
    return FALSE;
  for (outline = blob->outlines; outline != NULL; outline = outline->next)
    if (outline->Contains(split->point2->pos))
      return TRUE;
  return FALSE;
}
void hide_edge_pair ( EDGEPT pt1,
EDGEPT pt2 
)

Definition at line 457 of file seam.cpp.

                                              {
  EDGEPT *edgept;

  edgept = pt1;
  do {
    edgept->Hide();
    edgept = edgept->next;
  }
  while (!exact_point (edgept, pt2) && edgept != pt1);
  if (edgept == pt1) {
    /*              tprintf("Hid entire outline at (%d,%d)!!\n",
       edgept->pos.x,edgept->pos.y);                                */
  }
  edgept = pt2;
  do {
    edgept->Hide();
    edgept = edgept->next;
  }
  while (!exact_point (edgept, pt1) && edgept != pt2);
  if (edgept == pt2) {
    /*              tprintf("Hid entire outline at (%d,%d)!!\n",
       edgept->pos.x,edgept->pos.y);                                */
  }
}
void hide_seam ( SEAM seam)

Definition at line 436 of file seam.cpp.

                           {
  if (seam == NULL || seam->split1 == NULL)
    return;
  hide_edge_pair (seam->split1->point1, seam->split1->point2);

  if (seam->split2 == NULL)
    return;
  hide_edge_pair (seam->split2->point1, seam->split2->point2);

  if (seam->split3 == NULL)
    return;
  hide_edge_pair (seam->split3->point1, seam->split3->point2);
}
void insert_seam ( const TWERD word,
int  index,
SEAM seam,
GenericVector< SEAM * > *  seam_array 
)

Definition at line 193 of file seam.cpp.

                                                   {
  SEAM *test_seam;
  int list_length = seam_array->size();
  for (int test_index = 0; test_index < index; ++test_index) {
    test_seam = seam_array->get(test_index);
    if (test_index + test_seam->widthp >= index) {
      test_seam->widthp++;       /*got in the way */
    } else if (test_seam->widthp + test_index == index - 1) {
      test_seam->widthp = account_splits(test_seam, word, test_index + 1, 1);
      if (test_seam->widthp < 0) {
        tprintf("Failed to find any right blob for a split!\n");
        print_seam("New dud seam", seam);
        print_seam("Failed seam", test_seam);
      }
    }
  }
  for (int test_index = index; test_index < list_length; test_index++) {
    test_seam = seam_array->get(test_index);
    if (test_index - test_seam->widthn < index) {
      test_seam->widthn++;       /*got in the way */
    } else if (test_index - test_seam->widthn == index) {
      test_seam->widthn = account_splits(test_seam, word, test_index + 1, -1);
      if (test_seam->widthn < 0) {
        tprintf("Failed to find any left blob for a split!\n");
        print_seam("New dud seam", seam);
        print_seam("Failed seam", test_seam);
      }
    }
  }
  seam_array->insert(seam, index);
}
void join_pieces ( const GenericVector< SEAM * > &  seams,
int  first,
int  last,
TWERD word 
)

Definition at line 413 of file seam.cpp.

                              {
  TESSLINE *outline = word->blobs[first]->outlines;
  if (!outline)
    return;

  for (int x = first; x < last; ++x) {
    SEAM *seam = seams[x];
    if (x - seam->widthn >= first && x + seam->widthp < last)
      hide_seam(seam);
    while (outline->next)
      outline = outline->next;
    outline->next = word->blobs[x + 1]->outlines;
  }
}
SEAM* join_two_seams ( const SEAM seam1,
const SEAM seam2 
)

Definition at line 288 of file seam.cpp.

                                                           {
  SEAM *result = NULL;
  SEAM *temp;

  assert(seam1 &&seam2);

  if (((seam1->split3 == NULL && seam2->split2 == NULL) ||
       (seam1->split2 == NULL && seam2->split3 == NULL) ||
        seam1->split1 == NULL || seam2->split1 == NULL) &&
      (!shared_split_points(seam1, seam2))) {
    result = new SEAM(*seam1);
    temp = new SEAM(*seam2);
    combine_seams(result, temp);
  }
  return (result);
}
bool point_in_seam ( const SEAM seam,
SPLIT split 
)

Definition at line 68 of file seam.cpp.

                                                   {
  return (point_in_split(seam->split1, split->point1, split->point2) ||
          point_in_split(seam->split2, split->point1, split->point2) ||
          point_in_split(seam->split3, split->point1, split->point2));
}
bool point_in_split ( SPLIT split,
EDGEPT point1,
EDGEPT point2 
)

Definition at line 52 of file seam.cpp.

                                                                  {
  return ((split) ? ((exact_point (split->point1, point1) ||
                      exact_point (split->point1, point2) ||
                      exact_point (split->point2, point1) ||
                      exact_point (split->point2, point2)) ? TRUE : FALSE)
                  : FALSE);
}
bool point_used_by_seam ( SEAM seam,
EDGEPT point 
)

Definition at line 91 of file seam.cpp.

                                                   {
  if (seam == NULL) return false;
  return point_used_by_split(seam->split1, point) ||
      point_used_by_split(seam->split2, point) ||
      point_used_by_split(seam->split3, point);
}
bool point_used_by_split ( SPLIT split,
EDGEPT point 
)

Definition at line 80 of file seam.cpp.

                                                      {
  if (split == NULL) return false;
  return point == split->point1 || point == split->point2;
}
void print_seam ( const char *  label,
SEAM seam 
)

Definition at line 311 of file seam.cpp.

                                               {
  if (seam) {
    tprintf(label);
    tprintf(" %6.2f @ (%d,%d), p=%d, n=%d ",
            seam->priority, seam->location.x, seam->location.y,
            seam->widthp, seam->widthn);
    print_split(seam->split1);

    if (seam->split2) {
      tprintf(",   ");
      print_split (seam->split2);
      if (seam->split3) {
        tprintf(",   ");
        print_split (seam->split3);
      }
    }
    tprintf("\n");
  }
}
void print_seams ( const char *  label,
const GenericVector< SEAM * > &  seams 
)

Definition at line 338 of file seam.cpp.

                                                                       {
  char number[CHARS_PER_LINE];

  if (!seams.empty()) {
    tprintf("%s\n", label);
    for (int x = 0; x < seams.size(); ++x) {
      sprintf(number, "%2d:   ", x);
      print_seam(number, seams[x]);
    }
    tprintf("\n");
  }
}
void reveal_edge_pair ( EDGEPT pt1,
EDGEPT pt2 
)

Definition at line 510 of file seam.cpp.

                                                {
  EDGEPT *edgept;

  edgept = pt1;
  do {
    edgept->Reveal();
    edgept = edgept->next;
  }
  while (!exact_point (edgept, pt2) && edgept != pt1);
  if (edgept == pt1) {
    /*              tprintf("Hid entire outline at (%d,%d)!!\n",
       edgept->pos.x,edgept->pos.y);                                */
  }
  edgept = pt2;
  do {
    edgept->Reveal();
    edgept = edgept->next;
  }
  while (!exact_point (edgept, pt1) && edgept != pt2);
  if (edgept == pt2) {
    /*              tprintf("Hid entire outline at (%d,%d)!!\n",
       edgept->pos.x,edgept->pos.y);                                */
  }
}
void reveal_seam ( SEAM seam)

Definition at line 489 of file seam.cpp.

                             {
  if (seam == NULL || seam->split1 == NULL)
    return;
  reveal_edge_pair (seam->split1->point1, seam->split1->point2);

  if (seam->split2 == NULL)
    return;
  reveal_edge_pair (seam->split2->point1, seam->split2->point2);

  if (seam->split3 == NULL)
    return;
  reveal_edge_pair (seam->split3->point1, seam->split3->point2);
}
int shared_split_points ( const SEAM seam1,
const SEAM seam2 
)

Definition at line 359 of file seam.cpp.

                                                              {
  if (seam1 == NULL || seam2 == NULL)
    return (FALSE);

  if (seam2->split1 == NULL)
    return (FALSE);
  if (point_in_seam(seam1, seam2->split1))
    return (TRUE);

  if (seam2->split2 == NULL)
    return (FALSE);
  if (point_in_seam(seam1, seam2->split2))
    return (TRUE);

  if (seam2->split3 == NULL)
    return (FALSE);
  if (point_in_seam(seam1, seam2->split3))
    return (TRUE);

  return (FALSE);
}
void start_seam_list ( TWERD word,
GenericVector< SEAM * > *  seam_array 
)

Definition at line 147 of file seam.cpp.

                                                                    {
  seam_array->truncate(0);
  TPOINT location;

  for (int b = 1; b < word->NumBlobs(); ++b) {
    TBOX bbox = word->blobs[b - 1]->bounding_box();
    TBOX nbox = word->blobs[b]->bounding_box();
    location.x = (bbox.right() + nbox.left()) / 2;
    location.y = (bbox.bottom() + bbox.top() + nbox.bottom() + nbox.top()) / 4;
    seam_array->push_back(new SEAM(0.0f, location, NULL, NULL, NULL));
  }
}
bool test_insert_seam ( const GenericVector< SEAM * > &  seam_array,
TWERD word,
int  index 
)

Definition at line 166 of file seam.cpp.

                                              {
  SEAM *test_seam;
  int list_length = seam_array.size();
  for (int test_index = 0; test_index < index; ++test_index) {
    test_seam = seam_array[test_index];
    if (test_index + test_seam->widthp < index &&
        test_seam->widthp + test_index == index - 1 &&
        account_splits(test_seam, word, test_index + 1, 1) < 0)
      return false;
  }
  for (int test_index = index; test_index < list_length; test_index++) {
    test_seam = seam_array[test_index];
    if (test_index - test_seam->widthn >= index &&
        test_index - test_seam->widthn == index &&
        account_splits(test_seam, word, test_index + 1, -1) < 0)
      return false;
  }
  return true;
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines