textord/blkocc.cpp File Reference

#include "mfcpch.h"
#include <ctype.h>
#include <math.h>
#include "errcode.h"
#include "grphics.h"
#include "drawtord.h"
#include "blkocc.h"
#include "notdll.h"

Go to the source code of this file.

Defines

Functions

Variables


Define Documentation

#define EXTERN

#define REGION_TYPE_EMPTY   0

Referenced by find_region_type(), and record_region().

#define REGION_TYPE_ENCLOSED   7

Referenced by find_transitions().

#define REGION_TYPE_LOWER_BOUND   5

Referenced by find_region_type().

#define REGION_TYPE_LOWER_UNBOUND   6

Referenced by find_region_type(), and record_region().

#define REGION_TYPE_OPEN_LEFT   2

Referenced by compress_region_list(), and find_region_type().

#define REGION_TYPE_OPEN_RIGHT   1

Referenced by compress_region_list(), and find_region_type().

#define REGION_TYPE_UPPER_BOUND   3

Referenced by find_region_type().

#define REGION_TYPE_UPPER_UNBOUND   4

Referenced by find_region_type(), and record_region().


Function Documentation

void block_occ ( PBLOB blob,
float  occs[] 
)

Sets occupancy of block; used by test_underline.

Parameters:
blob Blob to do
occs Output histogram
Returns:
none (occs is changed)

Definition at line 327 of file blkocc.cpp.

References compress_region_list(), f, find_transitions(), MAX_NUM_BANDS, REGION_OCC::max_x, and REGION_OCC::min_x.

Referenced by test_underline().

00329   {
00330   int band_index;                // current band
00331   REGION_OCC *region;            // current segment
00332   REGION_OCC_LIST region_occ_list[MAX_NUM_BANDS + 1];
00333   REGION_OCC_IT region_it;       // region iterator
00334 
00335   find_transitions(blob, region_occ_list); 
00336   compress_region_list(region_occ_list); 
00337   for (band_index = 0; band_index <= MAX_NUM_BANDS; band_index++) {
00338     occs[band_index] = 0.0f;
00339     region_it.set_to_list (&region_occ_list[band_index]);
00340     for (region_it.mark_cycle_pt (); !region_it.cycled_list ();
00341     region_it.forward ()) {
00342       region = region_it.data ();
00343       occs[band_index] += region->max_x - region->min_x;
00344     }
00345   }
00346 }

void compress_region_list ( REGION_OCC_LIST *  region_occ_list  ) 

Join open regions.

Definition at line 771 of file blkocc.cpp.

References ABORT, BLOCKOCC, ERRCODE::error(), REGION_OCC::max_x, NULL, REGION_TYPE_OPEN_LEFT, and REGION_TYPE_OPEN_RIGHT.

Referenced by block_occ().

00772                                                             {
00773   REGION_OCC_IT it (&(region_occ_list[0]));
00774   REGION_OCC *open_right = NULL;
00775 
00776   INT16 i = 0;
00777 
00778   for (i = 0; i <= blockocc_band_count; i++) {
00779     it.set_to_list (&(region_occ_list[i]));
00780     if (!it.empty ()) {
00781       /* First check for left right pairs. Merge them into the
00782      open right and delete the open left. */
00783       open_right = NULL;
00784       for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00785         switch (it.data ()->region_type) {
00786           case REGION_TYPE_OPEN_RIGHT:
00787           {
00788             if (open_right != NULL)
00789               BLOCKOCC.error ("compress_region_list", ABORT,
00790                 "unmatched right");
00791             else
00792               open_right = it.data ();
00793             break;
00794           }
00795           case REGION_TYPE_OPEN_LEFT:
00796           {
00797             if (open_right == NULL)
00798               BLOCKOCC.error ("compress_region_list", ABORT,
00799                 "unmatched left");
00800             else {
00801               open_right->max_x = it.data ()->max_x;
00802               open_right = NULL;
00803               delete it.extract ();
00804             }
00805             break;
00806           }
00807           default:
00808             break;
00809         }
00810       }
00811       if (open_right != NULL)
00812         BLOCKOCC.error ("compress_region_list", ABORT,
00813           "unmatched right remaining");
00814 
00815       /* Now cycle the list again, merging and deleting any
00816      redundant regions */
00817       it.move_to_first ();
00818       open_right = it.data ();
00819       while (!it.at_last ()) {
00820         it.forward ();
00821         if (it.data ()->min_x <= open_right->max_x) {
00822         // Overlaps
00823           if (it.data ()->max_x > open_right->max_x)
00824             open_right->max_x = it.data ()->max_x;
00825           // Extend
00826           delete it.extract ();
00827         }
00828         else
00829           open_right = it.data ();
00830       }
00831     }
00832   }
00833 }

