Пример #1
0
int main(int    argc,
         char **argv)
{
l_int32       index;
l_uint32      val32;
BOX          *box, *box1, *box2, *box3, *box4, *box5;
BOXA         *boxa;
L_KERNEL     *kel;
PIX          *pixs, *pixg, *pixb, *pixd, *pixt, *pix1, *pix2, *pix3, *pix4;
PIXA         *pixa;
PIXCMAP      *cmap;
L_REGPARAMS  *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    pixa = pixaCreate(0);

        /* Color non-white pixels on RGB */
    pixs = pixRead("lucasta-frag.jpg");
    pixt = pixConvert8To32(pixs);
    box = boxCreate(120, 30, 200, 200);
    pixColorGray(pixt, box, L_PAINT_DARK, 220, 0, 0, 255);
    regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG);  /* 0 */
    pixaAddPix(pixa, pixt, L_COPY);
    pixColorGray(pixt, NULL, L_PAINT_DARK, 220, 255, 100, 100);
    regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG);  /* 1 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);

        /* Color non-white pixels on colormap */
    pixt = pixThresholdTo4bpp(pixs, 6, 1);
    box = boxCreate(120, 30, 200, 200);
    pixColorGray(pixt, box, L_PAINT_DARK, 220, 0, 0, 255);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 2 */
    pixaAddPix(pixa, pixt, L_COPY);
    pixColorGray(pixt, NULL, L_PAINT_DARK, 220, 255, 100, 100);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 3 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);

        /* Color non-black pixels on RGB */
    pixt = pixConvert8To32(pixs);
    box = boxCreate(120, 30, 200, 200);
    pixColorGray(pixt, box, L_PAINT_LIGHT, 20, 0, 0, 255);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 4 */
    pixaAddPix(pixa, pixt, L_COPY);
    pixColorGray(pixt, NULL, L_PAINT_LIGHT, 80, 255, 100, 100);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 5 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);

        /* Color non-black pixels on colormap */
    pixt = pixThresholdTo4bpp(pixs, 6, 1);
    box = boxCreate(120, 30, 200, 200);
    pixColorGray(pixt, box, L_PAINT_LIGHT, 20, 0, 0, 255);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 6 */
    pixaAddPix(pixa, pixt, L_COPY);
    pixColorGray(pixt, NULL, L_PAINT_LIGHT, 20, 255, 100, 100);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 7 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);

        /* Add highlight color to RGB */
    pixt = pixConvert8To32(pixs);
    box = boxCreate(507, 5, 385, 45);
    pixg = pixClipRectangle(pixs, box, NULL);
    pixb = pixThresholdToBinary(pixg, 180);
    pixInvert(pixb, pixb);
    pixDisplayWrite(pixb, 1);
    composeRGBPixel(50, 0, 250, &val32);
    pixPaintThroughMask(pixt, pixb, box->x, box->y, val32);
    boxDestroy(&box);
    pixDestroy(&pixg);
    pixDestroy(&pixb);
    box = boxCreate(236, 107, 262, 40);
    pixg = pixClipRectangle(pixs, box, NULL);
    pixb = pixThresholdToBinary(pixg, 180);
    pixInvert(pixb, pixb);
    composeRGBPixel(250, 0, 50, &val32);
    pixPaintThroughMask(pixt, pixb, box->x, box->y, val32);
    boxDestroy(&box);
    pixDestroy(&pixg);
    pixDestroy(&pixb);
    box = boxCreate(222, 208, 247, 43);
    pixg = pixClipRectangle(pixs, box, NULL);
    pixb = pixThresholdToBinary(pixg, 180);
    pixInvert(pixb, pixb);
    composeRGBPixel(60, 250, 60, &val32);
    pixPaintThroughMask(pixt, pixb, box->x, box->y, val32);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 8 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);
    pixDestroy(&pixg);
    pixDestroy(&pixb);

        /* Add highlight color to colormap */
    pixt = pixThresholdTo4bpp(pixs, 5, 1);
    cmap = pixGetColormap(pixt);
    pixcmapGetIndex(cmap, 255, 255, 255, &index);
    box = boxCreate(507, 5, 385, 45);
    pixSetSelectCmap(pixt, box, index, 50, 0, 250);
    boxDestroy(&box);
    box = boxCreate(236, 107, 262, 40);
    pixSetSelectCmap(pixt, box, index, 250, 0, 50);
    boxDestroy(&box);
    box = boxCreate(222, 208, 247, 43);
    pixSetSelectCmap(pixt, box, index, 60, 250, 60);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 9 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);

        /* Paint lines on RGB */
    pixt = pixConvert8To32(pixs);
    pixRenderLineArb(pixt, 450, 20, 850, 320, 5, 200, 50, 125);
    pixRenderLineArb(pixt, 30, 40, 440, 40, 5, 100, 200, 25);
    box = boxCreate(70, 80, 300, 245);
    pixRenderBoxArb(pixt, box, 3, 200, 200, 25);
    regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG);  /* 10 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);

        /* Paint lines on colormap */
    pixt = pixThresholdTo4bpp(pixs, 5, 1);
    pixRenderLineArb(pixt, 450, 20, 850, 320, 5, 200, 50, 125);
    pixRenderLineArb(pixt, 30, 40, 440, 40, 5, 100, 200, 25);
    box = boxCreate(70, 80, 300, 245);
    pixRenderBoxArb(pixt, box, 3, 200, 200, 25);
    regTestWritePixAndCheck(rp, pixt, IFF_PNG);  /* 11 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);

        /* Blend lines on RGB */
    pixt = pixConvert8To32(pixs);
    pixRenderLineBlend(pixt, 450, 20, 850, 320, 5, 200, 50, 125, 0.35);
    pixRenderLineBlend(pixt, 30, 40, 440, 40, 5, 100, 200, 25, 0.35);
    box = boxCreate(70, 80, 300, 245);
    pixRenderBoxBlend(pixt, box, 3, 200, 200, 25, 0.6);
    regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG);  /* 12 */
    pixaAddPix(pixa, pixt, L_INSERT);
    boxDestroy(&box);

        /* Colorize gray on cmapped image. */
    pix1 = pixRead("lucasta.150.jpg");
    pix2 = pixThresholdTo4bpp(pix1, 7, 1);
    box1 = boxCreate(73, 206, 140, 27);
    pixColorGrayCmap(pix2, box1, L_PAINT_LIGHT, 130, 207, 43);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 13 */
    pixaAddPix(pixa, pix2, L_COPY);
    if (rp->display)
        pixPrintStreamInfo(stderr, pix2, "One box added");

    box2 = boxCreate(255, 404, 197, 25);
    pixColorGrayCmap(pix2, box2, L_PAINT_LIGHT, 230, 67, 119);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 14 */
    pixaAddPix(pixa, pix2, L_COPY);
    if (rp->display)
        pixPrintStreamInfo(stderr, pix2, "Two boxes added");

    box3 = boxCreate(122, 756, 224, 22);
    pixColorGrayCmap(pix2, box3, L_PAINT_DARK, 230, 67, 119);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 15 */
    pixaAddPix(pixa, pix2, L_COPY);
    if (rp->display)
        pixPrintStreamInfo(stderr, pix2, "Three boxes added");

    box4 = boxCreate(11, 780, 147, 22);
    pixColorGrayCmap(pix2, box4, L_PAINT_LIGHT, 70, 137, 229);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 16 */
    pixaAddPix(pixa, pix2, L_COPY);
    if (rp->display)
        pixPrintStreamInfo(stderr, pix2, "Four boxes added");

    box5 = boxCreate(163, 605, 78, 22);
    pixColorGrayCmap(pix2, box5, L_PAINT_LIGHT, 70, 137, 229);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 17 */
    pixaAddPix(pixa, pix2, L_INSERT);
    if (rp->display)
        pixPrintStreamInfo(stderr, pix2, "Five boxes added");
    pixDestroy(&pix1);
    boxDestroy(&box1);
    boxDestroy(&box2);
    boxDestroy(&box3);
    boxDestroy(&box4);
    boxDestroy(&box5);
    pixDestroy(&pixs);

        /* Make a gray image and identify the fg pixels (val > 230) */
    pixs = pixRead("feyn-fract.tif");
    pix1 = pixConvertTo8(pixs, 0);
    kel = makeGaussianKernel(2, 2, 1.5, 1.0);
    pix2 = pixConvolve(pix1, kel, 8, 1);
    pix3 = pixThresholdToBinary(pix2, 230);
    boxa = pixConnComp(pix3, NULL, 8);
    pixDestroy(&pixs);
    pixDestroy(&pix1);
    pixDestroy(&pix3);
    kernelDestroy(&kel);

        /* Color the individual components in the gray image */
    pix4 = pixColorGrayRegions(pix2, boxa, L_PAINT_DARK, 230, 255, 0, 0);
    regTestWritePixAndCheck(rp, pix4, IFF_PNG);  /* 18 */
    pixaAddPix(pixa, pix4, L_INSERT);
    pixDisplayWithTitle(pix4, 0, 0, NULL, rp->display);

        /* Threshold to 10 levels of gray */
    pix3 = pixThresholdOn8bpp(pix2, 10, 1);
    regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 19 */
    pixaAddPix(pixa, pix3, L_COPY);

        /* Color the individual components in the cmapped image */
    pix4 = pixColorGrayRegions(pix3, boxa, L_PAINT_DARK, 230, 255, 0, 0);
    regTestWritePixAndCheck(rp, pix4, IFF_PNG);  /* 20 */
    pixaAddPix(pixa, pix4, L_INSERT);
    pixDisplayWithTitle(pix4, 0, 100, NULL, rp->display);
    boxaDestroy(&boxa);

        /* Color the entire gray image (not component-wise) */
    pixColorGray(pix2, NULL, L_PAINT_DARK, 230, 255, 0, 0);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 21 */
    pixaAddPix(pixa, pix2, L_INSERT);

        /* Color the entire cmapped image (not component-wise) */
    pixColorGray(pix3, NULL, L_PAINT_DARK, 230, 255, 0, 0);
    regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 22 */
    pixaAddPix(pixa, pix3, L_INSERT);

        /* Reconstruct cmapped images */
    pixd = ReconstructByValue(rp, "weasel2.4c.png");
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 23 */
    pixaAddPix(pixa, pixd, L_INSERT);
    pixd = ReconstructByValue(rp, "weasel4.11c.png");
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 24 */
    pixaAddPix(pixa, pixd, L_INSERT);
    pixd = ReconstructByValue(rp, "weasel8.240c.png");
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 25 */
    pixaAddPix(pixa, pixd, L_INSERT);

        /* Fake reconstruct cmapped images, with one color into a band */
    pixd = FakeReconstructByBand(rp, "weasel2.4c.png");
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 26 */
    pixaAddPix(pixa, pixd, L_INSERT);
    pixd = FakeReconstructByBand(rp, "weasel4.11c.png");
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 27 */
    pixaAddPix(pixa, pixd, L_INSERT);
    pixd = FakeReconstructByBand(rp, "weasel8.240c.png");
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 28 */
    pixaAddPix(pixa, pixd, L_INSERT);

        /* If in testing mode, make a pdf */
    if (rp->display) {
        pixaConvertToPdf(pixa, 100, 1.0, L_FLATE_ENCODE, 0,
                         "Colorize and paint", "/tmp/lept/regout/paint.pdf");
        L_INFO("Output pdf: /tmp/lept/regout/paint.pdf\n", rp->testname);
    }

    pixaDestroy(&pixa);
    return regTestCleanup(rp);
}
Пример #2
0
/*!
 *  pixSplitComponentWithProfile()
 *
 *      Input:  pixs (1 bpp, exactly one connected component)
 *              delta (distance used in extrema finding in a numa; typ. 10)
 *              mindel (minimum required difference between profile minimum
 *                      and profile values +2 and -2 away; typ. 7)
 *              &pixdebug (<optional return> debug image of splitting)
 *      Return: boxa (of c.c. after splitting), or null on error
 *
 *  Notes:
 *      (1) This will split the most obvious cases of touching characters.
 *          The split points it is searching for are narrow and deep
 *          minimima in the vertical pixel projection profile, after a
 *          large vertical closing has been applied to the component.
 */
