Exemplo n.º 1
0
/*!
 *  pixaSelectBySize()
 *
 *      Input:  pixas
 *              width, height (threshold dimensions)
 *              type (L_SELECT_WIDTH, L_SELECT_HEIGHT,
 *                    L_SELECT_IF_EITHER, L_SELECT_IF_BOTH)
 *              relation (L_SELECT_IF_LT, L_SELECT_IF_GT,
 *                        L_SELECT_IF_LTE, L_SELECT_IF_GTE)
 *              &changed (<optional return> 1 if changed; 0 otherwise)
 *      Return: pixad, or null on error
 *
 *  Notes:
 *      (1) The args specify constraints on the size of the
 *          components that are kept.
 *      (2) Uses pix and box clones in the new pixa.
 *      (3) If the selection type is L_SELECT_WIDTH, the input
 *          height is ignored, and v.v.
 *      (4) To keep small components, use relation = L_SELECT_IF_LT or
 *          L_SELECT_IF_LTE.
 *          To keep large components, use relation = L_SELECT_IF_GT or
 *          L_SELECT_IF_GTE.
 */
PIXA *
pixaSelectBySize(PIXA     *pixas,
                 l_int32   width,
                 l_int32   height,
                 l_int32   type,
                 l_int32   relation,
                 l_int32  *pchanged)
{
BOXA    *boxa;
NUMA    *na;
PIXA    *pixad;

    PROCNAME("pixaSelectBySize");

    if (!pixas)
        return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
    if (type != L_SELECT_WIDTH && type != L_SELECT_HEIGHT &&
        type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
        return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
    if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
        relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
        return (PIXA *)ERROR_PTR("invalid relation", procName, NULL);

        /* Compute the indicator array for saving components */
    boxa = pixaGetBoxa(pixas, L_CLONE);
    na = boxaMakeSizeIndicator(boxa, width, height, type, relation);
    boxaDestroy(&boxa);

        /* Filter to get output */
    pixad = pixaSelectWithIndicator(pixas, na, pchanged);

    numaDestroy(&na);
    return pixad;
}
Exemplo n.º 2
0
/*!
 *  pixaSelectByWidthHeightRatio()
 *
 *      Input:  pixas
 *              thresh (threshold ratio of width/height)
 *              type (L_SELECT_IF_LT, L_SELECT_IF_GT,
 *                    L_SELECT_IF_LTE, L_SELECT_IF_GTE)
 *              &changed (<optional return> 1 if changed; 0 if clone returned)
 *      Return: pixad, or null on error
 *
 *  Notes:
 *      (1) Returns a pixa clone if no components are removed.
 *      (2) Uses pix and box clones in the new pixa.
 *      (3) This filters components based on the width-to-height ratio
 *          of each pix.
 *      (4) Use L_SELECT_IF_LT or L_SELECT_IF_LTE to save components
 *          with less than the threshold ratio, and
 *          L_SELECT_IF_GT or L_SELECT_IF_GTE to remove them.
 */
PIXA *
pixaSelectByWidthHeightRatio(PIXA      *pixas,
                             l_float32  thresh,
                             l_int32    type,
                             l_int32   *pchanged)
{
NUMA  *na, *nai;
PIXA  *pixad;

    PROCNAME("pixaSelectByWidthHeightRatio");

    if (!pixas)
        return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
    if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
        type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
        return (PIXA *)ERROR_PTR("invalid type", procName, NULL);

        /* Compute component ratios. */
    na = pixaFindWidthHeightRatio(pixas);

        /* Generate indicator array for elements to be saved. */
    nai = numaMakeThresholdIndicator(na, thresh, type);
    numaDestroy(&na);

        /* Filter to get output */
    pixad = pixaSelectWithIndicator(pixas, nai, pchanged);

    numaDestroy(&nai);
    return pixad;
}
Exemplo n.º 3
0
int main(int    argc,
         char **argv)
{
l_int32  w, h, n, i, sum, sumi, empty;
BOX     *box1, *box2, *box3, *box4;
BOXA    *boxa, *boxat;
NUMA    *na1, *na2, *na3, *na4, *na5;
NUMA    *na2i, *na3i, *na4i, *nat, *naw, *nah;
PIX     *pixs, *pixc, *pixt, *pixt2, *pixd, *pixcount;
PIXA    *pixas, *pixad, *pixac;

    pixDisplayWrite(NULL, -1);

        /* Draw 4 filled boxes of different sizes */
    pixs = pixCreate(200, 200, 1);
    box1 = boxCreate(10, 10, 20, 30);
    box2 = boxCreate(50, 10, 40, 20);
    box3 = boxCreate(110, 10, 35, 5);
    box4 = boxCreate(160, 10, 5, 15);
    boxa = boxaCreate(4);
    boxaAddBox(boxa, box1, L_INSERT);
    boxaAddBox(boxa, box2, L_INSERT);
    boxaAddBox(boxa, box3, L_INSERT);
    boxaAddBox(boxa, box4, L_INSERT);
    pixRenderBox(pixs, box1, 1, L_SET_PIXELS);
    pixRenderBox(pixs, box2, 1, L_SET_PIXELS);
    pixRenderBox(pixs, box3, 1, L_SET_PIXELS);
    pixRenderBox(pixs, box4, 1, L_SET_PIXELS);
    pixt = pixFillClosedBorders(pixs, 4);
    pixDisplayWrite(pixt, 1);
    pixt2 = pixCreateTemplate(pixs);
    pixRenderHashBox(pixt2, box1, 6, 4, L_POS_SLOPE_LINE, 1, L_SET_PIXELS);
    pixRenderHashBox(pixt2, box2, 7, 2, L_POS_SLOPE_LINE, 1, L_SET_PIXELS);
    pixRenderHashBox(pixt2, box3, 4, 2, L_VERTICAL_LINE, 1, L_SET_PIXELS);
    pixRenderHashBox(pixt2, box4, 3, 1, L_HORIZONTAL_LINE, 1, L_SET_PIXELS);
    pixDisplayWrite(pixt2, 1);

        /* Exercise the parameters */
    pixd = pixSelectBySize(pixt, 0, 22, 8, L_SELECT_HEIGHT,
                           L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 1);
    pixd = pixSelectBySize(pixt, 0, 30, 8, L_SELECT_HEIGHT,
                           L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 3);
    pixd = pixSelectBySize(pixt, 0, 5, 8, L_SELECT_HEIGHT,
                           L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 3);
    pixd = pixSelectBySize(pixt, 0, 6, 8, L_SELECT_HEIGHT,
                           L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 1);
    pixd = pixSelectBySize(pixt, 20, 0, 8, L_SELECT_WIDTH,
                           L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 2);
    pixd = pixSelectBySize(pixt, 31, 0, 8, L_SELECT_WIDTH,
                           L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 2);
    pixd = pixSelectBySize(pixt, 21, 10, 8, L_SELECT_IF_EITHER,
                           L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 3);
    pixd = pixSelectBySize(pixt, 20, 30, 8, L_SELECT_IF_EITHER,
                           L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 2);
    pixd = pixSelectBySize(pixt, 22, 32, 8, L_SELECT_IF_BOTH,
                           L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 2);
    pixd = pixSelectBySize(pixt, 6, 32, 8, L_SELECT_IF_BOTH,
                           L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 1);
    pixd = pixSelectBySize(pixt, 5, 25, 8, L_SELECT_IF_BOTH,
                           L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 1);
    pixd = pixSelectBySize(pixt, 25, 5, 8, L_SELECT_IF_BOTH,
                           L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 1);

    pixd = pixSelectByPerimToAreaRatio(pixt, 0.3, 8, L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 2);
    pixd = pixSelectByPerimToAreaRatio(pixt, 0.15, 8, L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 3);
    pixd = pixSelectByPerimToAreaRatio(pixt, 0.4, 8, L_SELECT_IF_LTE, NULL);
    count_pieces(pixd, 2);
    pixd = pixSelectByPerimToAreaRatio(pixt, 0.45, 8, L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 3);

    pixd = pixSelectByPerimSizeRatio(pixt2, 2.3, 8, L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 2);
    pixd = pixSelectByPerimSizeRatio(pixt2, 1.2, 8, L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 3);
    pixd = pixSelectByPerimSizeRatio(pixt2, 1.7, 8, L_SELECT_IF_LTE, NULL);
    count_pieces(pixd, 1);
    pixd = pixSelectByPerimSizeRatio(pixt2, 2.9, 8, L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 3);

    pixd = pixSelectByAreaFraction(pixt2, 0.3, 8, L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 0);
    pixd = pixSelectByAreaFraction(pixt2, 0.9, 8, L_SELECT_IF_LT, NULL);
    count_pieces(pixd, 4);
    pixd = pixSelectByAreaFraction(pixt2, 0.5, 8, L_SELECT_IF_GTE, NULL);
    count_pieces(pixd, 3);
    pixd = pixSelectByAreaFraction(pixt2, 0.7, 8, L_SELECT_IF_GT, NULL);
    count_pieces(pixd, 2);

    boxat = boxaSelectBySize(boxa, 21, 10, L_SELECT_IF_EITHER,
                             L_SELECT_IF_LT, NULL);
    count_pieces2(boxat, 3);
    boxat = boxaSelectBySize(boxa, 22, 32, L_SELECT_IF_BOTH,
                             L_SELECT_IF_LT, NULL);
    count_pieces2(boxat, 2);

    boxaDestroy(&boxa);
    pixDestroy(&pixt);
    pixDestroy(&pixt2);
    pixDestroy(&pixs);

        /* Here's the most general method for selecting components.
         * We do it for area fraction, but any combination of
         * size, area/perimeter ratio and area fraction can be used. */
    pixs = pixRead("feyn.tif");
/*    pixs = pixRead("rabi.png"); */
    pixc = pixCopy(NULL, pixs);  /* subtract bands from this */
    pixt = pixCreateTemplate(pixs);  /* add bands to this */
    pixGetDimensions(pixs, &w, &h, NULL);
    boxa = pixConnComp(pixs, &pixas, 8);
    n = boxaGetCount(boxa);
    fprintf(stderr, "total: %d\n", n);
    na1 = pixaFindAreaFraction(pixas);
    nat = numaCreate(0);
    numaSetCount(nat, n);  /* initialize to all 0 */
    sum = sumi = 0;
    pixac = pixaCreate(0);
    for (i = 0; i < 12; i++) {
            /* Compute within the intervals using an intersection. */
        na2 = numaMakeThresholdIndicator(na1, edges[i], L_SELECT_IF_GTE);
        if (i != 11)
            na3 = numaMakeThresholdIndicator(na1, edges[i + 1], L_SELECT_IF_LT);
        else
            na3 = numaMakeThresholdIndicator(na1, edges[i + 1],
                                             L_SELECT_IF_LTE);
        na4 = numaLogicalOp(NULL, na2, na3, L_INTERSECTION);
        sum += count_ones(na4, 0, 0, NULL);

            /* Compute outside the intervals using a union, and invert */
        na2i = numaMakeThresholdIndicator(na1, edges[i], L_SELECT_IF_LT);
        if (i != 11)
            na3i = numaMakeThresholdIndicator(na1, edges[i + 1],
                                              L_SELECT_IF_GTE);
        else
            na3i = numaMakeThresholdIndicator(na1, edges[i + 1],
                                              L_SELECT_IF_GT);
        na4i = numaLogicalOp(NULL, na3i, na2i, L_UNION);
        numaInvert(na4i, na4i);
        sumi += count_ones(na4i, 0, 0, NULL);

            /* Compare the two methods */
        if (sum == sumi)
            fprintf(stderr, "\nCorrect: sum = sumi = %d\n", sum);
        else
            fprintf(stderr, "\nWRONG: sum = %d, sumi = %d\n", sum, sumi);

            /* Reconstruct the image, band by band. */
        numaLogicalOp(nat, nat, na4, L_UNION);
        pixad = pixaSelectWithIndicator(pixas, na4, NULL);
        pixd = pixaDisplay(pixad, w, h);
        pixOr(pixt, pixt, pixd);  /* add them in */
        pixcount = pixCopy(NULL, pixt);  /* destroyed by count_pieces */
        count_ones(na4, band[i], i, "band");
        count_pieces(pixd, band[i]);
        count_ones(nat, total[i], i, "total");
        count_pieces(pixcount, total[i]);
        pixaDestroy(&pixad);

            /* Remove band successively from full image */
        pixRemoveWithIndicator(pixc, pixas, na4);
        pixSaveTiled(pixc, pixac, 0.25, 1 - i % 2, 25, 8);

        numaDestroy(&na2);
        numaDestroy(&na3);
        numaDestroy(&na4);
        numaDestroy(&na2i);
        numaDestroy(&na3i);
        numaDestroy(&na4i);
    }

        /* Did we remove all components from pixc? */
    pixZero(pixc, &empty);
    if (!empty)
        fprintf(stderr, "\nWRONG: not all pixels removed from pixc\n");

    pixDestroy(&pixs);
    pixDestroy(&pixc);
    pixDestroy(&pixt);
    boxaDestroy(&boxa);
    pixaDestroy(&pixas);
    numaDestroy(&na1);
    numaDestroy(&nat);

        /* One last extraction.  Get all components that have either
         * a height of at least 50 or a width of between 30 and 35,
         * and also have a relatively large perimeter/area ratio. */
    pixs = pixRead("feyn.tif");
    boxa = pixConnComp(pixs, &pixas, 8);
    n = boxaGetCount(boxa);
    pixaFindDimensions(pixas, &naw, &nah);
    na1 = pixaFindPerimToAreaRatio(pixas);
    na2 = numaMakeThresholdIndicator(nah, 50, L_SELECT_IF_GTE);
    na3 = numaMakeThresholdIndicator(naw, 30, L_SELECT_IF_GTE);
    na4 = numaMakeThresholdIndicator(naw, 35, L_SELECT_IF_LTE);
    na5 = numaMakeThresholdIndicator(na1, 0.4, L_SELECT_IF_GTE);
    numaLogicalOp(na3, na3, na4, L_INTERSECTION);
    numaLogicalOp(na2, na2, na3, L_UNION);
    numaLogicalOp(na2, na2, na5, L_INTERSECTION);
    numaInvert(na2, na2);  /* get components to be removed */
    pixRemoveWithIndicator(pixs, pixas, na2);
    pixSaveTiled(pixs, pixac, 0.25, 1, 25, 8);
    pixDestroy(&pixs);
    boxaDestroy(&boxa);
    pixaDestroy(&pixas);
    numaDestroy(&naw);
    numaDestroy(&nah);
    numaDestroy(&na1);
    numaDestroy(&na2);
    numaDestroy(&na3);
    numaDestroy(&na4);
    numaDestroy(&na5);

    pixDisplayMultiple("/tmp/display/file*");
    pixd = pixaDisplay(pixac, 0, 0);
    pixDisplay(pixd, 100, 100);
    pixWrite("/tmp/comp.jpg", pixd, IFF_JFIF_JPEG);
    pixDestroy(&pixd);
    pixaDestroy(&pixac);
    return 0;
}