Example #1
0
main(int    argc,
     char **argv)
{
char        *infile;
PIX         *pixs, *pixg, *pixc, *pixd;
static char  mainName[] = "morphseq_reg";

    if (argc != 1)
	return ERROR_INT(" Syntax:  morphseq_reg", mainName, 1);

    pixs = pixRead("feyn.tif");

        /* 1 bpp */
    pixd = pixMorphSequence(pixs, SEQUENCE1, -1);
    pixDestroy(&pixd);
    pixd = pixMorphSequence(pixs, SEQUENCE1, DISPLAY_SEPARATION);
    pixWrite("/tmp/morphseq1.png", pixd, IFF_PNG);
    pixDestroy(&pixd);

    pixd = pixMorphCompSequence(pixs, SEQUENCE2, -2);
    pixDestroy(&pixd);
    pixd = pixMorphCompSequence(pixs, SEQUENCE2, DISPLAY_SEPARATION);
    pixWrite("/tmp/morphseq2.png", pixd, IFF_PNG);
    pixDestroy(&pixd);

    pixd = pixMorphSequenceDwa(pixs, SEQUENCE2, -3);
    pixDestroy(&pixd);
    pixd = pixMorphSequenceDwa(pixs, SEQUENCE2, DISPLAY_SEPARATION);
    pixWrite("/tmp/morphseq3.png", pixd, IFF_PNG);
    pixDestroy(&pixd);

    pixd = pixMorphCompSequenceDwa(pixs, SEQUENCE2, -4);
    pixDestroy(&pixd);
    pixd = pixMorphCompSequenceDwa(pixs, SEQUENCE2, DISPLAY_SEPARATION);
    pixWrite("/tmp/morphseq4.png", pixd, IFF_PNG);
    pixDestroy(&pixd);

        /* 8 bpp */
    pixg = pixScaleToGray(pixs, 0.25);
    pixd = pixGrayMorphSequence(pixg, SEQUENCE3, -5, 150);
    pixDestroy(&pixd);
    pixd = pixGrayMorphSequence(pixg, SEQUENCE3, DISPLAY_SEPARATION, 150);
    pixWrite("/tmp/morphseq5.png", pixd, IFF_PNG);
    pixDestroy(&pixd);

    pixd = pixGrayMorphSequence(pixg, SEQUENCE4, -6, 300);
    pixWrite("/tmp/morphseq6.png", pixd, IFF_PNG);
    pixDestroy(&pixd);

        /* 32 bpp */
    pixc = pixRead("wyom.jpg");
    pixd = pixColorMorphSequence(pixc, SEQUENCE5, -7, 150);
    pixDestroy(&pixd);
    pixd = pixColorMorphSequence(pixc, SEQUENCE5, DISPLAY_SEPARATION, 450);
    pixWrite("/tmp/morphseq7.png", pixd, IFF_PNG);
    pixDestroy(&pixc);
    pixDestroy(&pixd);

        /* Syntax error handling */
    fprintf(stderr, " ------------ Error messages follow ------------------\n");
    pixd = pixMorphSequence(pixs, BAD_SEQUENCE, 50);  /* fails; returns null */
    pixd = pixGrayMorphSequence(pixg, BAD_SEQUENCE, 50, 0);  /* this fails */

    pixDestroy(&pixg);
    pixDestroy(&pixs);
    return 0;
}
Example #2
0
/*!
 *  pixMirrorDetectDwa()
 *
 *      Input:  pixs (1 bpp, deskewed, English text)
 *              &conf (<return> confidence that text is not LR mirror reversed)
 *              mincount (min number of left + right; use 0 for default)
 *              debug (1 for debug output; 0 otherwise)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) We assume the text is horizontally oriented, with
 *          ascenders going up.
 *      (2) See notes in pixMirrorDetect().
 */
