static void test_gif(const char *fname, L_REGPARAMS *rp) { char buf[256]; l_int32 same; PIX *pixs, *pix1, *pix2; pixs = pixRead(fname); snprintf(buf, sizeof(buf), "/tmp/lept/gif/gifio-a.%d.gif", rp->index + 1); pixWrite(buf, pixs, IFF_GIF); pix1 = pixRead(buf); snprintf(buf, sizeof(buf), "/tmp/lept/gif/gifio-b.%d.gif", rp->index + 1); pixWrite(buf, pix1, IFF_GIF); pix2 = pixRead(buf); regTestWritePixAndCheck(rp, pix2, IFF_GIF); pixEqual(pixs, pix2, &same); if (!same && rp->index < 6) { fprintf(stderr, "Error for %s\n", fname); rp->success = FALSE; } if (rp->display) { fprintf(stderr, " depth: pixs = %d, pix1 = %d\n", pixGetDepth(pixs), pixGetDepth(pix1)); pixDisplayWrite(pix2, REDUCTION); } pixDestroy(&pixs); pixDestroy(&pix1); pixDestroy(&pix2); return; }
/*! * pixGenHalftoneMask() * * Input: pixs (1 bpp, assumed to be 150 to 200 ppi) * &pixtext (<optional return> text part of pixs) * &htfound (<optional return> 1 if the mask is not empty) * debug (flag: 1 for debug output) * Return: pixd (halftone mask), or null on error */ PIX * pixGenHalftoneMask(PIX *pixs, PIX **ppixtext, l_int32 *phtfound, l_int32 debug) { l_int32 empty; PIX *pixt1, *pixt2, *pixhs, *pixhm, *pixd; PROCNAME("pixGenHalftoneMask"); if (ppixtext) *ppixtext = NULL; 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); /* Compute seed for halftone parts at 8x reduction */ pixt1 = pixReduceRankBinaryCascade(pixs, 4, 4, 3, 0); pixt2 = pixOpenBrick(NULL, pixt1, 5, 5); pixhs = pixExpandReplicate(pixt2, 8); /* back to 2x reduction */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixDisplayWriteFormat(pixhs, debug, IFF_PNG); /* Compute mask for connected regions */ pixhm = pixCloseSafeBrick(NULL, pixs, 4, 4); pixDisplayWriteFormat(pixhm, debug, IFF_PNG); /* Fill seed into mask to get halftone mask */ pixd = pixSeedfillBinary(NULL, pixhs, pixhm, 4); #if 0 /* Moderate opening to remove thin lines, etc. */ pixOpenBrick(pixd, pixd, 10, 10); pixDisplayWrite(pixd, debug); #endif /* Check if mask is empty */ pixZero(pixd, &empty); if (phtfound) { *phtfound = 0; if (!empty) *phtfound = 1; } /* Optionally, get all pixels that are not under the halftone mask */ if (ppixtext) { if (empty) *ppixtext = pixCopy(NULL, pixs); else *ppixtext = pixSubtract(NULL, pixs, pixd); pixDisplayWriteFormat(*ppixtext, debug, IFF_PNG); } pixDestroy(&pixhs); pixDestroy(&pixhm); return pixd; }
/* simple comparison function */ static void pixCompare(PIX *pix1, PIX *pix2, const char *msg1, const char *msg2) { l_int32 same; pixEqual(pix1, pix2, &same); if (same) { fprintf(stderr, "%s\n", msg1); pixDisplayWrite(pix1, 1); } else { fprintf(stderr, "%s\n", msg2); pixDisplayWrite(pix1, 1); pixDisplayWrite(pix2, 1); } return; }
main(int argc, char **argv) { l_int32 i, w, h, d; l_float32 time; PIX *pixs, *pixf, *pixd; PIXA *pixa; char *filein, *fileout; static char mainName[] = "edgetest"; if (argc != 3) exit(ERROR_INT(" Syntax: edgetest filein fileout", mainName, 1)); filein = argv[1]; fileout = argv[2]; if ((pixs = pixRead(filein)) == NULL) exit(ERROR_INT("pix not made", mainName, 1)); pixGetDimensions(pixs, &w, &h, &d); if (d != 8) exit(ERROR_INT("pix not 8 bpp", mainName, 1)); /* Speed: about 12 Mpix/GHz/sec */ startTimer(); pixf = pixSobelEdgeFilter(pixs, L_HORIZONTAL_EDGES); pixd = pixThresholdToBinary(pixf, 60); pixInvert(pixd, pixd); time = stopTimer(); fprintf(stderr, "Time = %7.3f sec\n", time); fprintf(stderr, "MPix/sec: %7.3f\n", 0.000001 * w * h / time); pixDisplay(pixs, 0, 0); pixInvert(pixf, pixf); pixDisplay(pixf, 480, 0); pixDisplay(pixd, 960, 0); pixWrite(fileout, pixf, IFF_PNG); pixDestroy(&pixd); /* Threshold at different values */ pixInvert(pixf, pixf); for (i = 10; i <= 120; i += 10) { pixd = pixThresholdToBinary(pixf, i); pixInvert(pixd, pixd); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); } pixDestroy(&pixf); /* Display tiled */ pixa = pixaReadFiles("/tmp", "junk_write_display"); pixd = pixaDisplayTiledAndScaled(pixa, 8, 400, 3, 0, 25, 2); pixWrite("/tmp/junktiles.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixs); exit(0); }
/* Returns 1 on error */ static l_int32 test_writemem(PIX *pixs, l_int32 format, char *psfile) { l_uint8 *data = NULL; l_int32 same; size_t size = 0; PIX *pixd = NULL; if (format == IFF_PS) { pixWriteMemPS(&data, &size, pixs, NULL, 0, 1.0); l_binaryWrite(psfile, "w", data, size); lept_free(data); return 0; } /* Fail silently if library is not available */ #if !HAVE_LIBJPEG if (format == IFF_JFIF_JPEG) return 0; #endif /* !HAVE_LIBJPEG */ #if !HAVE_LIBPNG if (format == IFF_PNG) return 0; #endif /* !HAVE_LIBPNG */ #if !HAVE_LIBTIFF if (format == IFF_TIFF) return 0; #endif /* !HAVE_LIBTIFF */ if (pixWriteMem(&data, &size, pixs, format)) { fprintf(stderr, "Mem write fail for format %d\n", format); return 1; } if ((pixd = pixReadMem(data, size)) == NULL) { fprintf(stderr, "Mem read fail for format %d\n", format); lept_free(data); return 1; } if (format == IFF_JFIF_JPEG) { fprintf(stderr, "jpeg size = %ld\n", size); pixDisplayWrite(pixd, 1); same = TRUE; } else { pixEqual(pixs, pixd, &same); if (!same) fprintf(stderr, "Mem write/read fail for format %d\n", format); } pixDestroy(&pixd); lept_free(data); return (!same); }
void count_pieces(PIX *pix, l_int32 nexp) { l_int32 n; BOXA *boxa; pixDisplayWrite(pix, 1); boxa = pixConnComp(pix, NULL, 8); n = boxaGetCount(boxa); if (n == nexp) fprintf(stderr, "Correct: Num. comps: %d\n", n); else fprintf(stderr, "WRONG!: Num. comps: %d\n", n); boxaDestroy(&boxa); pixDestroy(&pix); }
main(int argc, char **argv) { l_int32 i; PIX *pixs, *pixt1, *pixt2, *pixt3, *pixd; PIXA *pixa; static char mainName[] = "livre_seedgen"; pixs = pixRead("pageseg2.tif"); startTimer(); for (i = 0; i < 100; i++) { pixt1 = pixReduceRankBinaryCascade(pixs, 1, 4, 4, 3); pixDestroy(&pixt1); } fprintf(stderr, "Time: %8.4f sec\n", stopTimer() / 100.); /* 4 2x rank reductions (levels 1, 4, 4, 3), followed by 5x5 opening */ pixDisplayWrite(NULL, -1); pixDisplayWriteFormat(pixs, 4, IFF_PNG); pixt1 = pixReduceRankBinaryCascade(pixs, 1, 4, 0, 0); pixDisplayWriteFormat(pixt1, 1, IFF_PNG); pixt2 = pixReduceRankBinaryCascade(pixt1, 4, 3, 0, 0); pixDisplayWriteFormat(pixt2, 1, IFF_PNG); pixOpenBrick(pixt2, pixt2, 5, 5); pixt3 = pixExpandBinaryReplicate(pixt2, 2); pixDisplayWriteFormat(pixt3, 1, IFF_PNG); /* Generate the output image */ pixa = pixaReadFiles("/tmp", "junk_write_display"); pixd = pixaDisplayTiledAndScaled(pixa, 8, 250, 4, 0, 25, 2); pixWrite("/tmp/seedgen.png", pixd, IFF_PNG); pixDestroy(&pixs); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixd); pixaDestroy(&pixa); return 0; }
main(int argc, char **argv) { PIX *pixs, *pixsg, *pixg, *pixd; PIXA *pixa; static char mainName[] = "livre_tophat"; if (argc != 1) return ERROR_INT(" Syntax: livre_tophat", mainName, 1); /* Read the image in at 150 ppi. */ if ((pixs = pixRead("brothers.150.jpg")) == NULL) return ERROR_INT("pix not made", mainName, 1); pixDisplayWrite(NULL, -1); pixDisplayWriteFormat(pixs, 2, IFF_JFIF_JPEG); pixsg = pixConvertRGBToLuminance(pixs); /* Black tophat (closing - original-image) and invert */ pixg = pixTophat(pixsg, 15, 15, L_TOPHAT_BLACK); pixInvert(pixg, pixg); pixDisplayWriteFormat(pixg, 2, IFF_JFIF_JPEG); /* Set black point at 200, white point at 245. */ pixd = pixGammaTRC(NULL, pixg, 1.0, 200, 245); pixDisplayWriteFormat(pixd, 2, IFF_JFIF_JPEG); pixDestroy(&pixg); pixDestroy(&pixd); /* Generate the output image */ pixa = pixaReadFiles("/tmp", "junk_write_display"); pixd = pixaDisplayTiledAndScaled(pixa, 8, 350, 3, 0, 25, 2); pixWrite("/tmp/tophat.jpg", pixd, IFF_JFIF_JPEG); pixDisplay(pixd, 0, 0); pixDestroy(&pixd); pixDestroy(&pixs); pixDestroy(&pixsg); return 0; }
main(int argc, char **argv) { #if HAVE_FMEMOPEN char psname[256]; #endif /* HAVE_FMEMOPEN */ char *tempname; l_uint8 *data; l_int32 i, d, n, success, failure, same; l_int32 w, h, bps, spp; size_t size, nbytes; PIX *pix1, *pix2, *pix4, *pix8, *pix16, *pix32; PIX *pix, *pixt, *pixd; PIXA *pixa; L_REGPARAMS *rp; #if !HAVE_LIBJPEG fprintf(stderr, "Omitting libjpeg tests in ioformats_reg\n"); #endif /* !HAVE_LIBJPEG */ #if !HAVE_LIBTIFF fprintf(stderr, "Omitting libtiff tests in ioformats_reg\n"); #endif /* !HAVE_LIBTIFF */ #if !HAVE_LIBPNG || !HAVE_LIBZ fprintf(stderr, "Omitting libpng tests in ioformats_reg\n"); #endif /* !HAVE_LIBPNG || !HAVE_LIBZ */ if (regTestSetup(argc, argv, &rp)) return 1; /* --------- Part 1: Test all lossless formats for r/w to file ---------*/ failure = FALSE; success = TRUE; fprintf(stderr, "Test bmp 1 bpp file:\n"); if (ioFormatTest(BMP_FILE)) success = FALSE; #if HAVE_LIBTIFF fprintf(stderr, "\nTest other 1 bpp file:\n"); if (ioFormatTest(FILE_1BPP)) success = FALSE; #endif /* HAVE_LIBTIFF */ #if HAVE_LIBPNG fprintf(stderr, "\nTest 2 bpp file:\n"); if (ioFormatTest(FILE_2BPP)) success = FALSE; fprintf(stderr, "\nTest 2 bpp file with cmap:\n"); if (ioFormatTest(FILE_2BPP_C)) success = FALSE; fprintf(stderr, "\nTest 4 bpp file:\n"); if (ioFormatTest(FILE_4BPP)) success = FALSE; fprintf(stderr, "\nTest 4 bpp file with cmap:\n"); if (ioFormatTest(FILE_4BPP_C)) success = FALSE; fprintf(stderr, "\nTest 8 bpp grayscale file with cmap:\n"); if (ioFormatTest(FILE_8BPP_1)) success = FALSE; fprintf(stderr, "\nTest 8 bpp color file with cmap:\n"); if (ioFormatTest(FILE_8BPP_2)) success = FALSE; #endif /* HAVE_LIBPNG */ #if HAVE_LIBJPEG fprintf(stderr, "\nTest 8 bpp file without cmap:\n"); if (ioFormatTest(FILE_8BPP_3)) success = FALSE; #endif /* HAVE_LIBJPEG */ #if HAVE_LIBTIFF fprintf(stderr, "\nTest 16 bpp file:\n"); if (ioFormatTest(FILE_16BPP)) success = FALSE; #endif /* HAVE_LIBTIFF */ #if HAVE_LIBJPEG fprintf(stderr, "\nTest 32 bpp file:\n"); if (ioFormatTest(FILE_32BPP)) success = FALSE; #endif /* HAVE_LIBJPEG */ if (success) fprintf(stderr, "\n ********** Success on all i/o format tests *********\n"); else fprintf(stderr, "\n ******* Failure on at least one i/o format test ******\n"); if (!success) failure = TRUE; /* ------------------ Part 2: Test tiff r/w to file ------------------- */ #if !HAVE_LIBTIFF goto part6; #endif /* !HAVE_LIBTIFF */ fprintf(stderr, "\nTest tiff r/w and format extraction\n"); pixa = pixaCreate(6); pix1 = pixRead(BMP_FILE); pix2 = pixConvert1To2(NULL, pix1, 3, 0); pix4 = pixConvert1To4(NULL, pix1, 15, 0); pix16 = pixRead(FILE_16BPP); fprintf(stderr, "Input format: %d\n", pixGetInputFormat(pix16)); pix8 = pixConvert16To8(pix16, 1); pix32 = pixRead(FILE_32BPP); pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); pixaAddPix(pixa, pix4, L_INSERT); pixaAddPix(pixa, pix8, L_INSERT); pixaAddPix(pixa, pix16, L_INSERT); pixaAddPix(pixa, pix32, L_INSERT); n = pixaGetCount(pixa); success = TRUE; for (i = 0; i < n; i++) { pix = pixaGetPix(pixa, i, L_CLONE); d = pixGetDepth(pix); fprintf(stderr, "%d bpp\n", d); if (i == 0) { /* 1 bpp */ pixWrite("/tmp/junkg3.tif", pix, IFF_TIFF_G3); pixWrite("/tmp/junkg4.tif", pix, IFF_TIFF_G4); pixWrite("/tmp/junkrle.tif", pix, IFF_TIFF_RLE); pixWrite("/tmp/junkpb.tif", pix, IFF_TIFF_PACKBITS); if (testcomp("/tmp/junkg3.tif", pix, IFF_TIFF_G3)) success = FALSE; if (testcomp("/tmp/junkg4.tif", pix, IFF_TIFF_G4)) success = FALSE; if (testcomp("/tmp/junkrle.tif", pix, IFF_TIFF_RLE)) success = FALSE; if (testcomp("/tmp/junkpb.tif", pix, IFF_TIFF_PACKBITS)) success = FALSE; } pixWrite("/tmp/junklzw.tif", pix, IFF_TIFF_LZW); pixWrite("/tmp/junkzip.tif", pix, IFF_TIFF_ZIP); pixWrite("/tmp/junknon.tif", pix, IFF_TIFF); if (testcomp("/tmp/junklzw.tif", pix, IFF_TIFF_LZW)) success = FALSE; if (testcomp("/tmp/junkzip.tif", pix, IFF_TIFF_ZIP)) success = FALSE; if (testcomp("/tmp/junknon.tif", pix, IFF_TIFF)) success = FALSE; pixDestroy(&pix); } if (success) fprintf(stderr, "\n ********** Success on tiff r/w to file *********\n\n"); else fprintf(stderr, "\n ******* Failure on at least one tiff r/w to file ******\n\n"); if (!success) failure = TRUE; /* ------------------ Part 3: Test tiff r/w to memory ----------------- */ success = TRUE; for (i = 0; i < n; i++) { pix = pixaGetPix(pixa, i, L_CLONE); d = pixGetDepth(pix); fprintf(stderr, "%d bpp\n", d); if (i == 0) { /* 1 bpp */ pixWriteMemTiff(&data, &size, pix, IFF_TIFF_G3); nbytes = nbytesInFile("/tmp/junkg3.tif"); fprintf(stderr, "nbytes = %ld, size = %ld\n", nbytes, size); pixt = pixReadMemTiff(data, size, 0); if (testcomp_mem(pix, &pixt, i, IFF_TIFF_G3)) success = FALSE; lept_free(data); pixWriteMemTiff(&data, &size, pix, IFF_TIFF_G4); nbytes = nbytesInFile("/tmp/junkg4.tif"); fprintf(stderr, "nbytes = %ld, size = %ld\n", nbytes, size); pixt = pixReadMemTiff(data, size, 0); if (testcomp_mem(pix, &pixt, i, IFF_TIFF_G4)) success = FALSE; readHeaderMemTiff(data, size, 0, &w, &h, &bps, &spp, NULL, NULL, NULL); fprintf(stderr, "(w,h,bps,spp) = (%d,%d,%d,%d)\n", w, h, bps, spp); lept_free(data); pixWriteMemTiff(&data, &size, pix, IFF_TIFF_RLE); nbytes = nbytesInFile("/tmp/junkrle.tif"); fprintf(stderr, "nbytes = %ld, size = %ld\n", nbytes, size); pixt = pixReadMemTiff(data, size, 0); if (testcomp_mem(pix, &pixt, i, IFF_TIFF_RLE)) success = FALSE; lept_free(data); pixWriteMemTiff(&data, &size, pix, IFF_TIFF_PACKBITS); nbytes = nbytesInFile("/tmp/junkpb.tif"); fprintf(stderr, "nbytes = %ld, size = %ld\n", nbytes, size); pixt = pixReadMemTiff(data, size, 0); if (testcomp_mem(pix, &pixt, i, IFF_TIFF_PACKBITS)) success = FALSE; lept_free(data); } pixWriteMemTiff(&data, &size, pix, IFF_TIFF_LZW); pixt = pixReadMemTiff(data, size, 0); if (testcomp_mem(pix, &pixt, i, IFF_TIFF_LZW)) success = FALSE; lept_free(data); pixWriteMemTiff(&data, &size, pix, IFF_TIFF_ZIP); pixt = pixReadMemTiff(data, size, 0); if (testcomp_mem(pix, &pixt, i, IFF_TIFF_ZIP)) success = FALSE; readHeaderMemTiff(data, size, 0, &w, &h, &bps, &spp, NULL, NULL, NULL); fprintf(stderr, "(w,h,bps,spp) = (%d,%d,%d,%d)\n", w, h, bps, spp); lept_free(data); pixWriteMemTiff(&data, &size, pix, IFF_TIFF); pixt = pixReadMemTiff(data, size, 0); if (testcomp_mem(pix, &pixt, i, IFF_TIFF)) success = FALSE; lept_free(data); pixDestroy(&pix); } if (success) fprintf(stderr, "\n ********** Success on tiff r/w to memory *********\n\n"); else fprintf(stderr, "\n ******* Failure on at least one tiff r/w to memory ******\n\n"); if (!success) failure = TRUE; /* ---------------- Part 4: Test non-tiff r/w to memory ---------------- */ #if HAVE_FMEMOPEN pixDisplayWrite(NULL, -1); success = TRUE; for (i = 0; i < n; i++) { pix = pixaGetPix(pixa, i, L_CLONE); d = pixGetDepth(pix); sprintf(psname, "/tmp/junkps.%d", d); fprintf(stderr, "%d bpp\n", d); if (d != 16) { if (test_writemem(pix, IFF_PNG, NULL)) success = FALSE; if (test_writemem(pix, IFF_BMP, NULL)) success = FALSE; } if (test_writemem(pix, IFF_PNM, NULL)) success = FALSE; if (test_writemem(pix, IFF_PS, psname)) success = FALSE; if (d == 8 || d == 32) if (test_writemem(pix, IFF_JFIF_JPEG, NULL)) success = FALSE; pixDestroy(&pix); } if (success) fprintf(stderr, "\n ********** Success on non-tiff r/w to memory *********\n\n"); else fprintf(stderr, "\n **** Failure on at least one non-tiff r/w to memory *****\n\n"); if (!success) failure = TRUE; #else fprintf(stderr, "\n ***** Non-tiff r/w to memory not enabled *****\n\n"); #endif /* HAVE_FMEMOPEN */ pixaDestroy(&pixa); /* ------------ Part 5: Test multipage tiff r/w to memory ------------ */ /* Make a multipage tiff file, and read it back into memory */ success = TRUE; pix = pixRead("feyn.tif"); pixa = pixaSplitPix(pix, 3, 3, 0, 0); for (i = 0; i < 9; i++) { pixt = pixaGetPix(pixa, i, L_CLONE); if (i == 0) pixWriteTiff("/tmp/junktiffmpage.tif", pixt, IFF_TIFF_G4, "w"); else pixWriteTiff("/tmp/junktiffmpage.tif", pixt, IFF_TIFF_G4, "a"); pixDestroy(&pixt); } data = l_binaryRead("/tmp/junktiffmpage.tif", &nbytes); pixaDestroy(&pixa); /* Read the individual pages from memory to a pix */ pixa = pixaCreate(9); for (i = 0; i < 9; i++) { pixt = pixReadMemTiff(data, nbytes, i); pixaAddPix(pixa, pixt, L_INSERT); } lept_free(data); /* Un-tile the pix in the pixa back to the original image */ pixt = pixaDisplayUnsplit(pixa, 3, 3, 0, 0); pixaDestroy(&pixa); /* Clip to foreground to remove any extra rows or columns */ pixClipToForeground(pix, &pix1, NULL); pixClipToForeground(pixt, &pix2, NULL); pixEqual(pix1, pix2, &same); if (same) fprintf(stderr, "\n ******* Success on tiff multipage read from memory ******\n\n"); else fprintf(stderr, "\n ******* Failure on tiff multipage read from memory ******\n\n"); if (!same) failure = TRUE; pixDestroy(&pix); pixDestroy(&pixt); pixDestroy(&pix1); pixDestroy(&pix2); /* ------------ Part 6: Test 24 bpp writing ------------ */ #if !HAVE_LIBTIFF part6: #endif /* !HAVE_LIBTIFF */ #if !HAVE_LIBPNG || !HAVE_LIBJPEG || !HAVE_LIBTIFF goto finish; #endif /* !HAVE_LIBPNG || !HAVE_LIBJPEG || !HAVE_LIBTIFF */ /* Generate a 24 bpp (not 32 bpp !!) rgb pix and write it out */ success = TRUE; pix = pixRead("marge.jpg"); pixt = make_24_bpp_pix(pix); pixWrite("/tmp/junk24.png", pixt, IFF_PNG); pixWrite("/tmp/junk24.jpg", pixt, IFF_JFIF_JPEG); pixWrite("/tmp/junk24.tif", pixt, IFF_TIFF); pixd = pixRead("/tmp/junk24.png"); pixEqual(pix, pixd, &same); if (!same) success = FALSE; pixDestroy(&pixd); pixd = pixRead("/tmp/junk24.jpg"); regTestCompareSimilarPix(rp, pix, pixd, 10, 0.0002, 0); pixDestroy(&pixd); pixd = pixRead("/tmp/junk24.tif"); pixEqual(pix, pixd, &same); if (!same) success = FALSE; pixDestroy(&pixd); if (success) fprintf(stderr, "\n ******* Success on 24 bpp rgb writing *******\n\n"); else fprintf(stderr, "\n ******* Failure on 24 bpp rgb writing *******\n\n"); if (!success) failure = TRUE; pixDestroy(&pix); pixDestroy(&pixt); /* -------------- Part 7: Read header information -------------- */ success = TRUE; if (get_header_data(FILE_1BPP, IFF_TIFF_G4)) success = FALSE; if (get_header_data(FILE_2BPP, IFF_PNG)) success = FALSE; if (get_header_data(FILE_2BPP_C, IFF_PNG)) success = FALSE; if (get_header_data(FILE_4BPP, IFF_PNG)) success = FALSE; if (get_header_data(FILE_4BPP_C, IFF_PNG)) success = FALSE; if (get_header_data(FILE_8BPP_1, IFF_PNG)) success = FALSE; if (get_header_data(FILE_8BPP_2, IFF_PNG)) success = FALSE; if (get_header_data(FILE_8BPP_3, IFF_JFIF_JPEG)) success = FALSE; if (get_header_data(FILE_16BPP, IFF_TIFF_ZIP)) success = FALSE; if (get_header_data(FILE_32BPP, IFF_JFIF_JPEG)) success = FALSE; #if HAVE_FMEMOPEN pix = pixRead(FILE_8BPP_1); tempname = genTempFilename((const char *)"/tmp", (const char *)".pnm", 1, 1); pixWrite(tempname, pix, IFF_PNM); if (get_header_data(tempname, IFF_PNM)) success = FALSE; pixDestroy(&pix); lept_free(tempname); #endif /* HAVE_FMEMOPEN */ pix = pixRead(FILE_1BPP); tempname = genTempFilename((const char *)"/tmp", (const char *)".tif", 1, 1); pixWrite(tempname, pix, IFF_TIFF_G3); if (get_header_data(tempname, IFF_TIFF_G3)) success = FALSE; pixWrite(tempname, pix, IFF_TIFF_G4); if (get_header_data(tempname, IFF_TIFF_G4)) success = FALSE; pixWrite(tempname, pix, IFF_TIFF_PACKBITS); if (get_header_data(tempname, IFF_TIFF_PACKBITS)) success = FALSE; pixWrite(tempname, pix, IFF_TIFF_RLE); if (get_header_data(tempname, IFF_TIFF_RLE)) success = FALSE; pixWrite(tempname, pix, IFF_TIFF_LZW); if (get_header_data(tempname, IFF_TIFF_LZW)) success = FALSE; pixWrite(tempname, pix, IFF_TIFF_ZIP); if (get_header_data(tempname, IFF_TIFF_ZIP)) success = FALSE; pixWrite(tempname, pix, IFF_TIFF); if (get_header_data(tempname, IFF_TIFF)) success = FALSE; pixDestroy(&pix); lept_free(tempname); if (success) fprintf(stderr, "\n ******* Success on reading headers *******\n\n"); else fprintf(stderr, "\n ******* Failure on reading headers *******\n\n"); if (!success) failure = TRUE; #if !HAVE_LIBPNG || !HAVE_LIBJPEG || !HAVE_LIBTIFF finish: #endif /* !HAVE_LIBPNG || !HAVE_LIBJPEG || !HAVE_LIBTIFF */ if (!failure) fprintf(stderr, " ******* Success on all tests *******\n\n"); else fprintf(stderr, " ******* Failure on at least one test *******\n\n"); return regTestCleanup(rp); }
main(int argc, char **argv) { l_int32 i, wf, hf, w, h, d, same; l_float32 rank, time; PIX *pixs, *pixd, *pixt1, *pixt2, *pixt3, *pixt4; PIXA *pixa; char *filein, *fileout; static char mainName[] = "ranktest"; if (argc != 6) exit(ERROR_INT(" Syntax: ranktest filein wf hf rank fileout", mainName, 1)); filein = argv[1]; wf = atoi(argv[2]); hf = atoi(argv[3]); rank = atof(argv[4]); fileout = argv[5]; if ((pixs = pixRead(filein)) == NULL) exit(ERROR_INT("pix not made", mainName, 1)); pixGetDimensions(pixs, &w, &h, &d); if (d != 8 && d != 32) exit(ERROR_INT("pix neither 8 nor 32 bpp", mainName, 1)); startTimer(); pixd = pixRankFilter(pixs, wf, hf, rank); time = stopTimer(); fprintf(stderr, "Time = %7.3f sec\n", time); fprintf(stderr, "MPix/sec: %7.3f\n", 0.000001 * w * h / time); pixDisplay(pixs, 0, 0); pixDisplay(pixd, 600, 0); pixWrite(fileout, pixd, IFF_PNG); pixDestroy(&pixd); /* Get results for different rank values */ for (i = 0; i <= 10; i++) { pixd = pixRankFilter(pixs, wf, hf, 0.1 * i); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); } /* Make the dimensions odd to compare with dilation & erosion */ if (wf % 2 == 0) wf++; if (hf % 2 == 0) hf++; /* Get results for dilation and erosion */ if (d == 8) { pixt1 = pixDilateGray(pixs, wf, hf); pixt2 = pixErodeGray(pixs, wf, hf); } else { pixt1 = pixColorMorph(pixs, L_MORPH_DILATE, wf, hf); pixt2 = pixColorMorph(pixs, L_MORPH_ERODE, wf, hf); } pixDisplayWrite(pixt1, 1); /* dilation */ /* Get results using the rank filter for rank = 0.0 and 1.0. * Don't use 0.0 or 1.0, because those are dispatched * automatically to erosion and dilation! */ pixt3 = pixRankFilter(pixs, wf, hf, 0.0001); pixt4 = pixRankFilter(pixs, wf, hf, 0.9999); /* Compare */ pixEqual(pixt1, pixt4, &same); if (same) fprintf(stderr, "Correct: dilation results same as rank 1.0\n"); else fprintf(stderr, "Error: dilation results differ from rank 1.0\n"); pixEqual(pixt2, pixt3, &same); if (same) fprintf(stderr, "Correct: erosion results same as rank 0.0\n"); else fprintf(stderr, "Error: erosion results differ from rank 0.0\n"); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); /* Display tiled */ pixa = pixaReadFiles("/tmp", "junk_write_display"); pixd = pixaDisplayTiledAndScaled(pixa, d, 400, 3, 0, 25, 2); pixWrite("/tmp/junktiles.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixs); return 0; }
int main(int argc, char **argv) { l_int32 index; l_uint32 val32; BOX *box, *box1, *box2, *box3, *box4, *box5; BOXA *boxa; L_KERNEL *kel; PIX *pixs, *pixg, *pixb, *pixd, *pixt, *pix1, *pix2, *pix3, *pix4; PIXA *pixa; PIXCMAP *cmap; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; pixa = pixaCreate(0); /* Color non-white pixels on RGB */ pixs = pixRead("lucasta-frag.jpg"); pixt = pixConvert8To32(pixs); box = boxCreate(120, 30, 200, 200); pixColorGray(pixt, box, L_PAINT_DARK, 220, 0, 0, 255); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 0 */ pixaAddPix(pixa, pixt, L_COPY); pixColorGray(pixt, NULL, L_PAINT_DARK, 220, 255, 100, 100); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 1 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); /* Color non-white pixels on colormap */ pixt = pixThresholdTo4bpp(pixs, 6, 1); box = boxCreate(120, 30, 200, 200); pixColorGray(pixt, box, L_PAINT_DARK, 220, 0, 0, 255); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 2 */ pixaAddPix(pixa, pixt, L_COPY); pixColorGray(pixt, NULL, L_PAINT_DARK, 220, 255, 100, 100); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 3 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); /* Color non-black pixels on RGB */ pixt = pixConvert8To32(pixs); box = boxCreate(120, 30, 200, 200); pixColorGray(pixt, box, L_PAINT_LIGHT, 20, 0, 0, 255); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 4 */ pixaAddPix(pixa, pixt, L_COPY); pixColorGray(pixt, NULL, L_PAINT_LIGHT, 80, 255, 100, 100); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 5 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); /* Color non-black pixels on colormap */ pixt = pixThresholdTo4bpp(pixs, 6, 1); box = boxCreate(120, 30, 200, 200); pixColorGray(pixt, box, L_PAINT_LIGHT, 20, 0, 0, 255); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 6 */ pixaAddPix(pixa, pixt, L_COPY); pixColorGray(pixt, NULL, L_PAINT_LIGHT, 20, 255, 100, 100); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 7 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); /* Add highlight color to RGB */ pixt = pixConvert8To32(pixs); box = boxCreate(507, 5, 385, 45); pixg = pixClipRectangle(pixs, box, NULL); pixb = pixThresholdToBinary(pixg, 180); pixInvert(pixb, pixb); pixDisplayWrite(pixb, 1); composeRGBPixel(50, 0, 250, &val32); pixPaintThroughMask(pixt, pixb, box->x, box->y, val32); boxDestroy(&box); pixDestroy(&pixg); pixDestroy(&pixb); box = boxCreate(236, 107, 262, 40); pixg = pixClipRectangle(pixs, box, NULL); pixb = pixThresholdToBinary(pixg, 180); pixInvert(pixb, pixb); composeRGBPixel(250, 0, 50, &val32); pixPaintThroughMask(pixt, pixb, box->x, box->y, val32); boxDestroy(&box); pixDestroy(&pixg); pixDestroy(&pixb); box = boxCreate(222, 208, 247, 43); pixg = pixClipRectangle(pixs, box, NULL); pixb = pixThresholdToBinary(pixg, 180); pixInvert(pixb, pixb); composeRGBPixel(60, 250, 60, &val32); pixPaintThroughMask(pixt, pixb, box->x, box->y, val32); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 8 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); pixDestroy(&pixg); pixDestroy(&pixb); /* Add highlight color to colormap */ pixt = pixThresholdTo4bpp(pixs, 5, 1); cmap = pixGetColormap(pixt); pixcmapGetIndex(cmap, 255, 255, 255, &index); box = boxCreate(507, 5, 385, 45); pixSetSelectCmap(pixt, box, index, 50, 0, 250); boxDestroy(&box); box = boxCreate(236, 107, 262, 40); pixSetSelectCmap(pixt, box, index, 250, 0, 50); boxDestroy(&box); box = boxCreate(222, 208, 247, 43); pixSetSelectCmap(pixt, box, index, 60, 250, 60); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 9 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); /* Paint lines on RGB */ pixt = pixConvert8To32(pixs); pixRenderLineArb(pixt, 450, 20, 850, 320, 5, 200, 50, 125); pixRenderLineArb(pixt, 30, 40, 440, 40, 5, 100, 200, 25); box = boxCreate(70, 80, 300, 245); pixRenderBoxArb(pixt, box, 3, 200, 200, 25); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 10 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); /* Paint lines on colormap */ pixt = pixThresholdTo4bpp(pixs, 5, 1); pixRenderLineArb(pixt, 450, 20, 850, 320, 5, 200, 50, 125); pixRenderLineArb(pixt, 30, 40, 440, 40, 5, 100, 200, 25); box = boxCreate(70, 80, 300, 245); pixRenderBoxArb(pixt, box, 3, 200, 200, 25); regTestWritePixAndCheck(rp, pixt, IFF_PNG); /* 11 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); /* Blend lines on RGB */ pixt = pixConvert8To32(pixs); pixRenderLineBlend(pixt, 450, 20, 850, 320, 5, 200, 50, 125, 0.35); pixRenderLineBlend(pixt, 30, 40, 440, 40, 5, 100, 200, 25, 0.35); box = boxCreate(70, 80, 300, 245); pixRenderBoxBlend(pixt, box, 3, 200, 200, 25, 0.6); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 12 */ pixaAddPix(pixa, pixt, L_INSERT); boxDestroy(&box); /* Colorize gray on cmapped image. */ pix1 = pixRead("lucasta.150.jpg"); pix2 = pixThresholdTo4bpp(pix1, 7, 1); box1 = boxCreate(73, 206, 140, 27); pixColorGrayCmap(pix2, box1, L_PAINT_LIGHT, 130, 207, 43); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 13 */ pixaAddPix(pixa, pix2, L_COPY); if (rp->display) pixPrintStreamInfo(stderr, pix2, "One box added"); box2 = boxCreate(255, 404, 197, 25); pixColorGrayCmap(pix2, box2, L_PAINT_LIGHT, 230, 67, 119); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 14 */ pixaAddPix(pixa, pix2, L_COPY); if (rp->display) pixPrintStreamInfo(stderr, pix2, "Two boxes added"); box3 = boxCreate(122, 756, 224, 22); pixColorGrayCmap(pix2, box3, L_PAINT_DARK, 230, 67, 119); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 15 */ pixaAddPix(pixa, pix2, L_COPY); if (rp->display) pixPrintStreamInfo(stderr, pix2, "Three boxes added"); box4 = boxCreate(11, 780, 147, 22); pixColorGrayCmap(pix2, box4, L_PAINT_LIGHT, 70, 137, 229); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 16 */ pixaAddPix(pixa, pix2, L_COPY); if (rp->display) pixPrintStreamInfo(stderr, pix2, "Four boxes added"); box5 = boxCreate(163, 605, 78, 22); pixColorGrayCmap(pix2, box5, L_PAINT_LIGHT, 70, 137, 229); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 17 */ pixaAddPix(pixa, pix2, L_INSERT); if (rp->display) pixPrintStreamInfo(stderr, pix2, "Five boxes added"); pixDestroy(&pix1); boxDestroy(&box1); boxDestroy(&box2); boxDestroy(&box3); boxDestroy(&box4); boxDestroy(&box5); pixDestroy(&pixs); /* Make a gray image and identify the fg pixels (val > 230) */ pixs = pixRead("feyn-fract.tif"); pix1 = pixConvertTo8(pixs, 0); kel = makeGaussianKernel(2, 2, 1.5, 1.0); pix2 = pixConvolve(pix1, kel, 8, 1); pix3 = pixThresholdToBinary(pix2, 230); boxa = pixConnComp(pix3, NULL, 8); pixDestroy(&pixs); pixDestroy(&pix1); pixDestroy(&pix3); kernelDestroy(&kel); /* Color the individual components in the gray image */ pix4 = pixColorGrayRegions(pix2, boxa, L_PAINT_DARK, 230, 255, 0, 0); regTestWritePixAndCheck(rp, pix4, IFF_PNG); /* 18 */ pixaAddPix(pixa, pix4, L_INSERT); pixDisplayWithTitle(pix4, 0, 0, NULL, rp->display); /* Threshold to 10 levels of gray */ pix3 = pixThresholdOn8bpp(pix2, 10, 1); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 19 */ pixaAddPix(pixa, pix3, L_COPY); /* Color the individual components in the cmapped image */ pix4 = pixColorGrayRegions(pix3, boxa, L_PAINT_DARK, 230, 255, 0, 0); regTestWritePixAndCheck(rp, pix4, IFF_PNG); /* 20 */ pixaAddPix(pixa, pix4, L_INSERT); pixDisplayWithTitle(pix4, 0, 100, NULL, rp->display); boxaDestroy(&boxa); /* Color the entire gray image (not component-wise) */ pixColorGray(pix2, NULL, L_PAINT_DARK, 230, 255, 0, 0); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 21 */ pixaAddPix(pixa, pix2, L_INSERT); /* Color the entire cmapped image (not component-wise) */ pixColorGray(pix3, NULL, L_PAINT_DARK, 230, 255, 0, 0); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 22 */ pixaAddPix(pixa, pix3, L_INSERT); /* Reconstruct cmapped images */ pixd = ReconstructByValue(rp, "weasel2.4c.png"); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 23 */ pixaAddPix(pixa, pixd, L_INSERT); pixd = ReconstructByValue(rp, "weasel4.11c.png"); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 24 */ pixaAddPix(pixa, pixd, L_INSERT); pixd = ReconstructByValue(rp, "weasel8.240c.png"); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 25 */ pixaAddPix(pixa, pixd, L_INSERT); /* Fake reconstruct cmapped images, with one color into a band */ pixd = FakeReconstructByBand(rp, "weasel2.4c.png"); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 26 */ pixaAddPix(pixa, pixd, L_INSERT); pixd = FakeReconstructByBand(rp, "weasel4.11c.png"); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 27 */ pixaAddPix(pixa, pixd, L_INSERT); pixd = FakeReconstructByBand(rp, "weasel8.240c.png"); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 28 */ pixaAddPix(pixa, pixd, L_INSERT); /* If in testing mode, make a pdf */ if (rp->display) { pixaConvertToPdf(pixa, 100, 1.0, L_FLATE_ENCODE, 0, "Colorize and paint", "/tmp/lept/regout/paint.pdf"); L_INFO("Output pdf: /tmp/lept/regout/paint.pdf\n", rp->testname); } pixaDestroy(&pixa); return regTestCleanup(rp); }
int main(int argc, char **argv) { char label[512]; l_int32 rval, gval, bval, w, h, i, j, rwhite, gwhite, bwhite, count; l_uint32 pixel; GPLOT *gplot1, *gplot2; NUMA *naseq, *na; NUMAA *naa1, *naa2; PIX *pixs, *pixt, *pixt0, *pixt1, *pixt2; PIX *pixr, *pixg, *pixb; PIXA *pixa; PIXCMAP *cmap; static char mainName[] = "colorspacetest"; if (argc != 2) return ERROR_INT(" Syntax: colorspacetest filein", mainName, 1); if ((pixs = pixRead(argv[1])) == NULL) return ERROR_INT("pixs not made", mainName, 1); /* Generate colors by sampling hue with max sat and value. * This was used to make the color strip 19-colors.png. */ pixa = pixaCreate(19); for (i = 0; i < 19; i++) { convertHSVToRGB((240 * i / 18), 255, 255, &rval, &gval, &bval); composeRGBPixel(rval, gval, bval, &pixel); pixt1 = pixCreate(50, 100, 32); pixSetAllArbitrary(pixt1, pixel); pixaAddPix(pixa, pixt1, L_INSERT); } pixt2 = pixaDisplayTiledInRows(pixa, 32, 1100, 1.0, 0, 0, 0); pixDisplayWrite(pixt2, 1); pixDestroy(&pixt2); pixaDestroy(&pixa); /* Colorspace conversion in rgb */ pixDisplayWrite(pixs, 1); pixt = pixConvertRGBToHSV(NULL, pixs); pixDisplayWrite(pixt, 1); pixConvertHSVToRGB(pixt, pixt); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); /* Colorspace conversion on a colormap */ pixt = pixOctreeQuantNumColors(pixs, 25, 0); pixDisplayWrite(pixt, 1); cmap = pixGetColormap(pixt); pixcmapWriteStream(stderr, cmap); pixcmapConvertRGBToHSV(cmap); pixcmapWriteStream(stderr, cmap); pixDisplayWrite(pixt, 1); pixcmapConvertHSVToRGB(cmap); pixcmapWriteStream(stderr, cmap); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); /* Color content extraction */ pixColorContent(pixs, 0, 0, 0, 0, &pixr, &pixg, &pixb); pixDisplayWrite(pixr, 1); pixDisplayWrite(pixg, 1); pixDisplayWrite(pixb, 1); pixDestroy(&pixr); pixDestroy(&pixg); pixDestroy(&pixb); /* Color content measurement */ pixa = pixaCreate(20); naseq = numaMakeSequence(100, 5, 20); naa1 = numaaCreate(6); naa2 = numaaCreate(6); for (i = 0; i < 6; i++) { na = numaCreate(20); numaaAddNuma(naa1, na, L_COPY); numaaAddNuma(naa2, na, L_INSERT); } pixGetDimensions(pixs, &w, &h, NULL); for (i = 0; i < 20; i++) { rwhite = 100 + 5 * i; gwhite = 200 - 5 * i; bwhite = 150; pixt0 = pixGlobalNormRGB(NULL, pixs, rwhite, gwhite, bwhite, 255); pixaAddPix(pixa, pixt0, L_INSERT); pixt1 = pixColorMagnitude(pixs, rwhite, gwhite, bwhite, L_MAX_DIFF_FROM_AVERAGE_2); for (j = 0; j < 6; j++) { pixt2 = pixThresholdToBinary(pixt1, 30 + 10 * j); pixInvert(pixt2, pixt2); pixCountPixels(pixt2, &count, NULL); na = numaaGetNuma(naa1, j, L_CLONE); numaAddNumber(na, (l_float32)count / (l_float32)(w * h)); numaDestroy(&na); pixDestroy(&pixt2); } pixDestroy(&pixt1); pixt1 = pixColorMagnitude(pixs, rwhite, gwhite, bwhite, L_MAX_MIN_DIFF_FROM_2); for (j = 0; j < 6; j++) { pixt2 = pixThresholdToBinary(pixt1, 30 + 10 * j); pixInvert(pixt2, pixt2); pixCountPixels(pixt2, &count, NULL); na = numaaGetNuma(naa2, j, L_CLONE); numaAddNumber(na, (l_float32)count / (l_float32)(w * h)); numaDestroy(&na); pixDestroy(&pixt2); } pixDestroy(&pixt1); } gplot1 = gplotCreate("/tmp/junkplot1", GPLOT_X11, "Fraction with given color (diff from average)", "white point space for red", "amount of color"); gplot2 = gplotCreate("/tmp/junkplot2", GPLOT_X11, "Fraction with given color (min diff)", "white point space for red", "amount of color"); for (j = 0; j < 6; j++) { na = numaaGetNuma(naa1, j, L_CLONE); sprintf(label, "thresh %d", 30 + 10 * j); gplotAddPlot(gplot1, naseq, na, GPLOT_LINES, label); numaDestroy(&na); na = numaaGetNuma(naa2, j, L_CLONE); gplotAddPlot(gplot2, naseq, na, GPLOT_LINES, label); numaDestroy(&na); } gplotMakeOutput(gplot1); gplotMakeOutput(gplot2); gplotDestroy(&gplot1); gplotDestroy(&gplot2); pixt1 = pixaDisplayTiledAndScaled(pixa, 32, 250, 4, 0, 10, 2); pixWrite("/tmp/junkcolormag", pixt1, IFF_PNG); pixDisplayWithTitle(pixt1, 0, 100, "Color magnitude", 1); pixDestroy(&pixt1); pixaDestroy(&pixa); numaDestroy(&naseq); numaaDestroy(&naa1); numaaDestroy(&naa2); pixDisplayMultiple("/tmp/display/file*"); pixDestroy(&pixs); return 0; }
int main(int argc, char **argv) { BOX *box; PIX *pix, *pixs, *pixd, *pixt; PIXA *pixa; SEL *sel, *sel1, *sel2, *sel3; SELA *sela4, *sela8, *sela48; static char mainName[] = "ccthin1_reg"; if (argc != 1) return ERROR_INT(" Syntax: ccthin1_reg", mainName, 1); /* Generate and display all of the 4-cc sels */ sela4 = selaCreate(9); sel = selCreateFromString(sel_4_1, 3, 3, "sel_4_1"); selaAddSel(sela4, sel, NULL, 0); sel = selCreateFromString(sel_4_2, 3, 3, "sel_4_2"); selaAddSel(sela4, sel, NULL, 0); sel = selCreateFromString(sel_4_3, 3, 3, "sel_4_3"); selaAddSel(sela4, sel, NULL, 0); sel = selCreateFromString(sel_4_4, 3, 3, "sel_4_4"); selaAddSel(sela4, sel, NULL, 0); sel = selCreateFromString(sel_4_5, 3, 3, "sel_4_5"); selaAddSel(sela4, sel, NULL, 0); sel = selCreateFromString(sel_4_6, 3, 3, "sel_4_6"); selaAddSel(sela4, sel, NULL, 0); sel = selCreateFromString(sel_4_7, 3, 3, "sel_4_7"); selaAddSel(sela4, sel, NULL, 0); sel = selCreateFromString(sel_4_8, 3, 3, "sel_4_8"); selaAddSel(sela4, sel, NULL, 0); sel = selCreateFromString(sel_4_9, 3, 3, "sel_4_9"); selaAddSel(sela4, sel, NULL, 0); pixt = selaDisplayInPix(sela4, 35, 3, 15, 3); pixWrite("/tmp/junkallsel4.png", pixt, IFF_PNG); pixDestroy(&pixt); selaDestroy(&sela4); /* Generate and display all of the 8-cc sels */ sela8 = selaCreate(9); sel = selCreateFromString(sel_8_1, 3, 3, "sel_8_1"); selaAddSel(sela8, sel, NULL, 0); sel = selCreateFromString(sel_8_2, 3, 3, "sel_8_2"); selaAddSel(sela8, sel, NULL, 0); sel = selCreateFromString(sel_8_3, 3, 3, "sel_8_3"); selaAddSel(sela8, sel, NULL, 0); sel = selCreateFromString(sel_8_4, 3, 3, "sel_8_4"); selaAddSel(sela8, sel, NULL, 0); sel = selCreateFromString(sel_8_5, 3, 3, "sel_8_5"); selaAddSel(sela8, sel, NULL, 0); sel = selCreateFromString(sel_8_6, 3, 3, "sel_8_6"); selaAddSel(sela8, sel, NULL, 0); sel = selCreateFromString(sel_8_7, 3, 3, "sel_8_7"); selaAddSel(sela8, sel, NULL, 0); sel = selCreateFromString(sel_8_8, 3, 3, "sel_8_8"); selaAddSel(sela8, sel, NULL, 0); sel = selCreateFromString(sel_8_9, 3, 3, "sel_8_9"); selaAddSel(sela8, sel, NULL, 0); pixt = selaDisplayInPix(sela8, 35, 3, 15, 3); pixWrite("/tmp/junkallsel8.png", pixt, IFF_PNG); pixDestroy(&pixt); selaDestroy(&sela8); /* Generate and display all of the 4 and 8-cc preserving sels */ sela48 = selaCreate(3); sel = selCreateFromString(sel_48_1, 3, 3, "sel_48_1"); selaAddSel(sela48, sel, NULL, 0); sel = selCreateFromString(sel_48_2, 3, 3, "sel_48_2"); selaAddSel(sela48, sel, NULL, 0); pixt = selaDisplayInPix(sela48, 35, 3, 15, 4); pixWrite("/tmp/junkallsel48.png", pixt, IFF_PNG); pixDestroy(&pixt); selaDestroy(&sela48); /* Generate and display three of the 4-cc sels and their rotations */ sela4 = selaCreate(3); sel = selCreateFromString(sel_4_1, 3, 3, "sel_4_1"); sel1 = selRotateOrth(sel, 1); sel2 = selRotateOrth(sel, 2); sel3 = selRotateOrth(sel, 3); selaAddSel(sela4, sel, NULL, 0); selaAddSel(sela4, sel1, "sel_4_1_90", 0); selaAddSel(sela4, sel2, "sel_4_1_180", 0); selaAddSel(sela4, sel3, "sel_4_1_270", 0); sel = selCreateFromString(sel_4_2, 3, 3, "sel_4_2"); sel1 = selRotateOrth(sel, 1); sel2 = selRotateOrth(sel, 2); sel3 = selRotateOrth(sel, 3); selaAddSel(sela4, sel, NULL, 0); selaAddSel(sela4, sel1, "sel_4_2_90", 0); selaAddSel(sela4, sel2, "sel_4_2_180", 0); selaAddSel(sela4, sel3, "sel_4_2_270", 0); sel = selCreateFromString(sel_4_3, 3, 3, "sel_4_3"); sel1 = selRotateOrth(sel, 1); sel2 = selRotateOrth(sel, 2); sel3 = selRotateOrth(sel, 3); selaAddSel(sela4, sel, NULL, 0); selaAddSel(sela4, sel1, "sel_4_3_90", 0); selaAddSel(sela4, sel2, "sel_4_3_180", 0); selaAddSel(sela4, sel3, "sel_4_3_270", 0); pixt = selaDisplayInPix(sela4, 35, 3, 15, 4); pixWrite("/tmp/junksel4.png", pixt, IFF_PNG); pixDestroy(&pixt); selaDestroy(&sela4); /* Generate and display four of the 8-cc sels and their rotations */ sela8 = selaCreate(4); sel = selCreateFromString(sel_8_2, 3, 3, "sel_8_2"); sel1 = selRotateOrth(sel, 1); sel2 = selRotateOrth(sel, 2); sel3 = selRotateOrth(sel, 3); selaAddSel(sela8, sel, NULL, 0); selaAddSel(sela8, sel1, "sel_8_2_90", 0); selaAddSel(sela8, sel2, "sel_8_2_180", 0); selaAddSel(sela8, sel3, "sel_8_2_270", 0); sel = selCreateFromString(sel_8_3, 3, 3, "sel_8_3"); sel1 = selRotateOrth(sel, 1); sel2 = selRotateOrth(sel, 2); sel3 = selRotateOrth(sel, 3); selaAddSel(sela8, sel, NULL, 0); selaAddSel(sela8, sel1, "sel_8_3_90", 0); selaAddSel(sela8, sel2, "sel_8_3_180", 0); selaAddSel(sela8, sel3, "sel_8_3_270", 0); sel = selCreateFromString(sel_8_5, 3, 3, "sel_8_5"); sel1 = selRotateOrth(sel, 1); sel2 = selRotateOrth(sel, 2); sel3 = selRotateOrth(sel, 3); selaAddSel(sela8, sel, NULL, 0); selaAddSel(sela8, sel1, "sel_8_5_90", 0); selaAddSel(sela8, sel2, "sel_8_5_180", 0); selaAddSel(sela8, sel3, "sel_8_5_270", 0); sel = selCreateFromString(sel_8_6, 3, 3, "sel_8_6"); sel1 = selRotateOrth(sel, 1); sel2 = selRotateOrth(sel, 2); sel3 = selRotateOrth(sel, 3); selaAddSel(sela8, sel, NULL, 0); selaAddSel(sela8, sel1, "sel_8_6_90", 0); selaAddSel(sela8, sel2, "sel_8_6_180", 0); selaAddSel(sela8, sel3, "sel_8_6_270", 0); pixt = selaDisplayInPix(sela8, 35, 3, 15, 4); pixWrite("/tmp/junksel8.png", pixt, IFF_PNG); pixDestroy(&pixt); selaDestroy(&sela8); /* Test the best 4 and 8 cc thinning */ pixDisplayWrite(NULL, 0); pix = pixRead("feyn.tif"); box = boxCreate(683, 799, 970, 479); pixs = pixClipRectangle(pix, box, NULL); pixDisplayWrite(pixs, 1); pixt = pixThin(pixs, L_THIN_FG, 4, 0); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThin(pixs, L_THIN_BG, 4, 0); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThin(pixs, L_THIN_FG, 8, 0); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThin(pixs, L_THIN_BG, 8, 0); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); /* Display tiled */ pixa = pixaReadFiles("/tmp/display", "file"); pixd = pixaDisplayTiledAndScaled(pixa, 8, 500, 1, 0, 25, 2); pixWrite("/tmp/junktiles.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pix); pixDestroy(&pixs); boxDestroy(&box); pixDisplayMultiple("/tmp/display/file*"); return 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; }
int main(int argc, char **argv) { l_int32 success; L_REGPARAMS *rp; #if !HAVE_LIBGIF && !HAVE_LIBUNGIF fprintf(stderr, "gifio is not enabled\n" "libgif or libungif are required for gifio_reg\n" "See environ.h: #define HAVE_LIBGIF or HAVE_LIBUNGIF 1\n" "See prog/Makefile: link in -lgif or -lungif\n\n"); return 0; #endif /* abort */ if (regTestSetup(argc, argv, &rp)) return 1; pixDisplayWrite(NULL, -1); lept_rmdir("lept/gif"); lept_mkdir("lept/gif"); /* ------------ Part 1: Test lossless r/w to file ------------*/ test_gif(FILE_1BPP, rp); test_gif(FILE_2BPP, rp); test_gif(FILE_4BPP, rp); test_gif(FILE_8BPP_1, rp); test_gif(FILE_8BPP_2, rp); test_gif(FILE_8BPP_3, rp); test_gif(FILE_16BPP, rp); test_gif(FILE_32BPP, rp); if (rp->success) { fprintf(stderr, "\n ****** Success on lossless r/w to file *****\n\n"); } else { fprintf(stderr, "\n ******* Failure on at least one r/w to file ******\n\n"); } if (rp->display) { fprintf(stderr, "Writing to: /tmp/lept/gif/giftest.pdf\n"); pixDisplayMultiple(150, 1.0, "/tmp/lept/gif/giftest.pdf"); } /* ------------ Part 2: Test lossless r/w to memory ------------ */ success = TRUE; #if HAVE_FMEMOPEN pixDisplayWrite(NULL, -1); if (test_mem_gif(FILE_1BPP, 0)) success = FALSE; if (test_mem_gif(FILE_2BPP, 1)) success = FALSE; if (test_mem_gif(FILE_4BPP, 2)) success = FALSE; if (test_mem_gif(FILE_8BPP_1, 3)) success = FALSE; if (test_mem_gif(FILE_8BPP_2, 4)) success = FALSE; if (test_mem_gif(FILE_8BPP_3, 5)) success = FALSE; if (test_mem_gif(FILE_16BPP, 6)) success = FALSE; if (test_mem_gif(FILE_32BPP, 7)) success = FALSE; if (success) { fprintf(stderr, "\n ****** Success on lossless r/w to memory *****\n\n"); } else { fprintf(stderr, "\n ******* Failure on at least one r/w to memory ******\n\n"); } #else fprintf(stderr, "\n ***** r/w to memory not enabled *****\n\n"); #endif /* HAVE_FMEMOPEN */ /* Success only if all tests are passed */ if (rp->success == TRUE) rp->success = success; return regTestCleanup(rp); }
int main(int argc, char **argv) { char dilateseq[BUF_SIZE], erodeseq[BUF_SIZE]; char openseq[BUF_SIZE], closeseq[BUF_SIZE]; char wtophatseq[BUF_SIZE], btophatseq[BUF_SIZE]; char *filein; l_int32 w, h, d; PIX *pixs, *pixt, *pixt2, *pixt3, *pixt3a, *pixt4; PIX *pixg, *pixd, *pixd1, *pixd2, *pixd3; PIXACC *pacc; PIXCMAP *cmap; static char mainName[] = "graymorph1_reg"; if (argc != 2) return ERROR_INT(" Syntax: graymorph1_reg filein", mainName, 1); filein = argv[1]; if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); pixGetDimensions(pixs, &w, &h, &d); if (d != 8) return ERROR_INT("pixs not 8 bpp", mainName, 1); /* -------- Test gray morph, including interpreter ------------ */ pixd = pixDilateGray(pixs, WSIZE, HSIZE); sprintf(dilateseq, "D%d.%d", WSIZE, HSIZE); pixg = pixGrayMorphSequence(pixs, dilateseq, HORIZ_SEP, 0); pixCompare(pixd, pixg, "results are the same", "results are different"); pixDestroy(&pixg); pixDestroy(&pixd); pixd = pixErodeGray(pixs, WSIZE, HSIZE); sprintf(erodeseq, "E%d.%d", WSIZE, HSIZE); pixg = pixGrayMorphSequence(pixs, erodeseq, HORIZ_SEP, 100); pixCompare(pixd, pixg, "results are the same", "results are different"); pixDestroy(&pixg); pixDestroy(&pixd); pixd = pixOpenGray(pixs, WSIZE, HSIZE); sprintf(openseq, "O%d.%d", WSIZE, HSIZE); pixg = pixGrayMorphSequence(pixs, openseq, HORIZ_SEP, 200); pixCompare(pixd, pixg, "results are the same", "results are different"); pixDestroy(&pixg); pixDestroy(&pixd); pixd = pixCloseGray(pixs, WSIZE, HSIZE); sprintf(closeseq, "C%d.%d", WSIZE, HSIZE); pixg = pixGrayMorphSequence(pixs, closeseq, HORIZ_SEP, 300); pixCompare(pixd, pixg, "results are the same", "results are different"); pixDestroy(&pixg); pixDestroy(&pixd); pixd = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_WHITE); sprintf(wtophatseq, "Tw%d.%d", WSIZE, HSIZE); pixg = pixGrayMorphSequence(pixs, wtophatseq, HORIZ_SEP, 400); pixCompare(pixd, pixg, "results are the same", "results are different"); pixDestroy(&pixg); pixDestroy(&pixd); pixd = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_BLACK); sprintf(btophatseq, "Tb%d.%d", WSIZE, HSIZE); pixg = pixGrayMorphSequence(pixs, btophatseq, HORIZ_SEP, 500); pixCompare(pixd, pixg, "results are the same", "results are different"); pixDestroy(&pixg); /* ------------- Test erode/dilate duality -------------- */ pixd = pixDilateGray(pixs, WSIZE, HSIZE); pixInvert(pixs, pixs); pixd2 = pixErodeGray(pixs, WSIZE, HSIZE); pixInvert(pixd2, pixd2); pixCompare(pixd, pixd2, "results are the same", "results are different"); pixDestroy(&pixd); pixDestroy(&pixd2); /* ------------- Test open/close duality -------------- */ pixd = pixOpenGray(pixs, WSIZE, HSIZE); pixInvert(pixs, pixs); pixd2 = pixCloseGray(pixs, WSIZE, HSIZE); pixInvert(pixd2, pixd2); pixCompare(pixd, pixd2, "results are the same", "results are different"); pixDestroy(&pixd); pixDestroy(&pixd2); /* ------------- Test tophat duality -------------- */ pixd = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_WHITE); pixInvert(pixs, pixs); pixd2 = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_BLACK); pixCompare(pixd, pixd2, "Correct: images are duals", "Error: images are not duals"); pixDestroy(&pixd); pixDestroy(&pixd2); pixInvert(pixs, pixs); pixd = pixGrayMorphSequence(pixs, "Tw9.5", HORIZ_SEP, 100); pixInvert(pixs, pixs); pixd2 = pixGrayMorphSequence(pixs, "Tb9.5", HORIZ_SEP, 300); pixCompare(pixd, pixd2, "Correct: images are duals", "Error: images are not duals"); pixDestroy(&pixd); pixDestroy(&pixd2); /* ------------- Test opening/closing for large sels -------------- */ pixd = pixGrayMorphSequence(pixs, "C9.9 + C19.19 + C29.29 + C39.39 + C49.49", HORIZ_SEP, 100); pixDestroy(&pixd); pixd = pixGrayMorphSequence(pixs, "O9.9 + O19.19 + O29.29 + O39.39 + O49.49", HORIZ_SEP, 400); pixDestroy(&pixd); /* ---------- Closing plus white tophat result ------------ * * Parameters: wsize, hsize = 9, 29 * * ---------------------------------------------------------*/ pixd = pixCloseGray(pixs, 9, 9); pixd1 = pixTophat(pixd, 9, 9, L_TOPHAT_WHITE); pixd2 = pixGrayMorphSequence(pixs, "C9.9 + TW9.9", HORIZ_SEP, 0); pixCompare(pixd1, pixd2, "correct: same", "wrong: different"); pixd3 = pixMaxDynamicRange(pixd1, L_LINEAR_SCALE); pixDisplayWrite(pixd3, 1); pixDestroy(&pixd); pixDestroy(&pixd1); pixDestroy(&pixd2); pixDestroy(&pixd3); pixd = pixCloseGray(pixs, 29, 29); pixd1 = pixTophat(pixd, 29, 29, L_TOPHAT_WHITE); pixd2 = pixGrayMorphSequence(pixs, "C29.29 + Tw29.29", HORIZ_SEP, 0); pixCompare(pixd1, pixd2, "correct: same", "wrong: different"); pixd3 = pixMaxDynamicRange(pixd1, L_LINEAR_SCALE); pixDisplayWrite(pixd3, 1); pixDestroy(&pixd); pixDestroy(&pixd1); pixDestroy(&pixd2); pixDestroy(&pixd3); /* --------- hdome with parameter height = 100 ------------*/ pixd = pixHDome(pixs, 100, 4); pixd2 = pixMaxDynamicRange(pixd, L_LINEAR_SCALE); pixDisplayWrite(pixd2, 1); pixDestroy(&pixd2); /* ----- Contrast enhancement with morph parameters 9, 9 -------*/ pixd1 = pixInitAccumulate(w, h, 0x8000); pixAccumulate(pixd1, pixs, L_ARITH_ADD); pixMultConstAccumulate(pixd1, 3., 0x8000); pixd2 = pixOpenGray(pixs, 9, 9); pixAccumulate(pixd1, pixd2, L_ARITH_SUBTRACT); pixDestroy(&pixd2); pixd2 = pixCloseGray(pixs, 9, 9); pixAccumulate(pixd1, pixd2, L_ARITH_SUBTRACT); pixDestroy(&pixd2); pixd = pixFinalAccumulate(pixd1, 0x8000, 8); pixDisplayWrite(pixd, 1); pixDestroy(&pixd1); /* Do the same thing with the Pixacc */ pacc = pixaccCreate(w, h, 1); pixaccAdd(pacc, pixs); pixaccMultConst(pacc, 3.); pixd1 = pixOpenGray(pixs, 9, 9); pixaccSubtract(pacc, pixd1); pixDestroy(&pixd1); pixd1 = pixCloseGray(pixs, 9, 9); pixaccSubtract(pacc, pixd1); pixDestroy(&pixd1); pixd2 = pixaccFinal(pacc, 8); pixaccDestroy(&pacc); pixDisplayWrite(pixd2, 1); pixCompare(pixd, pixd2, "Correct: same", "Wrong: different"); pixDestroy(&pixd); pixDestroy(&pixd2); /* ---- Tophat result on feynman stamp, to extract diagrams ----- */ pixDestroy(&pixs); pixs = pixRead("feynman-stamp.jpg"); /* Make output image to hold five intermediate images */ w = pixGetWidth(pixs); h = pixGetHeight(pixs); pixd = pixCreate(5 * w + 18, h + 6, 32); /* composite output image */ pixSetAllArbitrary(pixd, 0x0000ff00); /* set to blue */ /* Paste in the input image */ pixt = pixRemoveColormap(pixs, REMOVE_CMAP_TO_FULL_COLOR); pixRasterop(pixd, 3, 3, w, h, PIX_SRC, pixt, 0, 0); /* 1st one */ /* pixWrite("/tmp/junkgray.jpg", pixt, IFF_JFIF_JPEG); */ pixDestroy(&pixt); /* Paste in the grayscale version */ cmap = pixGetColormap(pixs); if (cmap) pixt = pixRemoveColormap(pixs, REMOVE_CMAP_TO_GRAYSCALE); else pixt = pixConvertRGBToGray(pixs, 0.33, 0.34, 0.33); pixt2 = pixConvertTo32(pixt); /* 8 --> 32 bpp */ pixRasterop(pixd, w + 6, 3, w, h, PIX_SRC, pixt2, 0, 0); /* 2nd one */ pixDestroy(&pixt2); /* Paste in a log dynamic range scaled version of the white tophat */ pixt2 = pixTophat(pixt, 3, 3, L_TOPHAT_WHITE); pixt3a = pixMaxDynamicRange(pixt2, L_LOG_SCALE); pixt3 = pixConvertTo32(pixt3a); pixRasterop(pixd, 2 * w + 9, 3, w, h, PIX_SRC, pixt3, 0, 0); /* 3rd */ /* pixWrite("/tmp/junktophat.jpg", pixt2, IFF_JFIF_JPEG); */ pixDestroy(&pixt3); pixDestroy(&pixt3a); pixDestroy(&pixt); /* Stretch the range and threshold to binary; paste it in */ pixt3a = pixGammaTRC(NULL, pixt2, 1.0, 0, 80); pixt3 = pixThresholdToBinary(pixt3a, 70); pixt4 = pixConvertTo32(pixt3); pixRasterop(pixd, 3 * w + 12, 3, w, h, PIX_SRC, pixt4, 0, 0); /* 4th */ /* pixWrite("/tmp/junkbin.png", pixt3, IFF_PNG); */ pixDestroy(&pixt2); pixDestroy(&pixt3a); pixDestroy(&pixt4); /* Invert; this is the final result */ pixInvert(pixt3, pixt3); pixt4 = pixConvertTo32(pixt3); pixRasterop(pixd, 4 * w + 15, 3, w, h, PIX_SRC, pixt4, 0, 0); /* 5th */ pixWrite("/tmp/junkbininvert.png", pixt3, IFF_PNG); pixDisplayWrite(pixd, 1); /* pixWrite("/tmp/junkall.jpg", pixd, IFF_JFIF_JPEG); */ pixDestroy(&pixt3); pixDestroy(&pixt4); pixDestroy(&pixd); pixDisplayMultiple("/tmp/display/file*"); pixDestroy(&pixs); return 0; }
main(int argc, char **argv) { char *filein, *fileout; l_int32 w, h, d, w2, h2, i, ncols; l_float32 angle, conf; BOX *box; BOXA *boxa, *boxas, *boxad, *boxa2; NUMA *numa; PIX *pixs, *pixt, *pixb, *pixb2, *pixd; PIX *pixtlm, *pixvws; PIX *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6; PIXA *pixam, *pixac, *pixad, *pixat; PIXAA *pixaa, *pixaa2; PTA *pta; SEL *selsplit; static char mainName[] = "textlinemask"; if (argc != 3) exit(ERROR_INT(" Syntax: textlinemask filein fileout", mainName, 1)); filein = argv[1]; fileout = argv[2]; pixDisplayWrite(NULL, -1); /* init debug output */ if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); pixGetDimensions(pixs, &w, &h, &d); /* Binarize input */ if (d == 8) pixt = pixThresholdToBinary(pixs, 128); else if (d == 1) pixt = pixClone(pixs); else { fprintf(stderr, "depth is %d\n", d); exit(1); } /* Deskew */ pixb = pixFindSkewAndDeskew(pixt, 1, &angle, &conf); pixDestroy(&pixt); fprintf(stderr, "Skew angle: %7.2f degrees; %6.2f conf\n", angle, conf); pixDisplayWrite(pixb, DEBUG_OUTPUT); #if 1 /* Use full image morphology to find columns, at 2x reduction. * This only works for very simple layouts where each column * of text extends the full height of the input image. * pixam has a pix component over each column. */ pixb2 = pixReduceRankBinary2(pixb, 2, NULL); pixt1 = pixMorphCompSequence(pixb2, "c5.500", 0); boxa = pixConnComp(pixt1, &pixam, 8); ncols = boxaGetCount(boxa); fprintf(stderr, "Num columns: %d\n", ncols); pixDisplayWrite(pixt1, DEBUG_OUTPUT); /* Use selective region-based morphology to get the textline mask. */ pixad = pixaMorphSequenceByRegion(pixb2, pixam, "c100.3", 0, 0); pixGetDimensions(pixb2, &w2, &h2, NULL); if (DEBUG_OUTPUT) { pixt2 = pixaDisplay(pixad, w2, h2); pixDisplayWrite(pixt2, DEBUG_OUTPUT); pixDestroy(&pixt2); } /* Some of the lines may be touching, so use a HMT to split the * lines in each column, and use a pixaa to save the results. */ selsplit = selCreateFromString(seltext, 17, 7, "selsplit"); pixaa = pixaaCreate(ncols); for (i = 0; i < ncols; i++) { pixt3 = pixaGetPix(pixad, i, L_CLONE); box = pixaGetBox(pixad, i, L_COPY); pixt4 = pixHMT(NULL, pixt3, selsplit); pixXor(pixt4, pixt4, pixt3); boxa2 = pixConnComp(pixt4, &pixac, 8); pixaaAddPixa(pixaa, pixac, L_INSERT); pixaaAddBox(pixaa, box, L_INSERT); if (DEBUG_OUTPUT) { pixt5 = pixaDisplayRandomCmap(pixac, 0, 0); pixDisplayWrite(pixt5, DEBUG_OUTPUT); fprintf(stderr, "Num textlines in col %d: %d\n", i, boxaGetCount(boxa2)); pixDestroy(&pixt5); } pixDestroy(&pixt3); pixDestroy(&pixt4); boxaDestroy(&boxa2); } /* Visual output */ if (DEBUG_OUTPUT) { pixDisplayMultiple("/tmp/junk_write_display*"); pixat = pixaReadFiles("/tmp", "junk_write_display"); pixt5 = selDisplayInPix(selsplit, 31, 2); pixaAddPix(pixat, pixt5, L_INSERT); pixt6 = pixaDisplayTiledAndScaled(pixat, 32, 400, 3, 0, 35, 3); pixWrite(fileout, pixt6, IFF_PNG); pixaDestroy(&pixat); pixDestroy(&pixt6); } /* Test pixaa I/O */ pixaaWrite("/tmp/junkpixaa", pixaa); pixaa2 = pixaaRead("/tmp/junkpixaa"); pixaaWrite("/tmp/junkpixaa2", pixaa2); /* Test pixaa display */ pixd = pixaaDisplay(pixaa, w2, h2); pixWrite("/tmp/junkdisplay", pixd, IFF_PNG); pixDestroy(&pixd); /* Cleanup */ pixDestroy(&pixb2); pixDestroy(&pixt1); pixaDestroy(&pixam); pixaDestroy(&pixad); pixaaDestroy(&pixaa); pixaaDestroy(&pixaa2); boxaDestroy(&boxa); selDestroy(&selsplit); #endif #if 0 /* Use the baseline finder; not really what is needed */ numa = pixFindBaselines(pixb, &pta, 1); #endif #if 0 /* Use the textline mask function; parameters are not quite right */ pixb2 = pixReduceRankBinary2(pixb, 2, NULL); pixtlm = pixGenTextlineMask(pixb2, &pixvws, NULL, 1); pixDisplay(pixtlm, 0, 100); pixDisplay(pixvws, 500, 100); pixDestroy(&pixb2); pixDestroy(&pixtlm); pixDestroy(&pixvws); #endif #if 0 /* Use the Breuel whitespace partition method; slow and we would * still need to work to extract the fg regions. */ pixb2 = pixReduceRankBinary2(pixb, 2, NULL); boxas = pixConnComp(pixb2, NULL, 8); boxad = boxaGetWhiteblocks(boxas, NULL, L_SORT_BY_HEIGHT, 3, 0.1, 200, 0.2, 0); pixd = pixDrawBoxa(pixb2, boxad, 7, 0xe0708000); pixDisplay(pixd, 100, 500); pixDestroy(&pixb2); pixDestroy(&pixd); boxaDestroy(&boxas); boxaDestroy(&boxad); #endif #if 0 /* Use morphology to find columns and then selective * region-based morphology to get the textline mask. * This is for display; we really want to get a pixa of the * specific textline masks. */ startTimer(); pixb2 = pixReduceRankBinary2(pixb, 2, NULL); pixt1 = pixMorphCompSequence(pixb2, "c5.500", 0); /* column mask */ pixt2 = pixMorphSequenceByRegion(pixb2, pixt1, "c100.3", 8, 0, 0, &boxa); fprintf(stderr, "time = %7.3f sec\n", stopTimer()); pixDisplay(pixt1, 100, 500); pixDisplay(pixt2, 800, 500); pixDestroy(&pixb2); pixDestroy(&pixt1); pixDestroy(&pixt2); boxaDestroy(&boxa); #endif pixDestroy(&pixs); pixDestroy(&pixb); exit(0); }
main(int argc, char **argv) { l_int32 d; PIX *pixs, *pixc, *pixr, *pixg, *pixb, *pixsg, *pixsm, *pixd; PIXA *pixa; static char mainName[] = "livre_adapt"; if (argc != 1) exit(ERROR_INT(" Syntax: livre_adapt", mainName, 1)); /* Read the image in at 150 ppi. */ pixDisplayWrite(NULL, -1); if ((pixs = pixRead("brothers.150.jpg")) == NULL) exit(ERROR_INT("pix not made", mainName, 1)); pixDisplayWriteFormat(pixs, 2, IFF_JFIF_JPEG); /* Normalize for uneven illumination on RGB image */ pixBackgroundNormRGBArraysMorph(pixs, NULL, 4, 5, 200, &pixr, &pixg, &pixb); pixd = pixApplyInvBackgroundRGBMap(pixs, pixr, pixg, pixb, 4, 4); pixDisplayWriteFormat(pixd, 2, IFF_JFIF_JPEG); pixDestroy(&pixr); pixDestroy(&pixg); pixDestroy(&pixb); pixDestroy(&pixd); /* Convert the RGB image to grayscale. */ pixsg = pixConvertRGBToLuminance(pixs); pixDisplayWriteFormat(pixsg, 2, IFF_JFIF_JPEG); /* Remove the text in the fg. */ pixc = pixCloseGray(pixsg, 25, 25); pixDisplayWriteFormat(pixc, 2, IFF_JFIF_JPEG); /* Smooth the bg with a convolution. */ pixsm = pixBlockconv(pixc, 15, 15); pixDisplayWriteFormat(pixsm, 2, IFF_JFIF_JPEG); pixDestroy(&pixc); /* Normalize for uneven illumination on gray image. */ pixBackgroundNormGrayArrayMorph(pixsg, NULL, 4, 5, 200, &pixg); pixc = pixApplyInvBackgroundGrayMap(pixsg, pixg, 4, 4); pixDisplayWriteFormat(pixc, 2, IFF_JFIF_JPEG); pixDestroy(&pixg); /* Increase the dynamic range. */ pixd = pixGammaTRC(NULL, pixc, 1.0, 30, 180); pixDisplayWriteFormat(pixd, 2, IFF_JFIF_JPEG); pixDestroy(&pixc); /* Threshold to 1 bpp. */ pixb = pixThresholdToBinary(pixd, 120); pixDisplayWriteFormat(pixb, 2, IFF_PNG); pixDestroy(&pixd); pixDestroy(&pixb); /* Generate the output image */ pixa = pixaReadFiles("/tmp", "junk_write_display"); pixd = pixaDisplayTiledAndScaled(pixa, 8, 350, 4, 0, 25, 2); pixWrite("/tmp/adapt.jpg", pixd, IFF_JFIF_JPEG); pixDisplayWithTitle(pixd, 100, 100, NULL, 1); pixDestroy(&pixd); pixDestroy(&pixs); pixDestroy(&pixsg); return 0; }
l_int32 DoPageSegmentation(PIX *pixs, /* should be at least 300 ppi */ l_int32 which) /* 1, 2, 3, 4 */ { char buf[256]; l_int32 zero; BOXA *boxatm, *boxahm; PIX *pixr; /* image reduced to 150 ppi */ PIX *pixhs; /* image of halftone seed, 150 ppi */ PIX *pixm; /* image of mask of components, 150 ppi */ PIX *pixhm1; /* image of halftone mask, 150 ppi */ PIX *pixhm2; /* image of halftone mask, 300 ppi */ PIX *pixht; /* image of halftone components, 150 ppi */ PIX *pixnht; /* image without halftone components, 150 ppi */ PIX *pixi; /* inverted image, 150 ppi */ PIX *pixvws; /* image of vertical whitespace, 150 ppi */ PIX *pixtm1; /* image of closed textlines, 150 ppi */ PIX *pixtm2; /* image of refined text line mask, 150 ppi */ PIX *pixtm3; /* image of refined text line mask, 300 ppi */ PIX *pixtb1; /* image of text block mask, 150 ppi */ PIX *pixtb2; /* image of text block mask, 300 ppi */ PIX *pixnon; /* image of non-text or halftone, 150 ppi */ PIX *pixt1, *pixt2, *pixt3; PIXA *pixa; PIXCMAP *cmap; PTAA *ptaa; l_int32 ht_flag = 0; l_int32 ws_flag = 0; l_int32 text_flag = 0; l_int32 block_flag = 0; PROCNAME("DoPageSegmentation"); if (which == 1) ht_flag = 1; else if (which == 2) ws_flag = 1; else if (which == 3) text_flag = 1; else if (which == 4) block_flag = 1; else return ERROR_INT("invalid parameter: not in [1...4]", procName, 1); pixDisplayWrite(NULL, -1); /* Reduce to 150 ppi */ pixt1 = pixScaleToGray2(pixs); pixDisplayWriteFormat(pixt1, L_MAX(ws_flag, L_MAX(ht_flag, block_flag)), IFF_PNG); if (which == 1) pixWrite("/tmp/orig.gray.150.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixr = pixReduceRankBinaryCascade(pixs, 1, 0, 0, 0); /* Get seed for halftone parts */ pixt1 = pixReduceRankBinaryCascade(pixr, 4, 4, 3, 0); pixt2 = pixOpenBrick(NULL, pixt1, 5, 5); pixhs = pixExpandBinaryPower2(pixt2, 8); pixDisplayWriteFormat(pixhs, ht_flag, IFF_PNG); if (which == 1) pixWrite("/tmp/htseed.150.png", pixhs, IFF_PNG); pixDestroy(&pixt1); pixDestroy(&pixt2); /* Get mask for connected regions */ pixm = pixCloseSafeBrick(NULL, pixr, 4, 4); pixDisplayWriteFormat(pixm, ht_flag, IFF_PNG); if (which == 1) pixWrite("/tmp/ccmask.150.png", pixm, IFF_PNG); /* Fill seed into mask to get halftone mask */ pixhm1 = pixSeedfillBinary(NULL, pixhs, pixm, 4); pixDisplayWriteFormat(pixhm1, ht_flag, IFF_PNG); if (which == 1) pixWrite("/tmp/htmask.150.png", pixhm1, IFF_PNG); pixhm2 = pixExpandBinaryPower2(pixhm1, 2); /* Extract halftone stuff */ pixht = pixAnd(NULL, pixhm1, pixr); if (which == 1) pixWrite("/tmp/ht.150.png", pixht, IFF_PNG); /* Extract non-halftone stuff */ pixnht = pixXor(NULL, pixht, pixr); pixDisplayWriteFormat(pixnht, text_flag, IFF_PNG); if (which == 1) pixWrite("/tmp/text.150.png", pixnht, IFF_PNG); pixZero(pixht, &zero); if (zero) fprintf(stderr, "No halftone parts found\n"); else fprintf(stderr, "Halftone parts found\n"); /* Get bit-inverted image */ pixi = pixInvert(NULL, pixnht); if (which == 1) pixWrite("/tmp/invert.150.png", pixi, IFF_PNG); pixDisplayWriteFormat(pixi, ws_flag, IFF_PNG); /* The whitespace mask will break textlines where there * is a large amount of white space below or above. * We can prevent this by identifying regions of the * inverted image that have large horizontal (bigger than * the separation between columns) and significant * vertical extent (bigger than the separation between * textlines), and subtracting this from the whitespace mask. */ pixt1 = pixMorphCompSequence(pixi, "o80.60", 0); pixt2 = pixSubtract(NULL, pixi, pixt1); pixDisplayWriteFormat(pixt2, ws_flag, IFF_PNG); pixDestroy(&pixt1); /* Identify vertical whitespace by opening inverted image */ pixt3 = pixOpenBrick(NULL, pixt2, 5, 1); /* removes thin vertical lines */ pixvws = pixOpenBrick(NULL, pixt3, 1, 200); /* gets long vertical lines */ pixDisplayWriteFormat(pixvws, L_MAX(text_flag, ws_flag), IFF_PNG); if (which == 1) pixWrite("/tmp/vertws.150.png", pixvws, IFF_PNG); pixDestroy(&pixt2); pixDestroy(&pixt3); /* Get proto (early processed) text line mask. */ /* First close the characters and words in the textlines */ pixtm1 = pixCloseSafeBrick(NULL, pixnht, 30, 1); pixDisplayWriteFormat(pixtm1, text_flag, IFF_PNG); if (which == 1) pixWrite("/tmp/textmask1.150.png", pixtm1, IFF_PNG); /* Next open back up the vertical whitespace corridors */ pixtm2 = pixSubtract(NULL, pixtm1, pixvws); if (which == 1) pixWrite("/tmp/textmask2.150.png", pixtm2, IFF_PNG); /* Do a small opening to remove noise */ pixOpenBrick(pixtm2, pixtm2, 3, 3); pixDisplayWriteFormat(pixtm2, text_flag, IFF_PNG); if (which == 1) pixWrite("/tmp/textmask3.150.png", pixtm2, IFF_PNG); pixtm3 = pixExpandBinaryPower2(pixtm2, 2); /* Join pixels vertically to make text block mask */ pixtb1 = pixMorphSequence(pixtm2, "c1.10 + o4.1", 0); pixDisplayWriteFormat(pixtb1, block_flag, IFF_PNG); if (which == 1) pixWrite("/tmp/textblock1.150.png", pixtb1, IFF_PNG); /* Solidify the textblock mask and remove noise: * (1) For each c.c., close the blocks and dilate slightly * to form a solid mask. * (2) Small horizontal closing between components * (3) Open the white space between columns, again * (4) Remove small components */ pixt1 = pixMorphSequenceByComponent(pixtb1, "c30.30 + d3.3", 8, 0, 0, NULL); pixCloseSafeBrick(pixt1, pixt1, 10, 1); pixDisplayWriteFormat(pixt1, block_flag, IFF_PNG); pixt2 = pixSubtract(NULL, pixt1, pixvws); pixt3 = pixSelectBySize(pixt2, 25, 5, 8, L_SELECT_IF_BOTH, L_SELECT_IF_GTE, NULL); pixDisplayWriteFormat(pixt3, block_flag, IFF_PNG); if (which == 1) pixWrite("/tmp/textblock2.150.png", pixt3, IFF_PNG); pixtb2 = pixExpandBinaryPower2(pixt3, 2); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); /* Identify the outlines of each textblock */ ptaa = pixGetOuterBordersPtaa(pixtb2); pixt1 = pixRenderRandomCmapPtaa(pixtb2, ptaa, 1, 8, 1); cmap = pixGetColormap(pixt1); pixcmapResetColor(cmap, 0, 130, 130, 130); /* set interior to gray */ if (which == 1) pixWrite("/tmp/textblock3.300.png", pixt1, IFF_PNG); pixDisplayWithTitle(pixt1, 480, 360, "textblock mask with outlines", DFLAG); ptaaDestroy(&ptaa); pixDestroy(&pixt1); /* Fill line mask (as seed) into the original */ pixt1 = pixSeedfillBinary(NULL, pixtm3, pixs, 8); pixOr(pixtm3, pixtm3, pixt1); pixDestroy(&pixt1); if (which == 1) pixWrite("/tmp/textmask.300.png", pixtm3, IFF_PNG); pixDisplayWithTitle(pixtm3, 480, 360, "textline mask 4", DFLAG); /* Fill halftone mask (as seed) into the original */ pixt1 = pixSeedfillBinary(NULL, pixhm2, pixs, 8); pixOr(pixhm2, pixhm2, pixt1); pixDestroy(&pixt1); if (which == 1) pixWrite("/tmp/htmask.300.png", pixhm2, IFF_PNG); pixDisplayWithTitle(pixhm2, 520, 390, "halftonemask 2", DFLAG); /* Find objects that are neither text nor halftones */ pixt1 = pixSubtract(NULL, pixs, pixtm3); /* remove text pixels */ pixnon = pixSubtract(NULL, pixt1, pixhm2); /* remove halftone pixels */ if (which == 1) pixWrite("/tmp/other.300.png", pixnon, IFF_PNG); pixDisplayWithTitle(pixnon, 540, 420, "other stuff", DFLAG); pixDestroy(&pixt1); /* Write out b.b. for text line mask and halftone mask components */ boxatm = pixConnComp(pixtm3, NULL, 4); boxahm = pixConnComp(pixhm2, NULL, 8); if (which == 1) boxaWrite("/tmp/textmask.boxa", boxatm); if (which == 1) boxaWrite("/tmp/htmask.boxa", boxahm); pixa = pixaReadFiles("/tmp/display", "file"); pixt1 = pixaDisplayTiledAndScaled(pixa, 8, 250, 4, 0, 25, 2); snprintf(buf, sizeof(buf), "/tmp/segout.%d.png", which); pixWrite(buf, pixt1, IFF_PNG); pixDestroy(&pixt1); pixaDestroy(&pixa); /* clean up to test with valgrind */ pixDestroy(&pixr); pixDestroy(&pixhs); pixDestroy(&pixm); pixDestroy(&pixhm1); pixDestroy(&pixhm2); pixDestroy(&pixht); pixDestroy(&pixnht); pixDestroy(&pixi); pixDestroy(&pixvws); pixDestroy(&pixtm1); pixDestroy(&pixtm2); pixDestroy(&pixtm3); pixDestroy(&pixtb1); pixDestroy(&pixtb2); pixDestroy(&pixnon); boxaDestroy(&boxatm); boxaDestroy(&boxahm); return 0; }
/*! * pixGetRegionsBinary() * * Input: pixs (1 bpp, assumed to be 300 to 400 ppi) * &pixhm (<optional return> halftone mask) * &pixtm (<optional return> textline mask) * &pixtb (<optional return> textblock mask) * debug (flag: set to 1 for debug output) * Return: 0 if OK, 1 on error * * Notes: * (1) It is best to deskew the image before segmenting. * (2) The debug flag enables a number of outputs. These * are included to show how to generate and save/display * these results. */ l_int32 pixGetRegionsBinary(PIX *pixs, PIX **ppixhm, PIX **ppixtm, PIX **ppixtb, l_int32 debug) { char *tempname; l_int32 htfound, tlfound; PIX *pixr, *pixt1, *pixt2; PIX *pixtext; /* text pixels only */ PIX *pixhm2; /* halftone mask; 2x reduction */ PIX *pixhm; /* halftone mask; */ PIX *pixtm2; /* textline mask; 2x reduction */ PIX *pixtm; /* textline mask */ PIX *pixvws; /* vertical white space mask */ PIX *pixtb2; /* textblock mask; 2x reduction */ PIX *pixtbf2; /* textblock mask; 2x reduction; small comps filtered */ PIX *pixtb; /* textblock mask */ PROCNAME("pixGetRegionsBinary"); if (ppixhm) *ppixhm = NULL; if (ppixtm) *ppixtm = NULL; if (ppixtb) *ppixtb = NULL; if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (pixGetDepth(pixs) != 1) return ERROR_INT("pixs not 1 bpp", procName, 1); /* 2x reduce, to 150 -200 ppi */ pixr = pixReduceRankBinaryCascade(pixs, 1, 0, 0, 0); pixDisplayWrite(pixr, debug); /* Get the halftone mask */ pixhm2 = pixGenHalftoneMask(pixr, &pixtext, &htfound, debug); /* Get the textline mask from the text pixels */ pixtm2 = pixGenTextlineMask(pixtext, &pixvws, &tlfound, debug); /* Get the textblock mask from the textline mask */ pixtb2 = pixGenTextblockMask(pixtm2, pixvws, debug); pixDestroy(&pixr); pixDestroy(&pixtext); pixDestroy(&pixvws); /* Remove small components from the mask, where a small * component is defined as one with both width and height < 60 */ pixtbf2 = pixSelectBySize(pixtb2, 60, 60, 4, L_SELECT_IF_EITHER, L_SELECT_IF_GTE, NULL); pixDestroy(&pixtb2); pixDisplayWriteFormat(pixtbf2, debug, IFF_PNG); /* Expand all masks to full resolution, and do filling or * small dilations for better coverage. */ pixhm = pixExpandReplicate(pixhm2, 2); pixt1 = pixSeedfillBinary(NULL, pixhm, pixs, 8); pixOr(pixhm, pixhm, pixt1); pixDestroy(&pixt1); pixDisplayWriteFormat(pixhm, debug, IFF_PNG); pixt1 = pixExpandReplicate(pixtm2, 2); pixtm = pixDilateBrick(NULL, pixt1, 3, 3); pixDestroy(&pixt1); pixDisplayWriteFormat(pixtm, debug, IFF_PNG); pixt1 = pixExpandReplicate(pixtbf2, 2); pixtb = pixDilateBrick(NULL, pixt1, 3, 3); pixDestroy(&pixt1); pixDisplayWriteFormat(pixtb, debug, IFF_PNG); pixDestroy(&pixhm2); pixDestroy(&pixtm2); pixDestroy(&pixtbf2); /* Debug: identify objects that are neither text nor halftone image */ if (debug) { pixt1 = pixSubtract(NULL, pixs, pixtm); /* remove text pixels */ pixt2 = pixSubtract(NULL, pixt1, pixhm); /* remove halftone pixels */ pixDisplayWriteFormat(pixt2, 1, IFF_PNG); pixDestroy(&pixt1); pixDestroy(&pixt2); } /* Debug: display textline components with random colors */ if (debug) { l_int32 w, h; BOXA *boxa; PIXA *pixa; boxa = pixConnComp(pixtm, &pixa, 8); pixGetDimensions(pixtm, &w, &h, NULL); pixt1 = pixaDisplayRandomCmap(pixa, w, h); pixcmapResetColor(pixGetColormap(pixt1), 0, 255, 255, 255); pixDisplay(pixt1, 100, 100); pixDisplayWriteFormat(pixt1, 1, IFF_PNG); pixaDestroy(&pixa); boxaDestroy(&boxa); pixDestroy(&pixt1); } /* Debug: identify the outlines of each textblock */ if (debug) { PIXCMAP *cmap; PTAA *ptaa; ptaa = pixGetOuterBordersPtaa(pixtb); tempname = genTempFilename("/tmp", "tb_outlines.ptaa", 0, 0); ptaaWrite(tempname, ptaa, 1); FREE(tempname); pixt1 = pixRenderRandomCmapPtaa(pixtb, ptaa, 1, 16, 1); cmap = pixGetColormap(pixt1); pixcmapResetColor(cmap, 0, 130, 130, 130); pixDisplay(pixt1, 500, 100); pixDisplayWriteFormat(pixt1, 1, IFF_PNG); pixDestroy(&pixt1); ptaaDestroy(&ptaa); } /* Debug: get b.b. for all mask components */ if (debug) { BOXA *bahm, *batm, *batb; bahm = pixConnComp(pixhm, NULL, 4); batm = pixConnComp(pixtm, NULL, 4); batb = pixConnComp(pixtb, NULL, 4); tempname = genTempFilename("/tmp", "htmask.boxa", 0, 0); boxaWrite(tempname, bahm); FREE(tempname); tempname = genTempFilename("/tmp", "textmask.boxa", 0, 0); boxaWrite(tempname, batm); FREE(tempname); tempname = genTempFilename("/tmp", "textblock.boxa", 0, 0); boxaWrite(tempname, batb); FREE(tempname); boxaDestroy(&bahm); boxaDestroy(&batm); boxaDestroy(&batb); } if (ppixhm) *ppixhm = pixhm; else pixDestroy(&pixhm); if (ppixtm) *ppixtm = pixtm; else pixDestroy(&pixtm); if (ppixtb) *ppixtb = pixtb; else pixDestroy(&pixtb); return 0; }
/*! * pixGenTextlineMask() * * Input: pixs (1 bpp, assumed to be 150 to 200 ppi) * &pixvws (<return> vertical whitespace mask) * &tlfound (<optional return> 1 if the mask is not empty) * debug (flag: 1 for debug output) * Return: pixd (textline mask), or null on error * * Notes: * (1) The input pixs should be deskewed. * (2) pixs should have no halftone pixels. * (3) Both the input image and the returned textline mask * are at the same resolution. */ PIX * pixGenTextlineMask(PIX *pixs, PIX **ppixvws, l_int32 *ptlfound, l_int32 debug) { l_int32 empty; PIX *pixt1, *pixt2, *pixvws, *pixd; PROCNAME("pixGenTextlineMask"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!ppixvws) return (PIX *)ERROR_PTR("&pixvws not defined", procName, NULL); if (pixGetDepth(pixs) != 1) return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL); /* First we need a vertical whitespace mask. Invert the image. */ pixt1 = pixInvert(NULL, pixs); /* The whitespace mask will break textlines where there * is a large amount of white space below or above. * This can be prevented by identifying regions of the * inverted image that have large horizontal extent (bigger than * the separation between columns) and significant * vertical extent (bigger than the separation between * textlines), and subtracting this from the bg. */ pixt2 = pixMorphCompSequence(pixt1, "o80.60", 0); pixSubtract(pixt1, pixt1, pixt2); pixDisplayWriteFormat(pixt1, debug, IFF_PNG); pixDestroy(&pixt2); /* Identify vertical whitespace by opening the remaining bg. * o5.1 removes thin vertical bg lines and o1.200 extracts * long vertical bg lines. */ pixvws = pixMorphCompSequence(pixt1, "o5.1 + o1.200", 0); *ppixvws = pixvws; pixDisplayWriteFormat(pixvws, debug, IFF_PNG); pixDestroy(&pixt1); /* Three steps to getting text line mask: * (1) close the characters and words in the textlines * (2) open the vertical whitespace corridors back up * (3) small opening to remove noise */ pixt1 = pixCloseSafeBrick(NULL, pixs, 30, 1); pixDisplayWrite(pixt1, debug); pixd = pixSubtract(NULL, pixt1, pixvws); pixOpenBrick(pixd, pixd, 3, 3); pixDisplayWriteFormat(pixd, debug, IFF_PNG); pixDestroy(&pixt1); /* Check if text line mask is empty */ if (ptlfound) { *ptlfound = 0; pixZero(pixd, &empty); if (!empty) *ptlfound = 1; } return pixd; }
int main(int argc, char **argv) { l_int32 i, j, w, h, same; l_float32 t, t1, t2; GPLOT *gplot; NUMA *nax, *nay1, *nay2; PIX *pixs, *pixd, *pixt1, *pixt2, *pixt3, *pixt4; PIXA *pixa; static char mainName[] = "rank_reg"; if (argc != 1) return ERROR_INT(" Syntax: rank_reg", mainName, 1); if ((pixs = pixRead("lucasta.150.jpg")) == NULL) return ERROR_INT("pixs not made", mainName, 1); pixGetDimensions(pixs, &w, &h, NULL); startTimer(); pixd = pixRankFilterGray(pixs, 15, 15, 0.4); t = stopTimer(); fprintf(stderr, "Time = %7.3f sec\n", t); fprintf(stderr, "MPix/sec: %7.3f\n", 0.000001 * w * h / t); pixDisplay(pixs, 0, 200); pixDisplay(pixd, 600, 200); pixWrite("/tmp/filter.png", pixd, IFF_PNG); pixDestroy(&pixd); /* Get results for dilation */ startTimer(); pixt1 = pixDilateGray(pixs, 15, 15); t = stopTimer(); fprintf(stderr, "Dilation time = %7.3f sec\n", t); /* Get results for erosion */ pixt2 = pixErodeGray(pixs, 15, 15); /* Get results using the rank filter for rank = 0.0 and 1.0. * Don't use 0.0 or 1.0, because those are dispatched * automatically to erosion and dilation! */ pixt3 = pixRankFilterGray(pixs, 15, 15, 0.0001); pixt4 = pixRankFilterGray(pixs, 15, 15, 0.9999); /* Compare */ pixEqual(pixt1, pixt4, &same); if (same) fprintf(stderr, "Correct: dilation results same as rank 1.0\n"); else fprintf(stderr, "Error: dilation results differ from rank 1.0\n"); pixEqual(pixt2, pixt3, &same); if (same) fprintf(stderr, "Correct: erosion results same as rank 0.0\n"); else fprintf(stderr, "Error: erosion results differ from rank 0.0\n"); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); fprintf(stderr, "\n----------------------------------------\n"); fprintf(stderr, "The next part takes about 30 seconds\n"); fprintf(stderr, "----------------------------------------\n\n"); nax = numaMakeSequence(1, 1, SIZE); nay1 = numaCreate(SIZE); nay2 = numaCreate(SIZE); gplot = gplotCreate("/tmp/rankroot", GPLOT_X11, "sec/MPix vs filter size", "size", "time"); for (i = 1; i <= SIZE; i++) { t1 = t2 = 0.0; for (j = 0; j < 5; j++) { startTimer(); pixt1 = pixRankFilterGray(pixs, i, SIZE + 1, 0.5); t1 += stopTimer(); pixDestroy(&pixt1); startTimer(); pixt1 = pixRankFilterGray(pixs, SIZE + 1, i, 0.5); t2 += stopTimer(); if (j == 0) pixDisplayWrite(pixt1, 1); pixDestroy(&pixt1); } numaAddNumber(nay1, 1000000. * t1 / (5. * w * h)); numaAddNumber(nay2, 1000000. * t2 / (5. * w * h)); } gplotAddPlot(gplot, nax, nay1, GPLOT_LINES, "vertical"); gplotAddPlot(gplot, nax, nay2, GPLOT_LINES, "horizontal"); gplotMakeOutput(gplot); gplotDestroy(&gplot); /* Display tiled */ pixa = pixaReadFiles("/tmp/display", "file"); pixd = pixaDisplayTiledAndScaled(pixa, 8, 250, 5, 0, 25, 2); pixWrite("/tmp/tiles.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixs); pixDisplayWrite(NULL, -1); /* clear out */ pixs = pixRead("test8.jpg"); for (i = 1; i <= 4; i++) { pixt1 = pixScaleGrayRank2(pixs, i); pixDisplay(pixt1, 300 * (i - 1), 100); pixDestroy(&pixt1); } pixDestroy(&pixs); pixs = pixRead("test24.jpg"); pixt1 = pixConvertRGBToLuminance(pixs); pixt2 = pixScale(pixt1, 1.5, 1.5); for (i = 1; i <= 4; i++) { for (j = 1; j <= 4; j++) { pixt3 = pixScaleGrayRankCascade(pixt2, i, j, 0, 0); pixDisplayWrite(pixt3, 1); pixDestroy(&pixt3); } } pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixs); pixDisplayMultiple("/tmp/display/file*"); return 0; }
int main(int argc, char **argv) { char *filein; l_float32 angle, conf, deg2rad; PIX *pixs, *pix1, *pix2, *pix3, *pix4, *pix5; PIX *pix6, *pix7, *pix8, *pix9; static char mainName[] = "lineremoval"; if (argc != 2) return ERROR_INT(" Syntax: lineremoval filein", mainName, 1); filein = argv[1]; deg2rad = 3.14159 / 180.; if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pix not made", mainName, 1); /* threshold to binary, extracting much of the lines */ pix1 = pixThresholdToBinary(pixs, 170); pixWrite("/tmp/dave-proc1.png", pix1, IFF_PNG); pixDisplayWrite(pix1, 1); /* find the skew angle and deskew using an interpolated * rotator for anti-aliasing (to avoid jaggies) */ pixFindSkew(pix1, &angle, &conf); pix2 = pixRotateAMGray(pixs, deg2rad * angle, 255); pixWrite("/tmp/dave-proc2.png", pix2, IFF_PNG); pixDisplayWrite(pix2, 1); /* extract the lines to be removed */ pix3 = pixCloseGray(pix2, 51, 1); pixWrite("/tmp/dave-proc3.png", pix3, IFF_PNG); pixDisplayWrite(pix3, 1); /* solidify the lines to be removed */ pix4 = pixErodeGray(pix3, 1, 5); pixWrite("/tmp/dave-proc4.png", pix4, IFF_PNG); pixDisplayWrite(pix4, 1); /* clean the background of those lines */ pix5 = pixThresholdToValue(NULL, pix4, 210, 255); pixWrite("/tmp/dave-proc5.png", pix5, IFF_PNG); pixDisplayWrite(pix5, 1); pix6 = pixThresholdToValue(NULL, pix5, 200, 0); pixWrite("/tmp/dave-proc6.png", pix6, IFF_PNG); pixDisplayWrite(pix6, 1); /* get paint-through mask for changed pixels */ pix7 = pixThresholdToBinary(pix6, 210); pixWrite("/tmp/dave-proc7.png", pix7, IFF_PNG); pixDisplayWrite(pix7, 1); /* add the inverted, cleaned lines to orig. Because * the background was cleaned, the inversion is 0, * so when you add, it doesn't lighten those pixels. * It only lightens (to white) the pixels in the lines! */ pixInvert(pix6, pix6); pix8 = pixAddGray(NULL, pix2, pix6); pixWrite("/tmp/dave-proc8.png", pix8, IFF_PNG); pixDisplayWrite(pix8, 1); pix9 = pixOpenGray(pix8, 1, 9); pixWrite("/tmp/dave-proc9.png", pix9, IFF_PNG); pixDisplayWrite(pix9, 1); pixCombineMasked(pix8, pix9, pix7); pixWrite("/tmp/dave-result.png", pix8, IFF_PNG); pixDisplayWrite(pix8, 1); pixDisplayMultiple("/tmp/display/file*"); return 0; }
main(int argc, char **argv) { l_int32 index, maxiters, type; BOX *box; PIX *pix, *pixs, *pixd, *pixt; PIXA *pixa; static char mainName[] = "ccthin2_reg"; if (argc != 1 && argc != 3) exit(ERROR_INT(" Syntax: ccthin2_reg [index maxiters]", mainName, 1)); pixDisplayWrite(NULL, 0); if ((pix = pixRead("feyn.tif")) == NULL) exit(ERROR_INT("pix not made", mainName, 1)); box = boxCreate(683, 799, 970, 479); pixs = pixClipRectangle(pix, box, NULL); pixDisplayWrite(pixs, 1); /* Just do one of the examples */ if (argc == 3) { index = atoi(argv[1]); maxiters = atoi(argv[2]); if (index <= 7) type = L_THIN_FG; else type = L_THIN_BG; pixt = pixThinExamples(pixs, type, index, maxiters, "/tmp/junksels.png"); pixDisplay(pixt, 100, 100); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixDisplayMultiple("/tmp/junk_write_display*"); return 0; } /* Do all the examples */ pixt = pixThinExamples(pixs, L_THIN_FG, 1, 0, "/tmp/junksel_example1.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThinExamples(pixs, L_THIN_FG, 2, 0, "/tmp/junksel_example2.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThinExamples(pixs, L_THIN_FG, 3, 0, "/tmp/junksel_example3.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThinExamples(pixs, L_THIN_FG, 4, 0, "/tmp/junksel_example4.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThinExamples(pixs, L_THIN_FG, 5, 0, "/tmp/junksel_example5.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThinExamples(pixs, L_THIN_FG, 6, 0, "/tmp/junksel_example6.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThinExamples(pixs, L_THIN_FG, 7, 0, "/tmp/junksel_example7.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThinExamples(pixs, L_THIN_BG, 8, 5, "/tmp/junksel_example8.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); pixt = pixThinExamples(pixs, L_THIN_BG, 9, 5, "/tmp/junksel_example9.png"); pixDisplayWrite(pixt, 1); pixDestroy(&pixt); /* Display the thinning results */ pixa = pixaReadFiles("/tmp", "junk_write_display"); pixd = pixaDisplayTiledAndScaled(pixa, 8, 500, 1, 0, 25, 2); pixWrite("/tmp/junktiles.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); /* Display the sels used in the examples */ pixa = pixaReadFiles("/tmp", "junksel_example"); pixd = pixaDisplayTiledInRows(pixa, 1, 500, 1.0, 0, 50, 2); pixWrite("/tmp/junksels.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pix); pixDestroy(&pixs); boxDestroy(&box); pixDisplayMultiple("/tmp/junk_write_display*"); return 0; }
main(int argc, char **argv) { char *filein, *fileout; l_int32 w, h; l_float32 scale; FILE *fp; PIX *pix, *pixs, *pixd; PIXCMAP *cmap; static char mainName[] = "dithertest"; if (argc != 3) exit(ERROR_INT(" Syntax: dithertest filein fileout", mainName, 1)); filein = argv[1]; fileout = argv[2]; if ((pix = pixRead(filein)) == NULL) exit(ERROR_INT("pix not made", mainName, 1)); if (pixGetDepth(pix) != 8) exit(ERROR_INT("pix not 8 bpp", mainName, 1)); pixs = pixGammaTRC(NULL, pix, GAMMA, 0, 255); startTimer(); pixd = pixDitherToBinary(pixs); fprintf(stderr, " time for binarized dither = %7.3f sec\n", stopTimer()); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); /* Dither to 2 bpp, with colormap */ startTimer(); pixd = pixDitherTo2bpp(pixs, 1); fprintf(stderr, " time for dither = %7.3f sec\n", stopTimer()); pixDisplayWrite(pixd, 1); cmap = pixGetColormap(pixd); pixcmapWriteStream(stderr, cmap); pixDestroy(&pixd); /* Dither to 2 bpp, without colormap */ startTimer(); pixd = pixDitherTo2bpp(pixs, 0); fprintf(stderr, " time for dither = %7.3f sec\n", stopTimer()); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); /* Dither to 2 bpp, without colormap; output in PostScript */ pixd = pixDitherTo2bpp(pixs, 0); w = pixGetWidth(pixs); h = pixGetHeight(pixs); scale = L_MIN(FACTOR * 2550 / w, FACTOR * 3300 / h); fp = lept_fopen(fileout, "wb+"); pixWriteStreamPS(fp, pixd, NULL, 300, scale); lept_fclose(fp); pixDestroy(&pixd); /* Dither 2x upscale to 1 bpp */ startTimer(); pixd = pixScaleGray2xLIDither(pixs); fprintf(stderr, " time for scale/dither = %7.3f sec\n", stopTimer()); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); /* Dither 4x upscale to 1 bpp */ startTimer(); pixd = pixScaleGray4xLIDither(pixs); fprintf(stderr, " time for scale/dither = %7.3f sec\n", stopTimer()); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); pixDisplayMultiple("/tmp/junk_write_display*"); pixDestroy(&pix); pixDestroy(&pixs); return 0; }
int main(int argc, char **argv) { l_int32 w, h, d, w2, h2, i, ncols, ret; l_float32 angle, conf; BOX *box; BOXA *boxa, *boxa2; PIX *pix, *pixs, *pixb, *pixb2, *pixd; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6; PIXA *pixam; /* mask with a single component over each column */ PIXA *pixac, *pixad, *pixat; PIXAA *pixaa, *pixaa2; SEL *selsplit; static char mainName[] = "arabic_lines"; if (argc != 1) return ERROR_INT(" Syntax: arabic_lines", mainName, 1); pixDisplayWrite(NULL, -1); /* init debug output */ /* Binarize input */ pixs = pixRead("arabic.png"); pixGetDimensions(pixs, &w, &h, &d); pix = pixConvertTo1(pixs, 128); /* Deskew */ pixb = pixFindSkewAndDeskew(pix, 1, &angle, &conf); pixDestroy(&pix); fprintf(stderr, "Skew angle: %7.2f degrees; %6.2f conf\n", angle, conf); pixDisplayWrite(pixb, 1); /* Use full image morphology to find columns, at 2x reduction. This only works for very simple layouts where each column of text extends the full height of the input image. */ pixb2 = pixReduceRankBinary2(pixb, 2, NULL); pix1 = pixMorphCompSequence(pixb2, "c5.500", 0); boxa = pixConnComp(pix1, &pixam, 8); ncols = boxaGetCount(boxa); fprintf(stderr, "Num columns: %d\n", ncols); pixDisplayWrite(pix1, 1); /* Use selective region-based morphology to get the textline mask. */ pixad = pixaMorphSequenceByRegion(pixb2, pixam, "c100.3", 0, 0); pixGetDimensions(pixb2, &w2, &h2, NULL); pix2 = pixaDisplay(pixad, w2, h2); pixDisplayWrite(pix2, 1); pixDestroy(&pix2); /* Some of the lines may be touching, so use a HMT to split the lines in each column, and use a pixaa to save the results. */ selsplit = selCreateFromString(seltext, 17, 7, "selsplit"); pixaa = pixaaCreate(ncols); for (i = 0; i < ncols; i++) { pix3 = pixaGetPix(pixad, i, L_CLONE); box = pixaGetBox(pixad, i, L_COPY); pix4 = pixHMT(NULL, pix3, selsplit); pixXor(pix4, pix4, pix3); boxa2 = pixConnComp(pix4, &pixac, 8); pixaaAddPixa(pixaa, pixac, L_INSERT); pixaaAddBox(pixaa, box, L_INSERT); pix5 = pixaDisplayRandomCmap(pixac, 0, 0); pixDisplayWrite(pix5, 1); fprintf(stderr, "Num textlines in col %d: %d\n", i, boxaGetCount(boxa2)); pixDestroy(&pix5); pixDestroy(&pix3); pixDestroy(&pix4); boxaDestroy(&boxa2); } /* Visual output */ ret = system("gthumb /tmp/display/file* &"); pixat = pixaReadFiles("/tmp/display", "file"); pix5 = selDisplayInPix(selsplit, 31, 2); pixaAddPix(pixat, pix5, L_INSERT); pix6 = pixaDisplayTiledAndScaled(pixat, 32, 400, 3, 0, 35, 3); pixWrite("/tmp/result.png", pix6, IFF_PNG); pixaDestroy(&pixat); pixDestroy(&pix6); /* Test pixaa I/O */ pixaaWrite("/tmp/pixaa", pixaa); pixaa2 = pixaaRead("/tmp/pixaa"); pixaaWrite("/tmp/pixaa2", pixaa2); /* Test pixaa display */ pixd = pixaaDisplay(pixaa, w2, h2); pixWrite("/tmp/textlines.png", pixd, IFF_PNG); pixDestroy(&pixd); /* Cleanup */ pixDestroy(&pixb2); pixDestroy(&pix1); pixaDestroy(&pixam); pixaDestroy(&pixad); pixaaDestroy(&pixaa); pixaaDestroy(&pixaa2); boxaDestroy(&boxa); selDestroy(&selsplit); pixDestroy(&pixs); pixDestroy(&pixb); return 0; }
int main(int argc, char **argv) { char *filein; l_int32 i, n, count; BOX *box; BOXA *boxa; PIX *pixs, *pixd; PIXA *pixa; PIXCMAP *cmap; static char mainName[] = "cctest1"; if (argc != 2) return ERROR_INT(" Syntax: cctest1 filein", mainName, 1); filein = argv[1]; if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); if (pixGetDepth(pixs) != 1) exit(ERROR_INT("pixs not 1 bpp", mainName, 1)); /* Test speed of pixCountConnComp() */ startTimer(); for (i = 0; i < NTIMES; i++) pixCountConnComp(pixs, 4, &count); fprintf(stderr, "Time to compute 4-cc: %6.3f sec\n", stopTimer()/NTIMES); fprintf(stderr, "Number of 4-cc: %d\n", count); startTimer(); for (i = 0; i < NTIMES; i++) pixCountConnComp(pixs, 8, &count); fprintf(stderr, "Time to compute 8-cc: %6.3f sec\n", stopTimer()/NTIMES); fprintf(stderr, "Number of 8-cc: %d\n", count); /* Test speed of pixConnComp(), with only boxa output */ startTimer(); for (i = 0; i < NTIMES; i++) { boxa = pixConnComp(pixs, NULL, 4); boxaDestroy(&boxa); } fprintf(stderr, "Time to compute 4-cc: %6.3f sec\n", stopTimer()/NTIMES); startTimer(); for (i = 0; i < NTIMES; i++) { boxa = pixConnComp(pixs, NULL, 8); boxaDestroy(&boxa); } fprintf(stderr, "Time to compute 8-cc: %6.3f sec\n", stopTimer()/NTIMES); /* Draw outline of each c.c. box */ boxa = pixConnComp(pixs, NULL, 4); n = boxaGetCount(boxa); fprintf(stderr, "Num 4-cc boxes: %d\n", n); for (i = 0; i < n; i++) { box = boxaGetBox(boxa, i, L_CLONE); pixRenderBox(pixs, box, 3, L_FLIP_PIXELS); boxDestroy(&box); /* remember, clones need to be destroyed */ } pixDisplayWrite(pixs, 1); boxaDestroy(&boxa); /* Display each component as a random color in cmapped 8 bpp. * Background is color 0; it is set to white. */ boxa = pixConnComp(pixs, &pixa, 4); pixd = pixaDisplayRandomCmap(pixa, pixGetWidth(pixs), pixGetHeight(pixs)); cmap = pixGetColormap(pixd); pixcmapResetColor(cmap, 0, 255, 255, 255); /* reset background to white */ pixDisplay(pixd, 100, 100); pixDisplayWrite(pixd, 1); boxaDestroy(&boxa); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixs); return 0; }
main(int argc, char **argv) { l_int32 same; l_uint32 *rtab, *gtab, *btab; l_int32 *cmaptab; BOX *box; PIX *pixs, *pixt1, *pixt2, *pixt3, *pixt4; PIXCMAP *cmap; static char mainName[] = "cmapquant_reg"; pixs = pixRead("lucasta-frag.jpg"); if (argc != 1) exit(ERROR_INT("syntax: cmapquant_req", mainName, 1)); /* Convert to 4 bpp with 6 levels and a colormap */ pixt1 = pixThresholdTo4bpp(pixs, 6, 1); /* Color some non-white pixels, preserving antialiasing, and * adding these colors to the colormap */ box = boxCreate(120, 30, 200, 200); pixColorGray(pixt1, box, L_PAINT_DARK, 220, 0, 0, 255); pixDisplayWrite(pixt1, 1); boxDestroy(&box); /* Scale up by 1.5; losing the colormap */ startTimer(); pixt2 = pixScale(pixt1, 1.5, 1.5); fprintf(stderr, "Time to scale by 1.5x = %7.3f sec\n", stopTimer()); pixDisplayWrite(pixt2, 1); /* Re-quantize using the same colormap */ startTimer(); cmap = pixGetColormap(pixt1); pixt3 = pixOctcubeQuantFromCmap(pixt2, cmap, MIN_DEPTH, LEVEL, L_EUCLIDEAN_DISTANCE); fprintf(stderr, "Time to requantize to cmap = %7.3f sec\n", stopTimer()); pixDisplayWrite(pixt3, 1); /* Re-quantize first making the tables and then * using the lower-level function */ startTimer(); makeRGBToIndexTables(&rtab, >ab, &btab, LEVEL); cmaptab = pixcmapToOctcubeLUT(cmap, LEVEL, L_EUCLIDEAN_DISTANCE); fprintf(stderr, "Time to make tables = %7.3f sec\n", stopTimer()); startTimer(); pixt4 = pixOctcubeQuantFromCmapLUT(pixt2, cmap, MIN_DEPTH, cmaptab, rtab, gtab, btab); fprintf(stderr, "Time for lowlevel re-quant = %7.3f sec\n", stopTimer()); pixDisplayWrite(pixt4, 1); pixEqual(pixt3, pixt4, &same); if (same) fprintf(stderr, "Correct: images are the same\n"); else fprintf(stderr, "Error: images differ\n"); FREE(cmaptab); FREE(rtab); FREE(gtab); FREE(btab); pixDisplayMultiple("/tmp/junk_write_display*"); pixDestroy(&pixs); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); return 0; }
int main(int argc, char **argv) { l_int32 success, failure; L_REGPARAMS *rp; #if !HAVE_LIBPNG || !HAVE_LIBZ fprintf(stderr, "libpng & libz are required for testing pngio_reg\n"); return 1; #endif /* abort */ if (regTestSetup(argc, argv, &rp)) return 1; /* --------- Part 1: Test lossless r/w to file ---------*/ failure = FALSE; success = TRUE; fprintf(stderr, "Test bmp 1 bpp file:\n"); if (ioFormatTest(FILE_1BPP)) success = FALSE; fprintf(stderr, "\nTest 2 bpp file:\n"); if (ioFormatTest(FILE_2BPP)) success = FALSE; fprintf(stderr, "\nTest 2 bpp file with cmap:\n"); if (ioFormatTest(FILE_2BPP_C)) success = FALSE; fprintf(stderr, "\nTest 4 bpp file:\n"); if (ioFormatTest(FILE_4BPP)) success = FALSE; fprintf(stderr, "\nTest 4 bpp file with cmap:\n"); if (ioFormatTest(FILE_4BPP_C)) success = FALSE; fprintf(stderr, "\nTest 8 bpp grayscale file with cmap:\n"); if (ioFormatTest(FILE_8BPP)) success = FALSE; fprintf(stderr, "\nTest 8 bpp color file with cmap:\n"); if (ioFormatTest(FILE_8BPP_C)) success = FALSE; fprintf(stderr, "\nTest 16 bpp file:\n"); if (ioFormatTest(FILE_16BPP)) success = FALSE; fprintf(stderr, "\nTest 32 bpp RGB file:\n"); if (ioFormatTest(FILE_32BPP)) success = FALSE; fprintf(stderr, "\nTest 32 bpp RGBA file:\n"); if (ioFormatTest(FILE_32BPP_ALPHA)) success = FALSE; fprintf(stderr, "\nTest spp = 1, cmap with alpha file:\n"); if (ioFormatTest(FILE_CMAP_ALPHA)) success = FALSE; fprintf(stderr, "\nTest spp = 1, cmap with alpha (small alpha array):\n"); if (ioFormatTest(FILE_CMAP_ALPHA2)) success = FALSE; fprintf(stderr, "\nTest spp = 1, fully transparent with alpha file:\n"); if (ioFormatTest(FILE_TRANS_ALPHA)) success = FALSE; fprintf(stderr, "\nTest spp = 2, gray with alpha file:\n"); if (ioFormatTest(FILE_GRAY_ALPHA)) success = FALSE; if (success) { fprintf(stderr, "\n ********** Success on lossless r/w to file *********\n\n"); } else { fprintf(stderr, "\n ******* Failure on at least one r/w to file ******\n\n"); } if (!success) failure = TRUE; /* ------------ Part 2: Test lossless r/w to memory ------------ */ pixDisplayWrite(NULL, -1); success = TRUE; if (test_mem_png(FILE_1BPP)) success = FALSE; if (test_mem_png(FILE_2BPP)) success = FALSE; if (test_mem_png(FILE_2BPP_C)) success = FALSE; if (test_mem_png(FILE_4BPP)) success = FALSE; if (test_mem_png(FILE_4BPP_C)) success = FALSE; if (test_mem_png(FILE_8BPP)) success = FALSE; if (test_mem_png(FILE_8BPP_C)) success = FALSE; if (test_mem_png(FILE_16BPP)) success = FALSE; if (test_mem_png(FILE_32BPP)) success = FALSE; if (test_mem_png(FILE_32BPP_ALPHA)) success = FALSE; if (test_mem_png(FILE_CMAP_ALPHA)) success = FALSE; if (test_mem_png(FILE_CMAP_ALPHA2)) success = FALSE; if (test_mem_png(FILE_TRANS_ALPHA)) success = FALSE; if (test_mem_png(FILE_GRAY_ALPHA)) success = FALSE; if (success) { fprintf(stderr, "\n ****** Success on lossless r/w to memory *****\n"); } else { fprintf(stderr, "\n ******* Failure on at least one r/w to memory ******\n"); } if (!success) failure = TRUE; /* ------------ Part 3: Test lossless 1 and 8 bpp r/w ------------ */ fprintf(stderr, "\nTest lossless 1 and 8 bpp r/w\n"); success = TRUE; if (test_1bpp_trans(rp) == 0) success = FALSE; if (test_1bpp_color(rp) == 0) success = FALSE; if (test_1bpp_gray(rp) == 0) success = FALSE; if (test_1bpp_bw1(rp) == 0) success = FALSE; if (test_1bpp_bw2(rp) == 0) success = FALSE; if (test_8bpp_trans(rp) == 0) success = FALSE; if (success) { fprintf(stderr, "\n ******* Success on 1 and 8 bpp lossless *******\n\n"); } else { fprintf(stderr, "\n ******* Failure on 1 and 8 bpp lossless *******\n\n"); } if (!success) failure = TRUE; /* -------------- Part 4: Read header information -------------- */ success = TRUE; if (get_header_data(FILE_1BPP)) success = FALSE; if (get_header_data(FILE_2BPP)) success = FALSE; if (get_header_data(FILE_2BPP_C)) success = FALSE; if (get_header_data(FILE_4BPP)) success = FALSE; if (get_header_data(FILE_4BPP_C)) success = FALSE; if (get_header_data(FILE_8BPP)) success = FALSE; if (get_header_data(FILE_8BPP_C)) success = FALSE; if (get_header_data(FILE_16BPP)) success = FALSE; if (get_header_data(FILE_32BPP)) success = FALSE; if (get_header_data(FILE_32BPP_ALPHA)) success = FALSE; if (get_header_data(FILE_CMAP_ALPHA)) success = FALSE; if (get_header_data(FILE_CMAP_ALPHA2)) success = FALSE; if (get_header_data(FILE_TRANS_ALPHA)) success = FALSE; if (get_header_data(FILE_GRAY_ALPHA)) success = FALSE; if (success) { fprintf(stderr, "\n ******* Success on reading headers *******\n\n"); } else { fprintf(stderr, "\n ******* Failure on reading headers *******\n\n"); } if (!success) failure = TRUE; if (!failure) { fprintf(stderr, " ******* Success on all tests *******\n\n"); } else { fprintf(stderr, " ******* Failure on at least one test *******\n\n"); } if (failure) rp->success = FALSE; return regTestCleanup(rp); }
main(int argc, char **argv) { char *filename; l_int32 w, h, type, maxboxes; l_float32 ovlap; BOX *box; BOXA *boxa, *boxat, *boxad; PIX *pix, *pixt, *pixs, *pixd; static char mainName[] = "partitiontest"; if (argc != 3 && argc != 5) return ERROR_INT("syntax: partitiontest <fname> type [maxboxes ovlap]", mainName, 1); filename = argv[1]; type = atoi(argv[2]); if (type == L_SORT_BY_WIDTH) fprintf(stderr, "Sorting by width:\n"); else if (type == L_SORT_BY_HEIGHT) fprintf(stderr, "Sorting by height:\n"); else if (type == L_SORT_BY_MAX_DIMENSION) fprintf(stderr, "Sorting by maximum dimension:\n"); else if (type == L_SORT_BY_MIN_DIMENSION) fprintf(stderr, "Sorting by minimum dimension:\n"); else if (type == L_SORT_BY_PERIMETER) fprintf(stderr, "Sorting by perimeter:\n"); else if (type == L_SORT_BY_AREA) fprintf(stderr, "Sorting by area:\n"); else { fprintf(stderr, "Use one of the following for 'type':\n" " 5: L_SORT_BY_WIDTH\n" " 6: L_SORT_BY_HEIGHT\n" " 7: L_SORT_BY_MIN_DIMENSION\n" " 8: L_SORT_BY_MAX_DIMENSION\n" " 9: L_SORT_BY_PERIMETER\n" " 10: L_SORT_BY_AREA\n"); return ERROR_INT("invalid type: see source", mainName, 1); } if (argc == 5) { maxboxes = atoi(argv[3]); ovlap = atof(argv[4]); } else { maxboxes = 100; ovlap = 0.2; } pix = pixRead(filename); pixs = pixConvertTo1(pix, 128); pixDilateBrick(pixs, pixs, 5, 5); boxa = pixConnComp(pixs, NULL, 4); pixGetDimensions(pixs, &w, &h, NULL); box = boxCreate(0, 0, w, h); startTimer(); boxaPermuteRandom(boxa, boxa); boxat = boxaSelectBySize(boxa, 500, 500, L_SELECT_IF_BOTH, L_SELECT_IF_LT, NULL); boxad = boxaGetWhiteblocks(boxat, box, type, maxboxes, ovlap, 200, 0.15, 20000); fprintf(stderr, "Time: %7.3f sec\n", stopTimer()); boxaWriteStream(stderr, boxad); pixDisplayWrite(NULL, -1); pixDisplayWrite(pixs, REDUCTION); /* Display box outlines in a single color in a cmapped image */ pixd = pixDrawBoxa(pixs, boxad, 7, 0xe0708000); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixd); /* Display box outlines in a single color in an RGB image */ pixt = pixConvertTo8(pixs, FALSE); pixd = pixDrawBoxa(pixt, boxad, 7, 0x40a0c000); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixt); pixDestroy(&pixd); /* Display box outlines with random colors in a cmapped image */ pixd = pixDrawBoxaRandom(pixs, boxad, 7); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixd); /* Display box outlines with random colors in an RGB image */ pixt = pixConvertTo8(pixs, FALSE); pixd = pixDrawBoxaRandom(pixt, boxad, 7); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixt); pixDestroy(&pixd); /* Display boxes in the same color in a cmapped image */ pixd = pixPaintBoxa(pixs, boxad, 0x60e0a000); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixd); /* Display boxes in the same color in an RGB image */ pixt = pixConvertTo8(pixs, FALSE); pixd = pixPaintBoxa(pixt, boxad, 0xc030a000); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixt); pixDestroy(&pixd); /* Display boxes in random colors in a cmapped image */ pixd = pixPaintBoxaRandom(pixs, boxad); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixd); /* Display boxes in random colors in an RGB image */ pixt = pixConvertTo8(pixs, FALSE); pixd = pixPaintBoxaRandom(pixt, boxad); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixt); pixDestroy(&pixd); pixDisplayMultiple("/tmp/junk_write_display*"); pixDestroy(&pix); pixDestroy(&pixs); boxDestroy(&box); boxaDestroy(&boxa); boxaDestroy(&boxat); boxaDestroy(&boxad); return 0; }