wordrec/chopper.cpp File Reference

#include "chopper.h"
#include "wordclass.h"
#include "makechop.h"
#include "associate.h"
#include "metrics.h"
#include "tordvars.h"
#include "stopper.h"
#include "callcpp.h"
#include "structures.h"
#include "findseam.h"
#include "render.h"
#include "seam.h"
#include "const.h"
#include "freelist.h"
#include "pieces.h"
#include "permute.h"
#include <math.h>

Go to the source code of this file.

Defines

Functions

Variables


Define Documentation

#define bounds_inside ( inner_tl,
inner_br,
outer_tl,
outer_br   ) 

Value:

((inner_tl.x >= outer_tl.x)   && \
(inner_tl.y <= outer_tl.y) && \
(inner_br.x <= outer_br.x)   && \
(inner_br.y >= outer_br.y))     \
Check to see if the bounding box of one thing is inside the bounding box of another.

Definition at line 60 of file chopper.cpp.

Referenced by total_containment().

#define set_null_choice ( choice   ) 

Value:

(class_string      (choice) =  NULL,     \
class_probability (choice) =  MAX_FLOAT32, \
class_certainty   (choice) = -MAX_FLOAT32) \
Set the fields in this choice to be defaulted bad initial values.

Definition at line 69 of file chopper.cpp.

Referenced by chop_word_main().

#define TEXT_PROGRESS   1


Function Documentation

int any_shared_split_points ( SEAMS  seam_list,
SEAM seam 
)

Return TRUE if any of the splits share a point with this one.

Definition at line 271 of file chopper.cpp.

References array_count, array_value, FALSE, shared_split_points(), and TRUE.

Referenced by attempt_blob_chop().

00271                                                          {
00272   int length;
00273   int index;
00274 
00275   length = array_count (seam_list);
00276   for (index = 0; index < length; index++)
00277     if (shared_split_points ((SEAM *) array_value (seam_list, index), seam))
00278       return TRUE;
00279   return FALSE;
00280 }

SEAM* attempt_blob_chop ( TWERD word,
INT32  blob_number,
SEAMS  seam_list 
)

Try to split the blob after this one & check to make sure that it was successful.

Parameters:
word Word around which seams to be 'probed'
blob_number Number of blobs around/in word
seam_list Check if any splits share point with this one
Note:
Globals:
  • repair_unchopped_blobs
  • chop_debug
Returns:
Pointer to SEAM

Definition at line 181 of file chopper.cpp.

References any_shared_split_points(), apply_seam(), CHAR_SAMPLE::blob(), wordstruct::blobs, check_blob(), check_seam_order(), chop_debug, chops_attempted1, chops_attempted2, cprintf(), delete_seam(), display_blob(), first_pass, newblob(), blobstruct::next, NULL, oldblob(), blobstruct::outlines, pick_good_seam(), preserve_outline_tree(), print_seam(), Red, restore_outline_tree(), test_insert_seam(), total_containment(), and undo_seam().

Referenced by improve_one_blob().

