Exemplo n.º 1
0
/*!
 * \brief   pixConnCompTransform()
 *
 * \param[in]     pixs 1 bpp
 * \param[in]     connect connectivity: 4 or 8
 * \param[in]     depth of pixd: 8 or 16 bpp; use 0 for auto determination
 * \return   pixd 8, 16 or 32 bpp, or NULL on error
 *
 * <pre>
 * Notes:
 *      (1) pixd is 8, 16 or 32 bpp, and the pixel values label the
 *          fg component, starting with 1.  Pixels in the bg are labelled 0.
 *      (2) If %depth = 0, the depth of pixd is 8 if the number of c.c.
 *          is less than 254, 16 if the number of c.c is less than 0xfffe,
 *          and 32 otherwise.
 *      (3) If %depth = 8, the assigned label for the n-th component is
 *          1 + n % 254.  We use mod 254 because 0 is uniquely assigned
 *          to black: e.g., see pixcmapCreateRandom().  Likewise,
 *          if %depth = 16, the assigned label uses mod(2^16 - 2), and
 *          if %depth = 32, no mod is taken.
 * </pre>
 */
PIX *
pixConnCompTransform(PIX     *pixs,
                     l_int32  connect,
                     l_int32  depth)
{
l_int32  i, n, index, w, h, xb, yb, wb, hb;
BOXA    *boxa;
PIX     *pix1, *pix2, *pixd;
PIXA    *pixa;

    PROCNAME("pixConnCompTransform");

    if (!pixs || pixGetDepth(pixs) != 1)
        return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
    if (connect != 4 && connect != 8)
        return (PIX *)ERROR_PTR("connectivity must be 4 or 8", procName, NULL);
    if (depth != 0 && depth != 8 && depth != 16 && depth != 32)
        return (PIX *)ERROR_PTR("depth must be 0, 8, 16 or 32", procName, NULL);

    boxa = pixConnComp(pixs, &pixa, connect);
    n = pixaGetCount(pixa);
    boxaDestroy(&boxa);
    pixGetDimensions(pixs, &w, &h, NULL);
    if (depth == 0) {
        if (n < 254)
            depth = 8;
        else if (n < 0xfffe)
            depth = 16;
        else
            depth = 32;
    }
    pixd = pixCreate(w, h, depth);
    pixSetSpp(pixd, 1);
    if (n == 0) {  /* no fg */
        pixaDestroy(&pixa);
        return pixd;
    }

       /* Label each component and blit it in */
    for (i = 0; i < n; i++) {
        pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb);
        pix1 = pixaGetPix(pixa, i, L_CLONE);
        if (depth == 8) {
            index = 1 + (i % 254);
            pix2 = pixConvert1To8(NULL, pix1, 0, index);
        } else if (depth == 16) {
            index = 1 + (i % 0xfffe);
            pix2 = pixConvert1To16(NULL, pix1, 0, index);
        } else {  /* depth == 32 */
            index = 1 + i;
            pix2 = pixConvert1To32(NULL, pix1, 0, index);
        }
        pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pix2, 0, 0);
        pixDestroy(&pix1);
        pixDestroy(&pix2);
    }

    pixaDestroy(&pixa);
    return pixd;
}
Exemplo n.º 2
0
/*!
 *  pixConnCompAreaTransform()
 *
 *      Input:   pixs (1 bpp)
 *               connect (connectivity: 4 or 8)
 *      Return:  pixd (16 bpp), or null on error
 *
 *  Notes:
 *      (1) The pixel values in pixd label the area of the fg component
 *          to which the pixel belongs.  Pixels in the bg are labelled 0.
 *      (2) The pixel values cannot exceed 2^16 - 1, even if the area
 *          of the c.c. is larger.
 *      (3) For purposes of visualization, the output can be converted
 *          to 8 bpp, using pixConvert16To8() or pixMaxDynamicRange().
 */
PIX *
pixConnCompAreaTransform(PIX     *pixs,
                         l_int32  connect)
{
l_int32   i, n, npix, w, h, xb, yb, wb, hb;
l_int32  *tab8;
BOXA     *boxa;
PIX      *pix1, *pix2, *pixd;
PIXA     *pixa;

    PROCNAME("pixConnCompTransform");

    if (!pixs || pixGetDepth(pixs) != 1)
        return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
    if (connect != 4 && connect != 8)
        return (PIX *)ERROR_PTR("connectivity must be 4 or 8", procName, NULL);

    boxa = pixConnComp(pixs, &pixa, connect);
    n = pixaGetCount(pixa);
    boxaDestroy(&boxa);
    pixGetDimensions(pixs, &w, &h, NULL);
    pixd = pixCreate(w, h, 16);
    if (n == 0) {  /* no fg */
        pixaDestroy(&pixa);
        return pixd;
    }

       /* Label each component and blit it in */
    tab8 = makePixelSumTab8();
    for (i = 0; i < n; i++) {
        pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb);
        pix1 = pixaGetPix(pixa, i, L_CLONE);
        pixCountPixels(pix1, &npix, tab8);
        npix = L_MIN(npix, 0xffff);
        pix2 = pixConvert1To16(NULL, pix1, 0, npix);
        pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pix2, 0, 0);
        pixDestroy(&pix1);
        pixDestroy(&pix2);
    }

    pixaDestroy(&pixa);
    FREE(tab8);
    return pixd;
}