INT16 find_band ( float  y  ) 

Find POINT's band.

Definition at line 755 of file blkocc.cpp.

References ABORT, BLOCKOCC, and ERRCODE::error().

Referenced by next_region().

00756                          {
00757   INT16 band;
00758 
00759   for (band = 1; band <= blockocc_band_count; band++) {
00760     if (bands[band].in_nominal (y))
00761       return band;
00762   }
00763   BLOCKOCC.error ("find_band", ABORT, "Cant find band for %d", y);
00764   return 0;
00765 }

INT16 find_containing_maximal_band ( float  y1,
float  y2,
BOOL8 doubly_contained 
)

Find range's band.

Definition at line 548 of file blkocc.cpp.

References FALSE, TRUE, and UNDEFINED_BAND.

Referenced by find_transitions().

00551                                                             {
00552   INT16 band;
00553 
00554   *doubly_contained = FALSE;
00555 
00556   for (band = 1; band <= blockocc_band_count; band++) {
00557     if (bands[band].range_in_maximal (y1, y2)) {
00558       if ((band < blockocc_band_count) &&
00559         (bands[band + 1].range_in_maximal (y1, y2)))
00560         *doubly_contained = TRUE;
00561       return band;
00562     }
00563   }
00564   return UNDEFINED_BAND;
00565 }

void find_fbox ( OUTLINE_IT *  out_it,
float *  min_x,
float *  min_y,
float *  max_x,
float *  max_y 
)

find limits given blob's outlines

updates min_x, min_y, max_x, & max_y based on blob->out_list

Definition at line 841 of file blkocc.cpp.

References maintain_limits().

Referenced by find_transitions().

00845                              {
00846   POLYPT_IT pt_it = out_it->data ()->polypts ();
00847   FCOORD pt;
00848   *min_x = 9999.0f;
00849   *min_y = 9999.0f;
00850   *max_x = 0.0f;
00851   *max_y = 0.0f;
00852 
00853   for (pt_it.mark_cycle_pt (); !pt_it.cycled_list (); pt_it.forward ()) {
00854     pt = pt_it.data ()->pos;
00855     maintain_limits (min_x, max_x, pt.x ());
00856     maintain_limits (min_y, max_y, pt.y ());
00857   }
00858 }

INT16 find_overlapping_minimal_band ( float  y1,
float  y2 
)

Find range's band.

Definition at line 589 of file blkocc.cpp.

References UNDEFINED_BAND.

Referenced by find_significant_line().

00591                                               {
00592   INT16 band;
00593 
00594   for (band = 1; band <= blockocc_band_count; band++) {
00595     if (bands[band].range_overlaps_minimal (y1, y2))
00596       return band;
00597   }
00598   return UNDEFINED_BAND;
00599 }

INT16 find_region_type ( INT16  entry_band,
INT16  current_band,
INT16  exit_band,
float  entry_x,
float  exit_x 
)

Returns region type based on rules given in tess_transitions note.

Definition at line 605 of file blkocc.cpp.

