QSPLINE Class Reference

#include <quspline.h>

List of all members.


Detailed Description

Quadratic splines used in computing baseline?

Definition at line 35 of file quspline.h.

Public Member Functions

Private Member Functions

Private Attributes

Friends


Constructor & Destructor Documentation

QSPLINE::QSPLINE (  )  [inline]

Definition at line 47 of file quspline.h.

References NULL, quadratics, segments, and xcoords.

00047               {  //empty constructor
00048       segments = 0;
00049       xcoords = NULL;            //everything empty
00050       quadratics = NULL;
00051     }

QSPLINE::QSPLINE ( const QSPLINE src  ) 

Constructor to build a QSPLINE from another.

Definition at line 122 of file quspline.cpp.

References NULL, quadratics, segments, and xcoords.

00123                                      {
00124   segments = 0;
00125   xcoords = NULL;
00126   quadratics = NULL;
00127   *this = src;
00128 }

QSPLINE::QSPLINE ( INT32  count,
INT32 xstarts,
double *  coeffs 
)

Constructor to build a QSPLINE given the components used in the old code.

Definition at line 30 of file quspline.cpp.

References alloc_mem(), quadratics, segments, and xcoords.

00034                   {
00035   INT32 index;                   //segment index
00036 
00037                                  //get memory
00038   xcoords = (INT32 *) alloc_mem ((count + 1) * sizeof (INT32));
00039   quadratics = (QUAD_COEFFS *) alloc_mem (count * sizeof (QUAD_COEFFS));
00040   segments = count;
00041   for (index = 0; index < segments; index++) {
00042                                  //copy them
00043     xcoords[index] = xstarts[index];
00044     quadratics[index] = QUAD_COEFFS (coeffs[index * 3],
00045       coeffs[index * 3 + 1],
00046       coeffs[index * 3 + 2]);
00047   }
00048                                  //right edge
00049   xcoords[index] = xstarts[index];
00050 }

QSPLINE::~QSPLINE (  ) 

Destroy a QSPLINE.

Definition at line 134 of file quspline.cpp.

References free_mem(), NULL, quadratics, and xcoords.

00135   {
00136   if (xcoords != NULL) {
00137     free_mem(xcoords); 
00138     xcoords = NULL;
00139   }
00140   if (quadratics != NULL) {
00141     free_mem(quadratics); 
00142     quadratics = NULL;
00143   }
00144 }

QSPLINE::QSPLINE ( int  xstarts[],
int  segcount,
int  xcoords[],
int  ycoords[],
int  blobcount,
int  degree 
)

Constructor to build a QSPLINE by appproximation of points.

Definition at line 56 of file quspline.cpp.

References QUAD_COEFFS::a, QLSQ::add(), alloc_mem(), QUAD_COEFFS::b, QUAD_COEFFS::c, QLSQ::clear(), QLSQ::fit(), free_mem(), QLSQ::get_a(), QLSQ::get_b(), QLSQ::get_c(), quadratics, segments, and xcoords.