l_int32
pixMirrorDetectDwa(PIX        *pixs,
                   l_float32  *pconf,
                   l_int32     mincount,
                   l_int32     debug)
{
char       flipsel1[] = "flipsel1";
char       flipsel2[] = "flipsel2";
l_int32    count1, count2, nmax;
l_float32  nleft, nright;
PIX       *pixt0, *pixt1, *pixt2, *pixt3;

    PROCNAME("pixMirrorDetectDwa");

    if (!pconf)
        return ERROR_INT("&conf not defined", procName, 1);
    *pconf = 0.0;
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (mincount == 0)
        mincount = DEFAULT_MIN_MIRROR_FLIP_COUNT;

        /* Fill x-height characters but not space between them, sort of. */
    pixt3 = pixMorphSequenceDwa(pixs, "d1.30", 0);
    pixXor(pixt3, pixt3, pixs);
    pixt0 = pixMorphSequenceDwa(pixs, "c15.1", 0);
    pixXor(pixt0, pixt0, pixs);
    pixAnd(pixt0, pixt0, pixt3);
    pixOr(pixt3, pixt0, pixs);
    pixDestroy(&pixt0);
    pixt0 = pixAddBorderGeneral(pixt3, ADDED_BORDER, ADDED_BORDER,
                                ADDED_BORDER, ADDED_BORDER, 0);
    pixDestroy(&pixt3);

        /* Filter the right-facing characters. */
    pixt1 = pixFlipFHMTGen(NULL, pixt0, flipsel1);
    pixt3 = pixReduceRankBinaryCascade(pixt1, 1, 1, 0, 0);
    pixCountPixels(pixt3, &count1, NULL);
    pixDestroy(&pixt1);
    pixDestroy(&pixt3);

        /* Filter the left-facing characters. */
    pixt2 = pixFlipFHMTGen(NULL, pixt0, flipsel2);
    pixt3 = pixReduceRankBinaryCascade(pixt2, 1, 1, 0, 0);
    pixCountPixels(pixt3, &count2, NULL);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);

    pixDestroy(&pixt0);
    nright = (l_float32)count1;
    nleft = (l_float32)count2;
    nmax = L_MAX(count1, count2);

    if (nmax > mincount)
        *pconf = 2. * ((nright - nleft) / sqrt(nright + nleft));

    if (debug) {
        fprintf(stderr, "nright = %f, nleft = %f\n", nright, nleft);
        if (*pconf > DEFAULT_MIN_MIRROR_FLIP_CONF)
            fprintf(stderr, "Text is not mirror reversed\n");
        if (*pconf < -DEFAULT_MIN_MIRROR_FLIP_CONF)
            fprintf(stderr, "Text is mirror reversed\n");
    }

    return 0;
}
main(int    argc,
     char **argv)
{
l_int32      i, ok, same;
char         sequence[512];
PIX         *pixs, *pixref;
PIX         *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6;
PIX         *pixt7, *pixt8, *pixt9, *pixt10, *pixt11;
PIX         *pixt12, *pixt13, *pixt14;
SEL         *sel;
static char  mainName[] = "binmorph1_reg";

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

    if ((pixs = pixRead("feyn.tif")) == NULL)
	exit(ERROR_INT("pix not made", mainName, 1));

#if TEST_SYMMETRIC
        /* This works properly if there is an added border */
    resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC);
#if 1
    pixt1 = pixAddBorder(pixs, 32, 0);
    pixTransferAllData(pixs, &pixt1, 0, 0);
