/*!
 *  pixcmapShiftIntensity()
 *
 *      Input:  colormap
 *              fraction (between -1.0 and +1.0)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      - in-place transform
 *      - This does a proportional shift of the intensity for each color.
 *      - If fraction < 0.0, it moves all colors towards (0,0,0).
 *        This darkens the image.
 *      - If fraction > 0.0, it moves all colors towards (255,255,255)
 *        This fades the image.
 *      - The equivalent transform can be accomplished with pixcmapGammaTRC(),
 *        but it is considerably more difficult (see numaGammaTRC()).
 */
l_int32
pixcmapShiftIntensity(PIXCMAP   *cmap,
                      l_float32  fraction)
{
l_int32   i, ncolors, rval, gval, bval;

    PROCNAME("pixcmapShiftIntensity");

    if (!cmap)
        return ERROR_INT("cmap not defined", procName, 1);
    if (fraction < -1.0 || fraction > 1.0)
        return ERROR_INT("fraction not in [-1.0, 1.0]", procName, 1);

    ncolors = pixcmapGetCount(cmap);
    for (i = 0; i < ncolors; i++) {
        pixcmapGetColor(cmap, i, &rval, &gval, &bval);
        if (fraction < 0.0)
            pixcmapResetColor(cmap, i,
                              (l_int32)((1.0 + fraction) * rval),
                              (l_int32)((1.0 + fraction) * gval),
                              (l_int32)((1.0 + fraction) * bval));
        else
            pixcmapResetColor(cmap, i,
                              rval + (l_int32)(fraction * (255 - rval)),
                              gval + (l_int32)(fraction * (255 - gval)),
                              bval + (l_int32)(fraction * (255 - bval)));
    }

    return 0;
}
/*!
 *  pixcmapContrastTRC()
 *
 *      Input:  colormap
 *              factor (generally between 0.0 (no enhancement)
 *                      and 1.0, but can be larger than 1.0)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      - in-place transform
 *      - see pixContrastTRC() and numaContrastTRC() in enhance.c for
 *        description and use of transform
 */
l_int32
pixcmapContrastTRC(PIXCMAP   *cmap,
                   l_float32  factor)
{
l_int32   i, ncolors, rval, gval, bval, trval, tgval, tbval;
NUMA     *nac;

    PROCNAME("pixcmapContrastTRC");

    if (!cmap)
        return ERROR_INT("cmap not defined", procName, 1);
    if (factor < 0.0) {
        L_WARNING("factor must be >= 0.0; setting to 0.0", procName);
        factor = 0.0;
    }

    if ((nac = numaContrastTRC(factor)) == NULL)
        return ERROR_INT("nac not made", procName, 1);

    ncolors = pixcmapGetCount(cmap);
    for (i = 0; i < ncolors; i++) {
        pixcmapGetColor(cmap, i, &rval, &gval, &bval);
        numaGetIValue(nac, rval, &trval);
        numaGetIValue(nac, gval, &tgval);
        numaGetIValue(nac, bval, &tbval);
        pixcmapResetColor(cmap, i, trval, tgval, tbval);
    }

    numaDestroy(&nac);
    return 0;
}
/*!
 *  pixcmapSetBlackAndWhite()
 *
 *      Input:  cmap
 *              setblack (0 for no operation; 1 to set darkest color to black)
 *              setwhite (0 for no operation; 1 to set lightest color to white)
 *      Return: 0 if OK, 1 on error
 */
l_int32
pixcmapSetBlackAndWhite(PIXCMAP  *cmap,
                        l_int32   setblack,
                        l_int32   setwhite)
{
l_int32  index;

    PROCNAME("pixcmapSetBlackAndWhite");

    if (!cmap)
        return ERROR_INT("cmap not defined", procName, 1);

    if (setblack) {
        pixcmapGetRankIntensity(cmap, 0.0, &index);
        pixcmapResetColor(cmap, index, 0, 0, 0);
    }
    if (setwhite) {
        pixcmapGetRankIntensity(cmap, 1.0, &index);
        pixcmapResetColor(cmap, index, 255, 255, 255);
    }

    return 0;
}
/*!
 *  pixcmapConvertHSVToRGB()
 *
 *      Input:  colormap
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      - in-place transform
 *      - See convertRGBToHSV() for def'n of HSV space.
 *      - replaces: h --> r, s --> g, v --> b
 */
l_int32
pixcmapConvertHSVToRGB(PIXCMAP  *cmap)
{
l_int32   i, ncolors, rval, gval, bval, hval, sval, vval;

    PROCNAME("pixcmapConvertHSVToRGB");

    if (!cmap)
        return ERROR_INT("cmap not defined", procName, 1);

    ncolors = pixcmapGetCount(cmap);
    for (i = 0; i < ncolors; i++) {
        pixcmapGetColor(cmap, i, &hval, &sval, &vval);
        convertHSVToRGB(hval, sval, vval, &rval, &gval, &bval);
        pixcmapResetColor(cmap, i, rval, gval, bval);
    }
    return 0;
}
/*!
 *  pixcmapColorToGray()
 *
 *      Input:  cmap
 *              rwt, gwt, bwt  (non-negative; these should add to 1.0)
 *      Return: cmap (gray), or null on error
 *
 *  Notes:
 *      (1) This creates a gray colormap from an arbitrary colormap.
 *      (2) In use, attach the output gray colormap to the pix
 *          (or a copy of it) that provided the input colormap.
 */
PIXCMAP *
pixcmapColorToGray(PIXCMAP   *cmaps,
                   l_float32  rwt,
                   l_float32  gwt,
                   l_float32  bwt)
{
l_int32    i, n, rval, gval, bval, val;
l_float32  sum;
PIXCMAP   *cmapd;

    PROCNAME("pixcmapColorToGray");

    if (!cmaps)
        return (PIXCMAP *)ERROR_PTR("cmaps not defined", procName, NULL);
    if (rwt < 0.0 || gwt < 0.0 || bwt < 0.0)
        return (PIXCMAP *)ERROR_PTR("weights not all >= 0.0", procName, NULL);

        /* Make sure the sum of weights is 1.0; otherwise, you can get
         * overflow in the gray value. */
    sum = rwt + gwt + bwt;
    if (sum == 0.0) {
        L_WARNING("all weights zero; setting equal to 1/3", procName);
        rwt = gwt = bwt = 0.33333;
        sum = 1.0;
    }
    if (L_ABS(sum - 1.0) > 0.0001) {  /* maintain ratios with sum == 1.0 */
        L_WARNING("weights don't sum to 1; maintaining ratios", procName);
        rwt = rwt / sum;
        gwt = gwt / sum;
        bwt = bwt / sum;
    }

    cmapd = pixcmapCopy(cmaps);
    n = pixcmapGetCount(cmapd);
    for (i = 0; i < n; i++) {
        pixcmapGetColor(cmapd, i, &rval, &gval, &bval);
        val = (l_int32)(rwt * rval + gwt * gval + bwt * bval + 0.5);
        pixcmapResetColor(cmapd, i, val, val, val);
    }
        
    return cmapd;
}
/*!
 *  pixcmapGammaTRC()
 *
 *      Input:  colormap
 *              gamma (gamma correction; must be > 0.0)
 *              minval  (input value that gives 0 for output; can be < 0)
 *              maxval  (input value that gives 255 for output; can be > 255)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      - in-place transform
 *      - see pixGammaTRC() and numaGammaTRC() in enhance.c for
 *        description and use of transform
 */