00181                                                                          { 
00182   TBLOB *blob;
00183   TBLOB *other_blob;
00184   SEAM *seam;
00185   TBLOB *last_blob;
00186   TBLOB *next_blob;
00187   INT16 x;
00188 
00189   if (first_pass)
00190     chops_attempted1++;
00191   else
00192     chops_attempted2++;
00193 
00194   last_blob = NULL;
00195   blob = word->blobs;
00196   for (x = 0; x < blob_number; x++) {
00197     last_blob = blob;
00198     blob = blob->next;
00199   }
00200   next_blob = blob->next;
00201 
00202   if (repair_unchopped_blobs)
00203     preserve_outline_tree (blob->outlines);
00204   other_blob = newblob ();       /* Make new blob */
00205   other_blob->next = blob->next;
00206   other_blob->outlines = NULL;
00207   blob->next = other_blob;
00208 
00209   seam = pick_good_seam (blob);
00210 
00211 #define TEXT_PROGRESS 1
00212 #ifdef TEXT_PROGRESS
00213   #ifndef TEXT_VERBOSE
00214    // a dot per seam, if not debugging seams
00215    if (seam != NULL && !chop_debug)
00216       cprintf(".");
00217   #else
00218    // gets a 's', see ccmain/tesseractmain.dox
00219    if (seam != NULL && !chop_debug)
00220       cprintf("s");
00221   #endif
00222 #endif
00223   if (chop_debug) {
00224     if (seam != NULL) {
00225       print_seam ("Good seam picked=", seam);
00226     }
00227     else
00228       cprintf ("\n** no seam picked *** \n");
00229   }
00230   if (seam) {
00231     apply_seam(blob, other_blob, seam);
00232   }
00233 
00234   if ((seam == NULL) ||
00235     (blob->outlines == NULL) ||
00236     (other_blob->outlines == NULL) ||
00237     total_containment (blob, other_blob) ||
00238     check_blob (other_blob) ||
00239     !(check_seam_order (blob, seam) &&
00240     check_seam_order (other_blob, seam)) ||
00241     any_shared_split_points (seam_list, seam) ||
00242     !test_insert_seam(seam_list, blob_number, blob, word->blobs)) {
00243 
00244     blob->next = next_blob;
00245     if (seam) {
00246       undo_seam(blob, other_blob, seam);
00247       delete_seam(seam);
00248 #ifndef GRAPHICS_DISABLED
00249       if (chop_debug) {
00250         display_blob(blob, Red);
00251         cprintf ("\n** seam being removed ** \n");
00252       }
00253 #endif
00254     }
00255     else {
00256       oldblob(other_blob);
00257     }
00258 
00259     if (repair_unchopped_blobs)
00260       restore_outline_tree (blob->outlines);
00261     return (NULL);
00262   }
00263   return (seam);
00264 }

int check_blob ( TBLOB blob  ) 

Return TRUE if blob has a non whole outline.

Definition at line 287 of file chopper.cpp.

References CHAR_SAMPLE::blob(), olinestruct::loop, olinestruct::next, edgeptstruct::next, and NULL.

Referenced by attempt_blob_chop().

00287                             {
00288   TESSLINE *outline;
00289   EDGEPT *edgept;
00290 
00291   for (outline = blob->outlines; outline != NULL; outline = outline->next) {
00292     edgept = outline->loop;
00293     do {
00294       if (edgept == NULL)
00295         break;
00296       edgept = edgept->next;
00297     }
00298     while (edgept != outline->loop);
00299     if (edgept == NULL)
00300       return 1;
00301   }
00302   return 0;
00303 }

INT16 check_seam_order ( TBLOB blob,
SEAM seam 
)

Check that seam order ok.

Make sure that each of the splits in this seam match to outlines in this blob.

If any of the splits could not correspond to this blob then there is a problem (and FALSE should be returned to the caller).

Definition at line 379 of file chopper.cpp.

References CHAR_SAMPLE::blob(), FALSE, is_split_outline, olinestruct::next, NULL, seam_record::split1, seam_record::split2, seam_record::split3, and TRUE.

Referenced by attempt_blob_chop().

00379                                                 { 
00380   TESSLINE *outline;
00381   TESSLINE *last_outline;
00382   INT8 found_em[3];
00383 
00384   if (seam->split1 == NULL || seam->split1 == NULL || blob == NULL)
00385     return (TRUE);
00386 
00387   found_em[0] = found_em[1] = found_em[2] = FALSE;
00388 
00389   for (outline = blob->outlines; outline; outline = outline->next) {
00390     if (!found_em[0] &&
00391       ((seam->split1 == NULL) ||
00392     is_split_outline (outline, seam->split1))) {
00393       found_em[0] = TRUE;
00394     }
00395     if (!found_em[1] &&
00396       ((seam->split2 == NULL) ||
00397     is_split_outline (outline, seam->split2))) {
00398       found_em[1] = TRUE;
00399     }
00400     if (!found_em[2] &&
00401       ((seam->split3 == NULL) ||
00402     is_split_outline (outline, seam->split3))) {
00403       found_em[2] = TRUE;
00404     }
00405     last_outline = outline;
00406   }
00407 
00408   if (!found_em[0] || !found_em[1] || !found_em[2])
00409     return (FALSE);
00410   else
00411     return (TRUE);
00412 }

CHOICES_LIST chop_word_main ( register TWERD word,
int  fx,
A_CHOICE best_choice,
A_CHOICE raw_choice,
BOOL8  tester,
BOOL8  trainer 
)