00062   {
00063   register int pointindex;       /*no along text line */
00064   register int segment;          /*segment no */
00065   INT32 *ptcounts;               //no in each segment
00066   QLSQ qlsq;                     /*accumulator */
00067 
00068   segments = segcount;
00069   xcoords = (INT32 *) alloc_mem ((segcount + 1) * sizeof (INT32));
00070   ptcounts = (INT32 *) alloc_mem ((segcount + 1) * sizeof (INT32));
00071   quadratics = (QUAD_COEFFS *) alloc_mem (segcount * sizeof (QUAD_COEFFS));
00072   memmove (xcoords, xstarts, (segcount + 1) * sizeof (INT32));
00073   ptcounts[0] = 0;               /*none in any yet */
00074   for (segment = 0, pointindex = 0; pointindex < pointcount; pointindex++) {
00075     while (segment < segcount && xpts[pointindex] >= xstarts[segment]) {
00076       segment++;                 /*try next segment */
00077                                  /*cumulative counts */
00078       ptcounts[segment] = ptcounts[segment - 1];
00079     }
00080     ptcounts[segment]++;         /*no in previous partition */
00081   }
00082   while (segment < segcount) {
00083     segment++;
00084                                  /*zero the rest */
00085     ptcounts[segment] = ptcounts[segment - 1];
00086   }
00087 
00088   for (segment = 0; segment < segcount; segment++) {
00089     qlsq.clear ();
00090                                  /*first blob */
00091     pointindex = ptcounts[segment];
00092     if (pointindex > 0
00093       && xpts[pointindex] != xpts[pointindex - 1]
00094       && xpts[pointindex] != xstarts[segment])
00095       qlsq.add (xstarts[segment],
00096         ypts[pointindex - 1]
00097         + (ypts[pointindex] - ypts[pointindex - 1])
00098         * (xstarts[segment] - xpts[pointindex - 1])
00099         / (xpts[pointindex] - xpts[pointindex - 1]));
00100     for (; pointindex < ptcounts[segment + 1]; pointindex++) {
00101       qlsq.add (xpts[pointindex], ypts[pointindex]);
00102     }
00103     if (pointindex > 0 && pointindex < pointcount
00104       && xpts[pointindex] != xstarts[segment + 1])
00105       qlsq.add (xstarts[segment + 1],
00106         ypts[pointindex - 1]
00107         + (ypts[pointindex] - ypts[pointindex - 1])
00108         * (xstarts[segment + 1] - xpts[pointindex - 1])
00109         / (xpts[pointindex] - xpts[pointindex - 1]));
00110     qlsq.fit (degree);
00111     quadratics[segment].a = qlsq.get_a ();
00112     quadratics[segment].b = qlsq.get_b ();
00113     quadratics[segment].c = qlsq.get_c ();
00114   }
00115   free_mem(ptcounts); 
00116 }


Member Function Documentation

void QSPLINE::de_dump ( FILE *  f  )  [inline]

Definition at line 97 of file quspline.h.

References de_serialise_bytes(), quadratics, segments, and xcoords.

Referenced by ROW::de_dump().

00098                           {
00099       xcoords = (INT32 *) de_serialise_bytes (f,
00100         (segments + 1) * sizeof (INT32));
00101       quadratics = (QUAD_COEFFS *) de_serialise_bytes (f,
00102         segments *
00103         sizeof (QUAD_COEFFS));
00104     }

void QSPLINE::dump ( FILE *  f  )  [inline]

Definition at line 91 of file quspline.h.

References quadratics, segments, serialise_bytes(), and xcoords.

Referenced by ROW::dump().

00092                        {
00093       serialise_bytes (f, (void *) xcoords, (segments + 1) * sizeof (INT32));
00094       serialise_bytes (f, (void *) quadratics, segments * sizeof (QUAD_COEFFS));
00095     }

void QSPLINE::extrapolate ( double  gradient,
int  left,
int  right 
)

Extrapolates the spline linearly using the same gradient as the quadratic has at either end.

Definition at line 268 of file quspline.cpp.

References QUAD_COEFFS::a, alloc_mem(), QUAD_COEFFS::b, QUAD_COEFFS::c, free_mem(), quadratics, segments, xcoords, and y().

Referenced by find_textlines().