References REGION_TYPE_EMPTY, REGION_TYPE_LOWER_BOUND, REGION_TYPE_LOWER_UNBOUND, REGION_TYPE_OPEN_LEFT, REGION_TYPE_OPEN_RIGHT, REGION_TYPE_UPPER_BOUND, and REGION_TYPE_UPPER_UNBOUND.

Referenced by find_transitions().

00609                                      {
00610   if (entry_band > exit_band)
00611     return REGION_TYPE_OPEN_RIGHT;
00612   if (entry_band < exit_band)
00613     return REGION_TYPE_OPEN_LEFT;
00614   if (entry_x == exit_x)
00615     return REGION_TYPE_EMPTY;
00616   if (entry_band > current_band) {
00617     if (entry_x < exit_x)
00618       return REGION_TYPE_UPPER_BOUND;
00619     else
00620       return REGION_TYPE_UPPER_UNBOUND;
00621   }
00622   else {
00623     if (entry_x > exit_x)
00624       return REGION_TYPE_LOWER_BOUND;
00625     else
00626       return REGION_TYPE_LOWER_UNBOUND;
00627   }
00628 }

void find_significant_line ( POLYPT_IT  it,
INT16 band 
)

Look for a line which significantly occupies at least one band; part of the line is in the non-margin part of the band.

Definition at line 572 of file blkocc.cpp.

References find_overlapping_minimal_band(), and UNDEFINED_BAND.

Referenced by find_transitions().

00572                                                       { 
00573   *band = find_overlapping_minimal_band (it.data ()->pos.y (),
00574     it.data ()->pos.y () +
00575     it.data ()->vec.y ());
00576 
00577   while (*band == UNDEFINED_BAND) {
00578     it.forward ();
00579     *band = find_overlapping_minimal_band (it.data ()->pos.y (),
00580       it.data ()->pos.y () +
00581       it.data ()->vec.y ());
00582   }
00583 }

void find_trans_point ( POLYPT_IT *  pt_it,
INT16  current_band,
INT16  next_band,
FCOORD transition_pt 
)

Find transition point.

Definition at line 634 of file blkocc.cpp.

References max, and min.

Referenced by find_transitions(), and next_region().

00637                                              {
00638   float x1, x2, y1, y2;          // points of edge
00639   float gradient;                // m in y = mx + c
00640   float offset;                  // c in y = mx + c
00641 
00642   if (current_band < next_band)
00643     transition_pt->set_y (bands[current_band].max);
00644   //going up
00645   else
00646     transition_pt->set_y (bands[current_band].min);
00647   //going down
00648 
00649   x1 = pt_it->data ()->pos.x ();
00650   x2 = x1 + pt_it->data ()->vec.x ();
00651   y1 = pt_it->data ()->pos.y ();
00652   y2 = y1 + pt_it->data ()->vec.y ();
00653 
00654   if (x1 == x2)
00655     transition_pt->set_x (x1);   //avoid div by 0
00656   else {
00657     if (y1 == y2)                //avoid div by 0
00658       transition_pt->set_x ((x1 + x2) / 2.0);
00659     else {
00660       gradient = (y1 - y2) / (float) (x1 - x2);
00661       offset = y1 - x1 * gradient;
00662       transition_pt->set_x ((transition_pt->y () - offset) / gradient);
00663     }
00664   }
00665 }

void find_transitions ( PBLOB blob,
REGION_OCC_LIST *  region_occ_list 
)

Sets occupancy of block; used by test_underline.

Parameters:
blob Blob to do
region_occ_list List of region occupancy
Returns:
none (occs[] is changed)
Determining a good start point for recognising transitions between bands is complicated by error limits on bands. We need to find a line which significantly occupies a band.

Having found such a point, we need to find a significant transition out of its band and start the walk around the outline from there.

