ccstruct/blobbox.cpp File Reference

#include "mfcpch.h"
#include "blobbox.h"

Go to the source code of this file.

Defines

Functions


Define Documentation

#define EXTERN

Definition at line 24 of file blobbox.cpp.

#define PROJECTION_MARGIN   10

Note:
File: blobbox.cpp (Formerly blobnbox.c)
Code for the textord blob class.
Author:
Ray Smith
Date:
Thu Jul 30 09:08:51 BST 1992
 * (C) Copyright 1992, Hewlett-Packard Ltd.
 ** 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 23 of file blobbox.cpp.

Referenced by TO_ROW::compute_vertical_projection().


Function Documentation

BOX box_next ( BLOBNBOX_IT *  it  ) 

Get bounding box.

Compute the bounding box of this blob with merging of x overlaps but no pre-chopping. Then move the iterator on to the start of the next blob.

Definition at line 379 of file blobbox.cpp.

References NULL.

Referenced by block_spacing_stats(), check_pitch_sync(), check_pitch_sync2(), compute_pitch_sd(), compute_pitch_sd2(), GAPMAP::GAPMAP(), isolated_row_stats(), make_illegal_segment(), peek_at_next_gap(), plot_fp_cells(), plot_fp_cells2(), plot_row_cells(), print_pitch_sd(), and row_spacing_stats().

00381               {
00382   BLOBNBOX *blob;                //current blob
00383   BOX result;                    //total box
00384 
00385   blob = it->data ();
00386   result = blob->bounding_box ();
00387   do {
00388     it->forward ();
00389     blob = it->data ();
00390     if (blob->blob () == NULL && blob->cblob () == NULL)
00391                                  //was pre-chopped
00392       result += blob->bounding_box ();
00393   }
00394                                  //until next real blob
00395   while (blob->blob () == NULL && blob->cblob () == NULL || blob->joined_to_prev ());
00396   return result;
00397 }

BOX box_next_pre_chopped ( BLOBNBOX_IT *  it  ) 

Get bounding box.

Compute the bounding box of this blob with merging of x overlaps but WITH pre-chopping. Then move the iterator on to the start of the next pre-chopped blob.

Definition at line 407 of file blobbox.cpp.

Referenced by block_spacing_stats(), get_blob_coords(), isolated_row_stats(), linear_spline_baseline(), row_spacing_stats(), and segment_baseline().

00409                           {
00410   BLOBNBOX *blob;                //current blob
00411   BOX result;                    //total box
00412 
00413   blob = it->data ();
00414   result = blob->bounding_box ();
00415   do {
00416     it->forward ();
00417     blob = it->data ();
00418   }
00419                                  //until next real blob
00420   while (blob->joined_to_prev ());
00421   return result;
00422 }

static void clear_blobnboxes ( BLOBNBOX_LIST *  boxes  )  [static]

Definition at line 715 of file blobbox.cpp.

References NULL.

00715                                                    {
00716   BLOBNBOX_IT it = boxes;
00717   // A BLOBNBOX generally doesn't own its blobs, so if they do, you
00718   // have to delete them explicitly.
00719   for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
00720     BLOBNBOX* box = it.data();
00721     if (box->blob() != NULL)
00722       delete box->blob();
00723     if (box->cblob() != NULL)
00724       delete box->cblob();
00725   }
00726 }

C_BLOB* crotate_cblob ( C_BLOB blob,
FCOORD  rotation 
)

Rotate the copy by the given vector and return a C_BLOB.

Definition at line 356 of file blobbox.cpp.

References C_BLOB::out_list(), and rotation.

Referenced by separate_underlines().

00359                        {
00360   C_OUTLINE_LIST out_list;       //output outlines
00361                                  //input outlines
00362   C_OUTLINE_IT in_it = blob->out_list ();
00363                                  //output outlines
00364   C_OUTLINE_IT out_it = &out_list;
00365 
00366   for (in_it.mark_cycle_pt (); !in_it.cycled_list (); in_it.forward ()) {
00367     out_it.add_after_then_move (new C_OUTLINE (in_it.data (), rotation));
00368   }
00369   return new C_BLOB (&out_list);
00370 }

ELISTIZE ( BLOBNBOX   ) 

Merge this blob with the given blob, which should be after this.

Definition at line 34 of file blobbox.cpp.

References TRUE.

00040                       {
00041   box += nextblob->box;          //merge boxes
00042   nextblob->joined = TRUE;
00043 }

void find_blob_limits ( PBLOB blob,
float  leftx,
float  rightx,
FCOORD  rotation,
float &  ymin,
float &  ymax 
)

Scan the outlines of the blob to locate the y min and max between the given x limits.