Classify blobs in this word and permute results.

Parameters:
word Word in question
fx Feature Extractor
best_choice Best choice (changed/output)
raw_choice Raw choice (changed/output)
tester BOOL flag, debugging?
trainer BOOL flag, debugging?
Note:
Global:
Returns:
CHOICES_LIST, the word level ratings.
Find the worst blob in the word and chop it up. Continue this process until a good answer has been found or all the blobs have been chopped up enough.

Return the word level ratings.

Definition at line 437 of file chopper.cpp.

References AcceptableChoice(), array_count, array_push(), bits_in_states, CHAR_SAMPLE::blob(), chop_debug, chop_enable, class_string, classify_blob(), enable_assoc, FilterWordChoices(), first_pass, free_matrix(), free_seam_list(), Green, improve_by_chopping(), matcher_fp, matcher_pass, new_choice_list, NULL, permute_characters(), print_seams(), ratings, rebuild_current_state(), set_n_ones(), set_null_choice, start_seam_list(), word_associator(), words_chopped1, and words_chopped2.

Referenced by cc_recog().

00442                                            {
00443   TBLOB *pblob;
00444   TBLOB *blob;
00445   CHOICES_LIST char_choices;
00446   int index;
00447   int did_chopping;
00448   float rating_limit = 1000.0;
00449   STATE state;
00450   SEAMS seam_list = NULL;
00451   CHOICES match_result;
00452   MATRIX ratings = NULL;
00453   DANGERR fixpt;                 /*dangerous ambig */
00454   INT32 state_count;             //no of states
00455   INT32 bit_count;               //no of bits
00456   static STATE best_state;
00457   static STATE chop_states[64];  //in between states
00458 
00459   state_count = 0;
00460   set_null_choice(best_choice);
00461   set_null_choice(raw_choice);
00462 
00463   char_choices = new_choice_list ();
00464 
00465   did_chopping = 0;
00466   for (blob = word->blobs, pblob = NULL, index = 0; blob != NULL;
00467   blob = blob->next, index++) {
00468     match_result =
00469       (CHOICES) classify_blob (pblob, blob, blob->next, NULL, fx,
00470       "chop_word:", Green, &chop_states[0],
00471       &best_state, matcher_pass, index);
00472     char_choices = array_push (char_choices, match_result);
00473     pblob = blob;
00474   }
00475   bit_count = index - 1;
00476   permute_characters(char_choices, rating_limit, best_choice, raw_choice);
00477 
00478   set_n_ones (&state, array_count (char_choices) - 1);
00479   if (matcher_fp != NULL) {
00480     if (matcher_pass == 0) {
00481       bits_in_states = bit_count;
00482       chop_states[state_count] = state;
00483     }
00484     state_count++;
00485   }
00486 
00487   if (!AcceptableChoice (char_choices, best_choice, raw_choice, &fixpt)
00488     || (tester || trainer)
00489   && strcmp (word->correct, class_string (best_choice))) {
00490     did_chopping = 1;
00491     if (first_pass)
00492       words_chopped1++;
00493     else
00494       words_chopped2++;
00495 
00496     seam_list = start_seam_list (word->blobs);
00497 
00498     if (chop_enable)
00499       improve_by_chopping(word,
00500                           &char_choices,
00501                           fx,
00502                           &state,
00503                           best_choice,
00504                           raw_choice,
00505                           &seam_list,
00506                           &fixpt,
00507                           chop_states,
00508                           &state_count,
00509                           &best_state,
00510                           matcher_pass);
00511 
00512     if (chop_debug)
00513       print_seams ("Final seam list:", seam_list);
00514 
00515     if (enable_assoc &&
00516       !AcceptableChoice (char_choices, best_choice, raw_choice, NULL)
00517       || (tester || trainer)
00518     && strcmp (word->correct, class_string (best_choice))) {
00519       ratings = word_associator (word->blobs, seam_list, &state, fx,
00520         best_choice, raw_choice, word->correct,
00521         /*0, */ &fixpt,
00522         &best_state, matcher_pass);
00523     }
00524     bits_in_states = bit_count + state_count - 1;
00525 
00526   }
00527   if (ratings != NULL)
00528     free_matrix(ratings);
00529   if (did_chopping || tester || trainer)
00530     char_choices = rebuild_current_state (word->blobs, seam_list, &state,
00531       char_choices, fx);
00532   if (seam_list != NULL)
00533     free_seam_list(seam_list);
00534   if (matcher_fp != NULL) {
00535     best_state = state;
00536   }
00537   FilterWordChoices();
00538   return char_choices;
00539 }