Note that we are relying on having recognised and dealt with elsewhere, outlines which do not significantly occupy more than one region. A particularly nasty case of this are outlines which do not significantly occupy ANY band. I.e. they lie entirely within the error limits. Given this condition, all remaining outlines must contain at least one significant line.

Definition at line 371 of file blkocc.cpp.

References DOT_BAND, find_containing_maximal_band(), find_fbox(), find_region_type(), find_significant_line(), find_trans_point(), maintain_limits(), next_region(), PBLOB::out_list(), outline_it, record_region(), REGION_TYPE_ENCLOSED, and UNDEFINED_BAND.

Referenced by block_occ().

00372                                                         {
00373   OUTLINE_IT outline_it;
00374   BOX box;
00375   POLYPT_IT pt_it;
00376   FCOORD point1;
00377   FCOORD point2;
00378   FCOORD *entry_pt = &point1;
00379   FCOORD *exit_pt = &point2;
00380   FCOORD *temp_pt;
00381   INT16 increment;
00382   INT16 prev_band;
00383   INT16 band;
00384   INT16 next_band;
00385   float min_x;
00386   float max_x;
00387   float min_y;
00388   float max_y;
00389   BOOL8 doubly_contained;
00390 
00391   outline_it = blob->out_list ();
00392   for (outline_it.mark_cycle_pt (); !outline_it.cycled_list ();
00393   outline_it.forward ()) {
00394     find_fbox(&outline_it, &min_x, &min_y, &max_x, &max_y); 
00395 
00396     if (bands[DOT_BAND].range_in_nominal (max_y, min_y)) {
00397       record_region(DOT_BAND,
00398                     min_x,
00399                     max_x,
00400                     REGION_TYPE_ENCLOSED,
00401                     region_occ_list);
00402     }
00403     else {
00404       band = find_containing_maximal_band (max_y, min_y,
00405         &doubly_contained);
00406       if (band != UNDEFINED_BAND) {
00407                                  //No transitions
00408         if (!doubly_contained)
00409           record_region(band,
00410                         min_x,
00411                         max_x,
00412                         REGION_TYPE_ENCLOSED,
00413                         region_occ_list);
00414         else {
00415           //   if (wordocc_debug_on && blockocc_show_result)
00416           //   {
00417           //       fprintf( db_win,
00418           //         "Ignoring doubly contained outline (%d, %d) (%d, %d)\n",
00419           //         box.left(), box.top(),
00420           //         box.right(), box.bottom());
00421           //       fprintf( db_win, "\tContained in bands %d and %d\n",
00422           //         band, band + 1 );
00423           //    }
00424         }
00425       }
00426       else {
00427       //There are transitions
00428 
00429         pt_it = outline_it.data ()->polypts ();
00430 
00431         find_significant_line(pt_it, &band); 
00432         *entry_pt = pt_it.data ()->pos;
00433         next_region(&pt_it,
00434                     band,
00435                     &next_band,
00436                     &min_x,
00437                     &max_x,
00438                     &increment,
00439                     exit_pt);
00440         pt_it.mark_cycle_pt ();
00441 
00442         // Found the first real transition, so start walking the outline from here.
00443 
00444         do {
00445           prev_band = band;
00446           band = band + increment;
00447 
00448           while (band != next_band) {
00449             temp_pt = entry_pt;
00450             entry_pt = exit_pt;
00451             exit_pt = temp_pt;
00452             min_x = max_x = entry_pt->x ();
00453 
00454             find_trans_point (&pt_it, band, band + increment,
00455               exit_pt);
00456             maintain_limits (&min_x, &max_x, exit_pt->x ());
00457 
00458             record_region (band,
00459               min_x,
00460               max_x,
00461               find_region_type (prev_band,
00462               band,
00463               band + increment,
00464               entry_pt->x (),
00465               exit_pt->x ()),
00466               region_occ_list);
00467             prev_band = band;
00468             band = band + increment;
00469           }
00470 
00471           temp_pt = entry_pt;
00472           entry_pt = exit_pt;
00473           exit_pt = temp_pt;
00474           min_x = max_x = entry_pt->x ();
00475           next_region(&pt_it,
00476                       band,
00477                       &next_band,
00478                       &min_x,
00479                       &max_x,
00480                       &increment,
00481                       exit_pt);
00482 
00483           record_region (band,
00484             min_x,
00485             max_x,
00486             find_region_type (prev_band,
00487             band,
00488             band + increment,
00489             entry_pt->x (),
00490             exit_pt->x ()),
00491             region_occ_list);
00492         }
00493         while (!pt_it.cycled_list ());
00494       }
00495     }
00496   }
00497 }

