int main(int argc, char **argv) { l_int32 i, nsels, same1, same2, ok; char *filein, *selname; PIX *pixs, *pixref, *pixt1, *pixt2, *pixt3, *pixt4; SEL *sel; SELA *sela; static char mainName[] = "fhmtauto_reg"; if (argc != 2) return ERROR_INT(" Syntax: fhmtauto_reg filein", mainName, 1); filein = argv[1]; if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); sela = selaAddHitMiss(NULL); nsels = selaGetCount(sela); ok = TRUE; for (i = 0; i < nsels; i++) { sel = selaGetSel(sela, i); selname = selGetName(sel); pixref = pixHMT(NULL, pixs, sel); pixt1 = pixAddBorder(pixs, 32, 0); pixt2 = pixFHMTGen_1(NULL, pixt1, selname); pixt3 = pixRemoveBorder(pixt2, 32); pixt4 = pixHMTDwa_1(NULL, pixs, selname); pixEqual(pixref, pixt3, &same1); pixEqual(pixref, pixt4, &same2); if (same1 && same2) fprintf(stderr, "hmt are identical for sel %d (%s)\n", i, selname); else { fprintf(stderr, "hmt differ for sel %d (%s)\n", i, selname); ok = FALSE; } pixDestroy(&pixref); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); } if (ok) fprintf(stderr, "\n ******** All hmt are correct *******\n"); else fprintf(stderr, "\n ******** ERROR in at least one hmt *******\n"); pixDestroy(&pixs); selaDestroy(&sela); return 0; }
main(int argc, char **argv) { l_int32 i, nsels, same, xorcount; char *selname; PIX *pixs, *pixs1, *pixt1, *pixt2, *pixt3; SEL *sel; SELA *sela; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; if ((pixs = pixRead("feyn-fract.tif")) == NULL) { rp->success = FALSE; regTestCleanup(rp); return 1; } sela = selaAddDwaLinear(NULL); nsels = selaGetCount(sela); for (i = 0; i < nsels; i++) { sel = selaGetSel(sela, i); selname = selGetName(sel); /* --------- dilation ----------*/ pixt1 = pixDilate(NULL, pixs, sel); pixt2 = pixMorphDwa_3(NULL, pixs, L_MORPH_DILATE, selname); pixEqual(pixt1, pixt2, &same); if (same == 1) { fprintf(stderr, "dilations are identical for sel %d (%s)\n", i, selname); } else { rp->success = FALSE; fprintf(rp->fp, "dilations differ for sel %d (%s)\n", i, selname); pixt3 = pixXor(NULL, pixt1, pixt2); pixCountPixels(pixt3, &xorcount, NULL); fprintf(rp->fp, "Number of pixels in XOR: %d\n", xorcount); pixDestroy(&pixt3); } pixDestroy(&pixt1); pixDestroy(&pixt2); /* --------- erosion with asymmetric b.c ----------*/ resetMorphBoundaryCondition(ASYMMETRIC_MORPH_BC); fprintf(stderr, "MORPH_BC = %d ... ", MORPH_BC); pixt1 = pixErode(NULL, pixs, sel); pixt2 = pixMorphDwa_3(NULL, pixs, L_MORPH_ERODE, selname); pixEqual(pixt1, pixt2, &same); if (same == 1) { fprintf(stderr, "erosions are identical for sel %d (%s)\n", i, selname); } else { rp->success = FALSE; fprintf(rp->fp, "erosions differ for sel %d (%s)\n", i, selname); pixt3 = pixXor(NULL, pixt1, pixt2); pixCountPixels(pixt3, &xorcount, NULL); fprintf(rp->fp, "Number of pixels in XOR: %d\n", xorcount); pixDestroy(&pixt3); } pixDestroy(&pixt1); pixDestroy(&pixt2); /* --------- erosion with symmetric b.c ----------*/ resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC); fprintf(stderr, "MORPH_BC = %d ... ", MORPH_BC); pixt1 = pixErode(NULL, pixs, sel); pixt2 = pixMorphDwa_3(NULL, pixs, L_MORPH_ERODE, selname); pixEqual(pixt1, pixt2, &same); if (same == 1) { fprintf(stderr, "erosions are identical for sel %d (%s)\n", i, selname); } else { rp->success = FALSE; fprintf(rp->fp, "erosions differ for sel %d (%s)\n", i, selname); pixt3 = pixXor(NULL, pixt1, pixt2); pixCountPixels(pixt3, &xorcount, NULL); fprintf(rp->fp, "Number of pixels in XOR: %d\n", xorcount); pixDestroy(&pixt3); } pixDestroy(&pixt1); pixDestroy(&pixt2); /* --------- opening with asymmetric b.c ----------*/ resetMorphBoundaryCondition(ASYMMETRIC_MORPH_BC); fprintf(stderr, "MORPH_BC = %d ... ", MORPH_BC); pixt1 = pixOpen(NULL, pixs, sel); pixt2 = pixMorphDwa_3(NULL, pixs, L_MORPH_OPEN, selname); pixEqual(pixt1, pixt2, &same); if (same == 1) { fprintf(stderr, "openings are identical for sel %d (%s)\n", i, selname); } else { rp->success = FALSE; fprintf(rp->fp, "openings differ for sel %d (%s)\n", i, selname); pixt3 = pixXor(NULL, pixt1, pixt2); pixCountPixels(pixt3, &xorcount, NULL); fprintf(rp->fp, "Number of pixels in XOR: %d\n", xorcount); pixDestroy(&pixt3); } pixDestroy(&pixt1); pixDestroy(&pixt2); /* --------- opening with symmetric b.c ----------*/ resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC); fprintf(stderr, "MORPH_BC = %d ... ", MORPH_BC); pixt1 = pixOpen(NULL, pixs, sel); pixt2 = pixMorphDwa_3(NULL, pixs, L_MORPH_OPEN, selname); pixEqual(pixt1, pixt2, &same); if (same == 1) { fprintf(stderr, "openings are identical for sel %d (%s)\n", i, selname); } else { rp->success = FALSE; fprintf(rp->fp, "openings differ for sel %d (%s)\n", i, selname); pixt3 = pixXor(NULL, pixt1, pixt2); pixCountPixels(pixt3, &xorcount, NULL); fprintf(rp->fp, "Number of pixels in XOR: %d\n", xorcount); pixDestroy(&pixt3); } pixDestroy(&pixt1); pixDestroy(&pixt2); /* --------- safe closing with asymmetric b.c ----------*/ resetMorphBoundaryCondition(ASYMMETRIC_MORPH_BC); fprintf(stderr, "MORPH_BC = %d ... ", MORPH_BC); pixt1 = pixCloseSafe(NULL, pixs, sel); /* must use safe version */ pixt2 = pixMorphDwa_3(NULL, pixs, L_MORPH_CLOSE, selname); pixEqual(pixt1, pixt2, &same); if (same == 1) { fprintf(stderr, "closings are identical for sel %d (%s)\n", i, selname); } else { rp->success = FALSE; fprintf(rp->fp, "closings differ for sel %d (%s)\n", i, selname); pixt3 = pixXor(NULL, pixt1, pixt2); pixCountPixels(pixt3, &xorcount, NULL); fprintf(rp->fp, "Number of pixels in XOR: %d\n", xorcount); pixDestroy(&pixt3); } pixDestroy(&pixt1); pixDestroy(&pixt2); /* --------- safe closing with symmetric b.c ----------*/ resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC); fprintf(stderr, "MORPH_BC = %d ... ", MORPH_BC); pixt1 = pixClose(NULL, pixs, sel); /* safe version not required */ pixt2 = pixMorphDwa_3(NULL, pixs, L_MORPH_CLOSE, selname); pixEqual(pixt1, pixt2, &same); if (same == 1) { fprintf(stderr, "closings are identical for sel %d (%s)\n", i, selname); } else { rp->success = FALSE; fprintf(rp->fp, "closings differ for sel %d (%s)\n", i, selname); pixt3 = pixXor(NULL, pixt1, pixt2); pixCountPixels(pixt3, &xorcount, NULL); fprintf(rp->fp, "Number of pixels in XOR: %d\n", xorcount); pixDestroy(&pixt3); } pixDestroy(&pixt1); pixDestroy(&pixt2); } selaDestroy(&sela); pixDestroy(&pixs); return regTestCleanup(rp); }
/*! * pixThinGeneral() * * Input: pixs (1 bpp) * type (L_THIN_FG, L_THIN_BG) * sela (of Sels for parallel composite HMTs) * maxiters (max number of iters allowed; use 0 to iterate * until completion) * Return: pixd, or null on error * * Notes: * (1) See notes in pixThin(). That function chooses among * the best of the Sels for thinning. * (2) This is a general function that takes a Sela of HMTs * that are used in parallel for thinning from each * of four directions. One iteration consists of four * such parallel thins. */ PIX * pixThinGeneral(PIX *pixs, l_int32 type, SELA *sela, l_int32 maxiters) { l_int32 i, j, r, nsels, same; PIXA *pixahmt; PIX **pixhmt; /* array owned by pixahmt; do not destroy! */ PIX *pixd, *pixt; SEL *sel, *selr; PROCNAME("pixThinGeneral"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (pixGetDepth(pixs) != 1) return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL); if (type != L_THIN_FG && type != L_THIN_BG) return (PIX *)ERROR_PTR("invalid fg/bg type", procName, NULL); if (!sela) return (PIX *)ERROR_PTR("sela not defined", procName, NULL); if (maxiters == 0) maxiters = 10000; /* Set up array of temp pix to hold hmts */ nsels = selaGetCount(sela); pixahmt = pixaCreate(nsels); for (i = 0; i < nsels; i++) { pixt = pixCreateTemplate(pixs); pixaAddPix(pixahmt, pixt, L_INSERT); } pixhmt = pixaGetPixArray(pixahmt); if (!pixhmt) return (PIX *)ERROR_PTR("pixhmt array not made", procName, NULL); #if DEBUG_SELS pixt = selaDisplayInPix(sela, 35, 3, 15, 4); pixDisplayWithTitle(pixt, 100, 100, "allsels", 1); pixDestroy(&pixt); #endif /* DEBUG_SELS */ /* Set up initial image for fg thinning */ if (type == L_THIN_FG) pixd = pixCopy(NULL, pixs); else /* bg thinning */ pixd = pixInvert(NULL, pixs); /* Thin the fg, with up to maxiters iterations */ for (i = 0; i < maxiters; i++) { pixt = pixCopy(NULL, pixd); /* test for completion */ for (r = 0; r < 4; r++) { /* over 90 degree rotations of Sels */ for (j = 0; j < nsels; j++) { /* over individual sels in sela */ sel = selaGetSel(sela, j); /* not a copy */ selr = selRotateOrth(sel, r); pixHMT(pixhmt[j], pixd, selr); selDestroy(&selr); if (j > 0) pixOr(pixhmt[0], pixhmt[0], pixhmt[j]); /* accum result */ } pixSubtract(pixd, pixd, pixhmt[0]); /* remove result */ } pixEqual(pixd, pixt, &same); pixDestroy(&pixt); if (same) { L_INFO("%d iterations to completion\n", procName, i); break; } } if (type == L_THIN_BG) pixInvert(pixd, pixd); pixaDestroy(&pixahmt); return pixd; }
/* * fmorphautogen2() * * Input: sela * fileindex * filename (<optional>; can be null) * Return: 0 if OK; 1 on error * * Notes: * (1) This function uses morphtemplate2.txt to create a * low-level file that contains the low-level functions for * implementing dilation and erosion for every sel * in the input sela. * (2) The fileindex parameter is inserted into the output * filename, as described below. * (3) If filename == NULL, the output file is fmorphgenlow.<n>.c, * where <n> is equal to the 'fileindex' parameter. * (4) If filename != NULL, the output file is <filename>low.<n>.c. */ l_int32 fmorphautogen2(SELA *sela, l_int32 fileindex, const char *filename) { char *filestr, *linestr, *fname; char *str_doc1, *str_doc2, *str_doc3, *str_doc4, *str_def1; char bigbuf[L_BUF_SIZE]; char breakstring[] = " break;"; char staticstring[] = "static void"; l_int32 i, nsels, nbytes, actstart, end, newstart; l_int32 argstart, argend, loopstart, loopend, finalstart, finalend; size_t size; SARRAY *sa1, *sa2, *sa3, *sa4, *sa5, *sa6; SEL *sel; PROCNAME("fmorphautogen2"); if (!sela) return ERROR_INT("sela not defined", procName, 1); if (fileindex < 0) fileindex = 0; if ((nsels = selaGetCount(sela)) == 0) return ERROR_INT("no sels in sela", procName, 1); /* Make the array of textlines from morphtemplate2.txt */ if ((filestr = (char *)l_binaryRead(TEMPLATE2, &size)) == NULL) return ERROR_INT("filestr not made", procName, 1); sa1 = sarrayCreateLinesFromString(filestr, 1); LEPT_FREE(filestr); if (!sa1) return ERROR_INT("sa1 not made", procName, 1); /* Make the array of static function names */ if ((sa2 = sarrayCreate(2 * nsels)) == NULL) { sarrayDestroy(&sa1); return ERROR_INT("sa2 not made", procName, 1); } for (i = 0; i < nsels; i++) { sprintf(bigbuf, "fdilate_%d_%d", fileindex, i); sarrayAddString(sa2, bigbuf, L_COPY); sprintf(bigbuf, "ferode_%d_%d", fileindex, i); sarrayAddString(sa2, bigbuf, L_COPY); } /* Make the static prototype strings */ sa3 = sarrayCreate(2 * nsels); /* should be ok */ for (i = 0; i < 2 * nsels; i++) { fname = sarrayGetString(sa2, i, L_NOCOPY); sprintf(bigbuf, "static void %s%s", fname, PROTOARGS); sarrayAddString(sa3, bigbuf, L_COPY); } /* Make strings containing function names */ sprintf(bigbuf, " * l_int32 fmorphopgen_low_%d()", fileindex); str_doc1 = stringNew(bigbuf); sprintf(bigbuf, " * void fdilate_%d_*()", fileindex); str_doc2 = stringNew(bigbuf); sprintf(bigbuf, " * void ferode_%d_*()", fileindex); str_doc3 = stringNew(bigbuf); sprintf(bigbuf, " * fmorphopgen_low_%d()", fileindex); str_doc4 = stringNew(bigbuf); sprintf(bigbuf, "fmorphopgen_low_%d(l_uint32 *datad,", fileindex); str_def1 = stringNew(bigbuf); /* Output to this sa */ sa4 = sarrayCreate(0); /* Copyright notice and info header */ sarrayParseRange(sa1, 0, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); /* Insert function names as documentation */ sarrayAddString(sa4, str_doc1, L_INSERT); sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); sarrayAddString(sa4, str_doc2, L_INSERT); sarrayAddString(sa4, str_doc3, L_INSERT); sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); /* Insert static protos */ for (i = 0; i < 2 * nsels; i++) { if ((linestr = sarrayGetString(sa3, i, L_COPY)) == NULL) { sarrayDestroy(&sa1); sarrayDestroy(&sa2); sarrayDestroy(&sa3); sarrayDestroy(&sa4); return ERROR_INT("linestr not retrieved", procName, 1); } sarrayAddString(sa4, linestr, L_INSERT); } /* Insert function header */ sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); sarrayAddString(sa4, str_doc4, L_INSERT); sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); sarrayAddString(sa4, str_def1, L_INSERT); sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); /* Generate and insert the dispatcher code */ for (i = 0; i < 2 * nsels; i++) { sprintf(bigbuf, " case %d:", i); sarrayAddString(sa4, bigbuf, L_COPY); sprintf(bigbuf, " %s(datad, w, h, wpld, datas, wpls);", sarrayGetString(sa2, i, L_NOCOPY)); sarrayAddString(sa4, bigbuf, L_COPY); sarrayAddString(sa4, breakstring, L_COPY); } /* Finish the dispatcher and introduce the low-level code */ sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); /* Get the range for the args common to all functions */ sarrayParseRange(sa1, newstart, &argstart, &argend, &newstart, "--", 0); /* Get the range for the loop code common to all functions */ sarrayParseRange(sa1, newstart, &loopstart, &loopend, &newstart, "--", 0); /* Get the range for the ending code common to all functions */ sarrayParseRange(sa1, newstart, &finalstart, &finalend, &newstart, "--", 0); /* Do all the static functions */ for (i = 0; i < 2 * nsels; i++) { /* Generate the function header and add the common args */ sarrayAddString(sa4, staticstring, L_COPY); fname = sarrayGetString(sa2, i, L_NOCOPY); sprintf(bigbuf, "%s(l_uint32 *datad,", fname); sarrayAddString(sa4, bigbuf, L_COPY); sarrayAppendRange(sa4, sa1, argstart, argend); /* Declare and define wplsN args, as necessary */ if ((sel = selaGetSel(sela, i/2)) == NULL) { sarrayDestroy(&sa1); sarrayDestroy(&sa2); sarrayDestroy(&sa3); sarrayDestroy(&sa4); return ERROR_INT("sel not returned", procName, 1); } sa5 = sarrayMakeWplsCode(sel); sarrayJoin(sa4, sa5); sarrayDestroy(&sa5); /* Add the function loop code */ sarrayAppendRange(sa4, sa1, loopstart, loopend); /* Insert barrel-op code for *dptr */ sa6 = sarrayMakeInnerLoopDWACode(sel, i); sarrayJoin(sa4, sa6); sarrayDestroy(&sa6); /* Finish the function code */ sarrayAppendRange(sa4, sa1, finalstart, finalend); } /* Output to file */ filestr = sarrayToString(sa4, 1); nbytes = strlen(filestr); if (filename) snprintf(bigbuf, L_BUF_SIZE, "%slow.%d.c", filename, fileindex); else sprintf(bigbuf, "%slow.%d.c", OUTROOT, fileindex); l_binaryWrite(bigbuf, "w", filestr, nbytes); sarrayDestroy(&sa1); sarrayDestroy(&sa2); sarrayDestroy(&sa3); sarrayDestroy(&sa4); LEPT_FREE(filestr); return 0; }
/*! * \brief fmorphautogen1() * * \param[in] sela * \param[in] fileindex * \param[in] filename [optional]; can be null * \return 0 if OK; 1 on error * * <pre> * Notes: * (1) This function uses morphtemplate1.txt to create a * top-level file that contains two functions. These * functions will carry out dilation, erosion, * opening or closing for any of the sels in the input sela. * (2) The fileindex parameter is inserted into the output * filename, as described below. * (3) If filename == NULL, the output file is fmorphgen.<n>.c, * where <n> is equal to the 'fileindex' parameter. * (4) If filename != NULL, the output file is <filename>.<n>.c. * </pre> */ l_int32 fmorphautogen1(SELA *sela, l_int32 fileindex, const char *filename) { char *filestr; char *str_proto1, *str_proto2, *str_proto3; char *str_doc1, *str_doc2, *str_doc3, *str_doc4; char *str_def1, *str_def2, *str_proc1, *str_proc2; char *str_dwa1, *str_low_dt, *str_low_ds, *str_low_ts; char *str_low_tsp1, *str_low_dtp1; char bigbuf[L_BUF_SIZE]; l_int32 i, nsels, nbytes, actstart, end, newstart; size_t size; SARRAY *sa1, *sa2, *sa3; PROCNAME("fmorphautogen1"); if (!sela) return ERROR_INT("sela not defined", procName, 1); if (fileindex < 0) fileindex = 0; if ((nsels = selaGetCount(sela)) == 0) return ERROR_INT("no sels in sela", procName, 1); /* Make array of textlines from morphtemplate1.txt */ if ((filestr = (char *)l_binaryRead(TEMPLATE1, &size)) == NULL) return ERROR_INT("filestr not made", procName, 1); sa2 = sarrayCreateLinesFromString(filestr, 1); LEPT_FREE(filestr); if (!sa2) return ERROR_INT("sa2 not made", procName, 1); /* Make array of sel names */ sa1 = selaGetSelnames(sela); /* Make strings containing function call names */ sprintf(bigbuf, "PIX *pixMorphDwa_%d(PIX *pixd, PIX *pixs, " "l_int32 operation, char *selname);", fileindex); str_proto1 = stringNew(bigbuf); sprintf(bigbuf, "PIX *pixFMorphopGen_%d(PIX *pixd, PIX *pixs, " "l_int32 operation, char *selname);", fileindex); str_proto2 = stringNew(bigbuf); sprintf(bigbuf, "l_int32 fmorphopgen_low_%d(l_uint32 *datad, l_int32 w,\n" " l_int32 h, l_int32 wpld,\n" " l_uint32 *datas, l_int32 wpls,\n" " l_int32 index);", fileindex); str_proto3 = stringNew(bigbuf); sprintf(bigbuf, " * PIX *pixMorphDwa_%d()", fileindex); str_doc1 = stringNew(bigbuf); sprintf(bigbuf, " * PIX *pixFMorphopGen_%d()", fileindex); str_doc2 = stringNew(bigbuf); sprintf(bigbuf, " * pixMorphDwa_%d()", fileindex); str_doc3 = stringNew(bigbuf); sprintf(bigbuf, " * pixFMorphopGen_%d()", fileindex); str_doc4 = stringNew(bigbuf); sprintf(bigbuf, "pixMorphDwa_%d(PIX *pixd,", fileindex); str_def1 = stringNew(bigbuf); sprintf(bigbuf, "pixFMorphopGen_%d(PIX *pixd,", fileindex); str_def2 = stringNew(bigbuf); sprintf(bigbuf, " PROCNAME(\"pixMorphDwa_%d\");", fileindex); str_proc1 = stringNew(bigbuf); sprintf(bigbuf, " PROCNAME(\"pixFMorphopGen_%d\");", fileindex); str_proc2 = stringNew(bigbuf); sprintf(bigbuf, " pixt2 = pixFMorphopGen_%d(NULL, pixt1, operation, selname);", fileindex); str_dwa1 = stringNew(bigbuf); sprintf(bigbuf, " fmorphopgen_low_%d(datad, w, h, wpld, datat, wpls, index);", fileindex); str_low_dt = stringNew(bigbuf); sprintf(bigbuf, " fmorphopgen_low_%d(datad, w, h, wpld, datas, wpls, index);", fileindex); str_low_ds = stringNew(bigbuf); sprintf(bigbuf, " fmorphopgen_low_%d(datat, w, h, wpls, datas, wpls, index+1);", fileindex); str_low_tsp1 = stringNew(bigbuf); sprintf(bigbuf, " fmorphopgen_low_%d(datat, w, h, wpls, datas, wpls, index);", fileindex); str_low_ts = stringNew(bigbuf); sprintf(bigbuf, " fmorphopgen_low_%d(datad, w, h, wpld, datat, wpls, index+1);", fileindex); str_low_dtp1 = stringNew(bigbuf); /* Make the output sa */ sa3 = sarrayCreate(0); /* Copyright notice and info header */ sarrayParseRange(sa2, 0, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); /* Insert function names as documentation */ sarrayAddString(sa3, str_doc1, L_INSERT); sarrayAddString(sa3, str_doc2, L_INSERT); /* Add '#include's */ sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); /* Insert function prototypes */ sarrayAddString(sa3, str_proto1, L_INSERT); sarrayAddString(sa3, str_proto2, L_INSERT); sarrayAddString(sa3, str_proto3, L_INSERT); /* Add static globals */ sprintf(bigbuf, "\nstatic l_int32 NUM_SELS_GENERATED = %d;", nsels); sarrayAddString(sa3, bigbuf, L_COPY); sprintf(bigbuf, "static char SEL_NAMES[][80] = {"); sarrayAddString(sa3, bigbuf, L_COPY); for (i = 0; i < nsels - 1; i++) { sprintf(bigbuf, " \"%s\",", sarrayGetString(sa1, i, L_NOCOPY)); sarrayAddString(sa3, bigbuf, L_COPY); } sprintf(bigbuf, " \"%s\"};", sarrayGetString(sa1, i, L_NOCOPY)); sarrayAddString(sa3, bigbuf, L_COPY); /* Start pixMorphDwa_*() function description */ sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_doc3, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); /* Finish pixMorphDwa_*() function definition */ sarrayAddString(sa3, str_def1, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_proc1, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_dwa1, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); /* Start pixFMorphopGen_*() function description */ sarrayAddString(sa3, str_doc4, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); /* Finish pixFMorphopGen_*() function definition */ sarrayAddString(sa3, str_def2, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_proc2, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_low_dt, L_COPY); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_low_ds, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_low_tsp1, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_low_dt, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_low_ts, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); sarrayAddString(sa3, str_low_dtp1, L_INSERT); sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa3, sa2, actstart, end); /* Output to file */ filestr = sarrayToString(sa3, 1); nbytes = strlen(filestr); if (filename) snprintf(bigbuf, L_BUF_SIZE, "%s.%d.c", filename, fileindex); else sprintf(bigbuf, "%s.%d.c", OUTROOT, fileindex); l_binaryWrite(bigbuf, "w", filestr, nbytes); sarrayDestroy(&sa1); sarrayDestroy(&sa2); sarrayDestroy(&sa3); LEPT_FREE(filestr); return 0; }
int main(int argc, char **argv) { char *selname; l_int32 i, j, nsels, sx, sy; l_float32 fact, time; GPLOT *gplot; NUMA *na1, *na2, *na3, *na4, *nac1, *nac2, *nac3, *nac4, *nax; PIX *pixs, *pixt; PIXA *pixa; SEL *sel; SELA *selalinear; static char mainName[] = "dwamorph2_reg"; if (argc != 1) return ERROR_INT(" Syntax: dwamorph2_reg", mainName, 1); pixs = pixRead("feyn-fract.tif"); pixt = pixCreateTemplate(pixs); selalinear = selaAddDwaLinear(NULL); nsels = selaGetCount(selalinear); fact = 1000. / (l_float32)NTIMES; /* converts to time in msec */ na1 = numaCreate(64); na2 = numaCreate(64); na3 = numaCreate(64); na4 = numaCreate(64); lept_mkdir("lept/morph"); /* --------- dilation ----------*/ for (i = 0; i < nsels / 2; i++) { sel = selaGetSel(selalinear, i); selGetParameters(sel, &sy, &sx, NULL, NULL); selname = selGetName(sel); fprintf(stderr, " %d .", i); startTimer(); for (j = 0; j < NTIMES; j++) pixDilate(pixt, pixs, sel); time = fact * stopTimer(); numaAddNumber(na1, time); startTimer(); for (j = 0; j < NTIMES; j++) pixDilateCompBrick(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na2, time); startTimer(); for (j = 0; j < NTIMES; j++) pixMorphDwa_3(pixt, pixs, L_MORPH_DILATE, selname); time = fact * stopTimer(); numaAddNumber(na3, time); startTimer(); for (j = 0; j < NTIMES; j++) pixDilateCompBrickDwa(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na4, time); } nax = numaMakeSequence(2, 1, nsels / 2); nac1 = numaWindowedMean(na1, HALFWIDTH); nac2 = numaWindowedMean(na2, HALFWIDTH); nac3 = numaWindowedMean(na3, HALFWIDTH); nac4 = numaWindowedMean(na4, HALFWIDTH); gplot = gplotCreate("/tmp/lept/morph/dilate", GPLOT_PNG, "Dilation time vs sel size", "size", "time (ms)"); gplotAddPlot(gplot, nax, nac1, GPLOT_LINES, "linear rasterop"); gplotAddPlot(gplot, nax, nac2, GPLOT_LINES, "composite rasterop"); gplotAddPlot(gplot, nax, nac3, GPLOT_LINES, "linear dwa"); gplotAddPlot(gplot, nax, nac4, GPLOT_LINES, "composite dwa"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nac1); numaDestroy(&nac2); numaDestroy(&nac3); numaDestroy(&nac4); /* --------- erosion ----------*/ numaEmpty(na1); numaEmpty(na2); numaEmpty(na3); numaEmpty(na4); for (i = 0; i < nsels / 2; i++) { sel = selaGetSel(selalinear, i); selGetParameters(sel, &sy, &sx, NULL, NULL); selname = selGetName(sel); fprintf(stderr, " %d .", i); startTimer(); for (j = 0; j < NTIMES; j++) pixErode(pixt, pixs, sel); time = fact * stopTimer(); numaAddNumber(na1, time); startTimer(); for (j = 0; j < NTIMES; j++) pixErodeCompBrick(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na2, time); startTimer(); for (j = 0; j < NTIMES; j++) pixMorphDwa_3(pixt, pixs, L_MORPH_ERODE, selname); time = fact * stopTimer(); numaAddNumber(na3, time); startTimer(); for (j = 0; j < NTIMES; j++) pixErodeCompBrickDwa(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na4, time); } nac1 = numaWindowedMean(na1, HALFWIDTH); nac2 = numaWindowedMean(na2, HALFWIDTH); nac3 = numaWindowedMean(na3, HALFWIDTH); nac4 = numaWindowedMean(na4, HALFWIDTH); gplot = gplotCreate("/tmp/lept/morph/erode", GPLOT_PNG, "Erosion time vs sel size", "size", "time (ms)"); gplotAddPlot(gplot, nax, nac1, GPLOT_LINES, "linear rasterop"); gplotAddPlot(gplot, nax, nac2, GPLOT_LINES, "composite rasterop"); gplotAddPlot(gplot, nax, nac3, GPLOT_LINES, "linear dwa"); gplotAddPlot(gplot, nax, nac4, GPLOT_LINES, "composite dwa"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nac1); numaDestroy(&nac2); numaDestroy(&nac3); numaDestroy(&nac4); /* --------- opening ----------*/ numaEmpty(na1); numaEmpty(na2); numaEmpty(na3); numaEmpty(na4); for (i = 0; i < nsels / 2; i++) { sel = selaGetSel(selalinear, i); selGetParameters(sel, &sy, &sx, NULL, NULL); selname = selGetName(sel); fprintf(stderr, " %d .", i); startTimer(); for (j = 0; j < NTIMES; j++) pixOpen(pixt, pixs, sel); time = fact * stopTimer(); numaAddNumber(na1, time); startTimer(); for (j = 0; j < NTIMES; j++) pixOpenCompBrick(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na2, time); startTimer(); for (j = 0; j < NTIMES; j++) pixMorphDwa_3(pixt, pixs, L_MORPH_OPEN, selname); time = fact * stopTimer(); numaAddNumber(na3, time); startTimer(); for (j = 0; j < NTIMES; j++) pixOpenCompBrickDwa(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na4, time); } nac1 = numaWindowedMean(na1, HALFWIDTH); nac2 = numaWindowedMean(na2, HALFWIDTH); nac3 = numaWindowedMean(na3, HALFWIDTH); nac4 = numaWindowedMean(na4, HALFWIDTH); gplot = gplotCreate("/tmp/lept/morph/open", GPLOT_PNG, "Opening time vs sel size", "size", "time (ms)"); gplotAddPlot(gplot, nax, nac1, GPLOT_LINES, "linear rasterop"); gplotAddPlot(gplot, nax, nac2, GPLOT_LINES, "composite rasterop"); gplotAddPlot(gplot, nax, nac3, GPLOT_LINES, "linear dwa"); gplotAddPlot(gplot, nax, nac4, GPLOT_LINES, "composite dwa"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nac1); numaDestroy(&nac2); numaDestroy(&nac3); numaDestroy(&nac4); /* --------- closing ----------*/ numaEmpty(na1); numaEmpty(na2); numaEmpty(na3); numaEmpty(na4); for (i = 0; i < nsels / 2; i++) { sel = selaGetSel(selalinear, i); selGetParameters(sel, &sy, &sx, NULL, NULL); selname = selGetName(sel); fprintf(stderr, " %d .", i); startTimer(); for (j = 0; j < NTIMES; j++) pixClose(pixt, pixs, sel); time = fact * stopTimer(); numaAddNumber(na1, time); startTimer(); for (j = 0; j < NTIMES; j++) pixCloseCompBrick(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na2, time); startTimer(); for (j = 0; j < NTIMES; j++) pixMorphDwa_3(pixt, pixs, L_MORPH_CLOSE, selname); time = fact * stopTimer(); numaAddNumber(na3, time); startTimer(); for (j = 0; j < NTIMES; j++) pixCloseCompBrickDwa(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na4, time); } nac1 = numaWindowedMean(na1, HALFWIDTH); nac2 = numaWindowedMean(na2, HALFWIDTH); nac3 = numaWindowedMean(na3, HALFWIDTH); nac4 = numaWindowedMean(na4, HALFWIDTH); gplot = gplotCreate("/tmp/lept/morph/close", GPLOT_PNG, "Closing time vs sel size", "size", "time (ms)"); gplotAddPlot(gplot, nax, nac1, GPLOT_LINES, "linear rasterop"); gplotAddPlot(gplot, nax, nac2, GPLOT_LINES, "composite rasterop"); gplotAddPlot(gplot, nax, nac3, GPLOT_LINES, "linear dwa"); gplotAddPlot(gplot, nax, nac4, GPLOT_LINES, "composite dwa"); gplotMakeOutput(gplot); #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ gplotDestroy(&gplot); numaDestroy(&nac1); numaDestroy(&nac2); numaDestroy(&nac3); numaDestroy(&nac4); numaDestroy(&na1); numaDestroy(&na2); numaDestroy(&na3); numaDestroy(&na4); numaDestroy(&nax); selaDestroy(&selalinear); pixDestroy(&pixt); pixDestroy(&pixs); /* Display the results together */ pixa = pixaCreate(0); pixs = pixRead("/tmp/lept/morph/dilate.png"); pixaAddPix(pixa, pixs, L_INSERT); pixs = pixRead("/tmp/lept/morph/erode.png"); pixaAddPix(pixa, pixs, L_INSERT); pixs = pixRead("/tmp/lept/morph/open.png"); pixaAddPix(pixa, pixs, L_INSERT); pixs = pixRead("/tmp/lept/morph/close.png"); pixaAddPix(pixa, pixs, L_INSERT); pixt = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 40, 3); pixWrite("/tmp/lept/morph/timings.png", pixt, IFF_PNG); pixDisplay(pixt, 100, 100); pixDestroy(&pixt); pixaDestroy(&pixa); return 0; }