l_int32
pixcmapGammaTRC(PIXCMAP   *cmap,
                l_float32  gamma,
                l_int32    minval,
                l_int32    maxval)
{
l_int32   rval, gval, bval, trval, tgval, tbval, i, ncolors;
NUMA     *nag;

    PROCNAME("pixcmapGammaTRC");

    if (!cmap)
        return ERROR_INT("cmap not defined", procName, 1);
    if (gamma <= 0.0) {
        L_WARNING("gamma must be > 0.0; setting to 1.0", procName);
        gamma = 1.0;
    }
    if (minval >= maxval)
        return ERROR_INT("minval not < maxval", procName, 1);

    if (gamma == 1.0 && minval == 0 && maxval == 255)  /* no-op */
        return 0;

    if ((nag = numaGammaTRC(gamma, minval, maxval)) == NULL)
        return ERROR_INT("nag not made", procName, 1);

    ncolors = pixcmapGetCount(cmap);
    for (i = 0; i < ncolors; i++) {
        pixcmapGetColor(cmap, i, &rval, &gval, &bval);
        numaGetIValue(nag, rval, &trval);
        numaGetIValue(nag, gval, &tgval);
        numaGetIValue(nag, bval, &tbval);
        pixcmapResetColor(cmap, i, trval, tgval, tbval);
    }

    numaDestroy(&nag);
    return 0;
}
Exemple #7
0
int main(int    argc,
         char **argv)
{
l_uint8      *array1, *array2;
l_int32       n1, n2, n3;
size_t        size1, size2;
FILE         *fp;
BOXA         *boxa1, *boxa2;
PIX          *pixs, *pix1;
PIXA         *pixa1;
PIXCMAP      *cmap;
L_REGPARAMS  *rp;

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

    pixs = pixRead("feyn.tif");

    /* --------------------------------------------------------------- *
     *         Test pixConnComp() and pixCountConnComp(),              *
     *            with output to both boxa and pixa                    *
     * --------------------------------------------------------------- */
        /* First, test with 4-cc */
    boxa1= pixConnComp(pixs, &pixa1, 4);
    n1 = boxaGetCount(boxa1);
    boxa2= pixConnComp(pixs, NULL, 4);
    n2 = boxaGetCount(boxa2);
    pixCountConnComp(pixs, 4, &n3);
    fprintf(stderr, "Number of 4 c.c.:  n1 = %d; n2 = %d, n3 = %d\n",
            n1, n2, n3);
    regTestCompareValues(rp, n1, n2, 0);  /* 0 */
    regTestCompareValues(rp, n1, n3, 0);  /* 1 */
    regTestCompareValues(rp, n1, 4452, 0);  /* 2 */
    pix1 = pixaDisplay(pixa1, pixGetWidth(pixs), pixGetHeight(pixs));
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 3 */
    regTestComparePix(rp, pixs, pix1);  /* 4 */
    pixaDestroy(&pixa1);
    boxaDestroy(&boxa1);
    boxaDestroy(&boxa2);
    pixDestroy(&pix1);

        /* Test with 8-cc */
    boxa1= pixConnComp(pixs, &pixa1, 8);
    n1 = boxaGetCount(boxa1);
    boxa2= pixConnComp(pixs, NULL, 8);
    n2 = boxaGetCount(boxa2);
    pixCountConnComp(pixs, 8, &n3);
    fprintf(stderr, "Number of 8 c.c.:  n1 = %d; n2 = %d, n3 = %d\n",
            n1, n2, n3);
    regTestCompareValues(rp, n1, n2, 0);  /* 5 */
    regTestCompareValues(rp, n1, n3, 0);  /* 6 */
    regTestCompareValues(rp, n1, 4305, 0);  /* 7 */
    pix1 = pixaDisplay(pixa1, pixGetWidth(pixs), pixGetHeight(pixs));
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 8 */
    regTestComparePix(rp, pixs, pix1);  /* 9 */
    pixaDestroy(&pixa1);
    boxaDestroy(&boxa1);
    boxaDestroy(&boxa2);
    pixDestroy(&pix1);


    /* --------------------------------------------------------------- *
     *                        Test boxa I/O                            *
     * --------------------------------------------------------------- */
    lept_mkdir("lept/conn");
    boxa1 = pixConnComp(pixs, NULL, 4);
    fp = lept_fopen("/tmp/lept/conn/boxa1.ba", "wb+");
    boxaWriteStream(fp, boxa1);
    lept_fclose(fp);
    fp = lept_fopen("/tmp/lept/conn/boxa1.ba", "rb");
    boxa2 = boxaReadStream(fp);
    lept_fclose(fp);
    fp = lept_fopen("/tmp/lept/conn/boxa2.ba", "wb+");
    boxaWriteStream(fp, boxa2);
    lept_fclose(fp);
    array1 = l_binaryRead("/tmp/lept/conn/boxa1.ba", &size1);
    array2 = l_binaryRead("/tmp/lept/conn/boxa2.ba", &size2);
    regTestCompareStrings(rp, array1, size1, array2, size2);  /* 10 */
    lept_free(array1);
    lept_free(array2);
    boxaDestroy(&boxa1);
    boxaDestroy(&boxa2);


    /* --------------------------------------------------------------- *
     *    Just for fun, display each component as a random color in    *
     *    cmapped 8 bpp.  Background is color 0; it is set to white.   *
     * --------------------------------------------------------------- */
    boxa1 = pixConnComp(pixs, &pixa1, 4);
    pix1 = pixaDisplayRandomCmap(pixa1, pixGetWidth(pixs), pixGetHeight(pixs));
    cmap = pixGetColormap(pix1);
    pixcmapResetColor(cmap, 0, 255, 255, 255);  /* reset background to white */
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 11 */
    if (rp->display) pixDisplay(pix1, 100, 100);
    boxaDestroy(&boxa1);
    pixDestroy(&pix1);
    pixaDestroy(&pixa1);

    pixDestroy(&pixs);
    return regTestCleanup(rp);
}
Exemple #8
0
int main(int    argc,
         char **argv)
{
char        *filein;
l_int32      i, n, count;
BOX         *box;
BOXA        *boxa;
PIX         *pixs, *pixd;
PIXA        *pixa;
PIXCMAP     *cmap;
static char  mainName[] = "cctest1";

    if (argc != 2)
        return ERROR_INT(" Syntax:  cctest1 filein", mainName, 1);

    filein = argv[1];

    if ((pixs = pixRead(filein)) == NULL)
        return ERROR_INT("pixs not made", mainName, 1);
    if (pixGetDepth(pixs) != 1)
        exit(ERROR_INT("pixs not 1 bpp", mainName, 1));

        /* Test speed of pixCountConnComp() */
    startTimer();
    for (i = 0; i < NTIMES; i++)
        pixCountConnComp(pixs, 4, &count);
    fprintf(stderr, "Time to compute 4-cc: %6.3f sec\n", stopTimer()/NTIMES);
    fprintf(stderr, "Number of 4-cc: %d\n", count);
    startTimer();
    for (i = 0; i < NTIMES; i++)
        pixCountConnComp(pixs, 8, &count);
    fprintf(stderr, "Time to compute 8-cc: %6.3f sec\n", stopTimer()/NTIMES);
    fprintf(stderr, "Number of 8-cc: %d\n", count);

        /* Test speed of pixConnComp(), with only boxa output  */
    startTimer();
    for (i = 0; i < NTIMES; i++) {
        boxa = pixConnComp(pixs, NULL, 4);
        boxaDestroy(&boxa);
    }
    fprintf(stderr, "Time to compute 4-cc: %6.3f sec\n", stopTimer()/NTIMES);
    startTimer();
    for (i = 0; i < NTIMES; i++) {
        boxa = pixConnComp(pixs, NULL, 8);
        boxaDestroy(&boxa);
    }
    fprintf(stderr, "Time to compute 8-cc: %6.3f sec\n", stopTimer()/NTIMES);

        /* Draw outline of each c.c. box */
    boxa = pixConnComp(pixs, NULL, 4);
    n = boxaGetCount(boxa);
    fprintf(stderr, "Num 4-cc boxes: %d\n", n);
    for (i = 0; i < n; i++) {
        box = boxaGetBox(boxa, i, L_CLONE);
        pixRenderBox(pixs, box, 3, L_FLIP_PIXELS);
        boxDestroy(&box);   /* remember, clones need to be destroyed */
    }
    pixDisplayWrite(pixs, 1);
    boxaDestroy(&boxa);

        /* Display each component as a random color in cmapped 8 bpp.
         * Background is color 0; it is set to white. */
    boxa = pixConnComp(pixs, &pixa, 4);
    pixd = pixaDisplayRandomCmap(pixa, pixGetWidth(pixs), pixGetHeight(pixs));
    cmap = pixGetColormap(pixd);
    pixcmapResetColor(cmap, 0, 255, 255, 255);  /* reset background to white */
    pixDisplay(pixd, 100, 100);
    pixDisplayWrite(pixd, 1);
    boxaDestroy(&boxa);
    pixDestroy(&pixd);
    pixaDestroy(&pixa);

    pixDestroy(&pixs);
    return 0;
}
Exemple #9
0
l_int32
DoPageSegmentation(PIX     *pixs,   /* should be at least 300 ppi */
                   l_int32  which)  /* 1, 2, 3, 4 */
{
char         buf[256];
l_int32      zero;
BOXA        *boxatm, *boxahm;
PIX         *pixr;   /* image reduced to 150 ppi */
PIX         *pixhs;  /* image of halftone seed, 150 ppi */
PIX         *pixm;   /* image of mask of components, 150 ppi */
PIX         *pixhm1; /* image of halftone mask, 150 ppi */
PIX         *pixhm2; /* image of halftone mask, 300 ppi */
PIX         *pixht;  /* image of halftone components, 150 ppi */
PIX         *pixnht; /* image without halftone components, 150 ppi */
PIX         *pixi;   /* inverted image, 150 ppi */
PIX         *pixvws; /* image of vertical whitespace, 150 ppi */
PIX         *pixm1;  /* image of closed textlines, 150 ppi */
PIX         *pixm2;  /* image of refined text line mask, 150 ppi */
PIX         *pixm3;  /* image of refined text line mask, 300 ppi */
PIX         *pixb1;  /* image of text block mask, 150 ppi */
PIX         *pixb2;  /* image of text block mask, 300 ppi */
PIX         *pixnon; /* image of non-text or halftone, 150 ppi */
PIX         *pix1, *pix2, *pix3, *pix4;
PIXA        *pixa;
PIXCMAP     *cmap;
PTAA        *ptaa;
l_int32      ht_flag = 0;
l_int32      ws_flag = 0;
l_int32      text_flag = 0;
l_int32      block_flag = 0;

    PROCNAME("DoPageSegmentation");

    if (which == 1)
        ht_flag = 1;
    else if (which == 2)
        ws_flag = 1;
    else if (which == 3)
        text_flag = 1;
    else if (which == 4)
        block_flag = 1;
    else
        return ERROR_INT("invalid parameter: not in [1...4]", procName, 1);

    pixa = pixaCreate(0);
    lept_mkdir("lept/livre");

        /* Reduce to 150 ppi */
    pix1 = pixScaleToGray2(pixs);
    if (ws_flag || ht_flag || block_flag) pixaAddPix(pixa, pix1, L_COPY);
    if (which == 1)
        pixWrite("/tmp/lept/livre/orig.gray.150.png", pix1, IFF_PNG);
    pixDestroy(&pix1);
    pixr = pixReduceRankBinaryCascade(pixs, 1, 0, 0, 0);

        /* Get seed for halftone parts */
    pix1 = pixReduceRankBinaryCascade(pixr, 4, 4, 3, 0);
    pix2 = pixOpenBrick(NULL, pix1, 5, 5);
    pixhs = pixExpandBinaryPower2(pix2, 8);
    if (ht_flag) pixaAddPix(pixa, pixhs, L_COPY);
    if (which == 1)
        pixWrite("/tmp/lept/livre/htseed.150.png", pixhs, IFF_PNG);
    pixDestroy(&pix1);
    pixDestroy(&pix2);

        /* Get mask for connected regions */
    pixm = pixCloseSafeBrick(NULL, pixr, 4, 4);
    if (ht_flag) pixaAddPix(pixa, pixm, L_COPY);
    if (which == 1)
        pixWrite("/tmp/lept/livre/ccmask.150.png", pixm, IFF_PNG);

        /* Fill seed into mask to get halftone mask */
    pixhm1 = pixSeedfillBinary(NULL, pixhs, pixm, 4);
    if (ht_flag) pixaAddPix(pixa, pixhm1, L_COPY);
    if (which == 1) pixWrite("/tmp/lept/livre/htmask.150.png", pixhm1, IFF_PNG);
    pixhm2 = pixExpandBinaryPower2(pixhm1, 2);

        /* Extract halftone stuff */
    pixht = pixAnd(NULL, pixhm1, pixr);
    if (which == 1) pixWrite("/tmp/lept/livre/ht.150.png", pixht, IFF_PNG);

        /* Extract non-halftone stuff */
    pixnht = pixXor(NULL, pixht, pixr);
    if (text_flag) pixaAddPix(pixa, pixnht, L_COPY);
    if (which == 1) pixWrite("/tmp/lept/livre/text.150.png", pixnht, IFF_PNG);
    pixZero(pixht, &zero);
    if (zero)
        fprintf(stderr, "No halftone parts found\n");
    else
        fprintf(stderr, "Halftone parts found\n");

        /* Get bit-inverted image */
    pixi = pixInvert(NULL, pixnht);
    if (ws_flag) pixaAddPix(pixa, pixi, L_COPY);
    if (which == 1) pixWrite("/tmp/lept/livre/invert.150.png", pixi, IFF_PNG);

        /* The whitespace mask will break textlines where there
         * is a large amount of white space below or above.
         * We can prevent this by identifying regions of the
         * inverted image that have large horizontal (bigger than
         * the separation between columns) and significant
         * vertical extent (bigger than the separation between
         * textlines), and subtracting this from the whitespace mask. */
    pix1 = pixMorphCompSequence(pixi, "o80.60", 0);
    pix2 = pixSubtract(NULL, pixi, pix1);
    if (ws_flag) pixaAddPix(pixa, pix2, L_COPY);
    pixDestroy(&pix1);

        /* Identify vertical whitespace by opening inverted image */
    pix3 = pixOpenBrick(NULL, pix2, 5, 1);  /* removes thin vertical lines */
    pixvws = pixOpenBrick(NULL, pix3, 1, 200);  /* gets long vertical lines */
    if (text_flag || ws_flag) pixaAddPix(pixa, pixvws, L_COPY);
    if (which == 1) pixWrite("/tmp/lept/livre/vertws.150.png", pixvws, IFF_PNG);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Get proto (early processed) text line mask. */
        /* First close the characters and words in the textlines */
    pixm1 = pixCloseSafeBrick(NULL, pixnht, 30, 1);
    if (text_flag) pixaAddPix(pixa, pixm1, L_COPY);
    if (which == 1)
        pixWrite("/tmp/lept/livre/textmask1.150.png", pixm1, IFF_PNG);

        /* Next open back up the vertical whitespace corridors */
    pixm2 = pixSubtract(NULL, pixm1, pixvws);
    if (which == 1)
        pixWrite("/tmp/lept/livre/textmask2.150.png", pixm2, IFF_PNG);

        /* Do a small opening to remove noise */
    pixOpenBrick(pixm2, pixm2, 3, 3);
    if (text_flag) pixaAddPix(pixa, pixm2, L_COPY);
    if (which == 1)
         pixWrite("/tmp/lept/livre/textmask3.150.png", pixm2, IFF_PNG);
    pixm3 = pixExpandBinaryPower2(pixm2, 2);

        /* Join pixels vertically to make text block mask */
    pixb1 = pixMorphSequence(pixm2, "c1.10 + o4.1", 0);
    if (block_flag) pixaAddPix(pixa, pixb1, L_COPY);
    if (which == 1)
        pixWrite("/tmp/lept/livre/textblock1.150.png", pixb1, IFF_PNG);

        /* Solidify the textblock mask and remove noise:
         *  (1) For each c.c., close the blocks and dilate slightly
         *      to form a solid mask.
         *  (2) Small horizontal closing between components
         *  (3) Open the white space between columns, again
         *  (4) Remove small components */
    pix1 = pixMorphSequenceByComponent(pixb1, "c30.30 + d3.3", 8, 0, 0, NULL);
    pixCloseSafeBrick(pix1, pix1, 10, 1);
    if (block_flag) pixaAddPix(pixa, pix1, L_COPY);
    pix2 = pixSubtract(NULL, pix1, pixvws);
    pix3 = pixSelectBySize(pix2, 25, 5, 8, L_SELECT_IF_BOTH,
                            L_SELECT_IF_GTE, NULL);
    if (block_flag) pixaAddPix(pixa, pix3, L_COPY);
    if (which == 1)
        pixWrite("/tmp/lept/livre/textblock2.150.png", pix3, IFF_PNG);
    pixb2 = pixExpandBinaryPower2(pix3, 2);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Identify the outlines of each textblock */
    ptaa = pixGetOuterBordersPtaa(pixb2);
    pix1 = pixRenderRandomCmapPtaa(pixb2, ptaa, 1, 8, 1);
    cmap = pixGetColormap(pix1);
    pixcmapResetColor(cmap, 0, 130, 130, 130);  /* set interior to gray */
    if (which == 1)
        pixWrite("/tmp/lept/livre/textblock3.300.png", pix1, IFF_PNG);
    pixDisplayWithTitle(pix1, 480, 360, "textblock mask with outlines", DFLAG);
    ptaaDestroy(&ptaa);
    pixDestroy(&pix1);

        /* Fill line mask (as seed) into the original */
    pix1 = pixSeedfillBinary(NULL, pixm3, pixs, 8);
    pixOr(pixm3, pixm3, pix1);
    pixDestroy(&pix1);
    if (which == 1)
        pixWrite("/tmp/lept/livre/textmask.300.png", pixm3, IFF_PNG);
    pixDisplayWithTitle(pixm3, 480, 360, "textline mask 4", DFLAG);

        /* Fill halftone mask (as seed) into the original */
    pix1 = pixSeedfillBinary(NULL, pixhm2, pixs, 8);
    pixOr(pixhm2, pixhm2, pix1);
    pixDestroy(&pix1);
    if (which == 1)
        pixWrite("/tmp/lept/livre/htmask.300.png", pixhm2, IFF_PNG);
    pixDisplayWithTitle(pixhm2, 520, 390, "halftonemask 2", DFLAG);

        /* Find objects that are neither text nor halftones */
    pix1 = pixSubtract(NULL, pixs, pixm3);  /* remove text pixels */
    pixnon = pixSubtract(NULL, pix1, pixhm2);  /* remove halftone pixels */
    pixDestroy(&pix1);
    if (which == 1)
        pixWrite("/tmp/lept/livre/other.300.png", pixnon, IFF_PNG);
    pixDisplayWithTitle(pixnon, 540, 420, "other stuff", DFLAG);

        /* Write out b.b. for text line mask and halftone mask components */
    boxatm = pixConnComp(pixm3, NULL, 4);
    boxahm = pixConnComp(pixhm2, NULL, 8);
    if (which == 1) {
        boxaWrite("/tmp/lept/livre/textmask.boxa", boxatm);
        boxaWrite("/tmp/lept/livre/htmask.boxa", boxahm);
    }

    pix1 = pixaDisplayTiledAndScaled(pixa, 8, 250, 4, 0, 25, 2);
    pixDisplay(pix1, 0, 375 * (which - 1));
    snprintf(buf, sizeof(buf), "/tmp/lept/livre/segout.%d.png", which);
    pixWrite(buf, pix1, IFF_PNG);
    pixDestroy(&pix1);
    pixaDestroy(&pixa);

        /* clean up to test with valgrind */
    pixDestroy(&pixr);
    pixDestroy(&pixhs);
    pixDestroy(&pixm);
    pixDestroy(&pixhm1);
    pixDestroy(&pixhm2);
    pixDestroy(&pixht);
    pixDestroy(&pixi);
    pixDestroy(&pixnht);
    pixDestroy(&pixvws);
    pixDestroy(&pixm1);
    pixDestroy(&pixm2);
    pixDestroy(&pixm3);
    pixDestroy(&pixb1);
    pixDestroy(&pixb2);
    pixDestroy(&pixnon);
    boxaDestroy(&boxatm);
    boxaDestroy(&boxahm);
    return 0;
}
Exemple #10
0
/*!
 * \brief   pixColorSegmentTryCluster()
 *
 * \param[in]    pixd
 * \param[in]    pixs
 * \param[in]    maxdist
 * \param[in]    maxcolors
 * \param[in]    debugflag  1 for debug output; 0 otherwise
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      This function should only be called from pixColorSegCluster()
 * </pre>
 */