void horizontal_cblob_projection ( C_BLOB blob,
STATS stats 
)

Compute the horizontal projection of a cblob from its outlines and add to the given STATS.

Definition at line 241 of file blkocc.cpp.

References horizontal_coutline_projection(), and C_BLOB::out_list().

Referenced by test_underline().

00244                                   {
00245                                  //outlines of blob
00246   C_OUTLINE_IT out_it = blob->out_list ();
00247 
00248   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00249     horizontal_coutline_projection (out_it.data (), stats);
00250   }
00251 }

void horizontal_coutline_projection ( C_OUTLINE outline,
STATS stats 
)

project outlines

Parameters:
outline Outline to project
stats Output
Returns:
none (stats modified)
Compute the horizontal projection of a outline from its outlines and add to the given STATS.

Definition at line 264 of file blkocc.cpp.

References STATS::add(), horizontal_coutline_projection(), and ICOORD::y().

Referenced by horizontal_cblob_projection(), and horizontal_coutline_projection().

00267                                      {
00268   ICOORD pos;                    // current point
00269   ICOORD step;                   // edge step
00270   INT32 length;                  // of outline
00271   INT16 stepindex;               // current step
00272   C_OUTLINE_IT out_it = outline->child ();
00273 
00274   pos = outline->start_pos ();
00275   length = outline->pathlength ();
00276   for (stepindex = 0; stepindex < length; stepindex++) {
00277     step = outline->step (stepindex);
00278     if (step.y () > 0) {
00279       stats->add (pos.y (), pos.x ());
00280     }
00281     else if (step.y () < 0) {
00282       stats->add (pos.y () - 1, -pos.x ());
00283     }
00284     pos += step;
00285   }
00286 
00287   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00288     horizontal_coutline_projection (out_it.data (), stats);
00289   }
00290 }

void maintain_limits ( float *  min_x,
float *  max_x,
float  x 
)

Updates min_x and max_x based on x.

Definition at line 864 of file blkocc.cpp.

Referenced by find_fbox(), find_transitions(), and next_region().

00864                                                           { 
00865   if (x > *max_x)
00866     *max_x = x;
00867   if (x < *min_x)
00868     *min_x = x;
00869 }

void next_region ( POLYPT_IT *  start_pt_it,
INT16  start_band,
INT16 to_band,
float *  min_x,
float *  max_x,
INT16 increment,
FCOORD exit_pt 
)

Find the significant end of the region containing the band.

Given an edge and a band which the edge significantly occupies, find the significant end of the region containing the band. I.e. find an edge which points to another band such that the outline subsequetly moves significantly out of the starting band.

Note that we can assume that we are significantly inside the current band to start with because the edges passed will be from previous calls to this routine apart from the first - the result of which is only used to establish the start of the first region.

Definition at line 681 of file blkocc.cpp.

References find_band(), find_trans_point(), and maintain_limits().

Referenced by find_transitions().

