/*! * boxRelocateOneSide() * * Input: boxd (<optional>; this can be null, equal to boxs, * or different from boxs); * boxs (starting box; to have one side relocated) * loc (new location of the side that is changing) * sideflag (L_FROM_LEFT, etc., indicating the side that moves) * Return: boxd, or null on error or if the computed boxd has * width or height <= 0. * * Notes: * (1) Set boxd == NULL to get new box; boxd == boxs for in-place; * or otherwise to resize existing boxd. * (2) For usage, suggest one of these: * boxd = boxRelocateOneSide(NULL, boxs, ...); // new * boxRelocateOneSide(boxs, boxs, ...); // in-place * boxRelocateOneSide(boxd, boxs, ...); // other */ BOX * boxRelocateOneSide(BOX *boxd, BOX *boxs, l_int32 loc, l_int32 sideflag) { l_int32 x, y, w, h; PROCNAME("boxRelocateOneSide"); if (!boxs) return (BOX *)ERROR_PTR("boxs not defined", procName, NULL); if (!boxd) boxd = boxCopy(boxs); boxGetGeometry(boxs, &x, &y, &w, &h); if (sideflag == L_FROM_LEFT) boxSetGeometry(boxd, loc, -1, w + x - loc, -1); else if (sideflag == L_FROM_RIGHT) boxSetGeometry(boxd, -1, -1, loc - x + 1, -1); else if (sideflag == L_FROM_TOP) boxSetGeometry(boxd, -1, loc, -1, h + y - loc); else if (sideflag == L_FROM_BOTTOM) boxSetGeometry(boxd, -1, -1, -1, loc - y + 1); return boxd; }
void resetStateVariables() { cancel_ocr = false; cachedEnv = NULL; cachedObject = NULL; lastProgress = 0; boxSetGeometry(currentTextBox, 0, 0, 0, 0); }
/*! * boxCreate() * * Input: x, y, width, height * Return: box, or null on error * * Notes: * (1) This clips the box to the +quad. If no part of the * box is in the +quad, this returns NULL. */ BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h) { BOX *box; PROCNAME("boxCreate"); if (w <= 0 || h <= 0) return (BOX *)ERROR_PTR("w and h not both > 0", procName, NULL); if (x < 0) { /* take part in +quad */ w = w + x; x = 0; if (w <= 0) return (BOX *)ERROR_PTR("x < 0 and box off +quad", procName, NULL); } if (y < 0) { /* take part in +quad */ h = h + y; y = 0; if (h <= 0) return (BOX *)ERROR_PTR("y < 0 and box off +quad", procName, NULL); } if ((box = (BOX *)CALLOC(1, sizeof(BOX))) == NULL) return (BOX *)ERROR_PTR("box not made", procName, NULL); boxSetGeometry(box, x, y, w, h); box->refcount = 1; return box; }
/*! * boxAdjustSides() * * Input: boxd (<optional>; this can be null, equal to boxs, * or different from boxs) * boxs (starting box; to have sides adjusted) * delleft, delright, deltop, delbot (changes in location of * each side) * Return: boxd, or null on error or if the computed boxd has * width or height <= 0. * * Notes: * (1) Set boxd == NULL to get new box; boxd == boxs for in-place; * or otherwise to resize existing boxd. * (2) For usage, suggest one of these: * boxd = boxAdjustSides(NULL, boxs, ...); // new * boxAdjustSides(boxs, boxs, ...); // in-place * boxAdjustSides(boxd, boxs, ...); // other * (1) New box dimensions are cropped at left and top to x >= 0 and y >= 0. * (2) For example, to expand in-place by 20 pixels on each side, use * boxAdjustSides(box, box, -20, 20, -20, 20); */ BOX * boxAdjustSides(BOX *boxd, BOX *boxs, l_int32 delleft, l_int32 delright, l_int32 deltop, l_int32 delbot) { l_int32 x, y, w, h, xl, xr, yt, yb, wnew, hnew; PROCNAME("boxAdjustSides"); if (!boxs) return (BOX *)ERROR_PTR("boxs not defined", procName, NULL); boxGetGeometry(boxs, &x, &y, &w, &h); xl = L_MAX(0, x + delleft); yt = L_MAX(0, y + deltop); xr = x + w + delright; /* one pixel beyond right edge */ yb = y + h + delbot; /* one pixel below bottom edge */ wnew = xr - xl; hnew = yb - yt; if (wnew < 1 || hnew < 1) return (BOX *)ERROR_PTR("boxd has 0 area", procName, NULL); if (!boxd) return boxCreate(xl, yt, wnew, hnew); else { boxSetGeometry(boxd, xl, yt, wnew, hnew); return boxd; } }
void setTextBoundaries(l_uint32 x, l_uint32 y, l_uint32 width, l_uint32 height) { boxSetGeometry(currentTextBox, x, y, width, height); }
int main(int argc, char* argv[]) { PIX *pixs, *pixb, *pixt; int minb; if (argc < 2) { USAGE: fprintf(stderr, "Usage: %s </path/to/text-image>\n" "\t\t[binarize-threshold] [minw:minh:maxw:maxh]\n", strrchr(argv[0], '/') + 1); return EINVAL; } if (2 < argc) { errno = 0; minb = strtol(argv[2], NULL, 10); if (errno < 0) { fprintf(stderr, "strtol: %s\n", strerror(errno)); goto USAGE; } } else minb = 180; if (!(pixs = pixRead(argv[1]))) ; if (1 && (pixt = pixBackgroundNormMorph(pixs, NULL, 4, 5, 248))) { pixDestroy(&pixs); pixs = pixt; } else if (0 && (pixt = pixBackgroundNorm(pixs, NULL, NULL, 10, 15, 60, 40, 248, 2, 1))) { pixDestroy(&pixs); pixs = pixt; } if (1 && (pixt = pixFindSkewAndDeskew(pixs, 1, NULL, NULL))) { pixDestroy(&pixs); pixs = pixt; } if (0 && pixDisplay(pixs, 0, 0)) ; if (1) { PTA *ptas, *ptad; if (!(pixb = pixConvertTo1(pixs, minb))) ; // pixt = pixDeskewLocal(pixs, 10, 0, 0, 0.0, 0.0, 0.0)) if (!pixGetLocalSkewTransform(pixb, 10, 0, 0, 0.0, 0.0, 0.0, &ptas, &ptad)) { if ((pixt = pixProjectiveSampledPta(pixs, ptad, ptas, L_BRING_IN_WHITE))) { pixDestroy(&pixs); pixs = pixt; } ptaDestroy(&ptas); ptaDestroy(&ptad); } pixDestroy(&pixb); } if (0 && (pixt = pixGammaTRC(NULL, pixs, 1.0, 30, 180))) { pixDestroy(&pixs); pixs = pixt; } if (!(pixb = pixConvertTo1(pixs, minb))) ; if (0) { pixDestroy(&pixs); pixs = pixCopy(pixs, pixb); } // XXX: if (1) { BOX* box; int i, n, j, m; PIX *pixi, *pixl; BOXA *boxi, *boxl; int x, y, w, h, wid; int X = INT_MAX, Y = INT_MAX, W = 0, H; // XXX: do smaller(or no) pixOpenBrick if (pixGetRegionsBinary(pixb, &pixi, &pixl, NULL, 0)) ; boxl = pixConnComp(pixl, NULL, 4); n = boxaGetCount(boxl); for (i = 0; i < n; ++i) { BOXA* boxa; box = boxaGetBox(boxl, i, L_CLONE); boxGetGeometry(box, &x, &y, &w, &h); if (w < 30 || h < 30 || w < h || h < (w / 40)) { boxDestroy(&box); continue; boxaRemoveBox(boxl, i); } if (x < X) X = x; if (y < Y) Y = y; if (W < w) W = w; pixt = pixClipRectangle(pixb, box, NULL); boxDestroy(&box); // XXX: for English if (0) pixt = pixDilateBrick(pixt, pixt, h >> 1, h >> 1); else pixt = pixDilateBrick(pixt, pixt, 16 < h ? h >> 4 : 1, h << 1); if (0 && pixDisplay(pixt, 0, 0)) ; boxa = pixConnComp(pixt, NULL, 8); pixDestroy(&pixt); wid = (h * 3) >> 2; //boxaShift(boxa, x, y); m = boxaGetCount(boxa); for (j = 0; j < m; ++j) { int x0, y0, w0; box = boxaGetBox(boxa, j, L_CLONE); boxGetGeometry(box, &x0, &y0, &w0, NULL); // merge adjacent 2 or 3 small boxes if (1 && w0 < wid && (j + 1) < m) { BOX* boxn; int xn, wn; boxn = boxaGetBox(boxa, j + 1, L_CLONE); boxGetGeometry(boxn, &xn, NULL, &wn, NULL); if ((w0 = xn + wn - x0) < h) { boxaSparseClearBox(boxa, ++j); if (w0 < wid && (j + 1) < m) { boxDestroy(&boxn); boxn = boxaGetBox(boxa, j + 1, L_CLONE); boxGetGeometry(boxn, &xn, NULL, &wn, NULL); if ((wn = xn + wn - x0) < h) { boxaSparseClearBox(boxa, ++j); w0 = wn; } } boxSetGeometry(box, -1, -1, w0, -1); } boxDestroy(&boxn); } boxSetGeometry(box, x + x0, y + y0, -1, -1); boxDestroy(&box); } boxaSparseCompact(boxa); if (1 && (pixt = pixDrawBoxa(pixs, boxa, 1, 0xff000000))) { pixDestroy(&pixs); pixs = pixt; } boxaDestroy(&boxa); } H = y + h;