void improve_by_chopping ( register TWERD word,
CHOICES_LIST char_choices,
int  fx,
STATE best_state,
A_CHOICE best_choice,
A_CHOICE raw_choice,
SEAMS seam_list,
DANGERR fixpt,
STATE chop_states,
INT32 state_count,
STATE correct_state,
INT32  pass 
)

Try to improve word by chopping constituent blobs.

Parameters:
word Word in question
char_choices Current classification choices (modified)
fx Features
best_state 
best_choice 
raw_choice 
seam_list Check if any splits share point with this one
fixpt 
chop_states 
state_count 
correct_state 
pass 
Note:
Global:
  • chop_debug
Returns:
none (but params get changed)
Start with the current word of blobs and its classification. Find the worst blobs and try to divide them up to improve the ratings. As long as ratings are produced by the new blob splitting. When all the splitting has been accomplished all the ratings memory is reclaimed.

Definition at line 568 of file chopper.cpp.

References AcceptableChoice(), array_count, blob_skip, chop_debug, chops_performed1, chops_performed2, class_probability, count_blobs(), first_pass, improve_one_blob(), DANGERR::index, insert_new_chunk(), INT32FORMAT, LogNewSplit(), matcher_fp, MAX_NUM_CHUNKS, NULL, permute_characters(), print_state(), and set_n_ones().

Referenced by chop_word_main().

00579                                      {
00580   INT32 blob_number;
00581   INT32 index;                   //to states
00582   CHOICES_LIST choices = *char_choices;
00583   float old_best;
00584   int fixpt_valid = 1;
00585   static INT32 old_count;        //from pass1
00586 
00587   do { /* Improvement loop */
00588     if (!fixpt_valid)
00589       fixpt->index = -1;
00590     old_best = class_probability (best_choice);
00591     choices = improve_one_blob (word, *char_choices, fx,
00592       &blob_number, seam_list, fixpt,
00593       chop_states + *state_count, correct_state,
00594       pass);
00595     if (choices != NULL) {
00596       LogNewSplit(blob_number);
00597       permute_characters (choices,
00598         class_probability (best_choice),
00599         best_choice, raw_choice);
00600       *char_choices = choices;
00601 
00602       if (old_best > class_probability (best_choice)) {
00603         set_n_ones (best_state, array_count (*char_choices) - 1);
00604         fixpt_valid = 1;
00605       }
00606       else {
00607         insert_new_chunk (best_state, blob_number,
00608           array_count (*char_choices) - 2);
00609         fixpt_valid = 0;
00610       }
00611       if (*state_count > 0) {
00612         if (pass == 0) {
00613           for (index = 0; index < *state_count; index++)
00614             insert_new_chunk (&chop_states[index], blob_number,
00615               array_count (*char_choices) - 2);
00616           set_n_ones (&chop_states[index],
00617             array_count (*char_choices) - 1);
00618         }
00619         (*state_count)++;
00620       }
00621 
00622       if (chop_debug)
00623         print_state ("best state = ",
00624           best_state, count_blobs (word->blobs) - 1);
00625       if (first_pass)
00626         chops_performed1++;
00627       else
00628         chops_performed2++;
00629 
00630     }
00631   }
00632   while (choices &&
00633     !AcceptableChoice (*char_choices, best_choice, raw_choice, fixpt) &&
00634     !blob_skip && array_count (*char_choices) < MAX_NUM_CHUNKS);
00635   if (pass == 0)
00636     old_count = *state_count;
00637   else {
00638     if (old_count != *state_count)
00639       fprintf (matcher_fp,
00640         "Mis-matched state counts, " INT32FORMAT " pass1, "
00641         INT32FORMAT " pass2\n", old_count, *state_count);
00642   }
00643   if (!fixpt_valid)
00644     fixpt->index = -1;
00645 }