00687                                   {
00688 
00689   INT16 band;                    // band of current edge
00690   INT16 prev_band = start_band;  // band of prev edge
00691   POLYPT_IT last_transition_out_it; // edge crossing out
00692   INT16 last_trans_out_to_band = 0; // band it pts to
00693   float ext_min_x = 0.0f;
00694   float ext_max_x = 0.0f;
00695 
00696   start_pt_it->forward ();
00697   band = find_band (start_pt_it->data ()->pos.y ());
00698 
00699   while ((band == start_band) ||
00700   bands[start_band].in_maximal (start_pt_it->data ()->pos.y ())) {
00701     if (band == start_band) {
00702                                  //Return to start band
00703       if (prev_band != start_band) {
00704         *min_x = ext_min_x;
00705         *max_x = ext_max_x;
00706       }
00707       maintain_limits (min_x, max_x, start_pt_it->data ()->pos.x ());
00708     }
00709     else {
00710       if (prev_band == start_band) {
00711                                  //Exit from start band
00712                                  //so remember edge
00713         last_transition_out_it = *start_pt_it;
00714                                  //before we left
00715         last_transition_out_it.backward ();
00716                                  //and band it pts to
00717         last_trans_out_to_band = band;
00718         ext_min_x = *min_x;
00719         ext_max_x = *max_x;
00720       }
00721       maintain_limits (&ext_min_x, &ext_max_x,
00722         start_pt_it->data ()->pos.x ());
00723     }
00724     prev_band = band;
00725     start_pt_it->forward ();
00726     band = find_band (start_pt_it->data ()->pos.y ());
00727   }
00728 
00729   if (prev_band == start_band) { //exit from start band
00730     *to_band = band;
00731                                  //so remember edge
00732     last_transition_out_it = *start_pt_it;
00733                                  //before we left
00734     last_transition_out_it.backward ();
00735   }
00736   else {
00737     *to_band = last_trans_out_to_band;
00738   }
00739 
00740   if (*to_band > start_band)
00741     *increment = 1;
00742   else
00743     *increment = -1;
00744 
00745   find_trans_point (&last_transition_out_it, start_band,
00746     start_band + *increment, exit_pt);
00747   maintain_limits (min_x, max_x, exit_pt->x ());
00748   *start_pt_it = last_transition_out_it;
00749 }

void record_region ( INT16  band,
float  new_min,
float  new_max,
INT16  region_type,
REGION_OCC_LIST *  region_occ_list 
)

Add region on list.

Add region of specified region_type to region_occ_list

Definition at line 504 of file blkocc.cpp.

References REGION_TYPE_EMPTY, REGION_TYPE_LOWER_UNBOUND, and REGION_TYPE_UPPER_UNBOUND.

Referenced by find_transitions().

00509                                                      {
00510   REGION_OCC_IT it (&(region_occ_list[band]));
00511 
00512   //   if (wordocc_debug_on && blockocc_show_result)
00513   //      fprintf( db_win, "\nBand %d, region type %d, from %f to %f",
00514   //         band, region_type, new_min, new_max );
00515 
00516   if ((region_type == REGION_TYPE_UPPER_UNBOUND) ||
00517     (region_type == REGION_TYPE_LOWER_UNBOUND) ||
00518     (region_type == REGION_TYPE_EMPTY))
00519     return;
00520 
00521   if (it.empty ()) {
00522     it.add_after_stay_put (new REGION_OCC (new_min, new_max, region_type));
00523   }
00524   else {
00525 
00526     /* Insert in sorted order of average limit */
00527 
00528     while ((new_min + new_max > it.data ()->min_x + it.data ()->max_x) &&
00529       (!it.at_last ()))
00530       it.forward ();
00531 
00532     if ((it.at_last ()) &&       //at the end
00533       (new_min + new_max > it.data ()->min_x + it.data ()->max_x))
00534       //new range > current
00535       it.add_after_stay_put (new REGION_OCC (new_min,
00536         new_max, region_type));
00537     else {
00538       it.add_before_stay_put (new REGION_OCC (new_min,
00539         new_max, region_type));
00540     }
00541   }
00542 }

