PIXROW Class Reference

#include <charcut.h>

Inheritance diagram for PIXROW:

ELIST_LINK List of all members.

Detailed Description

Class describes the pixels occupied by a blob.

This class describes the pixels occupied by a blob. It uses two arrays, (min and max), each with one element per row, to identify the min and max x coordinates of the black pixels in the character on that row of the image. The number of rows used to describe the blob is held in row_count - note that some rows may be unoccupied - signified by max < min. The page coordinate of the row defined by min[0] and max[0] is held in row_offset.

Definition at line 39 of file charcut.h.

Public Member Functions

Public Attributes


Constructor & Destructor Documentation

PIXROW::PIXROW (  )  [inline]

Definition at line 47 of file charcut.h.

References max, min, NULL, row_count, and row_offset.

00047              {  //empty constructor
00048       row_offset = 0;
00049       row_count = 0;
00050       min = NULL;
00051       max = NULL;
00052     }

PIXROW::PIXROW ( INT16  pos,
INT16  count,
PBLOB blob 
)

PIXROW::~PIXROW (  )  [inline]

Definition at line 58 of file charcut.h.

References free_mem(), max, min, and NULL.

00058                {                 //destructor
00059       if (min != NULL)
00060         free_mem(min); 
00061       if (max != NULL)
00062         free_mem(max); 
00063       max = NULL;
00064     }


Member Function Documentation

bool PIXROW::bad_box ( int  xsize,
int  ysize 
) const

Generate bounding box for blob image.

Parameters:
xsize horiz size
ysize vertical size
Returns:
TRUE if box exceeds image

Definition at line 127 of file charcut.cpp.

References BOX::bottom(), bounding_box(), BOX::left(), BOX::right(), BOX::top(), and tprintf().

00129                                       {
00130   BOX bbox = bounding_box ();
00131   if (bbox.left () < 0 || bbox.right () > xsize
00132   || bbox.top () > ysize || bbox.bottom () < 0) {
00133     tprintf("Box (%d,%d)->(%d,%d) bad compared to %d,%d\n",
00134             bbox.left(),bbox.bottom(), bbox.right(), bbox.top(),
00135             xsize, ysize);
00136     return true;
00137   }
00138   return false;
00139 }

BOX PIXROW::bounding_box (  )  const

Generate bounding box for blob image.

Parameters:
none 
Returns:
coordinates of bounding box

Definition at line 147 of file charcut.cpp.

References max, MAX_INT16, min, row_count, and row_offset.

Referenced by adapt_to_good_samples(), bad_box(), char_clip_image(), and clip_sample().

00147                                { 
00148   INT16 i;
00149   INT16 y_coord;
00150   INT16 min_x = MAX_INT16 - 1;
00151   INT16 min_y = MAX_INT16 - 1;
00152   INT16 max_x = -MAX_INT16 + 1;
00153   INT16 max_y = -MAX_INT16 + 1;
00154 
00155   for (i = 0; i < row_count; i++) {
00156     y_coord = row_offset + i;
00157     if (min[i] <= max[i]) {
00158       if (y_coord < min_y)
00159         min_y = y_coord;
00160       if (y_coord + 1 > max_y)
00161         max_y = y_coord + 1;
00162       if (min[i] < min_x)
00163         min_x = min[i];
00164       if (max[i] + 1 > max_x)
00165         max_x = max[i] + 1;
00166     }
00167   }
00168   if (min_x > max_x || min_y > max_y)
00169     return BOX ();
00170   else
00171     return BOX (ICOORD (min_x, min_y), ICOORD (max_x, max_y));
00172 }

void PIXROW::char_clip_image ( IMAGELINE imlines,
BOX im_box,
ROW row,
IMAGE clip_image,
float &  baseline_pos 
)

Cut out a sub image for a character.

Parameters:
imlines Box of imlines extnt
im_box Coordinates of bounding box
row Row containing word
clip_image Unscaled sq[square?] subimage
baseline_pos Baseline position relative to clip image
Returns:
none

The x_shift is the shift to be applied to the page coord in the pixrow to generate a centred char in the clip image. Thus the left hand edge of the char is shifted to the margin width of the centred character.