CHOICES_LIST improve_one_blob ( TWERD word,
CHOICES_LIST  char_choices,
int  fx,
INT32 blob_number,
SEAMS seam_list,
DANGERR fixpt,
STATE this_state,
STATE correct_state,
INT32  pass 
)

Try to improve worst rated blob.

Start with the current word of blobs and its classification; find the worst blobs and try to divide it up to improve the ratings.

Definition at line 313 of file chopper.cpp.

References array_insert(), array_value, attempt_blob_chop(), best_probability, CHAR_SAMPLE::blob(), blob_skip, wordstruct::blobs, classify_blob(), free_choices, insert_seam(), MAX_FLOAT32, NIL, NULL, Red, select_blob_to_split(), and Yellow.

Referenced by improve_by_chopping().

00321                                           {
00322   TBLOB *pblob;
00323   TBLOB *blob;
00324   INT16 x = 0;
00325   float rating_ceiling = MAX_FLOAT32;
00326   CHOICES answer;
00327   SEAM *seam;
00328 
00329   do {
00330     *blob_number = select_blob_to_split (char_choices, rating_ceiling);
00331     if (*blob_number == -1)
00332       return (NULL);
00333 
00334     seam = attempt_blob_chop (word, *blob_number, *seam_list);
00335     if (seam != NULL)
00336       break;
00337     /* Must split null blobs */
00338     answer = (CHOICES) array_value (char_choices, *blob_number);
00339     if (answer == NIL)
00340       return (NULL);             /* Try different blob */
00341     rating_ceiling = best_probability (answer);
00342   }
00343   while (!blob_skip);
00344   /* Split OK */
00345   for (blob = word->blobs, pblob = NULL; x < *blob_number; x++) {
00346     pblob = blob;
00347     blob = blob->next;
00348   }
00349 
00350   *seam_list =
00351     insert_seam (*seam_list, *blob_number, seam, blob, word->blobs);
00352 
00353   free_choices ((CHOICES) array_value (char_choices, *blob_number));
00354 
00355   answer =
00356     classify_blob (pblob, blob, blob->next, NULL, fx, "improve 1:", Red,
00357     this_state, correct_state, pass, *blob_number);
00358   char_choices = array_insert (char_choices, *blob_number, answer);
00359 
00360   answer =
00361     classify_blob (blob, blob->next, blob->next->next, NULL, fx, "improve 2:",
00362     Yellow, this_state, correct_state, pass, *blob_number + 1);
00363   array_value (char_choices, *blob_number + 1) = (char *) answer;
00364 
00365   return (char_choices);
00366 }

void preserve_outline ( EDGEPT start  ) 

Copy the list of outlines.

Note:
File: chopper.h (Formerly chopper.h)
Outline choppers
Author:
Mark Seaman, SW Productivity
Date:
Fri Oct 16 14:37:00 1987 Wed May 15 14:24:26 1991 (Mark Seaman) marks
 * (c) Copyright 1987, Hewlett-Packard Company.
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 ** http://www.apache.org/licenses/LICENSE-2.0
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.

Definition at line 81 of file chopper.cpp.

References edgeptstruct::flags, edgeptstruct::next, and NULL.

Referenced by preserve_outline_tree().

00081                                      { 
00082   EDGEPT *srcpt;
00083 
00084   if (start == NULL)
00085     return;
00086   srcpt = start;
00087   do {
00088     srcpt->flags[1] = 1;
00089     srcpt = srcpt->next;
00090   }
00091   while (srcpt != start);
00092   srcpt->flags[1] = 2;
00093 }

void preserve_outline_tree ( TESSLINE srcline  ) 

FIX: preserve_outline_tree ??

Recursive

Definition at line 102 of file chopper.cpp.

References olinestruct::child, olinestruct::loop, olinestruct::next, NULL, preserve_outline(), and preserve_outline_tree().

Referenced by attempt_blob_chop(), and preserve_outline_tree().

00102                                               { 
00103   TESSLINE *outline;
00104 
00105   for (outline = srcline; outline != NULL; outline = outline->next) {
00106     preserve_outline (outline->loop);
00107   }
00108   if (srcline->child != NULL)
00109     preserve_outline_tree (srcline->child);
00110 }

EDGEPT* restore_outline ( EDGEPT start  ) 