static l_int32
pixColorSegmentTryCluster(PIX     *pixd,
                          PIX     *pixs,
                          l_int32  maxdist,
                          l_int32  maxcolors,
                          l_int32  debugflag)
{
l_int32    rmap[256], gmap[256], bmap[256];
l_int32    w, h, wpls, wpld, i, j, k, found, ret, index, ncolors;
l_int32    rval, gval, bval, dist2, maxdist2;
l_int32    countarray[256];
l_int32    rsum[256], gsum[256], bsum[256];
l_uint32  *ppixel;
l_uint32  *datas, *datad, *lines, *lined;
PIXCMAP   *cmap;

    PROCNAME("pixColorSegmentTryCluster");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!pixd)
        return ERROR_INT("pixd not defined", procName, 1);

    w = pixGetWidth(pixs);
    h = pixGetHeight(pixs);
    maxdist2 = maxdist * maxdist;
    cmap = pixGetColormap(pixd);
    pixcmapClear(cmap);
    for (k = 0; k < 256; k++) {
        rsum[k] = gsum[k] = bsum[k] = 0;
        rmap[k] = gmap[k] = bmap[k] = 0;
    }

    datas = pixGetData(pixs);
    datad = pixGetData(pixd);
    wpls = pixGetWpl(pixs);
    wpld = pixGetWpl(pixd);
    ncolors = 0;
    for (i = 0; i < h; i++) {
        lines = datas + i * wpls;
        lined = datad + i * wpld;
        for (j = 0; j < w; j++) {
            ppixel = lines + j;
            rval = GET_DATA_BYTE(ppixel, COLOR_RED);
            gval = GET_DATA_BYTE(ppixel, COLOR_GREEN);
            bval = GET_DATA_BYTE(ppixel, COLOR_BLUE);
            ncolors = pixcmapGetCount(cmap);
            found = FALSE;
            for (k = 0; k < ncolors; k++) {
                dist2 = (rval - rmap[k]) * (rval - rmap[k]) +
                        (gval - gmap[k]) * (gval - gmap[k]) +
                        (bval - bmap[k]) * (bval - bmap[k]);
                if (dist2 <= maxdist2) {  /* take it; greedy */
                    found = TRUE;
                    SET_DATA_BYTE(lined, j, k);
                    countarray[k]++;
                    rsum[k] += rval;
                    gsum[k] += gval;
                    bsum[k] += bval;
                    break;
                }
            }
            if (!found) {  /* Add a new color */
                ret = pixcmapAddNewColor(cmap, rval, gval, bval, &index);
/*                fprintf(stderr,
                        "index = %d, (i,j) = (%d,%d), rgb = (%d, %d, %d)\n",
                        index, i, j, rval, gval, bval); */
                if (ret == 0 && index < maxcolors) {
                    countarray[index] = 1;
                    SET_DATA_BYTE(lined, j, index);
                    rmap[index] = rval;
                    gmap[index] = gval;
                    bmap[index] = bval;
                    rsum[index] = rval;
                    gsum[index] = gval;
                    bsum[index] = bval;
                } else {
                    if (debugflag) {
                        L_INFO("maxcolors exceeded for maxdist = %d\n",
                               procName, maxdist);
                    }
                    return 1;
                }
            }
        }
    }

        /* Replace the colors in the colormap by the averages */
    for (k = 0; k < ncolors; k++) {
        rval = rsum[k] / countarray[k];
        gval = gsum[k] / countarray[k];
        bval = bsum[k] / countarray[k];
        pixcmapResetColor(cmap, k, rval, gval, bval);
    }

    return 0;
}
Exemple #11
0
/*!
 *  pixGetRegionsBinary()
 *
 *      Input:  pixs (1 bpp, assumed to be 300 to 400 ppi)
 *              &pixhm (<optional return> halftone mask)
 *              &pixtm (<optional return> textline mask)
 *              &pixtb (<optional return> textblock mask)
 *              debug (flag: set to 1 for debug output)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) It is best to deskew the image before segmenting.
 *      (2) The debug flag enables a number of outputs.  These
 *          are included to show how to generate and save/display
 *          these results.
 */