BOXA *
pixSplitComponentWithProfile(PIX     *pixs,
                             l_int32  delta,
                             l_int32  mindel,
                             PIX    **ppixdebug)
{
l_int32   w, h, n2, i, firstmin, xmin, xshift;
l_int32   nmin, nleft, nright, nsplit, isplit, ncomp;
l_int32  *array1, *array2;
BOX      *box;
BOXA     *boxad;
NUMA     *na1, *na2, *nasplit;
PIX      *pix1, *pixdb;

    PROCNAME("pixSplitComponentsWithProfile");

    if (ppixdebug) *ppixdebug = NULL;
    if (!pixs || pixGetDepth(pixs) != 1)
        return (BOXA *)ERROR_PTR("pixa undefined or not 1 bpp", procName, NULL);
    pixGetDimensions(pixs, &w, &h, NULL);

        /* Closing to consolidate characters vertically */
    pix1 = pixCloseSafeBrick(NULL, pixs, 1, 100);

        /* Get extrema of column projections */
    boxad = boxaCreate(2);
    na1 = pixCountPixelsByColumn(pix1);  /* w elements */
    pixDestroy(&pix1);
    na2 = numaFindExtrema(na1, delta);
    n2 = numaGetCount(na2);
    if (n2 < 3) {  /* no split possible */
        box = boxCreate(0, 0, w, h);
        boxaAddBox(boxad, box, L_INSERT);
        numaDestroy(&na1);
        numaDestroy(&na2);
        return boxad;
    }

        /* Look for sufficiently deep and narrow minima.
         * All minima of of interest must be surrounded by max on each
         * side.  firstmin is the index of first possible minimum. */
    array1 = numaGetIArray(na1);
    array2 = numaGetIArray(na2);
    if (ppixdebug) numaWriteStream(stderr, na2);
    firstmin = (array1[array2[0]] > array1[array2[1]]) ? 1 : 2;
    nasplit = numaCreate(n2);  /* will hold split locations */
    for (i = firstmin; i < n2 - 1; i+= 2) {
        xmin = array2[i];
        nmin = array1[xmin];
        if (xmin + 2 >= w) break;  /* no more splits possible */
        nleft = array1[xmin - 2];
        nright = array1[xmin + 2];
        if (ppixdebug) {
            fprintf(stderr,
                "Splitting: xmin = %d, w = %d; nl = %d, nmin = %d, nr = %d\n",
                xmin, w, nleft, nmin, nright);
        }
        if (nleft - nmin >= mindel && nright - nmin >= mindel)  /* split */
            numaAddNumber(nasplit, xmin);
    }
    nsplit = numaGetCount(nasplit);

#if 0
    if (ppixdebug && nsplit > 0)
        gplotSimple1(na1, GPLOT_X11, "/tmp/splitroot", NULL);
#endif

    numaDestroy(&na1);
    numaDestroy(&na2);
    FREE(array1);
    FREE(array2);

    if (nsplit == 0) {  /* no splitting */
        box = boxCreate(0, 0, w, h);
        boxaAddBox(boxad, box, L_INSERT);
        return boxad;
    }

        /* Use split points to generate b.b. after splitting */
    for (i = 0, xshift = 0; i < nsplit; i++) {
        numaGetIValue(nasplit, i, &isplit);
        box = boxCreate(xshift, 0, isplit - xshift, h);
        boxaAddBox(boxad, box, L_INSERT);
        xshift = isplit + 1;
    }
    box = boxCreate(xshift, 0, w - xshift, h);
    boxaAddBox(boxad, box, L_INSERT);

    numaDestroy(&nasplit);

    if (ppixdebug) {
        pixdb = pixConvertTo32(pixs);
        ncomp = boxaGetCount(boxad);
        for (i = 0; i < ncomp; i++) {
            box = boxaGetBox(boxad, i, L_CLONE);
            pixRenderBoxBlend(pixdb, box, 1, 255, 0, 0, 0.5);
            boxDestroy(&box);
        }
        *ppixdebug = pixdb;
    }

    return boxad;
}