int main(int argc, char **argv) { char dilateseq[512], erodeseq[512]; char openseq[512], closeseq[512]; char wtophatseq[512], btophatseq[512]; l_int32 w, h; PIX *pixs, *pix1, *pix2, *pix3, *pix4, *pix5; PIXA *pixa; PIXACC *pacc; PIXCMAP *cmap; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; pixs = pixRead("aneurisms8.jpg"); pixa = pixaCreate(0); /* =========================================================== */ /* -------- Test gray morph, including interpreter ------------ */ pix1 = pixDilateGray(pixs, WSIZE, HSIZE); sprintf(dilateseq, "D%d.%d", WSIZE, HSIZE); pix2 = pixGrayMorphSequence(pixs, dilateseq, 0, 0); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 0 */ regTestComparePix(rp, pix1, pix2); /* 1 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pix1 = pixErodeGray(pixs, WSIZE, HSIZE); sprintf(erodeseq, "E%d.%d", WSIZE, HSIZE); pix2 = pixGrayMorphSequence(pixs, erodeseq, 0, 100); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 2 */ regTestComparePix(rp, pix1, pix2); /* 3 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pix1 = pixOpenGray(pixs, WSIZE, HSIZE); sprintf(openseq, "O%d.%d", WSIZE, HSIZE); pix2 = pixGrayMorphSequence(pixs, openseq, 0, 200); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 4 */ regTestComparePix(rp, pix1, pix2); /* 5 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pix1 = pixCloseGray(pixs, WSIZE, HSIZE); sprintf(closeseq, "C%d.%d", WSIZE, HSIZE); pix2 = pixGrayMorphSequence(pixs, closeseq, 0, 300); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 6 */ regTestComparePix(rp, pix1, pix2); /* 7 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pix1 = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_WHITE); sprintf(wtophatseq, "Tw%d.%d", WSIZE, HSIZE); pix2 = pixGrayMorphSequence(pixs, wtophatseq, 0, 400); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 8 */ regTestComparePix(rp, pix1, pix2); /* 9 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pix1 = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_BLACK); sprintf(btophatseq, "Tb%d.%d", WSIZE, HSIZE); pix2 = pixGrayMorphSequence(pixs, btophatseq, 0, 500); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 10 */ regTestComparePix(rp, pix1, pix2); /* 11 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); /* ------------- Test erode/dilate duality -------------- */ pix1 = pixDilateGray(pixs, WSIZE, HSIZE); pix2 = pixInvert(NULL, pixs); pix3 = pixErodeGray(pix2, WSIZE, HSIZE); pixInvert(pix3, pix3); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 12 */ regTestComparePix(rp, pix1, pix3); /* 13 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pixDestroy(&pix3); /* ------------- Test open/close duality -------------- */ pix1 = pixOpenGray(pixs, WSIZE, HSIZE); pix2 = pixInvert(NULL, pixs); pix3 = pixCloseGray(pix2, WSIZE, HSIZE); pixInvert(pix3, pix3); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 14 */ regTestComparePix(rp, pix1, pix3); /* 15 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pixDestroy(&pix3); /* ------------- Test tophat duality -------------- */ pix1 = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_WHITE); pix2 = pixInvert(NULL, pixs); pix3 = pixTophat(pix2, WSIZE, HSIZE, L_TOPHAT_BLACK); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 16 */ regTestComparePix(rp, pix1, pix3); /* 17 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pixDestroy(&pix3); pix1 = pixGrayMorphSequence(pixs, "Tw9.5", 0, 100); pix2 = pixInvert(NULL, pixs); pix3 = pixGrayMorphSequence(pix2, "Tb9.5", 0, 300); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 18 */ regTestComparePix(rp, pix1, pix3); /* 19 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pixDestroy(&pix3); /* ------------- Test opening/closing for large sels -------------- */ pix1 = pixGrayMorphSequence(pixs, "C9.9 + C19.19 + C29.29 + C39.39 + C49.49", 0, 100); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 20 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixGrayMorphSequence(pixs, "O9.9 + O19.19 + O29.29 + O39.39 + O49.49", 0, 400); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 21 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixaDisplayTiledInColumns(pixa, 4, 1.0, 20, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 22 */ pixDisplayWithTitle(pix1, 0, 0, NULL, rp->display); pixaDestroy(&pixa); pixDestroy(&pix1); /* =========================================================== */ pixa = pixaCreate(0); /* ---------- Closing plus white tophat result ------------ * * Parameters: wsize, hsize = 9, 29 * * ---------------------------------------------------------*/ pix1 = pixCloseGray(pixs, 9, 9); pix2 = pixTophat(pix1, 9, 9, L_TOPHAT_WHITE); pix3 = pixGrayMorphSequence(pixs, "C9.9 + TW9.9", 0, 0); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 23 */ regTestComparePix(rp, pix2, pix3); /* 24 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixMaxDynamicRange(pix2, L_LINEAR_SCALE); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 25 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pixDestroy(&pix3); pix1 = pixCloseGray(pixs, 29, 29); pix2 = pixTophat(pix1, 29, 29, L_TOPHAT_WHITE); pix3 = pixGrayMorphSequence(pixs, "C29.29 + Tw29.29", 0, 0); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 26 */ regTestComparePix(rp, pix2, pix3); /* 27 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixMaxDynamicRange(pix2, L_LINEAR_SCALE); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 28 */ pixaAddPix(pixa, pix1, L_INSERT); pixDestroy(&pix2); pixDestroy(&pix3); /* --------- hdome with parameter height = 100 ------------*/ pix1 = pixHDome(pixs, 100, 4); pix2 = pixMaxDynamicRange(pix1, L_LINEAR_SCALE); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 29 */ regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 30 */ pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); /* ----- Contrast enhancement with morph parameters 9, 9 -------*/ pixGetDimensions(pixs, &w, &h, NULL); pix1 = pixInitAccumulate(w, h, 0x8000); pixAccumulate(pix1, pixs, L_ARITH_ADD); pixMultConstAccumulate(pix1, 3., 0x8000); pix2 = pixOpenGray(pixs, 9, 9); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 31 */ pixaAddPix(pixa, pix2, L_INSERT); pixAccumulate(pix1, pix2, L_ARITH_SUBTRACT); pix2 = pixCloseGray(pixs, 9, 9); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 32 */ pixaAddPix(pixa, pix2, L_INSERT); pixAccumulate(pix1, pix2, L_ARITH_SUBTRACT); pix2 = pixFinalAccumulate(pix1, 0x8000, 8); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 33 */ pixaAddPix(pixa, pix2, L_INSERT); pixDestroy(&pix1); /* Do the same thing with the Pixacc */ pacc = pixaccCreate(w, h, 1); pixaccAdd(pacc, pixs); pixaccMultConst(pacc, 3.); pix1 = pixOpenGray(pixs, 9, 9); pixaccSubtract(pacc, pix1); pixDestroy(&pix1); pix1 = pixCloseGray(pixs, 9, 9); pixaccSubtract(pacc, pix1); pixDestroy(&pix1); pix1 = pixaccFinal(pacc, 8); pixaccDestroy(&pacc); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 34 */ pixaAddPix(pixa, pix1, L_INSERT); regTestComparePix(rp, pix1, pix2); /* 35 */ pix1 = pixaDisplayTiledInColumns(pixa, 4, 1.0, 20, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 36 */ pixDisplayWithTitle(pix1, 1100, 0, NULL, rp->display); pixaDestroy(&pixa); pixDestroy(&pix1); pixDestroy(&pixs); /* =========================================================== */ pixa = pixaCreate(0); /* ---- Tophat result on feynman stamp, to extract diagrams ----- */ pixs = pixRead("feynman-stamp.jpg"); pixGetDimensions(pixs, &w, &h, NULL); /* Make output image to hold five intermediate images */ pix1 = pixCreate(5 * w + 18, h + 6, 32); /* composite output image */ pixSetAllArbitrary(pix1, 0x0000ff00); /* set to blue */ /* Paste in the input image */ pix2 = pixRemoveColormap(pixs, REMOVE_CMAP_TO_FULL_COLOR); pixRasterop(pix1, 3, 3, w, h, PIX_SRC, pix2, 0, 0); /* 1st one */ regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 37 */ pixaAddPix(pixa, pix2, L_INSERT); /* Paste in the grayscale version */ cmap = pixGetColormap(pixs); if (cmap) pix2 = pixRemoveColormap(pixs, REMOVE_CMAP_TO_GRAYSCALE); else pix2 = pixConvertRGBToGray(pixs, 0.33, 0.34, 0.33); pix3 = pixConvertTo32(pix2); /* 8 --> 32 bpp */ pixRasterop(pix1, w + 6, 3, w, h, PIX_SRC, pix3, 0, 0); /* 2nd one */ regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 38 */ pixaAddPix(pixa, pix3, L_INSERT); /* Paste in a log dynamic range scaled version of the white tophat */ pix3 = pixTophat(pix2, 3, 3, L_TOPHAT_WHITE); pix4 = pixMaxDynamicRange(pix3, L_LOG_SCALE); pix5 = pixConvertTo32(pix4); pixRasterop(pix1, 2 * w + 9, 3, w, h, PIX_SRC, pix5, 0, 0); /* 3rd */ regTestWritePixAndCheck(rp, pix5, IFF_PNG); /* 39 */ pixaAddPix(pixa, pix5, L_INSERT); pixDestroy(&pix2); pixDestroy(&pix4); /* Stretch the range and threshold to binary; paste it in */ pix2 = pixGammaTRC(NULL, pix3, 1.0, 0, 80); pix4 = pixThresholdToBinary(pix2, 70); pix5 = pixConvertTo32(pix4); pixRasterop(pix1, 3 * w + 12, 3, w, h, PIX_SRC, pix5, 0, 0); /* 4th */ regTestWritePixAndCheck(rp, pix5, IFF_PNG); /* 40 */ pixaAddPix(pixa, pix5, L_INSERT); pixDestroy(&pix2); pixDestroy(&pix3); /* Invert; this is the final result */ pixInvert(pix4, pix4); pix5 = pixConvertTo32(pix4); pixRasterop(pix1, 4 * w + 15, 3, w, h, PIX_SRC, pix5, 0, 0); /* 5th */ regTestWritePixAndCheck(rp, pix5, IFF_PNG); /* 41 */ pixaAddPix(pixa, pix5, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix4); pix1 = pixaDisplayTiledInRows(pixa, 32, 1700, 1.0, 0, 20, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 42 */ pixDisplayWithTitle(pix1, 0, 800, NULL, rp->display); pixaDestroy(&pixa); pixDestroy(&pix1); pixDestroy(&pixs); 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 wsize, hsize, w, h; PIX *pixs, *pixd; static char mainName[] = "graymorphtest"; if (argc != 5) exit(ERROR_INT(" Syntax: graymorphtest wsize, hsizefilein fileout", mainName, 1)); filein = argv[1]; wsize = atoi(argv[2]); hsize = atoi(argv[3]); fileout = argv[4]; if ((pixs = pixRead(filein)) == NULL) exit(ERROR_INT("pix not made", mainName, 1)); w = pixGetWidth(pixs); h = pixGetHeight(pixs); /* ---------- Choose an operation ---------- */ #if 1 pixd = pixDilateGray(pixs, wsize, hsize); pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); #elif 0 pixd = pixErodeGray(pixs, wsize, hsize); pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); #elif 0 pixd = pixOpenGray(pixs, wsize, hsize); pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); #elif 0 pixd = pixCloseGray(pixs, wsize, hsize); pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); #elif 0 pixd = pixTophat(pixs, wsize, hsize, TOPHAT_WHITE); pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); #elif 0 pixd = pixTophat(pixs, wsize, hsize, TOPHAT_BLACK); pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); #endif /* ---------- Speed ---------- */ #if 0 startTimer(); pixd = pixCloseGray(pixs, wsize, hsize); fprintf(stderr, " Speed is %6.2f MPix/sec\n", (l_float32)(4 * w * h) / (1000000. * stopTimer())); pixWrite(fileout, pixd, IFF_PNG); #endif pixDestroy(&pixs); exit(0); }
/*! * pixGrayMorphSequence() * * Input: pixs * sequence (string specifying sequence) * dispsep (horizontal separation in pixels between * successive displays; use zero to suppress display) * dispy (if dispsep != 0, this gives the y-value of the * UL corner for display; otherwise it is ignored) * Return: pixd, or null on error * * Notes: * (1) This works on 8 bpp grayscale images. * (2) This runs a pipeline of operations; no branching is allowed. * (3) This only uses brick SELs. * (4) A new image is always produced; the input image is not changed. * (5) This contains an interpreter, allowing sequences to be * generated and run. * (6) The format of the sequence string is defined below. * (7) In addition to morphological operations, the composite * morph/subtract tophat can be performed. * (8) Sel sizes (width, height) must each be odd numbers. * (9) Intermediate results can optionally be displayed * (10) The sequence string is formatted as follows: * - An arbitrary number of operations, each separated * by a '+' character. White space is ignored. * - Each operation begins with a case-independent character * specifying the operation: * d or D (dilation) * e or E (erosion) * o or O (opening) * c or C (closing) * t or T (tophat) * - The args to the morphological operations are bricks of hits, * and are formatted as a.b, where a and b are horizontal and * vertical dimensions, rsp. (each must be an odd number) * - The args to the tophat are w or W (for white tophat) * or b or B (for black tophat), followed by a.b as for * the dilation, erosion, opening and closing. * Example valid sequences are: * "c5.3 + o7.5" * "c9.9 + tw9.9" */ PIX * pixGrayMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep, l_int32 dispy) { char *rawop, *op; l_int32 nops, i, valid, w, h, x; PIX *pixt1, *pixt2; SARRAY *sa; PROCNAME("pixGrayMorphSequence"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!sequence) return (PIX *)ERROR_PTR("sequence not defined", procName, NULL); /* Split sequence into individual operations */ sa = sarrayCreate(0); sarraySplitString(sa, sequence, "+"); nops = sarrayGetCount(sa); /* Verify that the operation sequence is valid */ valid = TRUE; for (i = 0; i < nops; i++) { rawop = sarrayGetString(sa, i, 0); op = stringRemoveChars(rawop, " \n\t"); switch (op[0]) { case 'd': case 'D': case 'e': case 'E': case 'o': case 'O': case 'c': case 'C': if (sscanf(&op[1], "%d.%d", &w, &h) != 2) { fprintf(stderr, "*** op: %s invalid\n", op); valid = FALSE; break; } if (w < 1 || (w & 1) == 0 || h < 1 || (h & 1) == 0 ) { fprintf(stderr, "*** op: %s; w = %d, h = %d; must both be odd\n", op, w, h); valid = FALSE; break; } /* fprintf(stderr, "op = %s; w = %d, h = %d\n", op, w, h); */ break; case 't': case 'T': if (op[1] != 'w' && op[1] != 'W' && op[1] != 'b' && op[1] != 'B') { fprintf(stderr, "*** op = %s; arg %c must be 'w' or 'b'\n", op, op[1]); valid = FALSE; break; } sscanf(&op[2], "%d.%d", &w, &h); if (w < 1 || (w & 1) == 0 || h < 1 || (h & 1) == 0 ) { fprintf(stderr, "*** op: %s; w = %d, h = %d; must both be odd\n", op, w, h); valid = FALSE; break; } /* fprintf(stderr, "op = %s", op); */ break; default: fprintf(stderr, "*** nonexistent op = %s\n", op); valid = FALSE; } FREE(op); } if (!valid) { sarrayDestroy(&sa); return (PIX *)ERROR_PTR("sequence invalid", procName, NULL); } /* Parse and operate */ pixt1 = pixCopy(NULL, pixs); pixt2 = NULL; x = 0; for (i = 0; i < nops; i++) { rawop = sarrayGetString(sa, i, 0); op = stringRemoveChars(rawop, " \n\t"); switch (op[0]) { case 'd': case 'D': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixDilateGray(pixt1, w, h); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, dispy); x += dispsep; } break; case 'e': case 'E': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixErodeGray(pixt1, w, h); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, dispy); x += dispsep; } break; case 'o': case 'O': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixOpenGray(pixt1, w, h); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, dispy); x += dispsep; } break; case 'c': case 'C': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixCloseGray(pixt1, w, h); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, dispy); x += dispsep; } break; case 't': case 'T': sscanf(&op[2], "%d.%d", &w, &h); if (op[1] == 'w' || op[1] == 'W') pixt2 = pixTophat(pixt1, w, h, L_TOPHAT_WHITE); else /* 'b' or 'B' */ pixt2 = pixTophat(pixt1, w, h, L_TOPHAT_BLACK); pixDestroy(&pixt1); pixt1 = pixClone(pixt2); pixDestroy(&pixt2); if (dispsep > 0) { pixDisplay(pixt1, x, dispy); x += dispsep; } break; default: /* All invalid ops are caught in the first pass */ break; } FREE(op); } sarrayDestroy(&sa); return pixt1; }
/*! * pixColorMorph() * * Input: pixs * type (L_MORPH_DILATE, L_MORPH_ERODE, L_MORPH_OPEN, * or L_MORPH_CLOSE) * hsize (of Sel; must be odd; origin implicitly in center) * vsize (ditto) * Return: pixd * * Notes: * (1) This does the morph operation on each component separately, * and recombines the result. * (2) Sel is a brick with all elements being hits. * (3) If hsize = vsize = 1, just returns a copy. */ PIX * pixColorMorph(PIX *pixs, l_int32 type, l_int32 hsize, l_int32 vsize) { PIX *pixr, *pixg, *pixb, *pixrm, *pixgm, *pixbm, *pixd; PROCNAME("pixColorMorph"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (pixGetDepth(pixs) != 32) return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL); if (type != L_MORPH_DILATE && type != L_MORPH_ERODE && type != L_MORPH_OPEN && type != L_MORPH_CLOSE) return (PIX *)ERROR_PTR("invalid morph type", procName, NULL); if (hsize < 1 || vsize < 1) return (PIX *)ERROR_PTR("hsize or vsize < 1", procName, NULL); if ((hsize & 1) == 0 ) { L_WARNING("horiz sel size must be odd; increasing by 1", procName); hsize++; } if ((vsize & 1) == 0 ) { L_WARNING("vert sel size must be odd; increasing by 1", procName); vsize++; } if (hsize == 1 && vsize == 1) return pixCopy(NULL, pixs); pixr = pixGetRGBComponent(pixs, COLOR_RED); pixg = pixGetRGBComponent(pixs, COLOR_GREEN); pixb = pixGetRGBComponent(pixs, COLOR_BLUE); if (type == L_MORPH_DILATE) { pixrm = pixDilateGray(pixr, hsize, vsize); pixgm = pixDilateGray(pixg, hsize, vsize); pixbm = pixDilateGray(pixb, hsize, vsize); } else if (type == L_MORPH_ERODE) { pixrm = pixErodeGray(pixr, hsize, vsize); pixgm = pixErodeGray(pixg, hsize, vsize); pixbm = pixErodeGray(pixb, hsize, vsize); } else if (type == L_MORPH_OPEN) { pixrm = pixOpenGray(pixr, hsize, vsize); pixgm = pixOpenGray(pixg, hsize, vsize); pixbm = pixOpenGray(pixb, hsize, vsize); } else { /* type == L_MORPH_CLOSE */ pixrm = pixCloseGray(pixr, hsize, vsize); pixgm = pixCloseGray(pixg, hsize, vsize); pixbm = pixCloseGray(pixb, hsize, vsize); } pixd = pixCreateRGBImage(pixrm, pixgm, pixbm); pixDestroy(&pixr); pixDestroy(&pixrm); pixDestroy(&pixg); pixDestroy(&pixgm); pixDestroy(&pixb); pixDestroy(&pixbm); return pixd; }
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; }
/*! * \brief pixGrayMorphSequence() * * \param[in] pixs * \param[in] sequence string specifying sequence * \param[in] dispsep controls debug display of each result in the sequence: * 0: no output * > 0: gives horizontal separation in pixels between * successive displays * < 0: pdf output; abs(dispsep) is used for naming * \param[in] dispy if dispsep > 0, this gives the y-value of the * UL corner for display; otherwise it is ignored * \return pixd, or NULL on error * * <pre> * Notes: * (1) This works on 8 bpp grayscale images. * (2) This runs a pipeline of operations; no branching is allowed. * (3) This only uses brick SELs. * (4) A new image is always produced; the input image is not changed. * (5) This contains an interpreter, allowing sequences to be * generated and run. * (6) The format of the sequence string is defined below. * (7) In addition to morphological operations, the composite * morph/subtract tophat can be performed. * (8) Sel sizes (width, height) must each be odd numbers. * (9) Intermediate results can optionally be displayed * (10) The sequence string is formatted as follows: * ~ An arbitrary number of operations, each separated * by a '+' character. White space is ignored. * ~ Each operation begins with a case-independent character * specifying the operation: * d or D (dilation) * e or E (erosion) * o or O (opening) * c or C (closing) * t or T (tophat) * ~ The args to the morphological operations are bricks of hits, * and are formatted as a.b, where a and b are horizontal and * vertical dimensions, rsp. (each must be an odd number) * ~ The args to the tophat are w or W (for white tophat) * or b or B (for black tophat), followed by a.b as for * the dilation, erosion, opening and closing. * Example valid sequences are: * "c5.3 + o7.5" * "c9.9 + tw9.9" * </pre> */ PIX * pixGrayMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep, l_int32 dispy) { char *rawop, *op, *fname; char buf[256]; l_int32 nops, i, valid, w, h, x, pdfout; PIX *pixt1, *pixt2; PIXA *pixa; SARRAY *sa; PROCNAME("pixGrayMorphSequence"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!sequence) return (PIX *)ERROR_PTR("sequence not defined", procName, NULL); /* Split sequence into individual operations */ sa = sarrayCreate(0); sarraySplitString(sa, sequence, "+"); nops = sarrayGetCount(sa); pdfout = (dispsep < 0) ? 1 : 0; /* Verify that the operation sequence is valid */ valid = TRUE; for (i = 0; i < nops; i++) { rawop = sarrayGetString(sa, i, L_NOCOPY); op = stringRemoveChars(rawop, " \n\t"); switch (op[0]) { case 'd': case 'D': case 'e': case 'E': case 'o': case 'O': case 'c': case 'C': if (sscanf(&op[1], "%d.%d", &w, &h) != 2) { fprintf(stderr, "*** op: %s invalid\n", op); valid = FALSE; break; } if (w < 1 || (w & 1) == 0 || h < 1 || (h & 1) == 0 ) { fprintf(stderr, "*** op: %s; w = %d, h = %d; must both be odd\n", op, w, h); valid = FALSE; break; } /* fprintf(stderr, "op = %s; w = %d, h = %d\n", op, w, h); */ break; case 't': case 'T': if (op[1] != 'w' && op[1] != 'W' && op[1] != 'b' && op[1] != 'B') { fprintf(stderr, "*** op = %s; arg %c must be 'w' or 'b'\n", op, op[1]); valid = FALSE; break; } sscanf(&op[2], "%d.%d", &w, &h); if (w < 1 || (w & 1) == 0 || h < 1 || (h & 1) == 0 ) { fprintf(stderr, "*** op: %s; w = %d, h = %d; must both be odd\n", op, w, h); valid = FALSE; break; } /* fprintf(stderr, "op = %s", op); */ break; default: fprintf(stderr, "*** nonexistent op = %s\n", op); valid = FALSE; } LEPT_FREE(op); } if (!valid) { sarrayDestroy(&sa); return (PIX *)ERROR_PTR("sequence invalid", procName, NULL); } /* Parse and operate */ pixa = NULL; if (pdfout) { pixa = pixaCreate(0); pixaAddPix(pixa, pixs, L_CLONE); snprintf(buf, sizeof(buf), "/tmp/seq_output_%d.pdf", L_ABS(dispsep)); fname = genPathname(buf, NULL); } pixt1 = pixCopy(NULL, pixs); pixt2 = NULL; x = 0; for (i = 0; i < nops; i++) { rawop = sarrayGetString(sa, i, L_NOCOPY); op = stringRemoveChars(rawop, " \n\t"); switch (op[0]) { case 'd': case 'D': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixDilateGray(pixt1, w, h); pixSwapAndDestroy(&pixt1, &pixt2); break; case 'e': case 'E': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixErodeGray(pixt1, w, h); pixSwapAndDestroy(&pixt1, &pixt2); break; case 'o': case 'O': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixOpenGray(pixt1, w, h); pixSwapAndDestroy(&pixt1, &pixt2); break; case 'c': case 'C': sscanf(&op[1], "%d.%d", &w, &h); pixt2 = pixCloseGray(pixt1, w, h); pixSwapAndDestroy(&pixt1, &pixt2); break; case 't': case 'T': sscanf(&op[2], "%d.%d", &w, &h); if (op[1] == 'w' || op[1] == 'W') pixt2 = pixTophat(pixt1, w, h, L_TOPHAT_WHITE); else /* 'b' or 'B' */ pixt2 = pixTophat(pixt1, w, h, L_TOPHAT_BLACK); pixSwapAndDestroy(&pixt1, &pixt2); break; default: /* All invalid ops are caught in the first pass */ break; } LEPT_FREE(op); /* Debug output */ if (dispsep > 0) { pixDisplay(pixt1, x, dispy); x += dispsep; } if (pdfout) pixaAddPix(pixa, pixt1, L_COPY); } if (pdfout) { pixaConvertToPdf(pixa, 0, 1.0, L_FLATE_ENCODE, 0, fname, fname); LEPT_FREE(fname); pixaDestroy(&pixa); } sarrayDestroy(&sa); return pixt1; }
main(int argc, char **argv) { PIX *pixs, *pixt1, *pixt2, *pixd; PIXA *pixa; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; pixs = pixRead("test8.jpg"); /* Dilation */ pixa = pixaCreate(0); pixSaveTiled(pixs, pixa, 1, 1, 20, 8); pixt1 = pixDilateGray3(pixs, 3, 1); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixDilateGray(pixs, 3, 1); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 0 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixDilateGray3(pixs, 1, 3); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixDilateGray(pixs, 1, 3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 1 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixDilateGray3(pixs, 3, 3); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixDilateGray(pixs, 3, 3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 2 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixd = pixaDisplay(pixa, 0, 0); pixDisplayWithTitle(pixd, 0, 100, "Dilation", rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); /* Erosion */ pixa = pixaCreate(0); pixSaveTiled(pixs, pixa, 1, 1, 20, 8); pixt1 = pixErodeGray3(pixs, 3, 1); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixErodeGray(pixs, 3, 1); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 3 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixErodeGray3(pixs, 1, 3); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixErodeGray(pixs, 1, 3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 4 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixErodeGray3(pixs, 3, 3); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixErodeGray(pixs, 3, 3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 5 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixd = pixaDisplay(pixa, 0, 0); pixDisplayWithTitle(pixd, 250, 100, "Erosion", rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); /* Opening */ pixa = pixaCreate(0); pixSaveTiled(pixs, pixa, 1, 1, 20, 8); pixt1 = pixOpenGray3(pixs, 3, 1); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixOpenGray(pixs, 3, 1); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 6 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixOpenGray3(pixs, 1, 3); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixOpenGray(pixs, 1, 3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 7 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixOpenGray3(pixs, 3, 3); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixOpenGray(pixs, 3, 3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 8 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixd = pixaDisplay(pixa, 0, 0); pixDisplayWithTitle(pixd, 500, 100, "Opening", rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); /* Closing */ pixa = pixaCreate(0); pixSaveTiled(pixs, pixa, 1, 1, 20, 8); pixt1 = pixCloseGray3(pixs, 3, 1); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixCloseGray(pixs, 3, 1); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 9 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixCloseGray3(pixs, 1, 3); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixCloseGray(pixs, 1, 3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 10 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixCloseGray3(pixs, 3, 3); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixCloseGray(pixs, 3, 3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); regTestComparePix(rp, pixt1, pixt2); /* 11 */ pixDestroy(&pixt1); pixDestroy(&pixt2); pixd = pixaDisplay(pixa, 0, 0); pixDisplayWithTitle(pixd, 750, 100, "Closing", rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixs); return regTestCleanup(rp); }
int main_line_removal() { PIX* pixs_source = pixRead("dave-start.png"); if (!pixs_source) { printf("Error opening file"); return 1; } double deg2rad = 3.1415926535 / 180.; l_float32 angle, conf, score; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pix8, *pix9; pix1 = pixThresholdToBinary(pixs_source, 160); printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-1.tif", pix1, IFF_TIFF_G4); pixFindSkew(pix1, &angle, &conf); pix2 = pixRotateAMGray(pixs_source, deg2rad * angle, 160); printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-2.tif", pix2, IFF_TIFF_G4); l_int32 HORIZ = 1; l_int32 VERT = 3; pix3 = pixCloseGray(pix2, 51, HORIZ); //k?p?c 51? printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-3.tif", pix3, IFF_TIFF_G4); pix4 = pixErodeGray(pix3, 5, VERT); //k?p?c 5? printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-4.tif", pix4, IFF_TIFF_G4); pix5 = pix4; pix5 = pixThresholdToValue(pix5, pix4, 230, 255); printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-5.tif", pix5, IFF_TIFF_G4); pix6 = pix5; pix6 = pixThresholdToValue(pix5, pix5, 210, 0); printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-6.tif", pix6, IFF_TIFF_G4); pix7 = pixThresholdToBinary(pix6, 230); printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-7.tif", pix7, IFF_TIFF_G4); pixInvert(pix6, pix6); pix8 = pixAddGray(NULL, pix2, pix6); printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-8.tif", pix8, IFF_TIFF_G4); VERT = 7; pix9 = pixOpenGray(pix8, 3, VERT); printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-9.tif", pix9, IFF_TIFF_G4); if (pixCombineMasked(pix8, pix9, pix7)) { printf("!!!Error while combining pixs!!!\n"); } printf("Create line removal image\n"); pixWrite("line-removal/result.line-removal-final.tif", pix8, IFF_TIFF_G4); printf("\n---\nEnd\n"); getchar(); return 0; }