/*! * pixMorphSequenceDwa() * * Input: pixs * sequence (string specifying sequence) * dispsep (horizontal separation in pixels between * successive displays; use zero to suppress display) * Return: pixd, or null on error * * Notes: * (1) This does dwa morphology on binary images. * (2) This runs a pipeline of operations; no branching is allowed. * (3) This only uses brick Sels that have been pre-compiled with * dwa code. * (4) A new image is always produced; the input image is not changed. * (5) This contains an interpreter, allowing sequences to be * generated and run. * (6) See pixMorphSequence() for further information about usage. */ PIX * pixMorphSequenceDwa(PIX *pixs, const char *sequence, l_int32 dispsep) { char *rawop, *op; l_int32 nops, i, j, nred, fact, w, h, x, y, border; l_int32 level[4]; PIX *pixt1, *pixt2; SARRAY *sa; PROCNAME("pixMorphSequenceDwa"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!sequence) return (PIX *)ERROR_PTR("sequence not defined", procName, NULL); /* Split sequence into individual operations */ sa = sarrayCreate(0); sarraySplitString(sa, sequence, "+"); nops = sarrayGetCount(sa); if (!morphSequenceVerify(sa)) { sarrayDestroy(&sa); return (PIX *)ERROR_PTR("sequence not valid", procName, NULL); } /* Parse and operate */ border = 0; pixt1 = pixCopy(NULL, pixs); pixt2 = NULL; x = y = 0; for (i = 0; i < nops; i++) { rawop = sarrayGetString(sa, i, 0); op = stringRemoveChars(rawop, " \n\t"); switch (op[0]) { case 'd': case 'D': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixDilateBrickDwa(NULL, pixt1, w, h); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, y); x += dispsep; } break; case 'e': case 'E': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixErodeBrickDwa(NULL, pixt1, w, h); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, y); x += dispsep; } break; case 'o': case 'O': sscanf(&op[1], "%d.%d", &w, &h); pixOpenBrickDwa(pixt1, pixt1, w, h); if (dispsep > 0) { pixDisplay(pixt1, x, y); x += dispsep; } break; case 'c': case 'C': sscanf(&op[1], "%d.%d", &w, &h); pixCloseBrickDwa(pixt1, pixt1, w, h); if (dispsep > 0) { pixDisplay(pixt1, x, y); x += dispsep; } break; case 'r': case 'R': nred = strlen(op) - 1; for (j = 0; j < nred; j++) level[j] = op[j + 1] - '0'; for (j = nred; j < 4; j++) level[j] = 0; pixt2 = pixReduceRankBinaryCascade(pixt1, level[0], level[1], level[2], level[3]); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, y); x += dispsep; } break; case 'x': case 'X': sscanf(&op[1], "%d", &fact); pixt2 = pixExpandReplicate(pixt1, fact); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, y); x += dispsep; } break; case 'b': case 'B': sscanf(&op[1], "%d", &border); pixt2 = pixAddBorder(pixt1, border, 0); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, y); x += dispsep; } break; default: /* All invalid ops are caught in the first pass */ break; } FREE(op); } if (border > 0) { pixt2 = pixRemoveBorder(pixt1, border); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); } sarrayDestroy(&sa); return pixt1; }
/* dwa composite with dwa non-composite */ l_int32 DoComparisonDwa3(PIX *pixs, PIX *pixt1, PIX *pixt2, PIX *pixt3, PIX *pixt4, PIX *pixt5, PIX *pixt6, l_int32 isize) { l_int32 fact1, fact2, size; selectComposableSizes(isize, &fact1, &fact2); size = fact1 * fact2; fprintf(stderr, "..%d..", size); if (TIMING) startTimer(); pixDilateCompBrickDwa(pixt1, pixs, size, 1); pixDilateCompBrickDwa(pixt3, pixs, 1, size); pixDilateCompBrickDwa(pixt5, pixs, size, size); if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer()); if (TIMING) startTimer(); pixDilateBrickDwa(pixt2, pixs, size, 1); pixDilateBrickDwa(pixt4, pixs, 1, size); pixDilateBrickDwa(pixt6, pixs, size, size); if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer()); PixCompareDwa(size, "dilate", pixt1, pixt2, pixt3, pixt4, pixt5, pixt6); /* pixDisplay(pixt1, 100, 100); */ /* pixDisplay(pixt2, 800, 100); */ if (TIMING) startTimer(); pixErodeCompBrickDwa(pixt1, pixs, size, 1); pixErodeCompBrickDwa(pixt3, pixs, 1, size); pixErodeCompBrickDwa(pixt5, pixs, size, size); if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer()); if (TIMING) startTimer(); pixErodeBrickDwa(pixt2, pixs, size, 1); pixErodeBrickDwa(pixt4, pixs, 1, size); pixErodeBrickDwa(pixt6, pixs, size, size); if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer()); PixCompareDwa(size, "erode", pixt1, pixt2, pixt3, pixt4, pixt5, pixt6); if (TIMING) startTimer(); pixOpenCompBrickDwa(pixt1, pixs, size, 1); pixOpenCompBrickDwa(pixt3, pixs, 1, size); pixOpenCompBrickDwa(pixt5, pixs, size, size); if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer()); if (TIMING) startTimer(); pixOpenBrickDwa(pixt2, pixs, size, 1); pixOpenBrickDwa(pixt4, pixs, 1, size); pixOpenBrickDwa(pixt6, pixs, size, size); if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer()); PixCompareDwa(size, "open", pixt1, pixt2, pixt3, pixt4, pixt5, pixt6); if (TIMING) startTimer(); pixCloseCompBrickDwa(pixt1, pixs, size, 1); pixCloseCompBrickDwa(pixt3, pixs, 1, size); pixCloseCompBrickDwa(pixt5, pixs, size, size); if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer()); if (TIMING) startTimer(); pixCloseBrickDwa(pixt2, pixs, size, 1); pixCloseBrickDwa(pixt4, pixs, 1, size); pixCloseBrickDwa(pixt6, pixs, size, size); if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer()); PixCompareDwa(size, "close", pixt1, pixt2, pixt3, pixt4, pixt5, pixt6); #if 0 pixWrite("/tmp/junkpixt1.png", pixt1, IFF_PNG); pixWrite("/tmp/junkpixt2.png", pixt2, IFF_PNG); pixXor(pixt1, pixt1, pixt2); pixWrite("/tmp/junkxor.png", pixt1, IFF_PNG); #endif return 0; }
/*! * \brief pixMorphSequenceDwa() * * \param[in] pixs * \param[in] sequence string specifying sequence * \param[in] dispsep controls debug display of each result in the sequence: * 0: no output * > 0: gives horizontal separation in pixels between * successive displays * < 0: pdf output; abs(dispsep) is used for naming * \return pixd, or NULL on error * * <pre> * Notes: * (1) This does dwa morphology on binary images. * (2) This runs a pipeline of operations; no branching is allowed. * (3) This only uses brick Sels that have been pre-compiled with * dwa code. * (4) A new image is always produced; the input image is not changed. * (5) This contains an interpreter, allowing sequences to be * generated and run. * (6) See pixMorphSequence() for further information about usage. * </pre> */ PIX * pixMorphSequenceDwa(PIX *pixs, const char *sequence, l_int32 dispsep) { char *rawop, *op, *fname; char buf[256]; l_int32 nops, i, j, nred, fact, w, h, x, y, border, pdfout; l_int32 level[4]; PIX *pixt1, *pixt2; PIXA *pixa; SARRAY *sa; PROCNAME("pixMorphSequenceDwa"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!sequence) return (PIX *)ERROR_PTR("sequence not defined", procName, NULL); /* Split sequence into individual operations */ sa = sarrayCreate(0); sarraySplitString(sa, sequence, "+"); nops = sarrayGetCount(sa); pdfout = (dispsep < 0) ? 1 : 0; if (!morphSequenceVerify(sa)) { sarrayDestroy(&sa); return (PIX *)ERROR_PTR("sequence not valid", procName, NULL); } /* Parse and operate */ pixa = NULL; if (pdfout) { pixa = pixaCreate(0); pixaAddPix(pixa, pixs, L_CLONE); snprintf(buf, sizeof(buf), "/tmp/seq_output_%d.pdf", L_ABS(dispsep)); fname = genPathname(buf, NULL); } border = 0; pixt1 = pixCopy(NULL, pixs); pixt2 = NULL; x = y = 0; for (i = 0; i < nops; i++) { rawop = sarrayGetString(sa, i, L_NOCOPY); op = stringRemoveChars(rawop, " \n\t"); switch (op[0]) { case 'd': case 'D': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixDilateBrickDwa(NULL, pixt1, w, h); pixSwapAndDestroy(&pixt1, &pixt2); break; case 'e': case 'E': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixErodeBrickDwa(NULL, pixt1, w, h); pixSwapAndDestroy(&pixt1, &pixt2); break; case 'o': case 'O': sscanf(&op[1], "%d.%d", &w, &h); pixOpenBrickDwa(pixt1, pixt1, w, h); break; case 'c': case 'C': sscanf(&op[1], "%d.%d", &w, &h); pixCloseBrickDwa(pixt1, pixt1, w, h); break; case 'r': case 'R': nred = strlen(op) - 1; for (j = 0; j < nred; j++) level[j] = op[j + 1] - '0'; for (j = nred; j < 4; j++) level[j] = 0; pixt2 = pixReduceRankBinaryCascade(pixt1, level[0], level[1], level[2], level[3]); pixSwapAndDestroy(&pixt1, &pixt2); break; case 'x': case 'X': sscanf(&op[1], "%d", &fact); pixt2 = pixExpandReplicate(pixt1, fact); pixSwapAndDestroy(&pixt1, &pixt2); break; case 'b': case 'B': sscanf(&op[1], "%d", &border); pixt2 = pixAddBorder(pixt1, border, 0); pixSwapAndDestroy(&pixt1, &pixt2); break; default: /* All invalid ops are caught in the first pass */ break; } LEPT_FREE(op); /* Debug output */ if (dispsep > 0) { pixDisplay(pixt1, x, y); x += dispsep; } if (pdfout) pixaAddPix(pixa, pixt1, L_COPY); } if (border > 0) { pixt2 = pixRemoveBorder(pixt1, border); pixSwapAndDestroy(&pixt1, &pixt2); } if (pdfout) { pixaConvertToPdf(pixa, 0, 1.0, L_FLATE_ENCODE, 0, fname, fname); LEPT_FREE(fname); pixaDestroy(&pixa); } sarrayDestroy(&sa); return pixt1; }
main(int argc, char **argv) { char *selnameh, *selnamev; l_int32 ok, same, w, h, i, bordercolor, extraborder; l_int32 width[3] = {21, 1, 21}; l_int32 height[3] = {1, 7, 7}; PIX *pixs, *pixref; PIX *pixt0, *pixt1, *pixt2, *pixt3, *pixt4; SEL *sel; SELA *sela; static char mainName[] = "binmorph3_reg"; if (argc != 1) exit(ERROR_INT(" Syntax: binmorph3_reg", mainName, 1)); if ((pixs = pixRead("feyn.tif")) == NULL) exit(ERROR_INT("pix not made", mainName, 1)); #if TEST_SYMMETRIC resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC); #endif /* TEST_SYMMETRIC */ for (i = 0; i < 3; i++) { w = width[i]; h = height[i]; sel = selCreateBrick(h, w, h / 2, w / 2, SEL_HIT); selnameh = NULL; selnamev = NULL; /* Get the selnames for horiz and vert */ sela = selaAddBasic(NULL); if (w > 1) { if ((selnameh = selaGetBrickName(sela, w, 1)) == NULL) { selaDestroy(&sela); return ERROR_INT("dwa hor sel not defined", mainName, 1); } } if (h > 1) { if ((selnamev = selaGetBrickName(sela, 1, h)) == NULL) { selaDestroy(&sela); return ERROR_INT("dwa vert sel not defined", mainName, 1); } } fprintf(stderr, "w = %d, h = %d, selh = %s, selv = %s\n", w, h, selnameh, selnamev); ok = TRUE; selaDestroy(&sela); /* ----------------- Dilation ----------------- */ fprintf(stderr, "Testing dilation\n"); pixref = pixDilate(NULL, pixs, sel); pixt1 = pixDilateBrickDwa(NULL, pixs, w, h); pixEqual(pixref, pixt1, &same); if (!same) { fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE; } pixDestroy(&pixt1); if (w > 1) pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_DILATE, selnameh); else pixt1 = pixClone(pixs); if (h > 1) pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_DILATE, selnamev); else pixt2 = pixClone(pixt1); pixEqual(pixref, pixt2, &same); if (!same) { fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE; } pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixAddBorder(pixs, 32, 0); if (w > 1) pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_DILATE, selnameh); else pixt2 = pixClone(pixt1); if (h > 1) pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_DILATE, selnamev); else pixt3 = pixClone(pixt2); pixt4 = pixRemoveBorder(pixt3, 32); pixEqual(pixref, pixt4, &same); if (!same) { fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; } pixDestroy(&pixref); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); /* ----------------- Erosion ----------------- */ fprintf(stderr, "Testing erosion\n"); pixref = pixErode(NULL, pixs, sel); pixt1 = pixErodeBrickDwa(NULL, pixs, w, h); pixEqual(pixref, pixt1, &same); if (!same) { fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE; } pixDestroy(&pixt1); if (w > 1) pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_ERODE, selnameh); else pixt1 = pixClone(pixs); if (h > 1) pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_ERODE, selnamev); else pixt2 = pixClone(pixt1); pixEqual(pixref, pixt2, &same); if (!same) { fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE; } pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixAddBorder(pixs, 32, 0); if (w > 1) pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_ERODE, selnameh); else pixt2 = pixClone(pixt1); if (h > 1) pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_ERODE, selnamev); else pixt3 = pixClone(pixt2); pixt4 = pixRemoveBorder(pixt3, 32); pixEqual(pixref, pixt4, &same); if (!same) { fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; } pixDestroy(&pixref); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); /* ----------------- Opening ----------------- */ fprintf(stderr, "Testing opening\n"); pixref = pixOpen(NULL, pixs, sel); pixt1 = pixOpenBrickDwa(NULL, pixs, w, h); pixEqual(pixref, pixt1, &same); if (!same) { fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE; } pixDestroy(&pixt1); if (h == 1) pixt2 = pixMorphDwa_1(NULL, pixs, L_MORPH_OPEN, selnameh); else if (w == 1) pixt2 = pixMorphDwa_1(NULL, pixs, L_MORPH_OPEN, selnamev); else { pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_ERODE, selnameh); pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_ERODE, selnamev); pixMorphDwa_1(pixt1, pixt2, L_MORPH_DILATE, selnameh); pixMorphDwa_1(pixt2, pixt1, L_MORPH_DILATE, selnamev); pixDestroy(&pixt1); } pixEqual(pixref, pixt2, &same); if (!same) { fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE; } pixDestroy(&pixt2); pixt1 = pixAddBorder(pixs, 32, 0); if (h == 1) pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_OPEN, selnameh); else if (w == 1) pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_OPEN, selnamev); else { pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_ERODE, selnameh); pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_ERODE, selnamev); pixFMorphopGen_1(pixt2, pixt3, L_MORPH_DILATE, selnameh); pixFMorphopGen_1(pixt3, pixt2, L_MORPH_DILATE, selnamev); pixDestroy(&pixt2); } pixt4 = pixRemoveBorder(pixt3, 32); pixEqual(pixref, pixt4, &same); if (!same) { fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; } pixDestroy(&pixref); pixDestroy(&pixt1); pixDestroy(&pixt3); pixDestroy(&pixt4); /* ----------------- Closing ----------------- */ fprintf(stderr, "Testing closing\n"); pixref = pixClose(NULL, pixs, sel); /* Note: L_MORPH_CLOSE for h==1 or w==1 gives safe closing, * so we can't use it here. */ if (h == 1) { pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_DILATE, selnameh); pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_ERODE, selnameh); } else if (w == 1) { pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_DILATE, selnamev); pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_ERODE, selnamev); } else { pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_DILATE, selnameh); pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_DILATE, selnamev); pixMorphDwa_1(pixt1, pixt2, L_MORPH_ERODE, selnameh); pixMorphDwa_1(pixt2, pixt1, L_MORPH_ERODE, selnamev); } pixDestroy(&pixt1); pixEqual(pixref, pixt2, &same); if (!same) { fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE; } pixDestroy(&pixt2); /* Note: by adding only 32 pixels of border, we get * the normal closing operation, even when calling * with L_MORPH_CLOSE, because it requires 32 pixels * of border to be safe. */ pixt1 = pixAddBorder(pixs, 32, 0); if (h == 1) pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_CLOSE, selnameh); else if (w == 1) pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_CLOSE, selnamev); else { pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_DILATE, selnameh); pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_DILATE, selnamev); pixFMorphopGen_1(pixt2, pixt3, L_MORPH_ERODE, selnameh); pixFMorphopGen_1(pixt3, pixt2, L_MORPH_ERODE, selnamev); pixDestroy(&pixt2); } pixt4 = pixRemoveBorder(pixt3, 32); pixEqual(pixref, pixt4, &same); if (!same) { fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; } pixDestroy(&pixref); pixDestroy(&pixt1); pixDestroy(&pixt3); pixDestroy(&pixt4); /* ------------- Safe Closing ----------------- */ fprintf(stderr, "Testing safe closing\n"); pixref = pixCloseSafe(NULL, pixs, sel); pixt0 = pixCloseSafeBrick(NULL, pixs, w, h); pixEqual(pixref, pixt0, &same); if (!same) { fprintf(stderr, "pixref != pixt0 !\n"); ok = FALSE; } pixDestroy(&pixt0); pixt1 = pixCloseBrickDwa(NULL, pixs, w, h); pixEqual(pixref, pixt1, &same); if (!same) { fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE; } pixDestroy(&pixt1); bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1); if (bordercolor == 0) /* asymmetric b.c. */ extraborder = 32; else /* symmetric b.c. */ extraborder = 0; /* Note: for safe closing we need 64 border pixels. * However, when we implement a separable Sel * with pixMorphDwa_*(), we must do dilation and * erosion explicitly, and these functions only * add/remove a 32-pixel border. Thus, for that * case we must add an additional 32-pixel border * before doing the operations. That is the reason * why the implementation in morphdwa.c adds the * 64 bit border and then uses the lower-level * pixFMorphopGen_*() functions. */ if (h == 1) pixt3 = pixMorphDwa_1(NULL, pixs, L_MORPH_CLOSE, selnameh); else if (w == 1) pixt3 = pixMorphDwa_1(NULL, pixs, L_MORPH_CLOSE, selnamev); else { pixt0 = pixAddBorder(pixs, extraborder, 0); pixt1 = pixMorphDwa_1(NULL, pixt0, L_MORPH_DILATE, selnameh); pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_DILATE, selnamev); pixMorphDwa_1(pixt1, pixt2, L_MORPH_ERODE, selnameh); pixMorphDwa_1(pixt2, pixt1, L_MORPH_ERODE, selnamev); pixt3 = pixRemoveBorder(pixt2, extraborder); pixDestroy(&pixt0); pixDestroy(&pixt1); pixDestroy(&pixt2); } pixEqual(pixref, pixt3, &same); if (!same) { fprintf(stderr, "pixref != pixt3 !\n"); ok = FALSE; } pixDestroy(&pixt3); pixt1 = pixAddBorder(pixs, 32 + extraborder, 0); if (h == 1) pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_CLOSE, selnameh); else if (w == 1) pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_CLOSE, selnamev); else { pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_DILATE, selnameh); pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_DILATE, selnamev); pixFMorphopGen_1(pixt2, pixt3, L_MORPH_ERODE, selnameh); pixFMorphopGen_1(pixt3, pixt2, L_MORPH_ERODE, selnamev); pixDestroy(&pixt2); } pixt4 = pixRemoveBorder(pixt3, 32 + extraborder); pixEqual(pixref, pixt4, &same); if (!same) { fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; } pixDestroy(&pixref); pixDestroy(&pixt1); pixDestroy(&pixt3); pixDestroy(&pixt4); if (ok) fprintf(stderr, "All morph tests OK!\n"); selDestroy(&sel); lept_free(selnameh); lept_free(selnamev); } pixDestroy(&pixs); 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); }