Copy the list of outlines.

Definition at line 117 of file chopper.cpp.

References edgeptstruct::flags, edgeptstruct::next, NULL, oldedgept(), edgeptstruct::pos, edgeptstruct::prev, edgeptstruct::vec, TPOINT::x, and TPOINT::y.

Referenced by restore_outline_tree().

00117                                        {
00118   EDGEPT *srcpt;
00119   EDGEPT *real_start;
00120   EDGEPT *deadpt;
00121 
00122   if (start == NULL)
00123     return NULL;
00124   srcpt = start;
00125   do {
00126     if (srcpt->flags[1] == 2)
00127       break;
00128     srcpt = srcpt->next;
00129   }
00130   while (srcpt != start);
00131   real_start = srcpt;
00132   do {
00133     if (srcpt->flags[1] == 0) {
00134       deadpt = srcpt;
00135       srcpt = srcpt->next;
00136       srcpt->prev = deadpt->prev;
00137       deadpt->prev->next = srcpt;
00138       deadpt->prev->vec.x = srcpt->pos.x - deadpt->prev->pos.x;
00139       deadpt->prev->vec.y = srcpt->pos.y - deadpt->prev->pos.y;
00140       oldedgept(deadpt);
00141     }
00142     else
00143       srcpt = srcpt->next;
00144   }
00145   while (srcpt != real_start);
00146   return real_start;
00147 }

void restore_outline_tree ( TESSLINE srcline  ) 

FIX: restore_outline_tree ??

Recursive

Definition at line 156 of file chopper.cpp.

References olinestruct::child, olinestruct::loop, olinestruct::next, NULL, edgeptstruct::pos, restore_outline(), restore_outline_tree(), and olinestruct::start.

Referenced by attempt_blob_chop(), and restore_outline_tree().

00156                                              { 
00157   TESSLINE *outline;
00158 
00159   for (outline = srcline; outline != NULL; outline = outline->next) {
00160     outline->loop = restore_outline (outline->loop);
00161     outline->start = outline->loop->pos;
00162   }
00163   if (srcline->child != NULL)
00164     restore_outline_tree (srcline->child);
00165 }

INT16 select_blob_to_split ( CHOICES_LIST  char_choices,
float  rating_ceiling 
)

These are the results of the last classification.

Find a likely place to apply splits.

Definition at line 654 of file chopper.cpp.

References array_value, best_certainty, best_probability, chop_debug, cprintf(), for_each_choice, MAX_FLOAT32, and NIL.

Referenced by improve_one_blob().

00654                                                                             { 
00655   CHOICES this_choice;
00656   int x;
00657   float worst = -MAX_FLOAT32;
00658   int worst_index = -1;
00659 
00660   if (chop_debug)
00661     if (rating_ceiling < MAX_FLOAT32)
00662       cprintf ("rating_ceiling = %8.4f\n", rating_ceiling);
00663   else
00664     cprintf ("rating_ceiling = No Limit\n");
00665 
00666   for_each_choice(char_choices, x) {
00667     this_choice = (CHOICES) array_value (char_choices, x);
00668     if (this_choice == NIL) {
00669       return (x);
00670     }
00671     else {
00672       if (best_probability (this_choice) > worst &&
00673         best_probability (this_choice) < rating_ceiling &&
00674       best_certainty (this_choice) < tessedit_certainty_threshold) {
00675         worst_index = x;
00676         worst = best_probability (this_choice);
00677       }
00678     }
00679   }
00680 
00681   if (chop_debug)
00682     cprintf ("blob_number = %4d\n", worst_index);
00683 
00684   return (worst_index);
00685 }

SEAMS start_seam_list ( TBLOB blobs  ) 

Make first node in a seam list.

Parameters:
blobs Pointer to list of TBLOB structures
Returns:
List of SEAMS
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.

Definition at line 700 of file chopper.cpp.

References add_seam(), CHAR_SAMPLE::blob(), blob_bounding_box(), new_seam(), new_seam_list(), NULL, and TPOINT::x.

Referenced by chop_word_main().