Definition at line 121 of file blobbox.cpp.

References MAX_INT32, PBLOB::out_list(), rotation, and POLYPT::vec.

Referenced by reduced_box_for_blob().

00127                                    {
00128   float testy;                   //y intercept
00129   FCOORD pos;                    //rotated
00130   FCOORD vec;
00131   POLYPT *polypt;                //current point
00132                                  //outlines
00133   OUTLINE_IT out_it = blob->out_list ();
00134   POLYPT_IT poly_it;             //outline pts
00135 
00136   ymin = (float) MAX_INT32;
00137   ymax = (float) -MAX_INT32;
00138   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00139                                  //get points
00140     poly_it.set_to_list (out_it.data ()->polypts ());
00141     for (poly_it.mark_cycle_pt (); !poly_it.cycled_list ();
00142     poly_it.forward ()) {
00143       polypt = poly_it.data ();
00144       pos = polypt->pos;
00145       pos.rotate (rotation);
00146       vec = polypt->vec;
00147       vec.rotate (rotation);
00148       if (pos.x () < leftx && pos.x () + vec.x () > leftx
00149       || pos.x () > leftx && pos.x () + vec.x () < leftx) {
00150         testy = pos.y () + vec.y () * (leftx - pos.x ()) / vec.x ();
00151         //intercept of boundary
00152         if (testy < ymin)
00153           ymin = testy;
00154         if (testy > ymax)
00155           ymax = testy;
00156       }
00157       if (pos.x () >= leftx && pos.x () <= rightx) {
00158         if (pos.y () > ymax)
00159           ymax = pos.y ();
00160         if (pos.y () < ymin)
00161           ymin = pos.y ();
00162       }
00163       if (pos.x () > rightx && pos.x () + vec.x () < rightx
00164       || pos.x () < rightx && pos.x () + vec.x () > rightx) {
00165         testy = pos.y () + vec.y () * (rightx - pos.x ()) / vec.x ();
00166         //intercept of boundary
00167         if (testy < ymin)
00168           ymin = testy;
00169         if (testy > ymax)
00170           ymax = testy;
00171       }
00172     }
00173   }
00174 }

void find_cblob_hlimits ( C_BLOB blob,
float  bottomy,
float  topy,
float &  xmin,
float &  xmax 
)

Scan the outlines of the cblob to locate the x min and max between the given y limits.

Definition at line 258 of file blobbox.cpp.

References MAX_INT32, C_BLOB::out_list(), and ICOORD::y().

Referenced by reduced_box_for_blob().

00263                                      {
00264   INT16 stepindex;               //current point
00265   ICOORD pos;                    //current coords
00266   ICOORD vec;                    //rotated step
00267   C_OUTLINE *outline;            //current outline
00268                                  //outlines
00269   C_OUTLINE_IT out_it = blob->out_list ();
00270 
00271   xmin = (float) MAX_INT32;
00272   xmax = (float) -MAX_INT32;
00273   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00274     outline = out_it.data ();
00275     pos = outline->start_pos (); //get coords
00276     for (stepindex = 0; stepindex < outline->pathlength (); stepindex++) {
00277                                  //inside
00278       if (pos.y () >= bottomy && pos.y () <= topy) {
00279         if (pos.x () > xmax)
00280           xmax = pos.x ();
00281         if (pos.x () < xmin)
00282           xmin = pos.x ();
00283       }
00284       vec = outline->step (stepindex);
00285       pos += vec;                //move to next
00286     }
00287   }
00288 }

void find_cblob_limits ( C_BLOB blob,
float  leftx,
float  rightx,
FCOORD  rotation,
float &  ymin,
float &  ymax 
)

Scan the outlines of the cblob to locate the y min and max between the given x limits.

Definition at line 181 of file blobbox.cpp.

References MAX_INT32, C_BLOB::out_list(), ICOORD::rotate(), rotation, and ICOORD::y().

00187                                     {
00188   INT16 stepindex;               //current point
00189   ICOORD pos;                    //current coords
00190   ICOORD vec;                    //rotated step
00191   C_OUTLINE *outline;            //current outline
00192                                  //outlines
00193   C_OUTLINE_IT out_it = blob->out_list ();
00194 
00195   ymin = (float) MAX_INT32;
00196   ymax = (float) -MAX_INT32;
00197   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00198     outline = out_it.data ();
00199     pos = outline->start_pos (); //get coords
00200     pos.rotate (rotation);
00201     for (stepindex = 0; stepindex < outline->pathlength (); stepindex++) {
00202                                  //inside
00203       if (pos.x () >= leftx && pos.x () <= rightx) {
00204         if (pos.y () > ymax)
00205           ymax = pos.y ();
00206         if (pos.y () < ymin)
00207           ymin = pos.y ();
00208       }
00209       vec = outline->step (stepindex);
00210       vec.rotate (rotation);
00211       pos += vec;                //move to next
00212     }
00213   }
00214 }