l_int32
pixGetRegionsBinary(PIX     *pixs,
                    PIX    **ppixhm,
                    PIX    **ppixtm,
                    PIX    **ppixtb,
                    l_int32  debug)
{
char    *tempname;
l_int32  htfound, tlfound;
PIX     *pixr, *pixt1, *pixt2;
PIX     *pixtext;  /* text pixels only */
PIX     *pixhm2;   /* halftone mask; 2x reduction */
PIX     *pixhm;    /* halftone mask;  */
PIX     *pixtm2;   /* textline mask; 2x reduction */
PIX     *pixtm;    /* textline mask */
PIX     *pixvws;   /* vertical white space mask */
PIX     *pixtb2;   /* textblock mask; 2x reduction */
PIX     *pixtbf2;  /* textblock mask; 2x reduction; small comps filtered */
PIX     *pixtb;    /* textblock mask */

    PROCNAME("pixGetRegionsBinary");

    if (ppixhm) *ppixhm = NULL;
    if (ppixtm) *ppixtm = NULL;
    if (ppixtb) *ppixtb = NULL;
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (pixGetDepth(pixs) != 1)
        return ERROR_INT("pixs not 1 bpp", procName, 1);

        /* 2x reduce, to 150 -200 ppi */
    pixr = pixReduceRankBinaryCascade(pixs, 1, 0, 0, 0);
    pixDisplayWrite(pixr, debug);

        /* Get the halftone mask */
    pixhm2 = pixGenHalftoneMask(pixr, &pixtext, &htfound, debug);

        /* Get the textline mask from the text pixels */
    pixtm2 = pixGenTextlineMask(pixtext, &pixvws, &tlfound, debug);

        /* Get the textblock mask from the textline mask */
    pixtb2 = pixGenTextblockMask(pixtm2, pixvws, debug);
    pixDestroy(&pixr);
    pixDestroy(&pixtext);
    pixDestroy(&pixvws);

        /* Remove small components from the mask, where a small
         * component is defined as one with both width and height < 60 */
    pixtbf2 = pixSelectBySize(pixtb2, 60, 60, 4, L_SELECT_IF_EITHER,
                              L_SELECT_IF_GTE, NULL);
    pixDestroy(&pixtb2);
    pixDisplayWriteFormat(pixtbf2, debug, IFF_PNG);

        /* Expand all masks to full resolution, and do filling or
         * small dilations for better coverage. */
    pixhm = pixExpandReplicate(pixhm2, 2);
    pixt1 = pixSeedfillBinary(NULL, pixhm, pixs, 8);
    pixOr(pixhm, pixhm, pixt1);
    pixDestroy(&pixt1);
    pixDisplayWriteFormat(pixhm, debug, IFF_PNG);

    pixt1 = pixExpandReplicate(pixtm2, 2);
    pixtm = pixDilateBrick(NULL, pixt1, 3, 3);
    pixDestroy(&pixt1);
    pixDisplayWriteFormat(pixtm, debug, IFF_PNG);

    pixt1 = pixExpandReplicate(pixtbf2, 2);
    pixtb = pixDilateBrick(NULL, pixt1, 3, 3);
    pixDestroy(&pixt1);
    pixDisplayWriteFormat(pixtb, debug, IFF_PNG);

    pixDestroy(&pixhm2);
    pixDestroy(&pixtm2);
    pixDestroy(&pixtbf2);

        /* Debug: identify objects that are neither text nor halftone image */
    if (debug) {
        pixt1 = pixSubtract(NULL, pixs, pixtm);  /* remove text pixels */
        pixt2 = pixSubtract(NULL, pixt1, pixhm);  /* remove halftone pixels */
        pixDisplayWriteFormat(pixt2, 1, IFF_PNG);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
    }

        /* Debug: display textline components with random colors */
    if (debug) {
        l_int32  w, h;
        BOXA    *boxa;
        PIXA    *pixa;
        boxa = pixConnComp(pixtm, &pixa, 8);
        pixGetDimensions(pixtm, &w, &h, NULL);
        pixt1 = pixaDisplayRandomCmap(pixa, w, h);
        pixcmapResetColor(pixGetColormap(pixt1), 0, 255, 255, 255);
        pixDisplay(pixt1, 100, 100);
        pixDisplayWriteFormat(pixt1, 1, IFF_PNG);
        pixaDestroy(&pixa);
        boxaDestroy(&boxa);
        pixDestroy(&pixt1);
    }

        /* Debug: identify the outlines of each textblock */
    if (debug) {
        PIXCMAP  *cmap;
        PTAA     *ptaa;
        ptaa = pixGetOuterBordersPtaa(pixtb);
        tempname = genTempFilename("/tmp", "tb_outlines.ptaa", 0, 0);
        ptaaWrite(tempname, ptaa, 1);
        FREE(tempname);
        pixt1 = pixRenderRandomCmapPtaa(pixtb, ptaa, 1, 16, 1);
        cmap = pixGetColormap(pixt1);
        pixcmapResetColor(cmap, 0, 130, 130, 130);
        pixDisplay(pixt1, 500, 100);
        pixDisplayWriteFormat(pixt1, 1, IFF_PNG);
        pixDestroy(&pixt1);
        ptaaDestroy(&ptaa);
    }

        /* Debug: get b.b. for all mask components */
    if (debug) {
        BOXA  *bahm, *batm, *batb;
        bahm = pixConnComp(pixhm, NULL, 4);
        batm = pixConnComp(pixtm, NULL, 4);
        batb = pixConnComp(pixtb, NULL, 4);
        tempname = genTempFilename("/tmp", "htmask.boxa", 0, 0);
        boxaWrite(tempname, bahm);
        FREE(tempname);
        tempname = genTempFilename("/tmp", "textmask.boxa", 0, 0);
        boxaWrite(tempname, batm);
        FREE(tempname);
        tempname = genTempFilename("/tmp", "textblock.boxa", 0, 0);
        boxaWrite(tempname, batb);
        FREE(tempname);
	boxaDestroy(&bahm);
	boxaDestroy(&batm);
	boxaDestroy(&batb);
    }

    if (ppixhm)
        *ppixhm = pixhm;
    else
        pixDestroy(&pixhm);
    if (ppixtm)
        *ppixtm = pixtm;
    else
        pixDestroy(&pixtm);
    if (ppixtb)
        *ppixtb = pixtb;
    else
        pixDestroy(&pixtb);

    return 0;
}
l_int32 main(int    argc,
             char **argv)
{
char          buf[512];
l_int32       i, n, index;
l_int32       rval[4], gval[4], bval[4];
l_uint32      scolor, dcolor;
L_BMF        *bmf;
PIX          *pix0, *pix1, *pix2, *pix3, *pix4, *pix5;
PIXA         *pixa;
PIXCMAP      *cmap;
L_REGPARAMS  *rp;

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

        /* Read in the bg colors */
    for (i = 0; i < 4; i++)
        sscanf(bgcolors[i], "%d %d %d", &rval[i], &gval[i], &bval[i]);
    bmf = bmfCreate("fonts", 8);

        /* Get the input image (100 ppi resolution) */
    pix0 = pixRead("harmoniam100-11.png");
    cmap = pixGetColormap(pix0);
    pixa = pixaCreate(0);

        /* Do cmapped coloring on the white pixels only */
    pixcmapGetIndex(cmap, 255, 255, 255, &index);  /* index of white pixels */
    for (i = 0; i < 4; i++) {
        pixcmapResetColor(cmap, index, rval[i], gval[i], bval[i]);
        snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)",
                 rval[i], gval[i], bval[i]);
        pix1 = pixAddSingleTextblock(pix0, bmf, buf, 0xff000000,
                                     L_ADD_AT_BOT, NULL);
        pixaAddPix(pixa, pix1, L_INSERT);
    }

        /* Do cmapped background coloring on all the pixels */
    for (i = 0; i < 4; i++) {
        scolor = 0xffffff00;  /* source color */
        composeRGBPixel(rval[i], gval[i], bval[i], &dcolor);  /* dest color */
        pix1 = pixShiftByComponent(NULL, pix0, scolor, dcolor);
        snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)",
                 rval[i], gval[i], bval[i]);
        pix2 = pixAddSingleTextblock(pix1, bmf, buf, 0xff000000,
                                     L_ADD_AT_BOT, NULL);
        pixaAddPix(pixa, pix2, L_INSERT);
        pixDestroy(&pix1);
    }


        /* Do background coloring on rgb */
    pix1 = pixConvertTo32(pix0);
    for (i = 0; i < 4; i++) {
        scolor = 0xffffff00;
        composeRGBPixel(rval[i], gval[i], bval[i], &dcolor);
        pix2 = pixShiftByComponent(NULL, pix1, scolor, dcolor);
        snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)",
                 rval[i], gval[i], bval[i]);
        pix3 = pixAddSingleTextblock(pix2, bmf, buf, 0xff000000,
                                     L_ADD_AT_BOT, NULL);
        pixaAddPix(pixa, pix3, L_INSERT);
        pixDestroy(&pix2);
    }
    pixDestroy(&pix1);

        /* Compare cmapped & rgb foreground coloring */
    scolor = 0x0;  /* source color */
    composeRGBPixel(200, 30, 150, &dcolor);  /* ugly fg dest color */
    pix1 = pixShiftByComponent(NULL, pix0, scolor, dcolor);  /* cmapped */
    snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)",
             200, 100, 50);
    pix2 = pixAddSingleTextblock(pix1, bmf, buf, 0xff000000,
                                 L_ADD_AT_BOT, NULL);
    pixaAddPix(pixa, pix2, L_INSERT);
    pix3 = pixConvertTo32(pix0);
    pix4 = pixShiftByComponent(NULL, pix3, scolor, dcolor);  /* rgb */
    snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)",
             200, 100, 50);
    pix5 = pixAddSingleTextblock(pix4, bmf, buf, 0xff000000,
                                 L_ADD_AT_BOT, NULL);
    pixaAddPix(pixa, pix5, L_INSERT);
    regTestComparePix(rp, pix1, pix4);
    regTestComparePix(rp, pix2, pix5);
    pixDestroy(&pix1);
    pixDestroy(&pix3);
    pixDestroy(&pix4);

        /* Log all the results */
    n = pixaGetCount(pixa);
    for (i = 0; i < n; i++) {
        pix1 = pixaGetPix(pixa, i, L_CLONE);
        regTestWritePixAndCheck(rp, pix1, IFF_PNG);
        pixDestroy(&pix1);
    }

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

    pixaDestroy(&pixa);
    pixDestroy(&pix0);
    bmfDestroy(&bmf);
    return regTestCleanup(rp);
}
Exemple #13
0
l_int32 main(int    argc,
             char **argv)
{
l_int32       index;
PIX          *pixs, *pixc, *pixd;
PIXCMAP      *cmap;
L_REGPARAMS  *rp;

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

    fprintf(stderr, "Test binary image:\n");
    pixs = pixRead(BINARY_IMAGE);
    pixd = shearTest(pixs, 1);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 0 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
    pixDestroy(&pixs);
    pixDestroy(&pixd);

        /* We change the black to dark red so that we can see
         * that the IP shear does brings in that color.  It
         * can't bring in black because the cmap is filled. */
    fprintf(stderr, "Test 2 bpp cmapped image with filled cmap:\n");
    pixs = pixRead(TWO_BPP_IMAGE);
    cmap = pixGetColormap(pixs);
    pixcmapGetIndex(cmap, 40, 44, 40, &index);
    pixcmapResetColor(cmap, index, 100, 0, 0);
    pixd = shearTest(pixs, 1);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 1 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
    pixDestroy(&pixs);
    pixDestroy(&pixd);

    fprintf(stderr, "Test 4 bpp cmapped image with unfilled cmap:\n");
    pixs = pixRead(FOUR_BPP_IMAGE1);
    pixd = shearTest(pixs, 1);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 2 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
    pixDestroy(&pixs);
    pixDestroy(&pixd);

    fprintf(stderr, "Test 4 bpp cmapped image with filled cmap:\n");
    pixs = pixRead(FOUR_BPP_IMAGE2);
    pixd = shearTest(pixs, 1);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 3 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
    pixDestroy(&pixs);
    pixDestroy(&pixd);

    fprintf(stderr, "Test 8 bpp grayscale image:\n");
    pixs = pixRead(EIGHT_BPP_IMAGE);
    pixd = shearTest(pixs, 2);
    regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG);  /* 4 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
    pixDestroy(&pixs);
    pixDestroy(&pixd);

    fprintf(stderr, "Test 8 bpp grayscale cmap image:\n");
    pixs = pixRead(EIGHT_BPP_CMAP_IMAGE1);
    pixd = shearTest(pixs, 1);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 5 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
    pixDestroy(&pixs);
    pixDestroy(&pixd);

    fprintf(stderr, "Test 8 bpp color cmap image:\n");
    pixs = pixRead(EIGHT_BPP_CMAP_IMAGE2);
    pixd = pixOctreeColorQuant(pixs, 200, 0);
    pixc = shearTest(pixd, 3);
    regTestWritePixAndCheck(rp, pixc, IFF_JFIF_JPEG);  /* 6 */
    pixDisplayWithTitle(pixc, 100, 100, NULL, rp->display);
    pixDestroy(&pixs);
    pixDestroy(&pixd);
    pixDestroy(&pixc);

    fprintf(stderr, "Test rgb image:\n");
    pixs = pixRead(RGB_IMAGE);
    pixd = shearTest(pixs, 2);
    regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG);  /* 7 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
    pixDestroy(&pixs);
    pixDestroy(&pixd);

    return regTestCleanup(rp);
}
main(int    argc,
     char **argv)
{
l_int32      w, h;
BOXA        *boxa;
PIX         *pixs, *pixt1, *pixt2, *pixg, *pixb, *pixd, *pixc;
PIX         *pixm, *pixm2, *pixd2, *pixs2;
PIXA        *pixa, *pixac;
PIXCMAP     *cmap, *cmapg;
static char  mainName[] = "misctest1";

    pixac = pixaCreate(0);

        /* Combine two grayscale images using a mask */
    pixd = pixRead("feyn.tif");
    pixs = pixRead("rabi.png");
    pixm = pixRead("pageseg2-seed.png");
    pixd2 = pixScaleToGray2(pixd);
    pixs2 = pixScaleToGray2(pixs);
    pixSaveTiled(pixd2, pixac, 2, 1, 40, 32);
    pixSaveTiled(pixs2, pixac, 2, 0, 40, 0);
    pixSaveTiled(pixm, pixac, 2, 0, 40, 0);
    pixCombineMaskedGeneral(pixd2, pixs2, pixm, 100, 100);
    pixSaveTiled(pixd2, pixac, 2, 1, 40, 0);
    pixDisplayWithTitle(pixd2, 100, 100, NULL, SHOW);
    pixDestroy(&pixd2);
    pixDestroy(&pixs2);

        /* Combine two binary images using a mask */
    pixm2 = pixExpandBinaryReplicate(pixm, 2);
    pixt1 = pixCopy(NULL, pixd);
    pixCombineMaskedGeneral(pixd, pixs, pixm2, 200, 200);
    pixSaveTiled(pixd, pixac, 4, 0, 40, 0);
    pixDisplayWithTitle(pixd, 700, 100, NULL, SHOW);
    pixCombineMasked(pixt1, pixs, pixm2);
    pixSaveTiled(pixt1, pixac, 4, 0, 40, 0);
    pixDestroy(&pixd);
    pixDestroy(&pixt1);
    pixDestroy(&pixs);
    pixDestroy(&pixm);
    pixDestroy(&pixm2);

        /* Do a restricted seedfill */
    pixs = pixRead("pageseg2-seed.png");
    pixm = pixRead("pageseg2-mask.png");
    pixd = pixSeedfillBinaryRestricted(NULL, pixs, pixm, 8, 50, 175);
    pixSaveTiled(pixs, pixac, 2, 1, 40, 0);
    pixSaveTiled(pixm, pixac, 2, 0, 40, 0);
    pixSaveTiled(pixd, pixac, 2, 0, 40, 0);
    pixDestroy(&pixs);
    pixDestroy(&pixm);
    pixDestroy(&pixd);

        /* Colorize a grayscale image */
    pixs = pixRead("lucasta.150.jpg");
    pixGetDimensions(pixs, &w, &h, NULL);
    pixb = pixThresholdToBinary(pixs, 128);
    boxa = pixConnComp(pixb, &pixa, 8);
    pixSaveTiled(pixs, pixac, 1, 1, 40, 0);
    cmap = pixcmapGrayToColor(0x6f90c0);
    pixSetColormap(pixs, cmap);
    pixSaveTiled(pixs, pixac, 1, 0, 40, 0);
    pixc = pixaDisplayRandomCmap(pixa, w, h);
    pixcmapResetColor(pixGetColormap(pixc), 0, 255, 255, 255);
    pixSaveTiled(pixc, pixac, 1, 0, 40, 0);
    pixDestroy(&pixs);
    pixDestroy(&pixb);
    pixDestroy(&pixc);
    boxaDestroy(&boxa);
    pixaDestroy(&pixa);

        /* Convert color to gray */
    pixs = pixRead("weasel4.16c.png");
    pixSaveTiled(pixs, pixac, 1, 1, 20, 0);
    pixc = pixConvertTo32(pixs);
    pixt1 = pixConvertRGBToGray(pixc, 3., 7., 5.);
    pixSaveTiled(pixt1, pixac, 1, 0, 20, 0);
    pixt2 = pixConvertRGBToGrayFast(pixc);
    pixSaveTiled(pixt2, pixac, 1, 0, 20, 0);
    pixg = pixCopy(NULL, pixs);
    cmap = pixGetColormap(pixs);
    cmapg = pixcmapColorToGray(cmap, 4., 6., 3.);
    pixSetColormap(pixg, cmapg);
    pixSaveTiled(pixg, pixac, 1, 0, 20, 0);
    pixDestroy(&pixs);
    pixDestroy(&pixc);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixg);

    pixd = pixaDisplay(pixac, 0, 0);
    pixDisplayWithTitle(pixd, 100, 100, NULL, 1);
    pixWrite("junkmisc1.png", pixd, IFF_PNG);
    pixDestroy(&pixd);
    pixaDestroy(&pixac);

    return 0;
}
main(int    argc,
     char **argv)
{
l_uint8     *array1, *array2;
l_int32      i, n, np, same, diff, nbytes1, nbytes2;
FILE        *fp;
BOX         *box;
BOXA        *boxa, *boxa2;
PIX         *pixs, *pixd;
PIXA        *pixa;
PIXCMAP     *cmap;
static char  mainName[] = "conncomp_reg";

    if (argc != 1)
	exit(ERROR_INT(" Syntax: conncomp_reg", mainName, 1));

    if ((pixs = pixRead("feyn.tif")) == NULL)
	exit(ERROR_INT("pixs not made", mainName, 1));
	    
	/* Test pixConnComp() with output to both boxa and pixa */
	/* First, test with 4-cc */
    boxa = pixConnComp(pixs, &pixa, 4);
    n = boxaGetCount(boxa);
    fprintf(stderr, "Number of 4 c.c. b.b: %d\n", n);
    np = pixaGetCount(pixa);
    fprintf(stderr, "Number of 4 c.c. pix: %d\n", np);
    pixd = pixaDisplay(pixa, pixGetWidth(pixs), pixGetHeight(pixs));
    pixWrite("/tmp/junkout1.png", pixd, IFF_PNG);
    pixEqual(pixs, pixd, &same);
    if (same == 1)
	fprintf(stderr, "Source and reconstructed pix are the same.\n");
    else
	fprintf(stderr, "Error: source and reconstructed pix differ!\n");
    pixaDestroy(&pixa);
    boxaDestroy(&boxa);
    pixDestroy(&pixd);

	/* Test with 8-cc */
    boxa = pixConnComp(pixs, &pixa, 8);
    n = boxaGetCount(boxa);
    fprintf(stderr, "Number of 8 c.c. b.b: %d\n", n);
    np = pixaGetCount(pixa);
    fprintf(stderr, "Number of 8 c.c. pix: %d\n", np);
    pixd = pixaDisplay(pixa, pixGetWidth(pixs), pixGetHeight(pixs));
    pixWrite("/tmp/junkout2.png", pixd, IFF_PNG);
    pixEqual(pixs, pixd, &same);
    if (same == 1)
	fprintf(stderr, "Source and reconstructed pix are the same.\n");
    else
	fprintf(stderr, "Error: source and reconstructed pix differ!\n");
    pixaDestroy(&pixa);
    boxaDestroy(&boxa);
    pixDestroy(&pixd);

	/* Test i/o */
    boxa = pixConnComp(pixs, NULL, 4);
    fp = fopen("/tmp/junk1.ba", "wb+");
    boxaWriteStream(fp, boxa);
    fclose(fp);
    fp = fopen("/tmp/junk1.ba", "r");
    boxa2 = boxaReadStream(fp);
    fclose(fp);
    fp = fopen("/tmp/junk2.ba", "wb+");
    boxaWriteStream(fp, boxa2);
    fclose(fp);
    array1 = arrayRead("/tmp/junk1.ba", &nbytes1);
    array2 = arrayRead("/tmp/junk2.ba", &nbytes2);
    diff = strcmp((char *)array1, (char *)array2);
    if (nbytes1 != nbytes2 || diff)
	fprintf(stderr, "I/O error for boxes.\n");
    else
	fprintf(stderr, "I/O valid for boxes.\n");
    FREE(array1);
    FREE(array2);
    boxaDestroy(&boxa);
    boxaDestroy(&boxa2);

        /* Just for fun, display each component as a random color
	 * in cmapped 8 bpp.  Background is color 0; it is set to white. */
    boxa = pixConnComp(pixs, &pixa, 4);
    pixd = pixaDisplayRandomCmap(pixa, pixGetWidth(pixs), pixGetHeight(pixs));
    cmap = pixGetColormap(pixd);
    pixcmapResetColor(cmap, 0, 255, 255, 255);  /* reset background to white */
    pixDisplay(pixd, 100, 100);
    boxaDestroy(&boxa);
    pixDestroy(&pixd);
    pixaDestroy(&pixa);

    pixDestroy(&pixs);

    exit(0);
}
Exemple #16
0
main(int    argc,
     char **argv)
{
l_int32      ws, hs;
BOX         *box;
BOXA        *boxa;
PIX         *pixs, *pixc, *pix32, *pixt, *pixd;
PIXA        *pixat, *pixas, *pixac;
static char  mainName[] = "pixadisp_reg";

    if (argc != 1)
        exit(ERROR_INT(" Syntax: pixadisp_reg", mainName, 1));

    if ((pixs = pixRead("feyn.tif")) == NULL)
        exit(ERROR_INT("pixs not made", mainName, 1));
    box = boxCreate(683, 799, 970, 479);
    pixc = pixClipRectangle(pixs, box, NULL);
    boxDestroy(&box);
    pixDisplayWrite(pixc, 1);
    if ((pix32 = pixRead("marge.jpg")) == NULL)
        exit(ERROR_INT("pix32 not made", mainName, 1));

        /* Generate pixas from pixs and pixac from pixc */
    boxa = pixConnComp(pixs, &pixat, 8);
    pixas = pixaSelectBySize(pixat, 60, 60, L_SELECT_IF_BOTH,
                             L_SELECT_IF_LTE, NULL);
    pixaDestroy(&pixat);
    boxaDestroy(&boxa);
    boxa = pixConnComp(pixc, &pixac, 8);
    boxaDestroy(&boxa);
 
        /* pixaDisplay() */
    pixGetDimensions(pixs, &ws, &hs, NULL);
    pixd = pixaDisplay(pixas, ws, hs);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

        /* pixaDisplayRandomCmap() */
    pixd = pixaDisplayRandomCmap(pixas, ws, hs);  /* black bg */
    pixDisplayWrite(pixd, 1);
    pixcmapResetColor(pixGetColormap(pixd), 0, 255, 255, 255);  /* white bg */
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

        /* pixaDisplayOnLattice() */
    pixd = pixaDisplayOnLattice(pixac, 50, 50);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

        /* pixaDisplayUnsplit() */
    pixat = pixaSplitPix(pix32, 5, 7, 10, 0x0000ff00);
    pixd = pixaDisplayUnsplit(pixat, 5, 7, 10, 0x00ff0000);
    pixDisplayWrite(pixd, 1);
    pixaDestroy(&pixat);
    pixDestroy(&pixd);

        /* pixaDisplayTiled() */
    pixd = pixaDisplayTiled(pixac, 1000, 0, 10);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

        /* pixaDisplayTiledInRows() */
    pixd = pixaDisplayTiledInRows(pixac, 1, 1000, 1.0, 0, 10, 2);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);


        /* pixaDisplayTiledAndScaled() */
    pixd = pixaDisplayTiledAndScaled(pixac, 1, 25, 20, 0, 5, 0);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

    pixat = pixaCreate(10);
    pixd = pixRankFilter(pix32, 8, 8, 0.5);
    pixaAddPix(pixat, pixd, L_INSERT);
    pixt = pixScale(pix32, 0.5, 0.5);
    pixd = pixRankFilter(pixt, 8, 8, 0.5);
    pixaAddPix(pixat, pixd, L_INSERT);
    pixDestroy(&pixt);
    pixt = pixScale(pix32, 0.25, 0.25);
    pixd = pixRankFilter(pixt, 8, 8, 0.5);
    pixaAddPix(pixat, pixd, L_INSERT);
    pixDestroy(&pixt);
    pixd = pixaDisplayTiledAndScaled(pixat, 32, 500, 1, 0, 25, 0);
    pixDisplayWrite(pixd, 1);
    pixaDestroy(&pixat);
    pixDestroy(&pixd);

    pixaDestroy(&pixas);
    pixaDestroy(&pixac);
    pixDestroy(&pixs);
    pixDestroy(&pixc);
    pixDestroy(&pix32);

    pixDisplayMultiple("/tmp/junk_write_display*");
    return 0;
}