00700                                     { 
00701   TBLOB *blob;
00702   SEAMS seam_list;
00703   TPOINT topleft;
00704   TPOINT botright;
00705   int location;
00706   /* Seam slot per char */
00707   seam_list = new_seam_list ();
00708 
00709   for (blob = blobs; blob->next != NULL; blob = blob->next) {
00710 
00711     blob_bounding_box(blob, &topleft, &botright);
00712     location = botright.x;
00713     blob_bounding_box (blob->next, &topleft, &botright);
00714     location += topleft.x;
00715     location /= 2;
00716 
00717     seam_list = add_seam (seam_list,
00718       new_seam (0.0, location, NULL, NULL, NULL));
00719   }
00720 
00721   return (seam_list);
00722 }

INT16 total_containment ( TBLOB blob1,
TBLOB blob2 
)

Check to see if one of these outlines is totally contained within the bounding box of the other.

Definition at line 730 of file chopper.cpp.

References blob_bounding_box(), and bounds_inside.

Referenced by attempt_blob_chop().

00730                                                     {
00731   TPOINT topleft1;
00732   TPOINT botright1;
00733   TPOINT topleft2;
00734   TPOINT botright2;
00735 
00736   blob_bounding_box(blob1, &topleft1, &botright1);
00737   blob_bounding_box(blob2, &topleft2, &botright2);
00738 
00739   return (bounds_inside (topleft1, botright1, topleft2, botright2) ||
00740     bounds_inside (topleft2, botright2, topleft1, botright1));
00741 }

MATRIX word_associator ( TBLOB blobs,
SEAMS  seams,
STATE state,
int  fxid,
A_CHOICE best_choice,
A_CHOICE raw_choice,
char *  correct,
DANGERR fixpt,
STATE best_state,
INT32  pass 
)

Reassociate and classify the blobs in a word until a good answer is found or all the possibilities have been tried.

Definition at line 749 of file chopper.cpp.

References array_count, best_first_search(), blobs_widths(), CHUNKS_RECORD::char_widths, chop_debug, CHUNKS_RECORD::chunk_widths, CHUNKS_RECORD::chunks, class_certainty, class_probability, first, free_widths, CHUNKS_RECORD::fx, matrix_get, print_matrix(), CHUNKS_RECORD::ratings, record_piece_ratings(), CHUNKS_RECORD::splits, and CHUNKS_RECORD::weights.

Referenced by chop_word_main().

00758                                    {
00759   CHUNKS_RECORD chunks_record;
00760   BLOB_WEIGHTS blob_weights;
00761   int x;
00762   int num_chunks;
00763   A_CHOICE *this_choice;
00764 
00765   num_chunks = array_count (seams) + 1;
00766 
00767   chunks_record.chunks = blobs;
00768   chunks_record.splits = seams;
00769   chunks_record.ratings = record_piece_ratings (blobs);
00770   chunks_record.char_widths = blobs_widths (blobs);
00771   chunks_record.chunk_widths = blobs_widths (blobs);
00772   chunks_record.fx = fxid;
00773   /* Save chunk weights */
00774   for (x = 0; x < num_chunks; x++) {
00775     this_choice =
00776       (A_CHOICE *) first (matrix_get (chunks_record.ratings, x, x));
00777     blob_weights[x] = -(INT16) (10 * class_probability (this_choice) /
00778       class_certainty (this_choice));
00779   }
00780   chunks_record.weights = blob_weights;
00781 
00782   if (chop_debug)
00783     print_matrix (chunks_record.ratings);
00784   best_first_search(&chunks_record,
00785                     best_choice,
00786                     raw_choice,
00787                     state,
00788                     fixpt,
00789                     best_state,
00790                     pass);
00791 
00792   free_widths (chunks_record.chunk_widths);
00793   free_widths (chunks_record.char_widths);
00794   return chunks_record.ratings;
00795 }


Variable Documentation

int blob_skip

Note:
File: chopper.cpp (Formerly chopper.c)
More chopping blobs
Author:
Mark Seaman, OCR Technology
Date:
Fri Oct 16 14:37:00 1987 Tue Jul 30 16:18:52 1991 (Mark Seaman) marks
 * (c) Copyright 1987, Hewlett-Packard Company.
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 ** http://www.apache.org/licenses/LICENSE-2.0
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.


Generated on Wed Feb 28 19:49:28 2007 for Tesseract by  doxygen 1.5.1