tesseract 4.1.1
Loading...
Searching...
No Matches
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 32 of file quspline.h.

Constructor & Destructor Documentation

◆ QSPLINE() [1/4]

QSPLINE::QSPLINE ( )
inline

Definition at line 44 of file quspline.h.

44 { //empty constructor
45 segments = 0;
46 xcoords = nullptr; //everything empty
47 quadratics = nullptr;
48 }

◆ QSPLINE() [2/4]

QSPLINE::QSPLINE ( const QSPLINE src)

Definition at line 137 of file quspline.cpp.

138 {
139 segments = 0;
140 xcoords = nullptr;
141 quadratics = nullptr;
142 *this = src;
143}

◆ QSPLINE() [3/4]

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

Definition at line 39 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];
59}
int count(LIST var_list)
Definition: oldlist.cpp:95

◆ ~QSPLINE()

QSPLINE::~QSPLINE ( )

Definition at line 152 of file quspline.cpp.

152 {
153 delete[] xcoords;
154 delete[] quadratics;
155}

◆ QSPLINE() [4/4]

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

Definition at line 68 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 }
127 delete[] ptcounts;
128}
Definition: quadlsq.h:26
double get_a()
Definition: quadlsq.h:45
void fit(int degree)
Definition: quadlsq.cpp:99
void clear()
Definition: quadlsq.cpp:33
double get_b()
Definition: quadlsq.h:48
void add(double x, double y)
Definition: quadlsq.cpp:55
double get_c()
Definition: quadlsq.h:51
float b
Definition: quadratc.h:58
float c
Definition: quadratc.h:59
double a
Definition: quadratc.h:57

Member Function Documentation

◆ extrapolate()

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

Definition at line 291 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;
327 quads[dest_segment].c = y (xcoords[segments])
328 - quads[dest_segment].b * xcoords[segments];
329 dest_segment++;
330 xstarts[dest_segment] = xmax + 1;
331 }
332 segments = dest_segment;
333 delete[] xcoords;
334 delete[] quadratics;
335 xcoords = xstarts;
336 quadratics = quads;
337}
double y(double x) const
Definition: quspline.cpp:209

◆ move()

void QSPLINE::move ( ICOORD  vec)

Definition at line 251 of file quspline.cpp.

253 {
254 int32_t segment; //index of segment
255 int16_t x_shift = vec.x ();
256
257 for (segment = 0; segment < segments; segment++) {
258 xcoords[segment] += x_shift;
259 quadratics[segment].move (vec);
260 }
261 xcoords[segment] += x_shift;
262}
int16_t x() const
access function
Definition: points.h:52
void move(ICOORD vec)
Definition: quadratc.h:43

◆ operator=()

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

Definition at line 164 of file quspline.cpp.

165 {
166 delete[] xcoords;
167 delete[] quadratics;
168
169 segments = source.segments;
170 xcoords = new int32_t[segments + 1];
171 quadratics = new QUAD_COEFFS[segments];
172 memmove (xcoords, source.xcoords, (segments + 1) * sizeof (int32_t));
173 memmove (quadratics, source.quadratics, segments * sizeof (QUAD_COEFFS));
174 return *this;
175}

◆ overlap()

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

Definition at line 272 of file quspline.cpp.

275 {
276 int leftlimit = xcoords[1]; /*common left limit */
277 int rightlimit = xcoords[segments - 1]; /*common right limit */
278 /*or too non-overlap */
279 return !(spline2->segments < 3 || spline2->xcoords[1] > leftlimit + fraction * (rightlimit - leftlimit) ||
280 spline2->xcoords[spline2->segments - 1] < rightlimit - fraction * (rightlimit - leftlimit));
281}

◆ plot() [1/2]

void QSPLINE::plot ( Pix *  pix) const

Definition at line 373 of file quspline.cpp.

373 {
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)) {
398 case 1:
399 pixRenderPolyline(pix, points, kLineWidth, L_SET_PIXELS, 1);
400 break;
401 case 32:
402 pixRenderPolylineArb(pix, points, kLineWidth, 255, 0, 0, 1);
403 break;
404 default:
405 pixRenderPolyline(pix, points, kLineWidth, L_CLEAR_PIXELS, 1);
406 break;
407 }
408 ptaDestroy(&points);
409}
#define QSPLINE_PRECISION
Definition: quspline.cpp:31
float y(float x) const
Definition: quadratc.h:38
double step(double x1, double x2)
Definition: quspline.cpp:184

◆ plot() [2/2]

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

Definition at line 347 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 =
359 static_cast<double>(xcoords[segment + 1] -
360 xcoords[segment]) / QSPLINE_PRECISION;
361 x = xcoords[segment];
362 for (step = 0; step <= QSPLINE_PRECISION; step++) {
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}
void DrawTo(int x, int y)
Definition: scrollview.cpp:525
void SetCursor(int x, int y)
Definition: scrollview.cpp:519
void Pen(Color color)
Definition: scrollview.cpp:719

◆ step()

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

Definition at line 184 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 +=
195 static_cast<double>(quadratics[index1 + 1].y (static_cast<float>(xcoords[index1 + 1])));
196 total -= static_cast<double>(quadratics[index1].y (static_cast<float>(xcoords[index1 + 1])));
197 index1++; /*next segment */
198 }
199 return total; /*total steps */
200}

◆ y()

double QSPLINE::y ( double  x) const

Definition at line 209 of file quspline.cpp.

211 {
212 int32_t index; //segment index
213
214 index = spline_index (x);
215 return quadratics[index].y (x);//in correct segment
216}

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 895 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
993 row->baseline = QSPLINE(dest_index, &xstarts[0], &coeffs[0]);
994}
@ baseline
Definition: mfoutline.h:63
WERD_LIST * word_list()
Definition: ocrrow.h:55
float base_line(float xpos) const
Definition: ocrrow.h:59
float x_height() const
Definition: ocrrow.h:64
QSPLINE()
Definition: quspline.h:44
Definition: rect.h:34
int16_t height() const
Definition: rect.h:108
int16_t left() const
Definition: rect.h:72
int16_t bottom() const
Definition: rect.h:65
int16_t right() const
Definition: rect.h:79
TBOX bounding_box() const
Definition: stepblob.cpp:253
Definition: werd.h:56
C_BLOB_LIST * cblob_list()
Definition: werd.h:95

The documentation for this class was generated from the following files: