Tesseract
3.02
|
#include <quspline.h>
Public Member Functions | |
QSPLINE () | |
QSPLINE (const QSPLINE &src) | |
QSPLINE (inT32 count, inT32 *xstarts, double *coeffs) | |
~QSPLINE () | |
QSPLINE (int xstarts[], int segcount, int xcoords[], int ycoords[], int blobcount, int degree) | |
double | step (double x1, double x2) |
double | y (double x) const |
void | move (ICOORD vec) |
BOOL8 | overlap (QSPLINE *spline2, double fraction) |
void | extrapolate (double gradient, int left, int right) |
void | plot (ScrollView *window, ScrollView::Color colour) const |
QSPLINE & | operator= (const QSPLINE &source) |
Friends | |
void | make_first_baseline (TBOX *, int, int *, int *, QSPLINE *, QSPLINE *, float) |
void | make_holed_baseline (TBOX *, int, QSPLINE *, QSPLINE *, float) |
void | tweak_row_baseline (ROW *, double, double) |
Definition at line 30 of file quspline.h.
QSPLINE::QSPLINE | ( | ) | [inline] |
Definition at line 42 of file quspline.h.
QSPLINE::QSPLINE | ( | const QSPLINE & | src | ) |
Definition at line 136 of file quspline.cpp.
Definition at line 38 of file quspline.cpp.
{ inT32 index; //segment index //get memory xcoords = (inT32 *) alloc_mem ((count + 1) * sizeof (inT32)); quadratics = (QUAD_COEFFS *) alloc_mem (count * sizeof (QUAD_COEFFS)); segments = count; for (index = 0; index < segments; index++) { //copy them xcoords[index] = xstarts[index]; quadratics[index] = QUAD_COEFFS (coeffs[index * 3], coeffs[index * 3 + 1], coeffs[index * 3 + 2]); } //right edge xcoords[index] = xstarts[index]; }
QSPLINE::~QSPLINE | ( | ) |
QSPLINE::QSPLINE | ( | int | xstarts[], |
int | segcount, | ||
int | xcoords[], | ||
int | ycoords[], | ||
int | blobcount, | ||
int | degree | ||
) |
Definition at line 67 of file quspline.cpp.
{ register int pointindex; /*no along text line */ register int segment; /*segment no */ inT32 *ptcounts; //no in each segment QLSQ qlsq; /*accumulator */ segments = segcount; xcoords = (inT32 *) alloc_mem ((segcount + 1) * sizeof (inT32)); ptcounts = (inT32 *) alloc_mem ((segcount + 1) * sizeof (inT32)); quadratics = (QUAD_COEFFS *) alloc_mem (segcount * sizeof (QUAD_COEFFS)); memmove (xcoords, xstarts, (segcount + 1) * sizeof (inT32)); ptcounts[0] = 0; /*none in any yet */ for (segment = 0, pointindex = 0; pointindex < pointcount; pointindex++) { while (segment < segcount && xpts[pointindex] >= xstarts[segment]) { segment++; /*try next segment */ /*cumulative counts */ ptcounts[segment] = ptcounts[segment - 1]; } ptcounts[segment]++; /*no in previous partition */ } while (segment < segcount) { segment++; /*zero the rest */ ptcounts[segment] = ptcounts[segment - 1]; } for (segment = 0; segment < segcount; segment++) { qlsq.clear (); /*first blob */ pointindex = ptcounts[segment]; if (pointindex > 0 && xpts[pointindex] != xpts[pointindex - 1] && xpts[pointindex] != xstarts[segment]) qlsq.add (xstarts[segment], ypts[pointindex - 1] + (ypts[pointindex] - ypts[pointindex - 1]) * (xstarts[segment] - xpts[pointindex - 1]) / (xpts[pointindex] - xpts[pointindex - 1])); for (; pointindex < ptcounts[segment + 1]; pointindex++) { qlsq.add (xpts[pointindex], ypts[pointindex]); } if (pointindex > 0 && pointindex < pointcount && xpts[pointindex] != xstarts[segment + 1]) qlsq.add (xstarts[segment + 1], ypts[pointindex - 1] + (ypts[pointindex] - ypts[pointindex - 1]) * (xstarts[segment + 1] - xpts[pointindex - 1]) / (xpts[pointindex] - xpts[pointindex - 1])); qlsq.fit (degree); quadratics[segment].a = qlsq.get_a (); quadratics[segment].b = qlsq.get_b (); quadratics[segment].c = qlsq.get_c (); } free_mem(ptcounts); }
void QSPLINE::extrapolate | ( | double | gradient, |
int | left, | ||
int | right | ||
) |
Definition at line 306 of file quspline.cpp.
{ register int segment; /*current segment of spline */ int dest_segment; //dest index int *xstarts; //new boundaries QUAD_COEFFS *quads; //new ones int increment; //in size increment = xmin < xcoords[0] ? 1 : 0; if (xmax > xcoords[segments]) increment++; if (increment == 0) return; xstarts = (int *) alloc_mem ((segments + 1 + increment) * sizeof (int)); quads = (QUAD_COEFFS *) alloc_mem ((segments + increment) * sizeof (QUAD_COEFFS)); if (xmin < xcoords[0]) { xstarts[0] = xmin; quads[0].a = 0; quads[0].b = gradient; quads[0].c = y (xcoords[0]) - quads[0].b * xcoords[0]; dest_segment = 1; } else dest_segment = 0; for (segment = 0; segment < segments; segment++) { xstarts[dest_segment] = xcoords[segment]; quads[dest_segment] = quadratics[segment]; dest_segment++; } xstarts[dest_segment] = xcoords[segment]; if (xmax > xcoords[segments]) { quads[dest_segment].a = 0; quads[dest_segment].b = gradient; quads[dest_segment].c = y (xcoords[segments]) - quads[dest_segment].b * xcoords[segments]; dest_segment++; xstarts[dest_segment] = xmax + 1; } segments = dest_segment; free_mem(xcoords); free_mem(quadratics); xcoords = (inT32 *) xstarts; quadratics = quads; }
void QSPLINE::move | ( | ICOORD | vec | ) |
Definition at line 170 of file quspline.cpp.
{ if (xcoords != NULL) free_mem(xcoords); if (quadratics != NULL) free_mem(quadratics); segments = source.segments; xcoords = (inT32 *) alloc_mem ((segments + 1) * sizeof (inT32)); quadratics = (QUAD_COEFFS *) alloc_mem (segments * sizeof (QUAD_COEFFS)); memmove (xcoords, source.xcoords, (segments + 1) * sizeof (inT32)); memmove (quadratics, source.quadratics, segments * sizeof (QUAD_COEFFS)); return *this; }
Definition at line 280 of file quspline.cpp.
{ int leftlimit; /*common left limit */ int rightlimit; /*common right limit */ leftlimit = xcoords[1]; rightlimit = xcoords[segments - 1]; /*or too non-overlap */ if (spline2->segments < 3 || spline2->xcoords[1] > leftlimit + fraction * (rightlimit - leftlimit) || spline2->xcoords[spline2->segments - 1] < rightlimit - fraction * (rightlimit - leftlimit)) return FALSE; else return TRUE; }
void QSPLINE::plot | ( | ScrollView * | window, |
ScrollView::Color | colour | ||
) | const |
Definition at line 363 of file quspline.cpp.
{ inT32 segment; //index of segment inT16 step; //index of poly piece double increment; //x increment double x; //x coord window->Pen(colour); for (segment = 0; segment < segments; segment++) { increment = (double) (xcoords[segment + 1] - xcoords[segment]) / QSPLINE_PRECISION; x = xcoords[segment]; for (step = 0; step <= QSPLINE_PRECISION; step++) { if (segment == 0 && step == 0) window->SetCursor(x, quadratics[segment].y (x)); else window->DrawTo(x, quadratics[segment].y (x)); x += increment; } } }
double QSPLINE::step | ( | double | x1, |
double | x2 | ||
) |
Definition at line 192 of file quspline.cpp.
{ int index1, index2; //indices of coords double total; /*total steps */ index1 = spline_index (x1); index2 = spline_index (x2); total = 0; while (index1 < index2) { total += (double) quadratics[index1 + 1].y ((float) xcoords[index1 + 1]); total -= (double) quadratics[index1].y ((float) xcoords[index1 + 1]); index1++; /*next segment */ } return total; /*total steps */ }
double QSPLINE::y | ( | double | x | ) | const |
Definition at line 217 of file quspline.cpp.
void tweak_row_baseline | ( | ROW * | , |
double | , | ||
double | |||
) | [friend] |
Definition at line 680 of file tordmain.cpp.
{ TBOX blob_box; //bounding box C_BLOB *blob; //current blob WERD *word; //current word inT32 blob_count; //no of blobs inT32 src_index; //source segment inT32 dest_index; //destination segment inT32 *xstarts; //spline segments double *coeffs; //spline coeffs float ydiff; //baseline error float x_centre; //centre of blob //words of row WERD_IT word_it = row->word_list (); C_BLOB_IT blob_it; //blob iterator blob_count = 0; for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) { word = word_it.data (); //current word //get total blobs blob_count += word->cblob_list ()->length (); } if (blob_count == 0) return; xstarts = (inT32 *) alloc_mem ((blob_count + row->baseline.segments + 1) * sizeof (inT32)); coeffs = (double *) alloc_mem ((blob_count + row->baseline.segments) * 3 * sizeof (double)); src_index = 0; dest_index = 0; xstarts[0] = row->baseline.xcoords[0]; for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) { word = word_it.data (); //current word //blobs in word blob_it.set_to_list (word->cblob_list ()); for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) { blob = blob_it.data (); blob_box = blob->bounding_box (); x_centre = (blob_box.left () + blob_box.right ()) / 2.0; ydiff = blob_box.bottom () - row->base_line (x_centre); if (ydiff < 0) ydiff = -ydiff / row->x_height (); else ydiff = ydiff / row->x_height (); if (ydiff < blshift_maxshift && blob_box.height () / row->x_height () > blshift_xfraction) { if (xstarts[dest_index] >= x_centre) xstarts[dest_index] = blob_box.left (); coeffs[dest_index * 3] = 0; coeffs[dest_index * 3 + 1] = 0; coeffs[dest_index * 3 + 2] = blob_box.bottom (); //shift it dest_index++; xstarts[dest_index] = blob_box.right () + 1; } else { if (xstarts[dest_index] <= x_centre) { while (row->baseline.xcoords[src_index + 1] <= x_centre && src_index < row->baseline.segments - 1) { if (row->baseline.xcoords[src_index + 1] > xstarts[dest_index]) { coeffs[dest_index * 3] = row->baseline.quadratics[src_index].a; coeffs[dest_index * 3 + 1] = row->baseline.quadratics[src_index].b; coeffs[dest_index * 3 + 2] = row->baseline.quadratics[src_index].c; dest_index++; xstarts[dest_index] = row->baseline.xcoords[src_index + 1]; } src_index++; } coeffs[dest_index * 3] = row->baseline.quadratics[src_index].a; coeffs[dest_index * 3 + 1] = row->baseline.quadratics[src_index].b; coeffs[dest_index * 3 + 2] = row->baseline.quadratics[src_index].c; dest_index++; xstarts[dest_index] = row->baseline.xcoords[src_index + 1]; } } } } while (src_index < row->baseline.segments && row->baseline.xcoords[src_index + 1] <= xstarts[dest_index]) src_index++; while (src_index < row->baseline.segments) { coeffs[dest_index * 3] = row->baseline.quadratics[src_index].a; coeffs[dest_index * 3 + 1] = row->baseline.quadratics[src_index].b; coeffs[dest_index * 3 + 2] = row->baseline.quadratics[src_index].c; dest_index++; src_index++; xstarts[dest_index] = row->baseline.xcoords[src_index]; } //turn to spline row->baseline = QSPLINE (dest_index, xstarts, coeffs); free_mem(xstarts); free_mem(coeffs); }