00272                            {
00273   register int segment;          /*current segment of spline */
00274   int dest_segment;              //dest index
00275   int *xstarts;                  //new boundaries
00276   QUAD_COEFFS *quads;            //new ones
00277   int increment;                 //in size
00278 
00279   increment = xmin < xcoords[0] ? 1 : 0;
00280   if (xmax > xcoords[segments])
00281     increment++;
00282   if (increment == 0)
00283     return;
00284   xstarts = (int *) alloc_mem ((segments + 1 + increment) * sizeof (int));
00285   quads =
00286     (QUAD_COEFFS *) alloc_mem ((segments + increment) * sizeof (QUAD_COEFFS));
00287   if (xmin < xcoords[0]) {
00288     xstarts[0] = xmin;
00289     quads[0].a = 0;
00290     quads[0].b = gradient;
00291     quads[0].c = y (xcoords[0]) - quads[0].b * xcoords[0];
00292     dest_segment = 1;
00293   }
00294   else
00295     dest_segment = 0;
00296   for (segment = 0; segment < segments; segment++) {
00297     xstarts[dest_segment] = xcoords[segment];
00298     quads[dest_segment] = quadratics[segment];
00299     dest_segment++;
00300   }
00301   xstarts[dest_segment] = xcoords[segment];
00302   if (xmax > xcoords[segments]) {
00303     quads[dest_segment].a = 0;
00304     quads[dest_segment].b = gradient;
00305     quads[dest_segment].c = y (xcoords[segments])
00306       - quads[dest_segment].b * xcoords[segments];
00307     dest_segment++;
00308     xstarts[dest_segment] = xmax + 1;
00309   }
00310   segments = dest_segment;
00311   free_mem(xcoords); 
00312   free_mem(quadratics); 
00313   xcoords = (INT32 *) xstarts;
00314   quadratics = quads;
00315 }

QSPLINE::make_serialise ( QSPLINE   ) 

void QSPLINE::move ( ICOORD  vec  ) 

Reposition spline by vector.

Definition at line 227 of file quspline.cpp.

References QUAD_COEFFS::move(), quadratics, segments, and xcoords.

Referenced by ROW::move().

00229                     {
00230   INT32 segment;                 //index of segment
00231   INT16 x_shift = vec.x ();
00232 
00233   for (segment = 0; segment < segments; segment++) {
00234     xcoords[segment] += x_shift;
00235     quadratics[segment].move (vec);
00236   }
00237   xcoords[segment] += x_shift;
00238 }

BOOL8 QSPLINE::overlap ( QSPLINE spline2,
double  fraction 
)

Return TRUE if spline2 overlaps this by no more than fraction less than the bounds of this.

Definition at line 245 of file quspline.cpp.

References FALSE, segments, TRUE, and xcoords.

Referenced by correlate_neighbours().

00248                         {
00249   int leftlimit;                 /*common left limit */
00250   int rightlimit;                /*common right limit */
00251 
00252   leftlimit = xcoords[1];
00253   rightlimit = xcoords[segments - 1];
00254                                  /*or too non-overlap */
00255   if (spline2->segments < 3 || spline2->xcoords[1] > leftlimit + fraction * (rightlimit - leftlimit)
00256     || spline2->xcoords[spline2->segments - 1] < rightlimit
00257     - fraction * (rightlimit - leftlimit))
00258     return FALSE;
00259   else
00260     return TRUE;
00261 }

void QSPLINE::plot ( WINDOW  window,
COLOUR  colour 
) const

Draw the QSPLINE in the given colour.

Definition at line 322 of file quspline.cpp.

References draw2d, line_color_index, move2d, QSPLINE_PRECISION, quadratics, segments, step(), xcoords, and y().

Referenced by find_textlines(), and ROW::plot_baseline().

00325                           {
00326   INT32 segment;                 //index of segment
00327   INT16 step;                    //index of poly piece
00328   double increment;              //x increment
00329   double x;                      //x coord
00330 
00331   line_color_index(window, colour); 
00332   for (segment = 0; segment < segments; segment++) {
00333     increment =
00334       (double) (xcoords[segment + 1] -
00335       xcoords[segment]) / QSPLINE_PRECISION;
00336     x = xcoords[segment];
00337     for (step = 0; step <= QSPLINE_PRECISION; step++) {
00338       if (segment == 0 && step == 0)
00339         move2d (window, x, quadratics[segment].y (x));
00340       else
00341         draw2d (window, x, quadratics[segment].y (x));
00342       x += increment;
00343     }
00344   }
00345 }

void QSPLINE::prep_serialise (  )  [inline]

Definition at line 88 of file quspline.h.

Referenced by ROW::prep_serialise().

00088                           {  //set ptrs to counts
00089     }                            //not required

INT32 QSPLINE::spline_index ( double  x  )  const [private]