void set_bands ( float  baseline,
float  xheight 
)

Init bands from varibles

Definition at line 295 of file blkocc.cpp.

References DOT_BAND, NO_LOWER_LIMIT, and NO_UPPER_LIMIT.

Referenced by test_underline().

00298                 {
00299   INT16 int_bl, int_xh;          //for band.set
00300 
00301   bands[DOT_BAND].set (0, 0, 0, 0, 0, 0);
00302 
00303   int_bl = (INT16) baseline;
00304   int_xh = (INT16) xheight;
00305   bands[1].set (int_bl, int_bl, int_bl,
00306     NO_LOWER_LIMIT, NO_LOWER_LIMIT, NO_LOWER_LIMIT);
00307 
00308   bands[2].set (int_bl + int_xh / 2, int_bl + int_xh / 2, int_bl + int_xh / 2,
00309     int_bl, int_bl, int_bl);
00310 
00311   bands[3].set (int_bl + int_xh, int_bl + int_xh, int_bl + int_xh,
00312     int_bl + int_xh / 2, int_bl + int_xh / 2,
00313     int_bl + int_xh / 2);
00314 
00315   bands[4].set (NO_UPPER_LIMIT, NO_UPPER_LIMIT, NO_UPPER_LIMIT,
00316     int_bl + int_xh, int_bl + int_xh, int_bl + int_xh);
00317 }

BOOL8 test_underline ( BOOL8  testing_on,
C_BLOB blob,
INT16  baseline,
INT16  xheight 
)

Check to see if the blob is an underline; occupancy is integer & works on compacted blobs.

Parameters:
testing_on 0 or 1, drawing blob
blob Blob to test
baseline Coords of baseline
xheight Height of line
Returns:
TRUE if blob is an underline

Definition at line 173 of file blkocc.cpp.

References BOX::bottom(), C_BLOB::bounding_box(), FALSE, horizontal_cblob_projection(), BOX::left(), STATS::pile_count(), STATS::print(), projection, BOX::right(), STATS::set_range(), BOX::top(), tprintf(), TRUE, and BOX::width().

00178                       {
00179   INT16 occ;
00180   INT16 blob_width;              //width of blob
00181   BOX blob_box;                  //bounding box
00182   INT32 desc_occ;
00183   INT32 x_occ;
00184   INT32 asc_occ;
00185   STATS projection;
00186 
00187   blob_box = blob->bounding_box ();
00188   blob_width = blob->bounding_box ().width ();
00189   projection.set_range (blob_box.bottom (), blob_box.top () + 1);
00190   if (testing_on) {
00191     //              blob->plot(to_win,GOLDENROD,GOLDENROD);
00192     //              line_color_index(to_win,GOLDENROD);
00193     //              move2d(to_win,blob_box.left(),baseline);
00194     //              draw2d(to_win,blob_box.right(),baseline);
00195     //              move2d(to_win,blob_box.left(),baseline+xheight);
00196     //              draw2d(to_win,blob_box.right(),baseline+xheight);
00197     tprintf
00198       ("Testing underline on blob at (%d,%d)->(%d,%d), base=%d\nOccs:",
00199       blob->bounding_box ().left (), blob->bounding_box ().bottom (),
00200       blob->bounding_box ().right (), blob->bounding_box ().top (),
00201       baseline);
00202   }
00203   horizontal_cblob_projection(blob, &projection); 
00204   desc_occ = 0;
00205   for (occ = blob_box.bottom (); occ < baseline; occ++)
00206     if (occ <= blob_box.top () && projection.pile_count (occ) > desc_occ)
00207                                  //max in region
00208       desc_occ = projection.pile_count (occ);
00209   x_occ = 0;
00210   for (occ = baseline; occ <= baseline + xheight; occ++)
00211     if (occ >= blob_box.bottom () && occ <= blob_box.top ()
00212     && projection.pile_count (occ) > x_occ)
00213                                  //max in region
00214       x_occ = projection.pile_count (occ);
00215   asc_occ = 0;
00216   for (occ = baseline + xheight + 1; occ <= blob_box.top (); occ++)
00217     if (occ >= blob_box.bottom () && projection.pile_count (occ) > asc_occ)
00218       asc_occ = projection.pile_count (occ);
00219   if (testing_on) {
00220     tprintf ("%d %d %d\n", desc_occ, x_occ, asc_occ);
00221   }
00222   if (desc_occ == 0 && x_occ == 0 && asc_occ == 0) {
00223     tprintf ("Bottom=%d, top=%d, base=%d, x=%d\n",
00224       blob_box.bottom (), blob_box.top (), baseline, xheight);
00225     projection.print (stdout, TRUE);
00226   }
00227   if (desc_occ > x_occ + x_occ
00228     && desc_occ > blob_width * textord_underline_threshold)
00229     return TRUE;                 //real underline
00230   if (asc_occ > x_occ + x_occ
00231     && asc_occ > blob_width * textord_underline_threshold)
00232     return TRUE;                 //overline
00233   return FALSE;                  //neither
00234 }