void find_cblob_vlimits ( C_BLOB blob,
float  leftx,
float  rightx,
float &  ymin,
float &  ymax 
)

Scan the outlines of the cblob to locate the y min and max between the given x limits.

Definition at line 221 of file blobbox.cpp.

References MAX_INT32, C_BLOB::out_list(), and ICOORD::y().

00226                                      {
00227   INT16 stepindex;               //current point
00228   ICOORD pos;                    //current coords
00229   ICOORD vec;                    //rotated step
00230   C_OUTLINE *outline;            //current outline
00231                                  //outlines
00232   C_OUTLINE_IT out_it = blob->out_list ();
00233 
00234   ymin = (float) MAX_INT32;
00235   ymax = (float) -MAX_INT32;
00236   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00237     outline = out_it.data ();
00238     pos = outline->start_pos (); //get coords
00239     for (stepindex = 0; stepindex < outline->pathlength (); stepindex++) {
00240                                  //inside
00241       if (pos.x () >= leftx && pos.x () <= rightx) {
00242         if (pos.y () > ymax)
00243           ymax = pos.y ();
00244         if (pos.y () < ymin)
00245           ymin = pos.y ();
00246       }
00247       vec = outline->step (stepindex);
00248       pos += vec;                //move to next
00249     }
00250   }
00251 }

PBLOB* rotate_blob ( PBLOB blob,
FCOORD  rotation 
)

Poly copy the blob and rotate the copy by the given vector.

Definition at line 294 of file blobbox.cpp.

References PBLOB::out_list(), rotation, and POLYPT::vec.

Referenced by separate_underlines().

00297                     {
00298   PBLOB *copy;                   //copy of blob
00299   POLYPT *polypt;                //current point
00300   OUTLINE_IT out_it;
00301   POLYPT_IT poly_it;             //outline pts
00302 
00303   copy = new PBLOB;
00304   *copy = *blob;                 //deep copy
00305   out_it.set_to_list (copy->out_list ());
00306   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00307                                  //get points
00308     poly_it.set_to_list (out_it.data ()->polypts ());
00309     for (poly_it.mark_cycle_pt (); !poly_it.cycled_list ();
00310     poly_it.forward ()) {
00311       polypt = poly_it.data ();
00312                                  //rotate it
00313       polypt->pos.rotate (rotation);
00314       polypt->vec.rotate (rotation);
00315     }
00316     out_it.data ()->compute_bb ();
00317   }
00318   return copy;
00319 }

PBLOB* rotate_cblob ( C_BLOB blob,
float  xheight,
FCOORD  rotation 
)

Poly copy the blob and rotate the copy by the given vector.

Definition at line 325 of file blobbox.cpp.

References PBLOB::out_list(), rotation, and POLYPT::vec.

Referenced by separate_underlines().

00329                      {
00330   PBLOB *copy;                   //copy of blob
00331   POLYPT *polypt;                //current point
00332   OUTLINE_IT out_it;
00333   POLYPT_IT poly_it;             //outline pts
00334 
00335   copy = new PBLOB (blob, xheight);
00336   out_it.set_to_list (copy->out_list ());
00337   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00338                                  //get points
00339     poly_it.set_to_list (out_it.data ()->polypts ());
00340     for (poly_it.mark_cycle_pt (); !poly_it.cycled_list ();
00341     poly_it.forward ()) {
00342       polypt = poly_it.data ();
00343                                  //rotate it
00344       polypt->pos.rotate (rotation);
00345       polypt->vec.rotate (rotation);
00346     }
00347     out_it.data ()->compute_bb ();
00348   }
00349   return copy;
00350 }

void vertical_blob_projection ( PBLOB blob,
STATS stats 
)

Project outlines.

Compute the vertical projection of a blob from its outlines and add to the given STATS.

Definition at line 544 of file blobbox.cpp.

References PBLOB::out_list(), and vertical_outline_projection().

Referenced by TO_ROW::compute_vertical_projection().

00547                                {
00548                                  //outlines of blob
00549   OUTLINE_IT out_it = blob->out_list ();
00550 
00551   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00552     vertical_outline_projection (out_it.data (), stats);
00553   }
00554 }

void vertical_cblob_projection ( C_BLOB blob,
STATS stats 
)

Project Outlines.

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

Definition at line 650 of file blobbox.cpp.

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

Referenced by TO_ROW::compute_vertical_projection().