Return the index to the largest xcoord not greater than x.

Definition at line 204 of file quspline.cpp.

References segments, and xcoords.

Referenced by step(), and y().

00206                                    {
00207   INT32 index;                   //segment index
00208   INT32 bottom;                  //bottom of range
00209   INT32 top;                     //top of range
00210 
00211   bottom = 0;
00212   top = segments;
00213   while (top - bottom > 1) {
00214     index = (top + bottom) / 2;  //centre of range
00215     if (x >= xcoords[index])
00216       bottom = index;            //new min
00217     else
00218       top = index;               //new max
00219   }
00220   return bottom;
00221 }

double QSPLINE::step ( double  x1,
double  x2 
)

Return the total of the step functions between the given coords.

Definition at line 169 of file quspline.cpp.

References quadratics, spline_index(), xcoords, and y().

Referenced by get_ydiffs(), and plot().

00171                                 {
00172   int index1, index2;            //indices of coords
00173   double total;                  /*total steps */
00174 
00175   index1 = spline_index (x1);
00176   index2 = spline_index (x2);
00177   total = 0;
00178   while (index1 < index2) {
00179     total +=
00180       (double) quadratics[index1 + 1].y ((float) xcoords[index1 + 1]);
00181     total -= (double) quadratics[index1].y ((float) xcoords[index1 + 1]);
00182     index1++;                    /*next segment */
00183   }
00184   return total;                  /*total steps */
00185 }

double QSPLINE::y ( double  x  )  const

Return the y value at the given x value.

Definition at line 191 of file quspline.cpp.

References quadratics, spline_index(), and QUAD_COEFFS::y().

Referenced by ROW::base_line(), compute_row_xheight(), extrapolate(), find_lesser_parts(), get_ydiffs(), make_first_baseline(), make_holed_baseline(), most_overlapping_row(), plot(), reduced_box_for_blob(), step(), suspected_punct_blob(), and try_doc_fixed().

00193                          {
00194   INT32 index;                   //segment index
00195 
00196   index = spline_index (x);
00197   return quadratics[index].y (x);//in correct segment
00198 }


Friends And Related Function Documentation

void make_first_baseline ( BOX ,
int  ,
int *  ,
int *  ,
QSPLINE ,
QSPLINE ,
float   
) [friend]

void make_holed_baseline ( BOX ,
int  ,
QSPLINE ,
QSPLINE ,
float   
) [friend]

void tweak_row_baseline ( ROW  )  [friend]

Remove empties.

Shift baseline to fit the blobs more accurately where they are close enough.

Definition at line 886 of file tordmain.cpp.

