tesseract  5.0.0-alpha-619-ge9db
QSPLINE Class Reference

#include <quspline.h>

Public Member Functions

 QSPLINE ()
 
 QSPLINE (const QSPLINE &src)
 
 QSPLINE (int32_t count, int32_t *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)
 
bool overlap (QSPLINE *spline2, double fraction)
 
void extrapolate (double gradient, int left, int right)
 
void plot (ScrollView *window, ScrollView::Color colour) const
 
void plot (Pix *pix) const
 
QSPLINEoperator= (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)
 

Detailed Description

Definition at line 31 of file quspline.h.

Constructor & Destructor Documentation

◆ QSPLINE() [1/4]

QSPLINE::QSPLINE ( )
inline

Definition at line 43 of file quspline.h.

43  :
44  QSPLINE() { //empty constructor
45  segments = 0;
46  xcoords = nullptr; //everything empty
47  quadratics = nullptr;

◆ QSPLINE() [2/4]

QSPLINE::QSPLINE ( const QSPLINE src)

Definition at line 134 of file quspline.cpp.

138  {
139  segments = 0;
140  xcoords = nullptr;

◆ QSPLINE() [3/4]

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

Definition at line 38 of file quspline.cpp.

43  {
44  int32_t index; //segment index
45 
46  //get memory
47  xcoords = new int32_t[count + 1];
48  quadratics = new QUAD_COEFFS[count];
49  segments = count;
50  for (index = 0; index < segments; index++) {
51  //copy them
52  xcoords[index] = xstarts[index];
53  quadratics[index] = QUAD_COEFFS (coeffs[index * 3],
54  coeffs[index * 3 + 1],
55  coeffs[index * 3 + 2]);
56  }
57  //right edge
58  xcoords[index] = xstarts[index];

◆ ~QSPLINE()

QSPLINE::~QSPLINE ( )

Definition at line 148 of file quspline.cpp.

◆ QSPLINE() [4/4]

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

Definition at line 66 of file quspline.cpp.

74  {
75  int pointindex; /*no along text line */
76  int segment; /*segment no */
77  int32_t *ptcounts; //no in each segment
78  QLSQ qlsq; /*accumulator */
79 
80  segments = segcount;
81  xcoords = new int32_t[segcount + 1];
82  ptcounts = new int32_t[segcount + 1];
83  quadratics = new QUAD_COEFFS[segcount];
84  memmove (xcoords, xstarts, (segcount + 1) * sizeof (int32_t));
85  ptcounts[0] = 0; /*none in any yet */
86  for (segment = 0, pointindex = 0; pointindex < pointcount; pointindex++) {
87  while (segment < segcount && xpts[pointindex] >= xstarts[segment]) {
88  segment++; /*try next segment */
89  /*cumulative counts */
90  ptcounts[segment] = ptcounts[segment - 1];
91  }
92  ptcounts[segment]++; /*no in previous partition */
93  }
94  while (segment < segcount) {
95  segment++;
96  /*zero the rest */
97  ptcounts[segment] = ptcounts[segment - 1];
98  }
99 
100  for (segment = 0; segment < segcount; segment++) {
101  qlsq.clear ();
102  /*first blob */
103  pointindex = ptcounts[segment];
104  if (pointindex > 0
105  && xpts[pointindex] != xpts[pointindex - 1]
106  && xpts[pointindex] != xstarts[segment])
107  qlsq.add (xstarts[segment],
108  ypts[pointindex - 1]
109  + (ypts[pointindex] - ypts[pointindex - 1])
110  * (xstarts[segment] - xpts[pointindex - 1])
111  / (xpts[pointindex] - xpts[pointindex - 1]));
112  for (; pointindex < ptcounts[segment + 1]; pointindex++) {
113  qlsq.add (xpts[pointindex], ypts[pointindex]);
114  }
115  if (pointindex > 0 && pointindex < pointcount
116  && xpts[pointindex] != xstarts[segment + 1])
117  qlsq.add (xstarts[segment + 1],
118  ypts[pointindex - 1]
119  + (ypts[pointindex] - ypts[pointindex - 1])
120  * (xstarts[segment + 1] - xpts[pointindex - 1])
121  / (xpts[pointindex] - xpts[pointindex - 1]));
122  qlsq.fit (degree);
123  quadratics[segment].a = qlsq.get_a ();
124  quadratics[segment].b = qlsq.get_b ();
125  quadratics[segment].c = qlsq.get_c ();
126  }

Member Function Documentation

◆ extrapolate()

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

Definition at line 280 of file quspline.cpp.

295  {
296  int segment; /*current segment of spline */
297  int dest_segment; //dest index
298  int32_t* xstarts; //new boundaries
299  QUAD_COEFFS *quads; //new ones
300  int increment; //in size
301 
302  increment = xmin < xcoords[0] ? 1 : 0;
303  if (xmax > xcoords[segments])
304  increment++;
305  if (increment == 0)
306  return;
307  xstarts = new int32_t[segments + 1 + increment];
308  quads = new QUAD_COEFFS[segments + increment];
309  if (xmin < xcoords[0]) {
310  xstarts[0] = xmin;
311  quads[0].a = 0;
312  quads[0].b = gradient;
313  quads[0].c = y (xcoords[0]) - quads[0].b * xcoords[0];
314  dest_segment = 1;
315  }
316  else
317  dest_segment = 0;
318  for (segment = 0; segment < segments; segment++) {
319  xstarts[dest_segment] = xcoords[segment];
320  quads[dest_segment] = quadratics[segment];
321  dest_segment++;
322  }
323  xstarts[dest_segment] = xcoords[segment];
324  if (xmax > xcoords[segments]) {
325  quads[dest_segment].a = 0;
326  quads[dest_segment].b = gradient;

◆ move()

void QSPLINE::move ( ICOORD  vec)

Definition at line 242 of file quspline.cpp.

253  {

◆ operator=()

QSPLINE & QSPLINE::operator= ( const QSPLINE source)

Definition at line 159 of file quspline.cpp.

165  {
166  delete[] xcoords;
167  delete[] quadratics;
168 
169  segments = source.segments;
170  xcoords = new int32_t[segments + 1];

◆ overlap()

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

Definition at line 262 of file quspline.cpp.

◆ plot() [1/2]

void QSPLINE::plot ( Pix *  pix) const

Definition at line 361 of file quspline.cpp.

362  {
363  if (segment == 0 && step == 0)
364  window->SetCursor(x, quadratics[segment].y (x));
365  else
366  window->DrawTo(x, quadratics[segment].y (x));
367  x += increment;
368  }
369  }
370 }
371 #endif
372 
373 void QSPLINE::plot(Pix *pix) const {
374  if (pix == nullptr) {
375  return;
376  }
377 
378  int32_t segment; // Index of segment
379  int16_t step; // Index of poly piece
380  double increment; // x increment
381  double x; // x coord
382  auto height = static_cast<double>(pixGetHeight(pix));
383  Pta* points = ptaCreate(QSPLINE_PRECISION * segments);
384  const int kLineWidth = 5;
385 
386  for (segment = 0; segment < segments; segment++) {
387  increment = static_cast<double>((xcoords[segment + 1] -
388  xcoords[segment])) / QSPLINE_PRECISION;
389  x = xcoords[segment];
390  for (step = 0; step <= QSPLINE_PRECISION; step++) {
391  double y = height - quadratics[segment].y(x);
392  ptaAddPt(points, x, y);
393  x += increment;
394  }
395  }
396 
397  switch (pixGetDepth(pix)) {

◆ plot() [2/2]

void QSPLINE::plot ( ScrollView window,
ScrollView::Color  colour 
) const

Definition at line 335 of file quspline.cpp.

350  {
351  int32_t segment; //index of segment
352  int16_t step; //index of poly piece
353  double increment; //x increment
354  double x; //x coord
355 
356  window->Pen(colour);
357  for (segment = 0; segment < segments; segment++) {
358  increment =

◆ step()

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

Definition at line 178 of file quspline.cpp.

186  {
187  int index1, index2; //indices of coords
188  double total; /*total steps */
189 
190  index1 = spline_index (x1);
191  index2 = spline_index (x2);
192  total = 0;
193  while (index1 < index2) {
194  total +=

◆ y()

double QSPLINE::y ( double  x) const

Definition at line 202 of file quspline.cpp.

211  {

Friends And Related Function Documentation

◆ make_first_baseline

void make_first_baseline ( TBOX ,
int  ,
int *  ,
int *  ,
QSPLINE ,
QSPLINE ,
float   
)
friend

◆ make_holed_baseline

void make_holed_baseline ( TBOX ,
int  ,
QSPLINE ,
QSPLINE ,
float   
)
friend

◆ tweak_row_baseline

void tweak_row_baseline ( ROW ,
double  ,
double   
)
friend

Definition at line 893 of file tordmain.cpp.

897  {
898  TBOX blob_box; //bounding box
899  C_BLOB *blob; //current blob
900  WERD *word; //current word
901  int32_t blob_count; //no of blobs
902  int32_t src_index; //source segment
903  int32_t dest_index; //destination segment
904  float ydiff; //baseline error
905  float x_centre; //centre of blob
906  //words of row
907  WERD_IT word_it = row->word_list ();
908  C_BLOB_IT blob_it; //blob iterator
909 
910  blob_count = 0;
911  for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
912  word = word_it.data (); //current word
913  //get total blobs
914  blob_count += word->cblob_list ()->length ();
915  }
916  if (blob_count == 0)
917  return;
918  // spline segments
919  std::vector<int32_t> xstarts(blob_count + row->baseline.segments + 1);
920  // spline coeffs
921  std::vector<double> coeffs((blob_count + row->baseline.segments) * 3);
922 
923  src_index = 0;
924  dest_index = 0;
925  xstarts[0] = row->baseline.xcoords[0];
926  for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
927  word = word_it.data (); //current word
928  //blobs in word
929  blob_it.set_to_list (word->cblob_list ());
930  for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
931  blob_it.forward ()) {
932  blob = blob_it.data ();
933  blob_box = blob->bounding_box ();
934  x_centre = (blob_box.left () + blob_box.right ()) / 2.0;
935  ydiff = blob_box.bottom () - row->base_line (x_centre);
936  if (ydiff < 0)
937  ydiff = -ydiff / row->x_height ();
938  else
939  ydiff = ydiff / row->x_height ();
940  if (ydiff < blshift_maxshift
941  && blob_box.height () / row->x_height () > blshift_xfraction) {
942  if (xstarts[dest_index] >= x_centre)
943  xstarts[dest_index] = blob_box.left ();
944  coeffs[dest_index * 3] = 0;
945  coeffs[dest_index * 3 + 1] = 0;
946  coeffs[dest_index * 3 + 2] = blob_box.bottom ();
947  //shift it
948  dest_index++;
949  xstarts[dest_index] = blob_box.right () + 1;
950  }
951  else {
952  if (xstarts[dest_index] <= x_centre) {
953  while (row->baseline.xcoords[src_index + 1] <= x_centre
954  && src_index < row->baseline.segments - 1) {
955  if (row->baseline.xcoords[src_index + 1] >
956  xstarts[dest_index]) {
957  coeffs[dest_index * 3] =
958  row->baseline.quadratics[src_index].a;
959  coeffs[dest_index * 3 + 1] =
960  row->baseline.quadratics[src_index].b;
961  coeffs[dest_index * 3 + 2] =
962  row->baseline.quadratics[src_index].c;
963  dest_index++;
964  xstarts[dest_index] =
965  row->baseline.xcoords[src_index + 1];
966  }
967  src_index++;
968  }
969  coeffs[dest_index * 3] =
970  row->baseline.quadratics[src_index].a;
971  coeffs[dest_index * 3 + 1] =
972  row->baseline.quadratics[src_index].b;
973  coeffs[dest_index * 3 + 2] =
974  row->baseline.quadratics[src_index].c;
975  dest_index++;
976  xstarts[dest_index] = row->baseline.xcoords[src_index + 1];
977  }
978  }
979  }
980  }
981  while (src_index < row->baseline.segments
982  && row->baseline.xcoords[src_index + 1] <= xstarts[dest_index])
983  src_index++;
984  while (src_index < row->baseline.segments) {
985  coeffs[dest_index * 3] = row->baseline.quadratics[src_index].a;
986  coeffs[dest_index * 3 + 1] = row->baseline.quadratics[src_index].b;
987  coeffs[dest_index * 3 + 2] = row->baseline.quadratics[src_index].c;
988  dest_index++;
989  src_index++;
990  xstarts[dest_index] = row->baseline.xcoords[src_index];
991  }
992  //turn to spline

The documentation for this class was generated from the following files:
QSPLINE_PRECISION
#define QSPLINE_PRECISION
Definition: quspline.cpp:31
C_BLOB::bounding_box
TBOX bounding_box() const
Definition: stepblob.cpp:247
ROW::base_line
float base_line(float xpos) const
Definition: ocrrow.h:58
QLSQ
Definition: quadlsq.h:24
QUAD_COEFFS::a
double a
Definition: quadratc.h:71
QLSQ::fit
void fit(int degree)
Definition: quadlsq.cpp:95
baseline
Definition: mfoutline.h:62
ScrollView::Pen
void Pen(Color color)
Definition: scrollview.cpp:717
QUAD_COEFFS::y
float y(float x) const
Definition: quadratc.h:53
QLSQ::get_c
double get_c()
Definition: quadlsq.h:66
C_BLOB
Definition: stepblob.h:36
TBOX::height
int16_t height() const
Definition: rect.h:107
QLSQ::get_b
double get_b()
Definition: quadlsq.h:63
WERD::cblob_list
C_BLOB_LIST * cblob_list()
Definition: werd.h:94
QLSQ::clear
void clear()
Definition: quadlsq.cpp:32
ROW::x_height
float x_height() const
Definition: ocrrow.h:63
QSPLINE::plot
void plot(ScrollView *window, ScrollView::Color colour) const
Definition: quspline.cpp:335
TBOX::bottom
int16_t bottom() const
Definition: rect.h:64
QLSQ::add
void add(double x, double y)
Definition: quadlsq.cpp:53
QSPLINE::step
double step(double x1, double x2)
Definition: quspline.cpp:178
QSPLINE::y
double y(double x) const
Definition: quspline.cpp:202
QLSQ::get_a
double get_a()
Definition: quadlsq.h:60
count
int count(LIST var_list)
Definition: oldlist.cpp:79
WERD
Definition: werd.h:55
TBOX::left
int16_t left() const
Definition: rect.h:71
TBOX::right
int16_t right() const
Definition: rect.h:78
QUAD_COEFFS
Definition: quadratc.h:24
QUAD_COEFFS::c
float c
Definition: quadratc.h:73
QSPLINE::QSPLINE
QSPLINE()
Definition: quspline.h:43
QUAD_COEFFS::b
float b
Definition: quadratc.h:72
ROW::word_list
WERD_LIST * word_list()
Definition: ocrrow.h:54
TBOX
Definition: rect.h:33