00653                                 {
00654                                  //outlines of blob
00655   C_OUTLINE_IT out_it = blob->out_list ();
00656 
00657   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00658     vertical_coutline_projection (out_it.data (), stats);
00659   }
00660 }

void vertical_coutline_projection ( C_OUTLINE outline,
STATS stats 
)

Project Outlines.

Compute the vertical projection of a outline from its outlines and add to the given STATS.

Definition at line 669 of file blobbox.cpp.

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

Referenced by vertical_cblob_projection(), and vertical_coutline_projection().

00672                                    {
00673   ICOORD pos;                    //current point
00674   ICOORD step;                   //edge step
00675   INT32 length;                  //of outline
00676   INT16 stepindex;               //current step
00677   C_OUTLINE_IT out_it = outline->child ();
00678 
00679   pos = outline->start_pos ();
00680   length = outline->pathlength ();
00681   for (stepindex = 0; stepindex < length; stepindex++) {
00682     step = outline->step (stepindex);
00683     if (step.x () > 0) {
00684       if (pitsync_projection_fix)
00685         stats->add (pos.x (), -pos.y ());
00686       else
00687         stats->add (pos.x (), pos.y ());
00688     }
00689     else if (step.x () < 0) {
00690       if (pitsync_projection_fix)
00691         stats->add (pos.x () - 1, pos.y ());
00692       else
00693         stats->add (pos.x () - 1, -pos.y ());
00694     }
00695     pos += step;
00696   }
00697 
00698   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00699     vertical_coutline_projection (out_it.data (), stats);
00700   }
00701 }

void vertical_outline_projection ( OUTLINE outline,
STATS stats 
)

Project Outlines.

Compute the vertical projection of a outline from its outlines and add to the given STATS.

Definition at line 563 of file blobbox.cpp.

References STATS::add(), f, POLYPT::vec, and vertical_outline_projection().

Referenced by vertical_blob_projection(), and vertical_outline_projection().

00566                                   {
00567   POLYPT *polypt;                //current point
00568   INT32 xcoord;                  //current pixel coord
00569   float end_x;                   //end of vec
00570   POLYPT_IT poly_it = outline->polypts ();
00571   OUTLINE_IT out_it = outline->child ();
00572   float ymean;                   //amount to add
00573   float width;                   //amount of x
00574 
00575   for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) {
00576     polypt = poly_it.data ();
00577     end_x = polypt->pos.x () + polypt->vec.x ();
00578     if (polypt->vec.x () > 0) {
00579       for (xcoord = (INT32) floor (polypt->pos.x ());
00580       xcoord < end_x; xcoord++) {
00581         if (polypt->pos.x () < xcoord) {
00582           width = (float) xcoord;
00583           ymean =
00584             polypt->vec.y () * (xcoord -
00585             polypt->pos.x ()) / polypt->vec.x () +
00586             polypt->pos.y ();
00587         }
00588         else {
00589           width = polypt->pos.x ();
00590           ymean = polypt->pos.y ();
00591         }
00592         if (end_x > xcoord + 1) {
00593           width -= xcoord + 1;
00594           ymean +=
00595             polypt->vec.y () * (xcoord + 1 -
00596             polypt->pos.x ()) / polypt->vec.x () +
00597             polypt->pos.y ();
00598         }
00599         else {
00600           width -= end_x;
00601           ymean += polypt->pos.y () + polypt->vec.y ();
00602         }
00603         ymean = ymean * width / 2;
00604         stats->add (xcoord, (INT32) floor (ymean + 0.5));
00605       }
00606     }
00607     else if (polypt->vec.x () < 0) {
00608       for (xcoord = (INT32) floor (end_x);
00609       xcoord < polypt->pos.x (); xcoord++) {
00610         if (polypt->pos.x () > xcoord + 1) {
00611           width = xcoord + 1.0f;
00612           ymean =
00613             polypt->vec.y () * (xcoord + 1 -
00614             polypt->pos.x ()) / polypt->vec.x () +
00615             polypt->pos.y ();
00616         }
00617         else {
00618           width = polypt->pos.x ();
00619           ymean = polypt->pos.y ();
00620         }
00621         if (end_x < xcoord) {
00622           width -= xcoord;
00623           ymean +=
00624             polypt->vec.y () * (xcoord -
00625             polypt->pos.x ()) / polypt->vec.x () +
00626             polypt->pos.y ();
00627         }
00628         else {
00629           width -= end_x;
00630           ymean += polypt->pos.y () + polypt->vec.y ();
00631         }
00632         ymean = ymean * width / 2;
00633         stats->add (xcoord, (INT32) floor (ymean + 0.5));
00634       }
00635     }
00636   }
00637 
00638   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00639     vertical_outline_projection (out_it.data (), stats);
00640   }
00641 }


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