00888                          {
00889   BOX blob_box;                  //bounding box
00890   C_BLOB *blob;                  //current blob
00891   WERD *word;                    //current word
00892   INT32 blob_count;              //no of blobs
00893   INT32 src_index;               //source segment
00894   INT32 dest_index;              //destination segment
00895   INT32 *xstarts;                //spline segments
00896   double *coeffs;                //spline coeffs
00897   float ydiff;                   //baseline error
00898   float x_centre;                //centre of blob
00899                                  //words of row
00900   WERD_IT word_it = row->word_list ();
00901   C_BLOB_IT blob_it;             //blob iterator
00902 
00903   blob_count = 0;
00904   for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
00905     word = word_it.data ();      //current word
00906                                  //get total blobs
00907     blob_count += word->cblob_list ()->length ();
00908   }
00909   if (blob_count == 0)
00910     return;
00911   xstarts =
00912     (INT32 *) alloc_mem ((blob_count + row->baseline.segments + 1) *
00913     sizeof (INT32));
00914   coeffs =
00915     (double *) alloc_mem ((blob_count + row->baseline.segments) * 3 *
00916     sizeof (double));
00917 
00918   src_index = 0;
00919   dest_index = 0;
00920   xstarts[0] = row->baseline.xcoords[0];
00921   for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
00922     word = word_it.data ();      //current word
00923                                  //blobs in word
00924     blob_it.set_to_list (word->cblob_list ());
00925     for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00926     blob_it.forward ()) {
00927       blob = blob_it.data ();
00928       blob_box = blob->bounding_box ();
00929       x_centre = (blob_box.left () + blob_box.right ()) / 2.0;
00930       ydiff = blob_box.bottom () - row->base_line (x_centre);
00931       if (ydiff < 0)
00932         ydiff = -ydiff / row->x_height ();
00933       else
00934         ydiff = ydiff / row->x_height ();
00935       if (ydiff < textord_blshift_maxshift
00936         && blob_box.height () / row->x_height () >
00937       textord_blshift_xfraction) {
00938         if (xstarts[dest_index] >= x_centre)
00939           xstarts[dest_index] = blob_box.left ();
00940         coeffs[dest_index * 3] = 0;
00941         coeffs[dest_index * 3 + 1] = 0;
00942         coeffs[dest_index * 3 + 2] = blob_box.bottom ();
00943         //shift it
00944         dest_index++;
00945         xstarts[dest_index] = blob_box.right () + 1;
00946       }
00947       else {
00948         if (xstarts[dest_index] <= x_centre) {
00949           while (row->baseline.xcoords[src_index + 1] <= x_centre
00950           && src_index < row->baseline.segments - 1) {
00951             if (row->baseline.xcoords[src_index + 1] >
00952             xstarts[dest_index]) {
00953               coeffs[dest_index * 3] =
00954                 row->baseline.quadratics[src_index].a;
00955               coeffs[dest_index * 3 + 1] =
00956                 row->baseline.quadratics[src_index].b;
00957               coeffs[dest_index * 3 + 2] =
00958                 row->baseline.quadratics[src_index].c;
00959               dest_index++;
00960               xstarts[dest_index] =
00961                 row->baseline.xcoords[src_index + 1];
00962             }
00963             src_index++;
00964           }
00965           coeffs[dest_index * 3] =
00966             row->baseline.quadratics[src_index].a;
00967           coeffs[dest_index * 3 + 1] =
00968             row->baseline.quadratics[src_index].b;
00969           coeffs[dest_index * 3 + 2] =
00970             row->baseline.quadratics[src_index].c;
00971           dest_index++;
00972           xstarts[dest_index] = row->baseline.xcoords[src_index + 1];
00973         }
00974       }
00975     }
00976   }
00977   while (src_index < row->baseline.segments
00978     && row->baseline.xcoords[src_index + 1] <= xstarts[dest_index])
00979     src_index++;
00980   while (src_index < row->baseline.segments) {
00981     coeffs[dest_index * 3] = row->baseline.quadratics[src_index].a;
00982     coeffs[dest_index * 3 + 1] = row->baseline.quadratics[src_index].b;
00983     coeffs[dest_index * 3 + 2] = row->baseline.quadratics[src_index].c;
00984     dest_index++;
00985     src_index++;
00986     xstarts[dest_index] = row->baseline.xcoords[src_index];
00987   }
00988                                  //turn to spline
00989   row->baseline = QSPLINE (dest_index, xstarts, coeffs);
00990   free_mem(xstarts);
00991   free_mem(coeffs);
00992 }


Member Data Documentation

QUAD_COEFFS* QSPLINE::quadratics [private]

Definition at line 116 of file quspline.h.

Referenced by de_dump(), dump(), extrapolate(), move(), plot(), QSPLINE(), step(), tweak_row_baseline(), y(), and ~QSPLINE().

INT32 QSPLINE::segments [private]

Definition at line 114 of file quspline.h.

Referenced by de_dump(), dump(), extrapolate(), make_first_baseline(), make_holed_baseline(), move(), overlap(), plot(), QSPLINE(), spline_index(), and tweak_row_baseline().

INT32* QSPLINE::xcoords [private]

Definition at line 115 of file quspline.h.

Referenced by de_dump(), dump(), extrapolate(), make_first_baseline(), make_holed_baseline(), move(), overlap(), plot(), QSPLINE(), spline_index(), step(), tweak_row_baseline(), and ~QSPLINE().


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