#endif
#endif  /* TEST_SYMMETRIC */

        /* This is our test sel */
    sel = selCreateBrick(HEIGHT, WIDTH, HEIGHT / 2, WIDTH / 2, SEL_HIT);

        /* Dilation */
    fprintf(stderr, "Testing dilation\n");
    ok = TRUE;
    pixref = pixDilate(NULL, pixs, sel);   /* new one */
    pixt1 = pixCreateTemplate(pixs);
    pixDilate(pixt1, pixs, sel);           /* existing one */
    pixEqual(pixref, pixt1, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE;
    }
    pixt2 = pixCopy(NULL, pixs);
    pixDilate(pixt2, pixt2, sel);          /* in-place */
    pixEqual(pixref, pixt2, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE;
    }
    sprintf(sequence, "d%d.%d", WIDTH, HEIGHT);
    pixt3 = pixMorphSequence(pixs, sequence, 0);    /* sequence, atomic */
    pixEqual(pixref, pixt3, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt3 !\n"); ok = FALSE;
    }
    sprintf(sequence, "d%d.1 + d1.%d", WIDTH, HEIGHT);
    pixt4 = pixMorphSequence(pixs, sequence, 0);    /* sequence, separable */
    pixEqual(pixref, pixt4, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE;
    }
    pixt5 = pixDilateBrick(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt5, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt5 !\n"); ok = FALSE;
    }
    pixt6 = pixCreateTemplate(pixs);
    pixDilateBrick(pixt6, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt6, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt6 !\n"); ok = FALSE;
    }
    pixt7 = pixCopy(NULL, pixs);
    pixDilateBrick(pixt7, pixt7, WIDTH, HEIGHT);  /* in-place */
    pixEqual(pixref, pixt7, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt7 !\n"); ok = FALSE;
    }
    pixt8 = pixDilateBrickDwa(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt8, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt8 !\n"); ok = FALSE;
    }
    pixt9 = pixCreateTemplate(pixs);
    pixDilateBrickDwa(pixt9, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt9, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt9 !\n"); ok = FALSE;
    }
    pixt10 = pixCopy(NULL, pixs);
    pixDilateBrickDwa(pixt10, pixt10, WIDTH, HEIGHT);  /* in-place */
    pixEqual(pixref, pixt10, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt10 !\n"); ok = FALSE;
    }
    pixt11 = pixCreateTemplate(pixs);
    pixDilateCompBrickDwa(pixt11, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt11, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt11 !\n"); ok = FALSE;
    }
    sprintf(sequence, "d%d.%d", WIDTH, HEIGHT);
    pixt12 = pixMorphCompSequence(pixs, sequence, 0);    /* comp sequence */
    pixEqual(pixref, pixt12, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt12!\n"); ok = FALSE;
    }
    pixt13 = pixMorphSequenceDwa(pixs, sequence, 0);    /* dwa sequence */
    pixEqual(pixref, pixt13, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt13!\n"); ok = FALSE;
    }
    pixDestroy(&pixref);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);
    pixDestroy(&pixt4);
    pixDestroy(&pixt5);
    pixDestroy(&pixt6);
    pixDestroy(&pixt7);
    pixDestroy(&pixt8);
    pixDestroy(&pixt9);
    pixDestroy(&pixt10);
    pixDestroy(&pixt11);
    pixDestroy(&pixt12);
    pixDestroy(&pixt13);

        /* Erosion */
    fprintf(stderr, "Testing erosion\n");
    pixref = pixErode(NULL, pixs, sel);   /* new one */
    pixt1 = pixCreateTemplate(pixs);
    pixErode(pixt1, pixs, sel);           /* existing one */
    pixEqual(pixref, pixt1, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE;
    }
    pixt2 = pixCopy(NULL, pixs);
    pixErode(pixt2, pixt2, sel);          /* in-place */
    pixEqual(pixref, pixt2, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE;
    }
    sprintf(sequence, "e%d.%d", WIDTH, HEIGHT);
    pixt3 = pixMorphSequence(pixs, sequence, 0);    /* sequence, atomic */
    pixEqual(pixref, pixt3, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt3 !\n"); ok = FALSE;
    }
    sprintf(sequence, "e%d.1 + e1.%d", WIDTH, HEIGHT);
    pixt4 = pixMorphSequence(pixs, sequence, 0);    /* sequence, separable */
    pixEqual(pixref, pixt4, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE;
    }
    pixt5 = pixErodeBrick(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt5, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt5 !\n"); ok = FALSE;
    }
    pixt6 = pixCreateTemplate(pixs);
    pixErodeBrick(pixt6, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt6, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt6 !\n"); ok = FALSE;
    }
    pixt7 = pixCopy(NULL, pixs);
    pixErodeBrick(pixt7, pixt7, WIDTH, HEIGHT);  /* in-place */
    pixEqual(pixref, pixt7, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt7 !\n"); ok = FALSE;
    }
    pixt8 = pixErodeBrickDwa(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt8, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt8 !\n"); ok = FALSE;
    }
    pixt9 = pixCreateTemplate(pixs);
    pixErodeBrickDwa(pixt9, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt9, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt9 !\n"); ok = FALSE;
    }
    pixt10 = pixCopy(NULL, pixs);
    pixErodeBrickDwa(pixt10, pixt10, WIDTH, HEIGHT);  /* in-place */
    pixEqual(pixref, pixt10, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt10 !\n"); ok = FALSE;
    }
    pixt11 = pixCreateTemplate(pixs);
    pixErodeCompBrickDwa(pixt11, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt11, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt11 !\n"); ok = FALSE;
    }
    
    sprintf(sequence, "e%d.%d", WIDTH, HEIGHT);
    pixt12 = pixMorphCompSequence(pixs, sequence, 0);    /* comp sequence */
    pixEqual(pixref, pixt12, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt12!\n"); ok = FALSE;
    }
    pixt13 = pixMorphSequenceDwa(pixs, sequence, 0);    /* dwa sequence */
    pixEqual(pixref, pixt13, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt13!\n"); ok = FALSE;
    }
    pixDestroy(&pixref);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);
    pixDestroy(&pixt4);
    pixDestroy(&pixt5);
    pixDestroy(&pixt6);
    pixDestroy(&pixt7);
    pixDestroy(&pixt8);
    pixDestroy(&pixt9);
    pixDestroy(&pixt10);
    pixDestroy(&pixt11);
    pixDestroy(&pixt12);
    pixDestroy(&pixt13);

        /* Opening */
    fprintf(stderr, "Testing opening\n");
    pixref = pixOpen(NULL, pixs, sel);   /* new one */
    pixt1 = pixCreateTemplate(pixs);
    pixOpen(pixt1, pixs, sel);           /* existing one */
    pixEqual(pixref, pixt1, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE;
    }
    pixt2 = pixCopy(NULL, pixs);
    pixOpen(pixt2, pixt2, sel);          /* in-place */
    pixEqual(pixref, pixt2, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE;
    }
    sprintf(sequence, "o%d.%d", WIDTH, HEIGHT);
    pixt3 = pixMorphSequence(pixs, sequence, 0);    /* sequence, atomic */
    pixEqual(pixref, pixt3, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt3 !\n"); ok = FALSE;
    }
    sprintf(sequence, "e%d.%d + d%d.%d", WIDTH, HEIGHT, WIDTH, HEIGHT);
    pixt4 = pixMorphSequence(pixs, sequence, 0);    /* sequence, separable */
    pixEqual(pixref, pixt4, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE;
    }
    sprintf(sequence, "e%d.1 + e1.%d + d%d.1 + d1.%d", WIDTH, HEIGHT,
            WIDTH, HEIGHT);
    pixt5 = pixMorphSequence(pixs, sequence, 0);    /* sequence, separable^2 */
    pixEqual(pixref, pixt5, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt5 !\n"); ok = FALSE;
    }
    pixt6 = pixOpenBrick(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt6, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt6 !\n"); ok = FALSE;
    }
    pixt7 = pixCreateTemplate(pixs);
    pixOpenBrick(pixt7, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt7, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt7 !\n"); ok = FALSE;
    }
    pixt8 = pixCopy(NULL, pixs);  /* in-place */
    pixOpenBrick(pixt8, pixt8, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt8, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt8 !\n"); ok = FALSE;
    }
    pixt9 = pixOpenBrickDwa(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt9, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt9 !\n"); ok = FALSE;
    }
    pixt10 = pixCreateTemplate(pixs);
    pixOpenBrickDwa(pixt10, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt10, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt10 !\n"); ok = FALSE;
    }
    pixt11 = pixCopy(NULL, pixs);
    pixOpenBrickDwa(pixt11, pixt11, WIDTH, HEIGHT);  /* in-place */
    pixEqual(pixref, pixt11, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt11 !\n"); ok = FALSE;
    }
    sprintf(sequence, "o%d.%d", WIDTH, HEIGHT);
    pixt12 = pixMorphCompSequence(pixs, sequence, 0);    /* comp sequence */
    pixEqual(pixref, pixt12, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt12!\n"); ok = FALSE;
    }

