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;
126BOXA *boxa1, *boxa2, *boxa3;
128NUMA *nasum, *nadiff, *naloc, *naval;
132 if (ppta) *ppta = NULL;
133 if (!pixs || pixGetDepth(pixs) != 1)
134 return (
NUMA *)ERROR_PTR(
"pixs undefined or not 1 bpp", __func__, NULL);
137 pix1 = pixMorphSequence(pixs,
"c25.1 + e15.1", 0);
140 if (pixadb) pixaAddPix(pixadb, pixScale(pix1, 0.25, 0.25),
L_INSERT);
144 if ((nasum = pixCountPixelsByRow(pix1, NULL)) == NULL) {
146 return (
NUMA *)ERROR_PTR(
"nasum not made", __func__, NULL);
148 h = pixGetHeight(pixs);
149 nadiff = numaCreate(h);
150 numaGetIValue(nasum, 0, &val2);
151 for (i = 0; i < h - 1; i++) {
153 numaGetIValue(nasum, i + 1, &val2);
154 numaAddNumber(nadiff, val1 - val2);
159 lept_mkdir(
"lept/baseline");
160 gplotSimple1(nadiff, GPLOT_PNG,
"/tmp/lept/baseline/diff",
"Diff Sig");
161 pix2 = pixRead(
"/tmp/lept/baseline/diff.png");
166 array = numaGetIArray(nadiff);
167 ndiff = numaGetCount(nadiff);
168 numaGetMax(nadiff, &maxval, &imaxloc);
169 numaDestroy(&nadiff);
172 peakthresh = (l_int32)maxval / PeakThresholdRatio;
174 zerothresh = (l_int32)maxval / ZeroThresholdRatio;
176 naloc = numaCreate(0);
177 naval = numaCreate(0);
179 for (i = 0; i < ndiff; i++) {
180 if (inpeak == FALSE) {
181 if (array[i] > peakthresh) {
183 mintosearch = i + MinDistInPeak;
189 if (array[i] > max) {
192 mintosearch = i + MinDistInPeak;
193 }
else if (i > mintosearch && array[i] <= zerothresh) {
195 numaAddNumber(naval, max);
196 numaAddNumber(naloc, maxloc);
204 numaAddNumber(naval, max);
205 numaAddNumber(naloc, maxloc);
209 gplot = gplotCreate(
"/tmp/lept/baseline/loc", GPLOT_PNG,
"Peak locs",
210 "rasterline",
"height");
211 gplotAddPlot(gplot, naloc, naval, GPLOT_POINTS,
"locs");
212 gplotMakeOutput(gplot);
213 gplotDestroy(&gplot);
214 pix2 = pixRead(
"/tmp/lept/baseline/loc.png");
222 pix2 = pixMorphSequence(pix1,
"r11 + c20.1 + o30.1 +c1.3", 0);
223 if (pixadb) pixaAddPix(pixadb, pix2,
L_COPY);
224 boxa1 = pixConnComp(pix2, NULL, 4);
227 if (boxaGetCount(boxa1) == 0) {
230 L_INFO(
"no components after filtering\n", __func__);
233 boxa2 = boxaTransform(boxa1, 0, 0, 4., 4.);
245 nloc = numaGetCount(naloc);
246 nbox = boxaGetCount(boxa3);
247 for (i = 0; i < nbox; i++) {
248 boxaGetBoxGeometry(boxa3, i, &bx, &by, &bw, &bh);
249 for (j = 0; j < nloc; j++) {
250 numaGetIValue(naloc, j, &locval);
251 if (L_ABS(locval - (by + bh)) > 25)
253 ptaAddPt(pta, bx, locval);
254 ptaAddPt(pta, bx + bw, locval);
262 l_int32 npts, x1, y1, x2, y2;
263 pix1 = pixConvertTo32(pixs);
264 npts = ptaGetCount(pta);
265 for (i = 0; i < npts; i += 2) {
266 ptaGetIPt(pta, i, &x1, &y1);
267 ptaGetIPt(pta, i + 1, &x2, &y2);
268 pixRenderLineArb(pix1, x1, y1, x2, y2, 2, 255, 0, 0);
270 pixWriteDebug(
"/tmp/lept/baseline/baselines.png", pix1, IFF_PNG);
271 pixaAddPix(pixadb, pixScale(pix1, 0.25, 0.25),
L_INSERT);
393 l_float32 sweeprange,
394 l_float32 sweepdelta,
395 l_float32 minbsdelta,
400l_float32 deg2rad, angr, angd, dely;
404 if (!pptas || !pptad)
405 return ERROR_INT(
"&ptas and &ptad not defined", __func__, 1);
406 *pptas = *pptad = NULL;
407 if (!pixs || pixGetDepth(pixs) != 1)
408 return ERROR_INT(
"pixs not defined or not 1 bpp", __func__, 1);
409 if (nslices < 2 || nslices > 20)
410 nslices = DefaultSlices;
411 if (redsweep < 1 || redsweep > 8)
412 redsweep = DefaultSweepReduction;
413 if (redsearch < 1 || redsearch > redsweep)
414 redsearch = DefaultBsReduction;
415 if (sweeprange == 0.0)
416 sweeprange = DefaultSweepRange;
417 if (sweepdelta == 0.0)
418 sweepdelta = DefaultSweepDelta;
419 if (minbsdelta == 0.0)
420 minbsdelta = DefaultMinbsDelta;
423 sweeprange, sweepdelta, minbsdelta,
426 return ERROR_INT(
"naskew not made", __func__, 1);
428 deg2rad = 3.14159265f / 180.f;
429 w = pixGetWidth(pixs);
430 h = pixGetHeight(pixs);
437 for (i = 0; i < h; i++) {
438 numaGetFValue(naskew, i, &angd);
439 angr = angd * deg2rad;
440 dely = w * tan(angr);
441 if (i - dely > 0.05 * h)
444 ptaAddPt(ptas, 0, i);
445 ptaAddPt(ptas, w - 1, i - dely);
446 ptaAddPt(ptad, 0, i);
447 ptaAddPt(ptad, w - 1, i);
450 for (i = h - 1; i > 0; i--) {
451 numaGetFValue(naskew, i, &angd);
452 angr = angd * deg2rad;
453 dely = w * tan(angr);
454 if (i - dely < 0.95 * h)
457 ptaAddPt(ptas, 0, i);
458 ptaAddPt(ptas, w - 1, i - dely);
459 ptaAddPt(ptad, 0, i);
460 ptaAddPt(ptad, w - 1, i);
462 numaDestroy(&naskew);
512 l_float32 sweeprange,
513 l_float32 sweepdelta,
514 l_float32 minbsdelta,
519l_int32 w, h, hs, i, ystart, yend, ovlap, npts;
520l_float32 angle, conf, ycenter, a, b;
523NUMA *naskew, *nax, *nay;
527 if (!pixs || pixGetDepth(pixs) != 1)
528 return (
NUMA *)ERROR_PTR(
"pixs undefined or not 1 bpp", __func__, NULL);
529 if (nslices < 2 || nslices > 20)
530 nslices = DefaultSlices;
531 if (redsweep < 1 || redsweep > 8)
532 redsweep = DefaultSweepReduction;
533 if (redsearch < 1 || redsearch > redsweep)
534 redsearch = DefaultBsReduction;
535 if (sweeprange == 0.0)
536 sweeprange = DefaultSweepRange;
537 if (sweepdelta == 0.0)
538 sweepdelta = DefaultSweepDelta;
539 if (minbsdelta == 0.0)
540 minbsdelta = DefaultMinbsDelta;
542 pixGetDimensions(pixs, &w, &h, NULL);
544 ovlap = (l_int32)(OverlapFraction * hs);
545 pta = ptaCreate(nslices);
546 for (i = 0; i < nslices; i++) {
547 ystart = L_MAX(0, hs * i - ovlap);
548 yend = L_MIN(h - 1, hs * (i + 1) + ovlap);
549 ycenter = (l_float32)(ystart + yend) / 2;
550 box = boxCreate(0, ystart, w, yend - ystart + 1);
551 pix = pixClipRectangle(pixs, box, NULL);
552 pixFindSkewSweepAndSearch(pix, &angle, &conf, redsweep, redsearch,
553 sweeprange, sweepdelta, minbsdelta);
554 if (conf > MinAllowedConfidence)
555 ptaAddPt(pta, ycenter, angle);
561 if ((npts = ptaGetCount(pta)) < 2) {
563 return (
NUMA *)ERROR_PTR(
"can't fit skew", __func__, NULL);
565 ptaGetLinearLSF(pta, &a, &b, NULL);
570 naskew = numaCreate(h);
571 for (i = 0; i < h; i++) {
573 numaAddNumber(naskew, angle);
577 lept_mkdir(
"lept/baseline");
578 ptaGetArrays(pta, &nax, &nay);
579 gplot = gplotCreate(
"/tmp/lept/baseline/skew", GPLOT_PNG,
580 "skew as fctn of y",
"y (in raster lines from top)",
581 "angle (in degrees)");
582 gplotAddPlot(gplot, NULL, naskew, GPLOT_POINTS,
"linear lsf");
583 gplotAddPlot(gplot, nax, nay, GPLOT_POINTS,
"actual data pts");
584 gplotMakeOutput(gplot);
585 gplotDestroy(&gplot);