Leptonica 1.82.0
Image processing and image analysis suite
baseline.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
50#ifdef HAVE_CONFIG_H
51#include <config_auto.h>
52#endif /* HAVE_CONFIG_H */
53
54#include <math.h>
55#include "allheaders.h"
56
57 /* Min to travel after finding max before abandoning peak */
58static const l_int32 MinDistInPeak = 35;
59
60 /* Thresholds for peaks and zeros, relative to the max peak */
61static const l_int32 PeakThresholdRatio = 20;
62static const l_int32 ZeroThresholdRatio = 100;
63
64 /* Default values for determining local skew */
65static const l_int32 DefaultSlices = 10;
66static const l_int32 DefaultSweepReduction = 2;
67static const l_int32 DefaultBsReduction = 1;
68static const l_float32 DefaultSweepRange = 5.; /* degrees */
69static const l_float32 DefaultSweepDelta = 1.; /* degrees */
70static const l_float32 DefaultMinbsDelta = 0.01; /* degrees */
71
72 /* Overlap slice fraction added to top and bottom of each slice */
73static const l_float32 OverlapFraction = 0.5;
74
75 /* Minimum allowed confidence (ratio) for accepting a value */
76static const l_float32 MinAllowedConfidence = 3.0;
77
78
79/*---------------------------------------------------------------------*
80 * Locate text baselines in an image *
81 *---------------------------------------------------------------------*/
116NUMA *
118 PTA **ppta,
119 PIXA *pixadb)
120{
121l_int32 h, i, j, nbox, val1, val2, ndiff, bx, by, bw, bh;
122l_int32 imaxloc, peakthresh, zerothresh, inpeak;
123l_int32 mintosearch, max, maxloc, nloc, locval;
124l_int32 *array;
125l_float32 maxval;
126BOXA *boxa1, *boxa2, *boxa3;
127GPLOT *gplot;
128NUMA *nasum, *nadiff, *naloc, *naval;
129PIX *pix1, *pix2;
130PTA *pta;
131
132 PROCNAME("pixFindBaselines");
133
134 if (ppta) *ppta = NULL;
135 if (!pixs || pixGetDepth(pixs) != 1)
136 return (NUMA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
137
138 /* Close up the text characters, removing noise */
139 pix1 = pixMorphSequence(pixs, "c25.1 + e15.1", 0);
140
141 /* Estimate the resolution */
142 if (pixadb) pixaAddPix(pixadb, pixScale(pix1, 0.25, 0.25), L_INSERT);
143
144 /* Save the difference of adjacent row sums.
145 * The high positive-going peaks are the baselines */
146 if ((nasum = pixCountPixelsByRow(pix1, NULL)) == NULL) {
147 pixDestroy(&pix1);
148 return (NUMA *)ERROR_PTR("nasum not made", procName, NULL);
149 }
150 h = pixGetHeight(pixs);
151 nadiff = numaCreate(h);
152 numaGetIValue(nasum, 0, &val2);
153 for (i = 0; i < h - 1; i++) {
154 val1 = val2;
155 numaGetIValue(nasum, i + 1, &val2);
156 numaAddNumber(nadiff, val1 - val2);
157 }
158 numaDestroy(&nasum);
159
160 if (pixadb) { /* show the difference signal */
161 lept_mkdir("lept/baseline");
162 gplotSimple1(nadiff, GPLOT_PNG, "/tmp/lept/baseline/diff", "Diff Sig");
163 pix2 = pixRead("/tmp/lept/baseline/diff.png");
164 pixaAddPix(pixadb, pix2, L_INSERT);
165 }
166
167 /* Use the zeroes of the profile to locate each baseline. */
168 array = numaGetIArray(nadiff);
169 ndiff = numaGetCount(nadiff);
170 numaGetMax(nadiff, &maxval, &imaxloc);
171 numaDestroy(&nadiff);
172
173 /* Use this to begin locating a new peak: */
174 peakthresh = (l_int32)maxval / PeakThresholdRatio;
175 /* Use this to begin a region between peaks: */
176 zerothresh = (l_int32)maxval / ZeroThresholdRatio;
177
178 naloc = numaCreate(0);
179 naval = numaCreate(0);
180 inpeak = FALSE;
181 for (i = 0; i < ndiff; i++) {
182 if (inpeak == FALSE) {
183 if (array[i] > peakthresh) { /* transition to in-peak */
184 inpeak = TRUE;
185 mintosearch = i + MinDistInPeak; /* accept no zeros
186 * between i and mintosearch */
187 max = array[i];
188 maxloc = i;
189 }
190 } else { /* inpeak == TRUE; look for max */
191 if (array[i] > max) {
192 max = array[i];
193 maxloc = i;
194 mintosearch = i + MinDistInPeak;
195 } else if (i > mintosearch && array[i] <= zerothresh) { /* leave */
196 inpeak = FALSE;
197 numaAddNumber(naval, max);
198 numaAddNumber(naloc, maxloc);
199 }
200 }
201 }
202 LEPT_FREE(array);
203
204 /* If array[ndiff-1] is max, eg. no descenders, baseline at bottom */
205 if (inpeak) {
206 numaAddNumber(naval, max);
207 numaAddNumber(naloc, maxloc);
208 }
209
210 if (pixadb) { /* show the raster locations for the peaks */
211 gplot = gplotCreate("/tmp/lept/baseline/loc", GPLOT_PNG, "Peak locs",
212 "rasterline", "height");
213 gplotAddPlot(gplot, naloc, naval, GPLOT_POINTS, "locs");
214 gplotMakeOutput(gplot);
215 gplotDestroy(&gplot);
216 pix2 = pixRead("/tmp/lept/baseline/loc.png");
217 pixaAddPix(pixadb, pix2, L_INSERT);
218 }
219 numaDestroy(&naval);
220
221 /* Generate an approximate profile of text line width.
222 * First, filter the boxes of text, where there may be
223 * more than one box for a given textline. */
224 pix2 = pixMorphSequence(pix1, "r11 + c20.1 + o30.1 +c1.3", 0);
225 if (pixadb) pixaAddPix(pixadb, pix2, L_COPY);
226 boxa1 = pixConnComp(pix2, NULL, 4);
227 pixDestroy(&pix1);
228 pixDestroy(&pix2);
229 if (boxaGetCount(boxa1) == 0) {
230 numaDestroy(&naloc);
231 boxaDestroy(&boxa1);
232 L_INFO("no components after filtering\n", procName);
233 return NULL;
234 }
235 boxa2 = boxaTransform(boxa1, 0, 0, 4., 4.);
236 boxa3 = boxaSort(boxa2, L_SORT_BY_Y, L_SORT_INCREASING, NULL);
237 boxaDestroy(&boxa1);
238 boxaDestroy(&boxa2);
239
240 /* Optionally, find the baseline segments */
241 pta = NULL;
242 if (ppta) {
243 pta = ptaCreate(0);
244 *ppta = pta;
245 }
246 if (pta) {
247 nloc = numaGetCount(naloc);
248 nbox = boxaGetCount(boxa3);
249 for (i = 0; i < nbox; i++) {
250 boxaGetBoxGeometry(boxa3, i, &bx, &by, &bw, &bh);
251 for (j = 0; j < nloc; j++) {
252 numaGetIValue(naloc, j, &locval);
253 if (L_ABS(locval - (by + bh)) > 25)
254 continue;
255 ptaAddPt(pta, bx, locval);
256 ptaAddPt(pta, bx + bw, locval);
257 break;
258 }
259 }
260 }
261 boxaDestroy(&boxa3);
262
263 if (pixadb && pta) { /* display baselines */
264 l_int32 npts, x1, y1, x2, y2;
265 pix1 = pixConvertTo32(pixs);
266 npts = ptaGetCount(pta);
267 for (i = 0; i < npts; i += 2) {
268 ptaGetIPt(pta, i, &x1, &y1);
269 ptaGetIPt(pta, i + 1, &x2, &y2);
270 pixRenderLineArb(pix1, x1, y1, x2, y2, 2, 255, 0, 0);
271 }
272 pixWriteDebug("/tmp/lept/baseline/baselines.png", pix1, IFF_PNG);
273 pixaAddPix(pixadb, pixScale(pix1, 0.25, 0.25), L_INSERT);
274 pixDestroy(&pix1);
275 }
276
277 return naloc;
278}
279
280
281/*---------------------------------------------------------------------*
282 * Projective transform to remove local skew *
283 *---------------------------------------------------------------------*/
323PIX *
325 l_int32 nslices,
326 l_int32 redsweep,
327 l_int32 redsearch,
328 l_float32 sweeprange,
329 l_float32 sweepdelta,
330 l_float32 minbsdelta)
331{
332l_int32 ret;
333PIX *pixd;
334PTA *ptas, *ptad;
335
336 PROCNAME("pixDeskewLocal");
337
338 if (!pixs || pixGetDepth(pixs) != 1)
339 return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
340
341 /* Skew array gives skew angle (deg) as fctn of raster line
342 * where it intersects the LHS of the image */
343 ret = pixGetLocalSkewTransform(pixs, nslices, redsweep, redsearch,
344 sweeprange, sweepdelta, minbsdelta,
345 &ptas, &ptad);
346 if (ret != 0)
347 return (PIX *)ERROR_PTR("transform pts not found", procName, NULL);
348
349 /* Use a projective transform */
350 pixd = pixProjectiveSampledPta(pixs, ptad, ptas, L_BRING_IN_WHITE);
351
352 ptaDestroy(&ptas);
353 ptaDestroy(&ptad);
354 return pixd;
355}
356
357
358/*---------------------------------------------------------------------*
359 * Determine the local skew *
360 *---------------------------------------------------------------------*/
392l_ok
394 l_int32 nslices,
395 l_int32 redsweep,
396 l_int32 redsearch,
397 l_float32 sweeprange,
398 l_float32 sweepdelta,
399 l_float32 minbsdelta,
400 PTA **pptas,
401 PTA **pptad)
402{
403l_int32 w, h, i;
404l_float32 deg2rad, angr, angd, dely;
405NUMA *naskew;
406PTA *ptas, *ptad;
407
408 PROCNAME("pixGetLocalSkewTransform");
409
410 if (!pptas || !pptad)
411 return ERROR_INT("&ptas and &ptad not defined", procName, 1);
412 *pptas = *pptad = NULL;
413 if (!pixs || pixGetDepth(pixs) != 1)
414 return ERROR_INT("pixs not defined or not 1 bpp", procName, 1);
415 if (nslices < 2 || nslices > 20)
416 nslices = DefaultSlices;
417 if (redsweep < 1 || redsweep > 8)
418 redsweep = DefaultSweepReduction;
419 if (redsearch < 1 || redsearch > redsweep)
420 redsearch = DefaultBsReduction;
421 if (sweeprange == 0.0)
422 sweeprange = DefaultSweepRange;
423 if (sweepdelta == 0.0)
424 sweepdelta = DefaultSweepDelta;
425 if (minbsdelta == 0.0)
426 minbsdelta = DefaultMinbsDelta;
427
428 naskew = pixGetLocalSkewAngles(pixs, nslices, redsweep, redsearch,
429 sweeprange, sweepdelta, minbsdelta,
430 NULL, NULL, 0);
431 if (!naskew)
432 return ERROR_INT("naskew not made", procName, 1);
433
434 deg2rad = 3.14159265 / 180.;
435 w = pixGetWidth(pixs);
436 h = pixGetHeight(pixs);
437 ptas = ptaCreate(4);
438 ptad = ptaCreate(4);
439 *pptas = ptas;
440 *pptad = ptad;
441
442 /* Find i for skew line that intersects LHS at i and RHS at h / 20 */
443 for (i = 0; i < h; i++) {
444 numaGetFValue(naskew, i, &angd);
445 angr = angd * deg2rad;
446 dely = w * tan(angr);
447 if (i - dely > 0.05 * h)
448 break;
449 }
450 ptaAddPt(ptas, 0, i);
451 ptaAddPt(ptas, w - 1, i - dely);
452 ptaAddPt(ptad, 0, i);
453 ptaAddPt(ptad, w - 1, i);
454
455 /* Find i for skew line that intersects LHS at i and RHS at 19h / 20 */
456 for (i = h - 1; i > 0; i--) {
457 numaGetFValue(naskew, i, &angd);
458 angr = angd * deg2rad;
459 dely = w * tan(angr);
460 if (i - dely < 0.95 * h)
461 break;
462 }
463 ptaAddPt(ptas, 0, i);
464 ptaAddPt(ptas, w - 1, i - dely);
465 ptaAddPt(ptad, 0, i);
466 ptaAddPt(ptad, w - 1, i);
467
468 numaDestroy(&naskew);
469 return 0;
470}
471
472
513NUMA *
515 l_int32 nslices,
516 l_int32 redsweep,
517 l_int32 redsearch,
518 l_float32 sweeprange,
519 l_float32 sweepdelta,
520 l_float32 minbsdelta,
521 l_float32 *pa,
522 l_float32 *pb,
523 l_int32 debug)
524{
525l_int32 w, h, hs, i, ystart, yend, ovlap, npts;
526l_float32 angle, conf, ycenter, a, b;
527BOX *box;
528GPLOT *gplot;
529NUMA *naskew, *nax, *nay;
530PIX *pix;
531PTA *pta;
532
533 PROCNAME("pixGetLocalSkewAngles");
534
535 if (!pixs || pixGetDepth(pixs) != 1)
536 return (NUMA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
537 if (nslices < 2 || nslices > 20)
538 nslices = DefaultSlices;
539 if (redsweep < 1 || redsweep > 8)
540 redsweep = DefaultSweepReduction;
541 if (redsearch < 1 || redsearch > redsweep)
542 redsearch = DefaultBsReduction;
543 if (sweeprange == 0.0)
544 sweeprange = DefaultSweepRange;
545 if (sweepdelta == 0.0)
546 sweepdelta = DefaultSweepDelta;
547 if (minbsdelta == 0.0)
548 minbsdelta = DefaultMinbsDelta;
549
550 pixGetDimensions(pixs, &w, &h, NULL);
551 hs = h / nslices;
552 ovlap = (l_int32)(OverlapFraction * hs);
553 pta = ptaCreate(nslices);
554 for (i = 0; i < nslices; i++) {
555 ystart = L_MAX(0, hs * i - ovlap);
556 yend = L_MIN(h - 1, hs * (i + 1) + ovlap);
557 ycenter = (l_float32)(ystart + yend) / 2;
558 box = boxCreate(0, ystart, w, yend - ystart + 1);
559 pix = pixClipRectangle(pixs, box, NULL);
560 pixFindSkewSweepAndSearch(pix, &angle, &conf, redsweep, redsearch,
561 sweeprange, sweepdelta, minbsdelta);
562 if (conf > MinAllowedConfidence)
563 ptaAddPt(pta, ycenter, angle);
564 pixDestroy(&pix);
565 boxDestroy(&box);
566 }
567
568 /* Do linear least squares fit */
569 if ((npts = ptaGetCount(pta)) < 2) {
570 ptaDestroy(&pta);
571 return (NUMA *)ERROR_PTR("can't fit skew", procName, NULL);
572 }
573 ptaGetLinearLSF(pta, &a, &b, NULL);
574 if (pa) *pa = a;
575 if (pb) *pb = b;
576
577 /* Make skew angle array as function of raster line */
578 naskew = numaCreate(h);
579 for (i = 0; i < h; i++) {
580 angle = a * i + b;
581 numaAddNumber(naskew, angle);
582 }
583
584 if (debug) {
585 lept_mkdir("lept/baseline");
586 ptaGetArrays(pta, &nax, &nay);
587 gplot = gplotCreate("/tmp/lept/baseline/skew", GPLOT_PNG,
588 "skew as fctn of y", "y (in raster lines from top)",
589 "angle (in degrees)");
590 gplotAddPlot(gplot, NULL, naskew, GPLOT_POINTS, "linear lsf");
591 gplotAddPlot(gplot, nax, nay, GPLOT_POINTS, "actual data pts");
592 gplotMakeOutput(gplot);
593 gplotDestroy(&gplot);
594 numaDestroy(&nax);
595 numaDestroy(&nay);
596 }
597
598 ptaDestroy(&pta);
599 return naskew;
600}
NUMA * pixFindBaselines(PIX *pixs, PTA **ppta, PIXA *pixadb)
pixFindBaselines()
Definition: baseline.c:117
NUMA * pixGetLocalSkewAngles(PIX *pixs, l_int32 nslices, l_int32 redsweep, l_int32 redsearch, l_float32 sweeprange, l_float32 sweepdelta, l_float32 minbsdelta, l_float32 *pa, l_float32 *pb, l_int32 debug)
pixGetLocalSkewAngles()
Definition: baseline.c:514
PIX * pixDeskewLocal(PIX *pixs, l_int32 nslices, l_int32 redsweep, l_int32 redsearch, l_float32 sweeprange, l_float32 sweepdelta, l_float32 minbsdelta)
pixDeskewLocal()
Definition: baseline.c:324
l_ok pixGetLocalSkewTransform(PIX *pixs, l_int32 nslices, l_int32 redsweep, l_int32 redsearch, l_float32 sweeprange, l_float32 sweepdelta, l_float32 minbsdelta, PTA **pptas, PTA **pptad)
pixGetLocalSkewTransform()
Definition: baseline.c:393
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
l_ok boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:879
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:734
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
BOXA * boxaTransform(BOXA *boxas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
boxaTransform()
Definition: boxfunc2.c:102
BOXA * boxaSort(BOXA *boxas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex)
boxaSort()
Definition: boxfunc2.c:637
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:151
l_ok gplotAddPlot(GPLOT *gplot, NUMA *nax, NUMA *nay, l_int32 plotstyle, const char *plotlabel)
gplotAddPlot()
Definition: gplot.c:320
l_ok gplotMakeOutput(GPLOT *gplot)
gplotMakeOutput()
Definition: gplot.c:466
GPLOT * gplotCreate(const char *rootname, l_int32 outformat, const char *title, const char *xlabel, const char *ylabel)
gplotCreate()
Definition: gplot.c:187
void gplotDestroy(GPLOT **pgplot)
gplotDestroy()
Definition: gplot.c:255
l_ok gplotSimple1(NUMA *na, l_int32 outformat, const char *outroot, const char *title)
gplotSimple1()
Definition: gplot.c:665
l_ok pixRenderLineArb(PIX *pix, l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderLineArb()
Definition: graphics.c:1536
PIX * pixMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequence()
Definition: morphseq.c:137
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:719
l_int32 * numaGetIArray(NUMA *na)
numaGetIArray()
Definition: numabasic.c:847
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:658
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:496
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
NUMA * pixCountPixelsByRow(PIX *pix, l_int32 *tab8)
pixCountPixelsByRow()
Definition: pix3.c:2143
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1026
@ L_SORT_BY_Y
Definition: pix.h:736
@ L_COPY
Definition: pix.h:712
@ L_INSERT
Definition: pix.h:711
@ L_SORT_INCREASING
Definition: pix.h:729
@ L_BRING_IN_WHITE
Definition: pix.h:869
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
PIX * pixProjectiveSampledPta(PIX *pixs, PTA *ptad, PTA *ptas, l_int32 incolor)
pixProjectiveSampledPta()
Definition: projective.c:144
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:578
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:343
l_ok ptaGetArrays(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaGetArrays()
Definition: ptabasic.c:639
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:527
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:195
l_ok ptaGetLinearLSF(PTA *pta, l_float32 *pa, l_float32 *pb, NUMA **pnafit)
ptaGetLinearLSF()
Definition: ptafunc1.c:1106
PIX * pixRead(const char *filename)
pixRead()
Definition: readfile.c:193
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:250
l_ok pixFindSkewSweepAndSearch(PIX *pixs, l_float32 *pangle, l_float32 *pconf, l_int32 redsweep, l_int32 redsearch, l_float32 sweeprange, l_float32 sweepdelta, l_float32 minbsdelta)
pixFindSkewSweepAndSearch()
Definition: skew.c:563
Definition: pix.h:481
Definition: pix.h:492
Definition: gplot.h:77
Definition: array.h:71
Definition: pix.h:139
Definition: pix.h:456
Definition: pix.h:517
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218