#if 0
    pixWrite("/tmp/junkref.png", pixref, IFF_PNG);
    pixWrite("/tmp/junk12.png", pixt12, IFF_PNG);
    pixt13 = pixXor(NULL, pixref, pixt12);
    pixWrite("/tmp/junk12a.png", pixt13, IFF_PNG);
    pixDestroy(&pixt13);
#endif

    pixt13 = pixMorphSequenceDwa(pixs, sequence, 0);    /* dwa sequence */
    pixEqual(pixref, pixt13, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt13!\n"); ok = FALSE;
    }
    pixt14 = pixCreateTemplate(pixs);
    pixOpenCompBrickDwa(pixt14, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt14, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt14 !\n"); ok = FALSE;
    }

    pixDestroy(&pixref);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);
    pixDestroy(&pixt4);
    pixDestroy(&pixt5);
    pixDestroy(&pixt6);
    pixDestroy(&pixt7);
    pixDestroy(&pixt8);
    pixDestroy(&pixt9);
    pixDestroy(&pixt10);
    pixDestroy(&pixt11);
    pixDestroy(&pixt12);
    pixDestroy(&pixt13);
    pixDestroy(&pixt14);

        /* Closing */
    fprintf(stderr, "Testing closing\n");
    pixref = pixClose(NULL, pixs, sel);   /* new one */
    pixt1 = pixCreateTemplate(pixs);
    pixClose(pixt1, pixs, sel);           /* existing one */
    pixEqual(pixref, pixt1, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE;
    }
    pixt2 = pixCopy(NULL, pixs);
    pixClose(pixt2, pixt2, sel);          /* in-place */
    pixEqual(pixref, pixt2, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE;
    }
    sprintf(sequence, "d%d.%d + e%d.%d", WIDTH, HEIGHT, WIDTH, HEIGHT);
    pixt3 = pixMorphSequence(pixs, sequence, 0);    /* sequence, separable */
    pixEqual(pixref, pixt3, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt3 !\n"); ok = FALSE;
    }
    sprintf(sequence, "d%d.1 + d1.%d + e%d.1 + e1.%d", WIDTH, HEIGHT,
            WIDTH, HEIGHT);
    pixt4 = pixMorphSequence(pixs, sequence, 0);    /* sequence, separable^2 */
    pixEqual(pixref, pixt4, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE;
    }
    pixt5 = pixCloseBrick(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt5, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt5 !\n"); ok = FALSE;
    }
    pixt6 = pixCreateTemplate(pixs);
    pixCloseBrick(pixt6, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt6, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt6 !\n"); ok = FALSE;
    }
    pixt7 = pixCopy(NULL, pixs);  /* in-place */
    pixCloseBrick(pixt7, pixt7, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt7, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt7 !\n"); ok = FALSE;
    }
    pixDestroy(&pixref);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);
    pixDestroy(&pixt4);
    pixDestroy(&pixt5);
    pixDestroy(&pixt6);
    pixDestroy(&pixt7);

        /* Safe closing (using pix, not pixs) */
    fprintf(stderr, "Testing safe closing\n");
    pixref = pixCloseSafe(NULL, pixs, sel);   /* new one */
    pixt1 = pixCreateTemplate(pixs);
    pixCloseSafe(pixt1, pixs, sel);           /* existing one */
    pixEqual(pixref, pixt1, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE;
    }
    pixt2 = pixCopy(NULL, pixs);
    pixCloseSafe(pixt2, pixt2, sel);          /* in-place */
    pixEqual(pixref, pixt2, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE;
    }
    sprintf(sequence, "c%d.%d", WIDTH, HEIGHT);
    pixt3 = pixMorphSequence(pixs, sequence, 0);    /* sequence, atomic */
    pixEqual(pixref, pixt3, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt3 !\n"); ok = FALSE;
    }
    sprintf(sequence, "b32 + d%d.%d + e%d.%d", WIDTH, HEIGHT, WIDTH, HEIGHT);
    pixt4 = pixMorphSequence(pixs, sequence, 0);    /* sequence, separable */
    pixEqual(pixref, pixt4, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE;
    }
    sprintf(sequence, "b32 + d%d.1 + d1.%d + e%d.1 + e1.%d", WIDTH, HEIGHT,
            WIDTH, HEIGHT);
    pixt5 = pixMorphSequence(pixs, sequence, 0);    /* sequence, separable^2 */
    pixEqual(pixref, pixt5, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt5 !\n"); ok = FALSE;
    }
    pixt6 = pixCloseSafeBrick(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt6, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt6 !\n"); ok = FALSE;
    }
    pixt7 = pixCreateTemplate(pixs);
    pixCloseSafeBrick(pixt7, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt7, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt7 !\n"); ok = FALSE;
    }
    pixt8 = pixCopy(NULL, pixs);  /* in-place */
    pixCloseSafeBrick(pixt8, pixt8, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt8, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt8 !\n"); ok = FALSE;
    }
    pixt9 = pixCloseBrickDwa(NULL, pixs, WIDTH, HEIGHT);  /* new one */
    pixEqual(pixref, pixt9, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt9 !\n"); ok = FALSE;
    }
    pixt10 = pixCreateTemplate(pixs);
    pixCloseBrickDwa(pixt10, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt10, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt10 !\n"); ok = FALSE;
    }
    pixt11 = pixCopy(NULL, pixs);
    pixCloseBrickDwa(pixt11, pixt11, WIDTH, HEIGHT);  /* in-place */
    pixEqual(pixref, pixt11, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt11 !\n"); ok = FALSE;
    }
    sprintf(sequence, "c%d.%d", WIDTH, HEIGHT);
    pixt12 = pixMorphCompSequence(pixs, sequence, 0);    /* comp sequence */
    pixEqual(pixref, pixt12, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt12!\n"); ok = FALSE;
    }
    pixt13 = pixMorphSequenceDwa(pixs, sequence, 0);    /* dwa sequence */
    pixEqual(pixref, pixt13, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt13!\n"); ok = FALSE;
    }
    pixt14 = pixCreateTemplate(pixs);
    pixCloseCompBrickDwa(pixt14, pixs, WIDTH, HEIGHT);  /* existing one */
    pixEqual(pixref, pixt14, &same);
    if (!same) {
        fprintf(stderr, "pixref != pixt14 !\n"); ok = FALSE;
    }

#if 0
    pixWrite("/tmp/junkref.png", pixref, IFF_PNG);
    pixWrite("/tmp/junk12.png", pixt12, IFF_PNG);
    pixt13 = pixXor(NULL, pixref, pixt12);
    pixWrite("/tmp/junk12a.png", pixt13, IFF_PNG);
    pixDestroy(&pixt13);
#endif

    pixDestroy(&pixref);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);
    pixDestroy(&pixt4);
    pixDestroy(&pixt5);
    pixDestroy(&pixt6);
    pixDestroy(&pixt7);
    pixDestroy(&pixt8);
    pixDestroy(&pixt9);
    pixDestroy(&pixt10);
    pixDestroy(&pixt11);
    pixDestroy(&pixt12);
    pixDestroy(&pixt13);
    pixDestroy(&pixt14);

    if (ok)
        fprintf(stderr, "All morph tests OK!\n");

    pixDestroy(&pixs);
    selDestroy(&sel);
    exit(0);
}
Example #4
0
/*!
 *  pixUpDownDetectGeneralDwa()
 *
 *      Input:  pixs (1 bpp, deskewed, English text)
 *              &conf (<return> confidence that text is rightside-up)
 *              mincount (min number of up + down; use 0 for default)
 *              npixels (number of pixels removed from each side of word box)
 *              debug (1 for debug output; 0 otherwise)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) See the notes in pixUpDownDetectGeneral() for usage.
 */