The y shift is calculated by first finding the coord of the bottom of the image relative to the image lines. Then reducing this so by the amount relative to the clip image size, necessary to vertically position the character.

Definition at line 371 of file charcut.cpp.

References ROW::base_line(), BOX::bottom(), bounding_box(), IMAGE::get_xsize(), IMAGE::get_ysize(), BOX::height(), IMAGELINE::init(), BOX::left(), max, min, NULL, IMAGELINE::pixels, IMAGE::put_line(), BOX::right(), row_count, row_offset, and BOX::width().

Referenced by clip_sample().

00377                               {
00378   INT16 clip_image_xsize;        //sub image x size
00379   INT16 clip_image_ysize;        //sub image y size
00384   INT16 x_shift;
00390   INT16 y_shift;
00391   BOX char_pix_box;              //bbox of char pixels
00392   INT16 y_dest;
00393   INT16 x_min;
00394   INT16 x_max;
00395   INT16 x_min_dest;
00396   INT16 x_max_dest;
00397   INT16 x_width;
00398   INT16 y;
00399 
00400   clip_image_xsize = clip_image.get_xsize ();
00401   clip_image_ysize = clip_image.get_ysize ();
00402 
00403   char_pix_box = bounding_box ();
00404   y_shift = char_pix_box.bottom () - row_offset -
00405     (INT16) floor ((clip_image_ysize - char_pix_box.height () + 0.5) / 2);
00406 
00407   x_shift = char_pix_box.left () -
00408     (INT16) floor ((clip_image_xsize - char_pix_box.width () + 0.5) / 2);
00409 
00410   for (y = 0; y < row_count; y++) {
00411     /*
00412       Check that there is something in this row of the source that will fit in the
00413       sub image.  If there is, reduce x range if necessary, then copy it
00414     */
00415     y_dest = y - y_shift;
00416     if ((min[y] <= max[y]) && (y_dest >= 0) && (y_dest < clip_image_ysize)) {
00417       x_min = min[y];
00418       x_min_dest = x_min - x_shift;
00419       if (x_min_dest < 0) {
00420         x_min = x_min - x_min_dest;
00421         x_min_dest = 0;
00422       }
00423       x_max = max[y];
00424       x_max_dest = x_max - x_shift;
00425       if (x_max_dest > clip_image_xsize - 1) {
00426         x_max = x_max - (x_max_dest - (clip_image_xsize - 1));
00427         x_max_dest = clip_image_xsize - 1;
00428       }
00429       x_width = x_max - x_min + 1;
00430       if (x_width > 0) {
00431         x_min -= im_box.left ();
00432                                  //offset pixel ptr
00433         imlines[y].pixels += x_min;
00434         clip_image.put_line (x_min_dest, y_dest, x_width, imlines + y,
00435           0);
00436         imlines[y].init ();      //reset pixel ptr
00437       }
00438     }
00439   }
00440   /*
00441     Baseline position relative to clip image: First find the baseline relative
00442     to the page origin at the x coord of the centre of the character. Then
00443     make this relative to the character bottom. Finally shift by the margin
00444     between the bottom of the character and the bottom of the clip image.
00445   */
00446   if (row == NULL)
00447     baseline_pos = 0;            //Not needed
00448   else
00449     baseline_pos = row->base_line ((char_pix_box.left () +
00450       char_pix_box.right ()) / 2.0)
00451       - char_pix_box.bottom ()
00452       + ((clip_image_ysize - char_pix_box.height ()) / 2);
00453 }

void PIXROW::contract ( IMAGELINE imlines,
INT16  x_offset,
INT16  foreground_colour 
)

Reduce the mins and maxs so that they end on black pixels.

Parameters:
imlines box of imlines extnt
x_offset of pixels[0]
foreground_colour 0 or 1
Returns:
none

Definition at line 183 of file charcut.cpp.

References max, MAX_INT16, min, IMAGELINE::pixels, and row_count.

00187                        {
00188   INT16 i;
00189   UINT8 *line_pixels;
00190 
00191   for (i = 0; i < row_count; i++) {
00192     if (min[i] > max[i])
00193       continue;
00194 
00195     line_pixels = imlines[i].pixels;
00196     while (line_pixels[min[i] - x_offset] != foreground_colour) {
00197       if (min[i] == max[i]) {
00198         min[i] = MAX_INT16 - 1;
00199         max[i] = -MAX_INT16 + 1;
00200         goto nextline;
00201       }
00202       else
00203         min[i]++;
00204     }
00205     while (line_pixels[max[i] - x_offset] != foreground_colour) {
00206       if (min[i] == max[i]) {
00207         min[i] = MAX_INT16 - 1;
00208         max[i] = -MAX_INT16 + 1;
00209         goto nextline;
00210       }
00211       else
00212         max[i]--;
00213     }
00214     nextline:;
00215     //goto label!
00216   }
00217 }

void ELIST_LINK::de_serialise_asc ( FILE *  f  )  [inherited]

Reimplemented in ICOORDELT.

Definition at line 39 of file elst.cpp.

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

00040                                            {
00041   SERIALISE_LINKS.error ("ELIST_LINK::de_serialise_asc", ABORT,
00042     "Don't call this, override!");
00043 }

BOOL8 PIXROW::extend ( IMAGELINE imlines,
BOX imbox,
PIXROW prev,
PIXROW next,
INT16  foreground_colour 
)

Do one (1) pixel extension in each direction to cover extra black area.

Parameters:
imlines box of imlines extnt
imbox coordinates of bounding box
prev for prev blob
next for next blob
foreground_colour 0 or 1
Returns:
TRUE if extension was done

Definition at line 230 of file charcut.cpp.

References FALSE, LARGEST, BOX::left(), max, min, ELIST_LINK::next, NULL, IMAGELINE::pixels, BOX::right(), row_count, SMALLEST, and TRUE.

Referenced by char_clip_word().

00235                                               {
00236   INT16 i;
00237   INT16 x_offset = imbox.left ();
00238   INT16 limit;
00239   INT16 left_limit;
00240   INT16 right_limit;
00241   UINT8 *pixels = NULL;
00242   UINT8 *pixels_below = NULL;    //row below current
00243   UINT8 *pixels_above = NULL;    //row above current
00244   BOOL8 changed = FALSE;
00245 
00246   pixels_above = imlines[0].pixels;
00247   for (i = 0; i < row_count; i++) {
00248     pixels_below = pixels;
00249     pixels = pixels_above;
00250     if (i < (row_count - 1))
00251       pixels_above = imlines[i + 1].pixels;
00252     else
00253       pixels_above = NULL;
00254 
00255     /* Extend Left by one pixel*/
00256     if (prev == NULL || prev->max[i] < prev->min[i])
00257       limit = imbox.left ();
00258     else
00259       limit = prev->max[i] + 1;
00260     if ((min[i] <= max[i]) &&
00261       (min[i] > limit) &&
00262     (pixels[min[i] - 1 - x_offset] == foreground_colour)) {
00263       min[i]--;
00264       changed = TRUE;
00265     }
00266 
00267     /* Extend Right by one pixel*/
00268     if (next == NULL || next->min[i] > next->max[i])
00269       limit = imbox.right () - 1;//-1 to index inside pix
00270     else
00271       limit = next->min[i] - 1;
00272     if ((min[i] <= max[i]) &&
00273       (max[i] < limit) &&
00274     (pixels[max[i] + 1 - x_offset] == foreground_colour)) {
00275       max[i]++;
00276       changed = TRUE;
00277     }
00278 
00279     /* Extend down by one row */
00280     if (pixels_below != NULL) {
00281       if (min[i] < min[i - 1]) { //row goes left of row below
00282         if (prev == NULL || prev->max[i - 1] < prev->min[i - 1])
00283           left_limit = min[i];
00284         else
00285           left_limit = LARGEST (min[i], prev->max[i - 1] + 1);
00286       }
00287       else
00288         left_limit = min[i - 1];
00289 
00290       if (max[i] > max[i - 1]) { //row goes right of row below
00291         if (next == NULL || next->min[i - 1] > next->max[i - 1])
00292           right_limit = max[i];
00293         else
00294           right_limit = SMALLEST (max[i], next->min[i - 1] - 1);
00295       }
00296       else
00297         right_limit = max[i - 1];
00298 
00299       while ((left_limit <= right_limit) &&
00300         (pixels_below[left_limit - x_offset] != foreground_colour))
00301         left_limit++;            //find black extremity
00302 
00303       if ((left_limit <= right_limit) && (left_limit < min[i - 1])) {
00304         min[i - 1] = left_limit; //widen left if poss
00305         changed = TRUE;
00306       }
00307 
00308       while ((left_limit <= right_limit) &&
00309         (pixels_below[right_limit - x_offset] != foreground_colour))
00310         right_limit--;           //find black extremity
00311 
00312       if ((left_limit <= right_limit) && (right_limit > max[i - 1])) {
00313         max[i - 1] = right_limit;//widen right if poss
00314         changed = TRUE;
00315       }
00316     }
00317 
00318     /* Extend up by one row */
00319     if (pixels_above != NULL) {
00320       if (min[i] < min[i + 1]) { //row goes left of row above
00321         if (prev == NULL || prev->min[i + 1] > prev->max[i + 1])
00322           left_limit = min[i];
00323         else
00324           left_limit = LARGEST (min[i], prev->max[i + 1] + 1);
00325       }
00326       else
00327         left_limit = min[i + 1];
00328 
00329       if (max[i] > max[i + 1]) { //row goes right of row above
00330         if (next == NULL || next->min[i + 1] > next->max[i + 1])
00331           right_limit = max[i];
00332         else
00333           right_limit = SMALLEST (max[i], next->min[i + 1] - 1);
00334       }
00335       else
00336         right_limit = max[i + 1];
00337 
00338       while ((left_limit <= right_limit) &&
00339         (pixels_above[left_limit - x_offset] != foreground_colour))
00340         left_limit++;            //find black extremity
00341 
00342       if ((left_limit <= right_limit) && (left_limit < min[i + 1])) {
00343         min[i + 1] = left_limit; //widen left if poss
00344         changed = TRUE;
00345       }
00346 
00347       while ((left_limit <= right_limit) &&
00348         (pixels_above[right_limit - x_offset] != foreground_colour))
00349         right_limit--;           //find black extremity
00350 
00351       if ((left_limit <= right_limit) && (right_limit > max[i + 1])) {
00352         max[i + 1] = right_limit;//widen right if poss
00353         changed = TRUE;
00354       }
00355     }
00356   }
00357   return changed;
00358 }