BOOL8 test_underline ( BOOL8  testing_on,
PBLOB blob,
float  baseline,
float  xheight 
)

Look for underlines.

Parameters:
testing_on 0 or 1, drawing blob
blob Blob to test
baseline Coords of baseline
xheight Height of line
Returns:
TRUE if blob is an underline
Check to see if the blob is an underline; occupancy is floating-point & works on uncompacted blobs

Definition at line 121 of file blkocc.cpp.

Referenced by separate_underlines().

00126                       {
00127   INT16 occ;
00128   INT16 blob_width;              //width of blob
00129   BOX blob_box;                  //bounding box
00130   float occs[MAX_NUM_BANDS + 1]; //total occupancy
00131 
00132   blob_box = blob->bounding_box ();
00133   set_bands(baseline, xheight);  //setup block occ
00134   blob_width = blob->bounding_box ().width ();
00135   if (testing_on) {
00136     //              blob->plot(to_win,GOLDENROD,GOLDENROD);
00137     //              line_color_index(to_win,GOLDENROD);
00138     //              move2d(to_win,blob_box.left(),baseline);
00139     //              draw2d(to_win,blob_box.right(),baseline);
00140     //              move2d(to_win,blob_box.left(),baseline+xheight);
00141     //              draw2d(to_win,blob_box.right(),baseline+xheight);
00142     tprintf
00143       ("Testing underline on blob at (%d,%d)->(%d,%d), base=%g\nOccs:",
00144       blob->bounding_box ().left (), blob->bounding_box ().bottom (),
00145       blob->bounding_box ().right (), blob->bounding_box ().top (),
00146       baseline);
00147   }
00148   block_occ(blob, occs); 
00149   if (testing_on) {
00150     for (occ = 0; occ <= MAX_NUM_BANDS; occ++)
00151       tprintf ("%g ", occs[occ]);
00152     tprintf ("\n");
00153   }
00154   if (occs[1] > occs[2] + occs[2] && occs[1] > occs[3] + occs[3]
00155     && occs[1] > blob_width * textord_underline_threshold)
00156     return TRUE;                 //real underline
00157   if (occs[4] > occs[2] + occs[2]
00158     && occs[4] > blob_width * textord_underline_threshold)
00159     return TRUE;                 //overline
00160   return FALSE;                  //neither
00161 }


Variable Documentation

const ERRCODE BLOCKOCC = "BlockOcc"

Note:
File: blkocc.cpp (Formerly blockocc.c)
Block Occupancy routines
Author:
Chris Newton
Date:
Fri Nov 8
 * (c) Copyright 1991, 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 35 of file blkocc.cpp.

Referenced by compress_region_list(), and find_band().


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