l_int32
pixUpDownDetectGeneralDwa(PIX        *pixs,
                          l_float32  *pconf,
                          l_int32     mincount,
                          l_int32     npixels,
                          l_int32     debug)
{
char       flipsel1[] = "flipsel1";
char       flipsel2[] = "flipsel2";
char       flipsel3[] = "flipsel3";
char       flipsel4[] = "flipsel4";
l_int32    countup, countdown, nmax;
l_float32  nup, ndown;
PIX       *pixt, *pixt0, *pixt1, *pixt2, *pixt3, *pixm;

    PROCNAME("pixUpDownDetectGeneralDwa");

    if (!pconf)
        return ERROR_INT("&conf not defined", procName, 1);
    *pconf = 0.0;
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (mincount == 0)
        mincount = DEFAULT_MIN_UP_DOWN_COUNT;
    if (npixels < 0)
        npixels = 0;

        /* One of many reasonable pre-filtering sequences: (1, 8) and (30, 1).
         * This closes holes in x-height characters and joins them at
         * the x-height.  There is more noise in the descender detection
         * from this, but it works fairly well. */
    pixt = pixMorphSequenceDwa(pixs, "c1.8 + c30.1", 0);

        /* Be sure to add the border before the flip DWA operations! */
    pixt0 = pixAddBorderGeneral(pixt, ADDED_BORDER, ADDED_BORDER,
                                ADDED_BORDER, ADDED_BORDER, 0);
    pixDestroy(&pixt);

        /* Optionally, make a mask of the word bounding boxes, shortening
         * each of them by a fixed amount at each end. */
    pixm = NULL;
    if (npixels > 0) {
        l_int32  i, nbox, x, y, w, h;
        BOX   *box;
        BOXA  *boxa;
        pixt1 = pixMorphSequenceDwa(pixt0, "o10.1", 0);
        boxa = pixConnComp(pixt1, NULL, 8);
        pixm = pixCreateTemplate(pixt1);
        pixDestroy(&pixt1);
        nbox = boxaGetCount(boxa);
        for (i = 0; i < nbox; i++) {
            box = boxaGetBox(boxa, i, L_CLONE);
            boxGetGeometry(box, &x, &y, &w, &h);
            if (w > 2 * npixels)
                pixRasterop(pixm, x + npixels, y - 6, w - 2 * npixels, h + 13,
                            PIX_SET, NULL, 0, 0);
            boxDestroy(&box);
        }
        boxaDestroy(&boxa);
    }

        /* Find the ascenders and optionally filter with pixm.
         * For an explanation of the procedure used for counting the result
         * of the HMT, see comments in pixUpDownDetectGeneral().  */
    pixt1 = pixFlipFHMTGen(NULL, pixt0, flipsel1);
    pixt2 = pixFlipFHMTGen(NULL, pixt0, flipsel2);
    pixOr(pixt1, pixt1, pixt2);
    if (pixm)
        pixAnd(pixt1, pixt1, pixm);
    pixt3 = pixReduceRankBinaryCascade(pixt1, 1, 1, 0, 0);
    pixCountPixels(pixt3, &countup, NULL);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);

        /* Find the ascenders and optionally filter with pixm. */
    pixt1 = pixFlipFHMTGen(NULL, pixt0, flipsel3);
    pixt2 = pixFlipFHMTGen(NULL, pixt0, flipsel4);
    pixOr(pixt1, pixt1, pixt2);
    if (pixm)
        pixAnd(pixt1, pixt1, pixm);
    pixt3 = pixReduceRankBinaryCascade(pixt1, 1, 1, 0, 0);
    pixCountPixels(pixt3, &countdown, NULL);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);

        /* Evaluate statistically, generating a confidence that is
         * related to the probability with a gaussian distribution. */
    nup = (l_float32)(countup);
    ndown = (l_float32)(countdown);
    nmax = L_MAX(countup, countdown);
    if (nmax > mincount)
        *pconf = 2. * ((nup - ndown) / sqrt(nup + ndown));

    if (debug) {
        if (pixm) pixWrite("junkpixm2", pixm, IFF_PNG);
        fprintf(stderr, "nup = %7.3f, ndown = %7.3f, conf = %7.3f\n",
                nup, ndown, *pconf);
        if (*pconf > DEFAULT_MIN_UP_DOWN_CONF)
            fprintf(stderr, "Text is rightside-up\n");
        if (*pconf < -DEFAULT_MIN_UP_DOWN_CONF)
            fprintf(stderr, "Text is upside-down\n");
    }

    pixDestroy(&pixt0);
    pixDestroy(&pixm);
    return 0;
}