void PIXROW::plot ( WINDOW  fd  )  const

Draw the PIXROW.

Parameters:
fd where to paint
Returns:
none

Definition at line 106 of file charcut.cpp.

References max, min, rectangle, row_count, and row_offset.

00107                          {
00108   INT16 i;
00109   INT16 y_coord;
00110 
00111   for (i = 0; i < row_count; i++) {
00112     y_coord = row_offset + i;
00113     if (min[i] <= max[i]) {
00114       rectangle (fd, min[i], y_coord, max[i] + 1, y_coord + 1);
00115     }
00116   }
00117 }

void ELIST_LINK::serialise_asc ( FILE *  f  )  [inherited]

Generates an error, as it should never be called.

Definition at line 32 of file elst.cpp.

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

00033                                         {
00034   SERIALISE_LINKS.error ("ELIST_LINK::serialise_asc", ABORT,
00035     "Don't call this, override!");
00036 }


Member Data Documentation

INT16* PIXROW::max

Definition at line 45 of file charcut.h.

Referenced by bounding_box(), char_clip_image(), contract(), extend(), PIXROW(), plot(), and ~PIXROW().

INT16* PIXROW::min

Definition at line 44 of file charcut.h.

Referenced by bounding_box(), char_clip_image(), contract(), extend(), PIXROW(), plot(), and ~PIXROW().

INT16 PIXROW::row_count

Definition at line 43 of file charcut.h.

Referenced by bounding_box(), char_clip_image(), contract(), extend(), PIXROW(), and plot().

INT16 PIXROW::row_offset

Definition at line 42 of file charcut.h.

Referenced by bounding_box(), char_clip_image(), PIXROW(), and plot().


The documentation for this class was generated from the following files:
Generated on Wed Feb 28 19:49:33 2007 for Tesseract by  doxygen 1.5.1