main(int argc, char **argv) { l_int32 w; PIX *pixs, *pixt, *pixd; PIXA *pixa; static char mainName[] = "smoothedge_reg"; pixs = pixRead("raggededge.png"); w = pixGetWidth(pixs); pixa = pixaCreate(0); PixAddEdgeData(pixa, pixs, L_FROM_RIGHT, MIN_JUMP, MIN_REVERSAL); PixAddEdgeData(pixa, pixs, L_FROM_LEFT, MIN_JUMP, MIN_REVERSAL); pixt = pixRotateOrth(pixs, 1); PixAddEdgeData(pixa, pixt, L_FROM_BOTTOM, MIN_JUMP, MIN_REVERSAL); PixAddEdgeData(pixa, pixt, L_FROM_TOP, MIN_JUMP, MIN_REVERSAL); pixDestroy(&pixt); pixt = pixRotateOrth(pixs, 2); PixAddEdgeData(pixa, pixt, L_FROM_LEFT, MIN_JUMP, MIN_REVERSAL); PixAddEdgeData(pixa, pixt, L_FROM_RIGHT, MIN_JUMP, MIN_REVERSAL); pixDestroy(&pixt); pixt = pixRotateOrth(pixs, 3); PixAddEdgeData(pixa, pixt, L_FROM_TOP, MIN_JUMP, MIN_REVERSAL); PixAddEdgeData(pixa, pixt, L_FROM_BOTTOM, MIN_JUMP, MIN_REVERSAL); pixDestroy(&pixt); pixDestroy(&pixs); /* Display at 2x scaling */ pixd = pixaDisplayTiledAndScaled(pixa, 32, 2 * (w + 10), 2, 0, 25, 2); pixWrite("/tmp/junkpixd.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); return 0; }
void AddTransformsYUV(PIXA *pixa, L_BMF *bmf, l_int32 yval) { char textbuf[256]; l_int32 i, j, wpls; l_uint32 *datas, *lines; PIX *pixs, *pixt1, *pixt2, *pixt3, *pixt4; PIXA *pixat; pixs = pixCreate(225, 225, 32); wpls = pixGetWpl(pixs); datas = pixGetData(pixs); for (i = 0; i < 225; i++) { /* v */ lines = datas + i * wpls; for (j = 0; j < 225; j++) /* u */ composeRGBPixel(yval + 16, j + 16, i + 16, lines + j); } pixat = pixaCreate(3); pixaAddPix(pixat, pixs, L_INSERT); pixt1 = pixConvertYUVToRGB(NULL, pixs); pixaAddPix(pixat, pixt1, L_INSERT); pixt2 = pixConvertRGBToYUV(NULL, pixt1); pixaAddPix(pixat, pixt2, L_INSERT); pixt3 = pixaDisplayTiledAndScaled(pixat, 32, 225, 3, 0, 20, 2); snprintf(textbuf, sizeof(textbuf), "yval = %d", yval); pixt4 = pixAddSingleTextblock(pixt3, bmf, textbuf, 0xff000000, L_ADD_BELOW, NULL); pixaAddPix(pixa, pixt4, L_INSERT); pixDestroy(&pixt3); pixaDestroy(&pixat); 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); }
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) { char *dirin, *substr, *fileout; l_int32 depth, width, ncols; PIX *pixd; PIXA *pixa; static char mainName[] = "scaleandtile"; if (argc != 7) return ERROR_INT( "Syntax: scaleandtile dirin substr depth width ncols fileout", mainName, 1); dirin = argv[1]; substr = argv[2]; depth = atoi(argv[3]); width = atoi(argv[4]); ncols = atoi(argv[5]); fileout = argv[6]; /* Read the specified images from file */ if ((pixa = pixaReadFiles(dirin, substr)) == NULL) return ERROR_INT("safiles not made", mainName, 1); fprintf(stderr, "Number of pix: %d\n", pixaGetCount(pixa)); /* Tile them */ pixd = pixaDisplayTiledAndScaled(pixa, depth, width, ncols, BACKGROUND_COLOR, SPACING, BLACK_BORDER); if (depth < 8) pixWrite(fileout, pixd, IFF_PNG); else pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixd); return 0; }
/*! * pixaaDisplayTiledAndScaled() * * Input: pixaa * outdepth (output depth: 1, 8 or 32 bpp) * tilewidth (each pix is scaled to this width) * ncols (number of tiles in each row) * background (0 for white, 1 for black; this is the color * of the spacing between the images) * spacing (between images, and on outside) * border (width of additional black border on each image; * use 0 for no border) * Return: pixa (of tiled images, one image for each pixa in * the pixaa), or null on error * * Notes: * (1) For each pixa, this generates from all the pix a * tiled/scaled output pix, and puts it in the output pixa. * (2) See comments in pixaDisplayTiledAndScaled(). */ PIXA * pixaaDisplayTiledAndScaled(PIXAA *pixaa, l_int32 outdepth, l_int32 tilewidth, l_int32 ncols, l_int32 background, l_int32 spacing, l_int32 border) { l_int32 i, n; PIX *pix; PIXA *pixa, *pixad; PROCNAME("pixaaDisplayTiledAndScaled"); if (!pixaa) return (PIXA *)ERROR_PTR("pixaa not defined", procName, NULL); if (outdepth != 1 && outdepth != 8 && outdepth != 32) return (PIXA *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL); if (border < 0 || border > tilewidth / 5) border = 0; if ((n = pixaaGetCount(pixaa)) == 0) return (PIXA *)ERROR_PTR("no components", procName, NULL); pixad = pixaCreate(n); for (i = 0; i < n; i++) { pixa = pixaaGetPixa(pixaa, i, L_CLONE); pix = pixaDisplayTiledAndScaled(pixa, outdepth, tilewidth, ncols, background, spacing, border); pixaAddPix(pixad, pix, L_INSERT); pixaDestroy(&pixa); } return pixad; }
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; }
main(int argc, char **argv) { l_int32 i, j, x, y, rval, gval, bval; l_uint32 pixel; l_float32 frval, fgval, fbval; NUMA *nahue, *nasat, *napk; PIX *pixs, *pixhsv, *pixh, *pixg, *pixf, *pixd; PIX *pixr, *pixt1, *pixt2, *pixt3; PIXA *pixa, *pixapk; PTA *ptapk; L_REGPARAMS *rp; l_chooseDisplayProg(L_DISPLAY_WITH_XV); if (regTestSetup(argc, argv, &rp)) return 1; /* Make a graded frame color */ pixs = pixCreate(650, 900, 32); for (i = 0; i < 900; i++) { rval = 40 + i / 30; for (j = 0; j < 650; j++) { gval = 255 - j / 30; bval = 70 + j / 30; composeRGBPixel(rval, gval, bval, &pixel); pixSetPixel(pixs, j, i, pixel); } } /* Place an image inside the frame and convert to HSV */ pixt1 = pixRead("1555-3.jpg"); pixt2 = pixScale(pixt1, 0.5, 0.5); pixRasterop(pixs, 100, 100, 2000, 2000, PIX_SRC, pixt2, 0, 0); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDisplayWithTitle(pixs, 400, 0, "Input image", rp->display); pixa = pixaCreate(0); pixhsv = pixConvertRGBToHSV(NULL, pixs); /* Work in the HS projection of HSV */ pixh = pixMakeHistoHS(pixhsv, 5, &nahue, &nasat); pixg = pixMaxDynamicRange(pixh, L_LOG_SCALE); pixf = pixConvertGrayToFalseColor(pixg, 1.0); regTestWritePixAndCheck(rp, pixf, IFF_PNG); /* 0 */ pixDisplayWithTitle(pixf, 100, 0, "False color HS histo", rp->display); pixaAddPix(pixa, pixs, L_COPY); pixaAddPix(pixa, pixhsv, L_INSERT); pixaAddPix(pixa, pixg, L_INSERT); pixaAddPix(pixa, pixf, L_INSERT); gplotSimple1(nahue, GPLOT_PNG, "/tmp/junkhue", "Histogram of hue values"); #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ pixt3 = pixRead("/tmp/junkhue.png"); regTestWritePixAndCheck(rp, pixt3, IFF_PNG); /* 1 */ pixDisplayWithTitle(pixt3, 100, 300, "Histo of hue", rp->display); pixaAddPix(pixa, pixt3, L_INSERT); gplotSimple1(nasat, GPLOT_PNG, "/tmp/junksat", "Histogram of saturation values"); #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ pixt3 = pixRead("/tmp/junksat.png"); regTestWritePixAndCheck(rp, pixt3, IFF_PNG); /* 2 */ pixDisplayWithTitle(pixt3, 100, 800, "Histo of saturation", rp->display); pixaAddPix(pixa, pixt3, L_INSERT); pixd = pixaDisplayTiledAndScaled(pixa, 32, 270, 7, 0, 30, 3); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 3 */ pixDisplayWithTitle(pixd, 0, 400, "Hue and Saturation Mosaic", rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); numaDestroy(&nahue); numaDestroy(&nasat); /* Find all the peaks */ pixFindHistoPeaksHSV(pixh, L_HS_HISTO, 20, 20, 6, 2.0, &ptapk, &napk, &pixapk); numaWriteStream(stderr, napk); ptaWriteStream(stderr, ptapk, 1); pixd = pixaDisplayTiledInRows(pixapk, 32, 1400, 1.0, 0, 30, 2); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 4 */ pixDisplayWithTitle(pixd, 0, 550, "Peaks in HS", rp->display); pixDestroy(&pixh); pixDestroy(&pixd); pixaDestroy(&pixapk); /* Make masks for each of the peaks */ pixa = pixaCreate(0); pixr = pixScaleBySampling(pixs, 0.4, 0.4); for (i = 0; i < 6; i++) { ptaGetIPt(ptapk, i, &x, &y); pixt1 = pixMakeRangeMaskHS(pixr, y, 20, x, 20, L_INCLUDE_REGION); pixaAddPix(pixa, pixt1, L_INSERT); pixGetAverageMaskedRGB(pixr, pixt1, 0, 0, 1, L_MEAN_ABSVAL, &frval, &fgval, &fbval); composeRGBPixel((l_int32)frval, (l_int32)fgval, (l_int32)fbval, &pixel); pixt2 = pixCreateTemplate(pixr); pixSetAll(pixt2); pixPaintThroughMask(pixt2, pixt1, 0, 0, pixel); pixaAddPix(pixa, pixt2, L_INSERT); pixt3 = pixCreateTemplate(pixr); pixSetAllArbitrary(pixt3, pixel); pixaAddPix(pixa, pixt3, L_INSERT); } pixd = pixaDisplayTiledAndScaled(pixa, 32, 225, 3, 0, 30, 3); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 5 */ pixDisplayWithTitle(pixd, 600, 0, "Masks over peaks", rp->display); pixDestroy(&pixs); pixDestroy(&pixr); pixDestroy(&pixd); pixaDestroy(&pixa); ptaDestroy(&ptapk); numaDestroy(&napk); regTestCleanup(rp); return 0; }
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; /* for color content extraction */ PIXA *pixa, *pixat; PIXCMAP *cmap; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* Generate a pdf of results when called with display */ pixa = pixaCreate(0); /* Generate colors by sampling hue with max sat and value. * This image has been saved as 19-colors.png. */ pixat = 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(pixat, pixt1, L_INSERT); } pixt2 = pixaDisplayTiledInRows(pixat, 32, 1100, 1.0, 0, 0, 0); regTestWritePixAndCheck(rp, pixt2, IFF_PNG); /* 0 */ pixaAddPix(pixa, pixt2, L_INSERT); pixaDestroy(&pixat); /* Colorspace conversion in rgb */ pixs = pixRead("wyom.jpg"); pixaAddPix(pixa, pixs, L_INSERT); pixt = pixConvertRGBToHSV(NULL, pixs); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 1 */ pixaAddPix(pixa, pixt, L_COPY); pixConvertHSVToRGB(pixt, pixt); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 2 */ pixaAddPix(pixa, pixt, L_INSERT); /* Colorspace conversion on a colormap */ pixt = pixOctreeQuantNumColors(pixs, 25, 0); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 3 */ pixaAddPix(pixa, pixt, L_COPY); cmap = pixGetColormap(pixt); if (rp->display) pixcmapWriteStream(stderr, cmap); pixcmapConvertRGBToHSV(cmap); if (rp->display) pixcmapWriteStream(stderr, cmap); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 4 */ pixaAddPix(pixa, pixt, L_COPY); pixcmapConvertHSVToRGB(cmap); if (rp->display) pixcmapWriteStream(stderr, cmap); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); /* 5 */ pixaAddPix(pixa, pixt, L_INSERT); /* Color content extraction */ pixColorContent(pixs, 0, 0, 0, 0, &pixr, &pixg, &pixb); regTestWritePixAndCheck(rp, pixr, IFF_JFIF_JPEG); /* 6 */ pixaAddPix(pixa, pixr, L_INSERT); regTestWritePixAndCheck(rp, pixg, IFF_JFIF_JPEG); /* 7 */ pixaAddPix(pixa, pixg, L_INSERT); regTestWritePixAndCheck(rp, pixb, IFF_JFIF_JPEG); /* 8 */ pixaAddPix(pixa, pixb, L_INSERT); /* Color content measurement. This tests the global * mapping of (r,g,b) --> (white), for 20 different * values of (r,g,b). For each mappings, we compute * the color magnitude and threshold it at six values. * For each of those six thresholds, we plot the * fraction of pixels that exceeds the threshold * color magnitude, where the red value (mapped to * white) goes between 100 and 195. */ pixat = 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(pixat, 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/regout/colorspace.10", GPLOT_PNG, "Fraction with given color (diff from average)", "white point space for red", "amount of color"); gplot2 = gplotCreate("/tmp/regout/colorspace.11", GPLOT_PNG, "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(pixat, 32, 250, 4, 0, 10, 2); regTestWritePixAndCheck(rp, pixt1, IFF_JFIF_JPEG); /* 9 */ pixaAddPix(pixa, pixt1, L_INSERT); pixDisplayWithTitle(pixt1, 0, 100, "Color magnitude", rp->display); pixaDestroy(&pixat); numaDestroy(&naseq); numaaDestroy(&naa1); numaaDestroy(&naa2); /* Give gnuplot time to write out the files */ #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ /* Save as golden files, or check against them */ regTestCheckFile(rp, "/tmp/regout/colorspace.10.png"); /* 10 */ regTestCheckFile(rp, "/tmp/regout/colorspace.11.png"); /* 11 */ if (rp->display) { pixt = pixRead("/tmp/regout/colorspace.10.png"); pixaAddPix(pixa, pixt, L_INSERT); pixt = pixRead("/tmp/regout/colorspace.11.png"); pixaAddPix(pixa, pixt, L_INSERT); pixaConvertToPdf(pixa, 0, 1.0, 0, 0, "colorspace tests", "/tmp/regout/colorspace.pdf"); L_INFO("Output pdf: /tmp/regout/colorspace.pdf\n", rp->testname); } pixaDestroy(&pixa); return regTestCleanup(rp); }
/*! * dewarpShowResults() * * Input: dewa * sarray (of indexed input images) * boxa (crop boxes for input images; can be null) * firstpage, lastpage * fontdir (for text bitmap fonts) * pdfout (filename) * Return: 0 if OK, 1 on error * * Notes: * (1) This generates a pdf of image pairs (before, after) for * the designated set of input pages. * (2) If the boxa exists, its elements are aligned with numbers * in the filenames in @sa. It is used to crop the input images. * It is assumed that the dewa was generated from the cropped * images. No undercropping is applied before rendering. */ l_int32 dewarpShowResults(L_DEWARPA *dewa, SARRAY *sa, BOXA *boxa, l_int32 firstpage, l_int32 lastpage, const char *fontdir, const char *pdfout) { char bufstr[256]; char *outpath; l_int32 i, modelpage; L_BMF *bmf; BOX *box; L_DEWARP *dew; PIX *pixs, *pixc, *pixd, *pixt1, *pixt2; PIXA *pixa; PROCNAME("dewarpShowResults"); if (!dewa) return ERROR_INT("dewa not defined", procName, 1); if (!sa) return ERROR_INT("sa not defined", procName, 1); if (!pdfout) return ERROR_INT("pdfout not defined", procName, 1); if (firstpage > lastpage) return ERROR_INT("invalid first/last page numbers", procName, 1); lept_rmdir("dewarp_pdfout"); lept_mkdir("dewarp_pdfout"); if ((bmf = bmfCreate(fontdir, 6)) == NULL) L_ERROR("bmf not made; page info not displayed", procName); fprintf(stderr, "Dewarping and generating s/by/s view\n"); for (i = firstpage; i <= lastpage; i++) { if (i && (i % 10 == 0)) fprintf(stderr, ".. %d ", i); pixs = pixReadIndexed(sa, i); if (boxa) { box = boxaGetBox(boxa, i, L_CLONE); pixc = pixClipRectangle(pixs, box, NULL); boxDestroy(&box); } else pixc = pixClone(pixs); dew = dewarpaGetDewarp(dewa, i); pixd = NULL; if (dew) { dewarpaApplyDisparity(dewa, dew->pageno, pixc, GRAYIN_VALUE, 0, 0, &pixd, NULL); dewarpMinimize(dew); } pixa = pixaCreate(2); pixaAddPix(pixa, pixc, L_INSERT); if (pixd) pixaAddPix(pixa, pixd, L_INSERT); pixt1 = pixaDisplayTiledAndScaled(pixa, 32, 500, 2, 0, 35, 2); if (dew) { modelpage = (dew->hasref) ? dew->refpage : dew->pageno; snprintf(bufstr, sizeof(bufstr), "Page %d; using %d\n", i, modelpage); } else snprintf(bufstr, sizeof(bufstr), "Page %d; no dewarp\n", i); pixt2 = pixAddSingleTextblock(pixt1, bmf, bufstr, 0x0000ff00, L_ADD_BELOW, 0); snprintf(bufstr, sizeof(bufstr), "/tmp/dewarp_pdfout/%05d", i); pixWrite(bufstr, pixt2, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixs); pixDestroy(&pixt1); pixDestroy(&pixt2); } fprintf(stderr, "\n"); fprintf(stderr, "Generating pdf of result\n"); convertFilesToPdf("/tmp/dewarp_pdfout", NULL, 100, 1.0, L_JPEG_ENCODE, 0, "Dewarp sequence", pdfout); outpath = genPathname(pdfout, NULL); fprintf(stderr, "Output written to: %s\n", outpath); FREE(outpath); bmfDestroy(&bmf); 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) { 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; }
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) { 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) { char textstr[256]; l_int32 w, h, d, i; l_uint32 srcval, dstval; l_float32 scalefact, sat, fract; L_BMF *bmf8; L_KERNEL *kel; NUMA *na; PIX *pix, *pixs, *pixs1, *pixs2, *pixd; PIX *pixt0, *pixt1, *pixt2, *pixt3, *pixt4; PIXA *pixa, *pixaf; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; pix = pixRead(filein); pixGetDimensions(pix, &w, &h, &d); if (d != 32) return ERROR_INT("file not 32 bpp", argv[0], 1); scalefact = (l_float32)WIDTH / (l_float32)w; pixs = pixScale(pix, scalefact, scalefact); w = pixGetWidth(pixs); pixaf = pixaCreate(5); /* TRC: vary gamma */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixGammaTRC(NULL, pixs, 0.3 + 0.15 * i, 0, 255); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 32); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 0 */ pixDisplayWithTitle(pixt1, 0, 100, "TRC Gamma", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* TRC: vary black point */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixGammaTRC(NULL, pixs, 1.0, 5 * i, 255); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 1 */ pixDisplayWithTitle(pixt1, 300, 100, "TRC", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Vary hue */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixModifyHue(NULL, pixs, 0.01 + 0.05 * i); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 2 */ pixDisplayWithTitle(pixt1, 600, 100, "Hue", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Vary saturation */ pixa = pixaCreate(20); na = numaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixModifySaturation(NULL, pixs, -0.9 + 0.1 * i); pixMeasureSaturation(pixt0, 1, &sat); pixaAddPix(pixa, pixt0, L_INSERT); numaAddNumber(na, sat); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); gplotSimple1(na, GPLOT_PNG, "/tmp/regout/enhance.7", "Average Saturation"); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 3 */ pixDisplayWithTitle(pixt1, 900, 100, "Saturation", rp->display); numaDestroy(&na); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Vary contrast */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixContrastTRC(NULL, pixs, 0.1 * i); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 4 */ pixDisplayWithTitle(pixt1, 0, 400, "Contrast", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Vary sharpening */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixUnsharpMasking(pixs, 3, 0.01 + 0.15 * i); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 5 */ pixDisplayWithTitle(pixt1, 300, 400, "Sharp", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Hue constant mapping to lighter background */ pixa = pixaCreate(11); bmf8 = bmfCreate("fonts", 8); pixt0 = pixRead("candelabrum-11.jpg"); composeRGBPixel(230, 185, 144, &srcval); /* select typical bg pixel */ for (i = 0; i <= 10; i++) { fract = 0.10 * i; pixelFractionalShift(230, 185, 144, fract, &dstval); pixt1 = pixLinearMapToTargetColor(NULL, pixt0, srcval, dstval); snprintf(textstr, 50, "Fract = %5.1f", fract); pixt2 = pixAddSingleTextblock(pixt1, bmf8, textstr, 0xff000000, L_ADD_BELOW, NULL); pixSaveTiledOutline(pixt2, pixa, 1.0, (i % 4 == 0) ? 1 : 0, 30, 2, 32); pixDestroy(&pixt1); pixDestroy(&pixt2); } pixDestroy(&pixt0); pixd = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 6 */ pixDisplayWithTitle(pixd, 600, 400, "Constant hue", rp->display); bmfDestroy(&bmf8); pixaDestroy(&pixa); pixDestroy(&pixd); /* Delayed testing of saturation plot */ regTestCheckFile(rp, "/tmp/regout/enhance.7.png"); /* 7 */ /* Display results */ pixd = pixaDisplay(pixaf, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 8 */ pixDisplayWithTitle(pixd, 100, 100, "All", rp->display); pixDestroy(&pixd); pixaDestroy(&pixaf); pixDestroy(&pix); pixDestroy(&pixs); /* -----------------------------------------------* * Test global color transforms * * -----------------------------------------------*/ /* Make identical cmap and rgb images */ pix = pixRead("wet-day.jpg"); pixs1 = pixOctreeColorQuant(pix, 200, 0); pixs2 = pixRemoveColormap(pixs1, REMOVE_CMAP_TO_FULL_COLOR); regTestComparePix(rp, pixs1, pixs2); /* 9 */ /* Make a diagonal color transform matrix */ kel = kernelCreate(3, 3); kernelSetElement(kel, 0, 0, 0.7); kernelSetElement(kel, 1, 1, 0.4); kernelSetElement(kel, 2, 2, 1.3); /* Apply to both cmap and rgb images. */ pixt1 = pixMultMatrixColor(pixs1, kel); pixt2 = pixMultMatrixColor(pixs2, kel); regTestComparePix(rp, pixt1, pixt2); /* 10 */ kernelDestroy(&kel); /* Apply the same transform in the simpler interface */ pixt3 = pixMultConstantColor(pixs1, 0.7, 0.4, 1.3); pixt4 = pixMultConstantColor(pixs2, 0.7, 0.4, 1.3); regTestComparePix(rp, pixt3, pixt4); /* 11 */ regTestComparePix(rp, pixt1, pixt3); /* 12 */ regTestWritePixAndCheck(rp, pixt1, IFF_JFIF_JPEG); /* 13 */ pixDestroy(&pix); pixDestroy(&pixs1); pixDestroy(&pixs2); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); return regTestCleanup(rp); }
Pix* pixaDisplayDefault(Pixa* pixa){ return pixaDisplayTiledAndScaled(pixa, 32, 2048, pixaGetCount(pixa), 0, 25, 2); }
l_int32 GeneratePattern(l_int32 patno, l_int32 red, L_REGPARAMS *rp) { l_int32 width, cx, cy; PIX *pixs, *pixt, *pix, *pixr, *pixp, *pixsel, *pixhmt; PIX *pixc1, *pixc2, *pixc3, *pixd; PIXA *pixa; SEL *selhm; PROCNAME("GeneratePattern"); if ((pixs = pixRead(patname[patno])) == NULL) { rp->success = FALSE; return ERROR_INT("pixs not made", procName, 1); } /* Make a hit-miss sel at specified reduction factor */ if (red == 4) { pixt = pixReduceRankBinaryCascade(pixs, 4, 4, 0, 0); selhm = pixGenerateSelBoundary(pixt, 2, 2, 20, 30, 1, 1, 0, 0, &pixp); } else if (red == 8) { pixt = pixReduceRankBinaryCascade(pixs, 4, 4, 2, 0); selhm = pixGenerateSelBoundary(pixt, 1, 2, 6, 12, 1, 1, 0, 0, &pixp); } else { /* red == 16 */ pixt = pixReduceRankBinaryCascade(pixs, 4, 4, 2, 2); selhm = pixGenerateSelBoundary(pixt, 1, 1, 4, 8, 0, 0, 0, 0, &pixp); } pixDestroy(&pixt); /* Display the sel */ pixsel = pixDisplayHitMissSel(pixp, selhm, 7, HitColor, MissColor); pixa = pixaCreate(2); pixaAddPix(pixa, pixs, L_CLONE); pixaAddPix(pixa, pixsel, L_CLONE); width = (patno == 0) ? 1200 : 400; pixd = pixaDisplayTiledAndScaled(pixa, 32, width, 2, 0, 30, 2); regTestWritePixAndCheck(rp, pixd, IFF_PNG); pixDisplayWithTitle(pixd, 100, 100 + 100 * (3 * patno + red / 4), NULL, rp->display); pixaDestroy(&pixa); pixDestroy(&pixd); /* Use the sel to find all instances in the page */ pix = pixRead("tribune-page-4x.png"); /* 4x reduced */ if (red == 4) pixr = pixClone(pix); else if (red == 8) pixr = pixReduceRankBinaryCascade(pix, 2, 0, 0, 0); else if (red == 16) pixr = pixReduceRankBinaryCascade(pix, 2, 2, 0, 0); pixDestroy(&pix); startTimer(); pixhmt = pixHMT(NULL, pixr, selhm); fprintf(stderr, "Time to find patterns = %7.3f\n", stopTimer()); /* Color each instance at full res */ selGetParameters(selhm, NULL, NULL, &cy, &cx); pixc1 = pixDisplayMatchedPattern(pixr, pixp, pixhmt, cx, cy, 0x0000ff00, 1.0, 5); regTestWritePixAndCheck(rp, pixc1, IFF_PNG); pixDisplayWithTitle(pixc1, 500, 100, NULL, rp->display); /* Color each instance at 0.5 scale */ pixc2 = pixDisplayMatchedPattern(pixr, pixp, pixhmt, cx, cy, 0x0000ff00, 0.5, 5); regTestWritePixAndCheck(rp, pixc2, IFF_PNG); /* Remove each instance from the input image */ pixc3 = pixCopy(NULL, pixr); pixRemoveMatchedPattern(pixc3, pixp, pixhmt, cx, cy, 1); regTestWritePixAndCheck(rp, pixc3, IFF_PNG); selDestroy(&selhm); pixDestroy(&pixp); pixDestroy(&pixsel); pixDestroy(&pixhmt); pixDestroy(&pixc1); pixDestroy(&pixc2); pixDestroy(&pixc3); pixDestroy(&pixd); pixDestroy(&pixr); pixDestroy(&pixs); return 0; }
int main(int argc, char **argv) { l_uint8 *data1, *data2; l_int32 i, n; size_t size1, size2; BOX *box; PIX *pix, *pix1, *pix2, *pix3; PIXA *pixa, *pixa1; PIXC *pixc, *pixc1, *pixc2; PIXAC *pixac, *pixac1, *pixac2; L_REGPARAMS *rp; SARRAY *sa; if (regTestSetup(argc, argv, &rp)) return 1; lept_mkdir("lept/comp"); pixac = pixacompCreate(1); pixa = pixaCreate(0); /* --- Read in the images --- */ pix1 = pixRead("marge.jpg"); pixc1 = pixcompCreateFromPix(pix1, IFF_JFIF_JPEG); pix2 = pixCreateFromPixcomp(pixc1); pixc2 = pixcompCreateFromPix(pix2, IFF_JFIF_JPEG); pix3 = pixCreateFromPixcomp(pixc2); regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG); /* 0 */ pixSaveTiledOutline(pix3, pixa, 1.0, 1, 30, 2, 32); pixacompAddPix(pixac, pix1, IFF_DEFAULT); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixcompDestroy(&pixc1); pixcompDestroy(&pixc2); pix = pixRead("feyn.tif"); pix1 = pixScaleToGray6(pix); pixc1 = pixcompCreateFromPix(pix1, IFF_JFIF_JPEG); pix2 = pixCreateFromPixcomp(pixc1); pixc2 = pixcompCreateFromPix(pix2, IFF_JFIF_JPEG); pix3 = pixCreateFromPixcomp(pixc2); regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG); /* 1 */ pixSaveTiledOutline(pix3, pixa, 1.0, 1, 30, 2, 32); pixacompAddPix(pixac, pix1, IFF_DEFAULT); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixcompDestroy(&pixc1); pixcompDestroy(&pixc2); box = boxCreate(1144, 611, 690, 180); pix1 = pixClipRectangle(pix, box, NULL); pixc1 = pixcompCreateFromPix(pix1, IFF_TIFF_G4); pix2 = pixCreateFromPixcomp(pixc1); pixc2 = pixcompCreateFromPix(pix2, IFF_TIFF_G4); pix3 = pixCreateFromPixcomp(pixc2); regTestWritePixAndCheck(rp, pix3, IFF_TIFF_G4); /* 2 */ pixSaveTiledOutline(pix3, pixa, 1.0, 0, 30, 2, 32); pixacompAddPix(pixac, pix1, IFF_DEFAULT); boxDestroy(&box); pixDestroy(&pix); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixcompDestroy(&pixc1); pixcompDestroy(&pixc2); pix1 = pixRead("weasel4.11c.png"); pixc1 = pixcompCreateFromPix(pix1, IFF_PNG); pix2 = pixCreateFromPixcomp(pixc1); pixc2 = pixcompCreateFromPix(pix2, IFF_PNG); pix3 = pixCreateFromPixcomp(pixc2); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 3 */ pixSaveTiledOutline(pix3, pixa, 1.0, 0, 30, 2, 32); pixacompAddPix(pixac, pix1, IFF_DEFAULT); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixcompDestroy(&pixc1); pixcompDestroy(&pixc2); /* --- Extract formatting info from compressed strings --- */ for (i = 0; i < 4; i++) { pixc = pixacompGetPixcomp(pixac, i, L_NOCOPY); get_format_data(i, pixc->data, pixc->size); } /* Save a tiled composite from the pixa */ pix1 = pixaDisplayTiledAndScaled(pixa, 32, 400, 4, 0, 20, 2); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 4 */ pixDestroy(&pix1); /* Convert the pixac --> pixa and save a tiled composite */ pixa1 = pixaCreateFromPixacomp(pixac, L_COPY); pix1 = pixaDisplayTiledAndScaled(pixa1, 32, 400, 4, 0, 20, 2); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 5 */ pixaDestroy(&pixa1); pixDestroy(&pix1); /* Make a pixacomp from files, and join */ sa = sarrayCreate(0); for (i = 0; i < 6; i++) sarrayAddString(sa, (char *)fnames[i], L_COPY); pixac1 = pixacompCreateFromSA(sa, IFF_DEFAULT); pixacompJoin(pixac1, pixac, 0, -1); pixa1 = pixaCreateFromPixacomp(pixac1, L_COPY); pix1 = pixaDisplayTiledAndScaled(pixa1, 32, 250, 10, 0, 20, 2); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 6 */ pixacompDestroy(&pixac1); pixaDestroy(&pixa1); pixDestroy(&pix1); sarrayDestroy(&sa); /* Test serialized I/O */ pixacompWrite("/tmp/lept/comp/file1.pac", pixac); regTestCheckFile(rp, "/tmp/lept/comp/file1.pac"); /* 7 */ pixac1 = pixacompRead("/tmp/lept/comp/file1.pac"); pixacompWrite("/tmp/lept/comp/file2.pac", pixac1); regTestCheckFile(rp, "/tmp/lept/comp/file2.pac"); /* 8 */ regTestCompareFiles(rp, 7, 8); /* 9 */ pixac2 = pixacompRead("/tmp/lept/comp/file2.pac"); pixa1 = pixaCreateFromPixacomp(pixac2, L_COPY); pix1 = pixaDisplayTiledAndScaled(pixa1, 32, 250, 4, 0, 20, 2); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 10 */ pixacompDestroy(&pixac1); pixacompDestroy(&pixac2); pixaDestroy(&pixa1); pixDestroy(&pix1); /* Test serialized pixacomp I/O to and from memory */ pixacompWriteMem(&data1, &size1, pixac); pixac1 = pixacompReadMem(data1, size1); pixacompWriteMem(&data2, &size2, pixac1); pixac2 = pixacompReadMem(data2, size2); pixacompWrite("/tmp/lept/comp/file3.pac", pixac1); regTestCheckFile(rp, "/tmp/lept/comp/file3.pac"); /* 11 */ pixacompWrite("/tmp/lept/comp/file4.pac", pixac2); regTestCheckFile(rp, "/tmp/lept/comp/file4.pac"); /* 12 */ regTestCompareFiles(rp, 11, 12); /* 13 */ pixacompDestroy(&pixac1); pixacompDestroy(&pixac2); lept_free(data1); lept_free(data2); pixaDestroy(&pixa); pixacompDestroy(&pixac); return regTestCleanup(rp); }
int main(int argc, char **argv) { l_int32 success; PIX *pix; PIXA *pixa; 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; /* Set up for display output */ pixa = (rp->display) ? pixaCreate(0) : NULL; lept_rmdir("lept/gif"); lept_mkdir("lept/gif"); /* ------------ Part 1: Test lossless r/w to file ------------*/ test_gif(FILE_1BPP, pixa, rp); test_gif(FILE_2BPP, pixa, rp); test_gif(FILE_4BPP, pixa, rp); test_gif(FILE_8BPP_1, pixa, rp); test_gif(FILE_8BPP_2, pixa, rp); test_gif(FILE_8BPP_3, pixa, rp); test_gif(FILE_16BPP, pixa, rp); test_gif(FILE_32BPP, pixa, 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) { pix = pixaDisplayTiledAndScaled(pixa, 32, 450, 3, 0, 20, 2); pixWrite("/tmp/lept/gif/giftest.jpg", pix, IFF_JFIF_JPEG); pixDisplay(pix, 100, 100); pixDestroy(&pix); pixaDestroy(&pixa); } /* ------------ Part 2: Test lossless r/w to memory ------------ */ success = TRUE; 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"); } /* Success only if all tests are passed */ if (rp->success == TRUE) rp->success = success; 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; }
main(int argc, char **argv) { l_int32 ws, hs; BOX *box; BOXA *boxa; PIX *pixs, *pixc, *pix32, *pixt, *pixd; PIXA *pixat, *pixas, *pixac; static char mainName[] = "pixadisp_reg"; if (argc != 1) exit(ERROR_INT(" Syntax: pixadisp_reg", mainName, 1)); if ((pixs = pixRead("feyn.tif")) == NULL) exit(ERROR_INT("pixs not made", mainName, 1)); box = boxCreate(683, 799, 970, 479); pixc = pixClipRectangle(pixs, box, NULL); boxDestroy(&box); pixDisplayWrite(pixc, 1); if ((pix32 = pixRead("marge.jpg")) == NULL) exit(ERROR_INT("pix32 not made", mainName, 1)); /* Generate pixas from pixs and pixac from pixc */ boxa = pixConnComp(pixs, &pixat, 8); pixas = pixaSelectBySize(pixat, 60, 60, L_SELECT_IF_BOTH, L_SELECT_IF_LTE, NULL); pixaDestroy(&pixat); boxaDestroy(&boxa); boxa = pixConnComp(pixc, &pixac, 8); boxaDestroy(&boxa); /* pixaDisplay() */ pixGetDimensions(pixs, &ws, &hs, NULL); pixd = pixaDisplay(pixas, ws, hs); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); /* pixaDisplayRandomCmap() */ pixd = pixaDisplayRandomCmap(pixas, ws, hs); /* black bg */ pixDisplayWrite(pixd, 1); pixcmapResetColor(pixGetColormap(pixd), 0, 255, 255, 255); /* white bg */ pixDisplayWrite(pixd, 1); pixDestroy(&pixd); /* pixaDisplayOnLattice() */ pixd = pixaDisplayOnLattice(pixac, 50, 50); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); /* pixaDisplayUnsplit() */ pixat = pixaSplitPix(pix32, 5, 7, 10, 0x0000ff00); pixd = pixaDisplayUnsplit(pixat, 5, 7, 10, 0x00ff0000); pixDisplayWrite(pixd, 1); pixaDestroy(&pixat); pixDestroy(&pixd); /* pixaDisplayTiled() */ pixd = pixaDisplayTiled(pixac, 1000, 0, 10); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); /* pixaDisplayTiledInRows() */ pixd = pixaDisplayTiledInRows(pixac, 1, 1000, 1.0, 0, 10, 2); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); /* pixaDisplayTiledAndScaled() */ pixd = pixaDisplayTiledAndScaled(pixac, 1, 25, 20, 0, 5, 0); pixDisplayWrite(pixd, 1); pixDestroy(&pixd); pixat = pixaCreate(10); pixd = pixRankFilter(pix32, 8, 8, 0.5); pixaAddPix(pixat, pixd, L_INSERT); pixt = pixScale(pix32, 0.5, 0.5); pixd = pixRankFilter(pixt, 8, 8, 0.5); pixaAddPix(pixat, pixd, L_INSERT); pixDestroy(&pixt); pixt = pixScale(pix32, 0.25, 0.25); pixd = pixRankFilter(pixt, 8, 8, 0.5); pixaAddPix(pixat, pixd, L_INSERT); pixDestroy(&pixt); pixd = pixaDisplayTiledAndScaled(pixat, 32, 500, 1, 0, 25, 0); pixDisplayWrite(pixd, 1); pixaDestroy(&pixat); pixDestroy(&pixd); pixaDestroy(&pixas); pixaDestroy(&pixac); pixDestroy(&pixs); pixDestroy(&pixc); pixDestroy(&pix32); pixDisplayMultiple("/tmp/junk_write_display*"); return 0; }
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; }
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 *pixm1; /* image of closed textlines, 150 ppi */ PIX *pixm2; /* image of refined text line mask, 150 ppi */ PIX *pixm3; /* image of refined text line mask, 300 ppi */ PIX *pixb1; /* image of text block mask, 150 ppi */ PIX *pixb2; /* image of text block mask, 300 ppi */ PIX *pixnon; /* image of non-text or halftone, 150 ppi */ PIX *pix1, *pix2, *pix3, *pix4; 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); pixa = pixaCreate(0); lept_mkdir("lept/livre"); /* Reduce to 150 ppi */ pix1 = pixScaleToGray2(pixs); if (ws_flag || ht_flag || block_flag) pixaAddPix(pixa, pix1, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/orig.gray.150.png", pix1, IFF_PNG); pixDestroy(&pix1); pixr = pixReduceRankBinaryCascade(pixs, 1, 0, 0, 0); /* Get seed for halftone parts */ pix1 = pixReduceRankBinaryCascade(pixr, 4, 4, 3, 0); pix2 = pixOpenBrick(NULL, pix1, 5, 5); pixhs = pixExpandBinaryPower2(pix2, 8); if (ht_flag) pixaAddPix(pixa, pixhs, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/htseed.150.png", pixhs, IFF_PNG); pixDestroy(&pix1); pixDestroy(&pix2); /* Get mask for connected regions */ pixm = pixCloseSafeBrick(NULL, pixr, 4, 4); if (ht_flag) pixaAddPix(pixa, pixm, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/ccmask.150.png", pixm, IFF_PNG); /* Fill seed into mask to get halftone mask */ pixhm1 = pixSeedfillBinary(NULL, pixhs, pixm, 4); if (ht_flag) pixaAddPix(pixa, pixhm1, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/htmask.150.png", pixhm1, IFF_PNG); pixhm2 = pixExpandBinaryPower2(pixhm1, 2); /* Extract halftone stuff */ pixht = pixAnd(NULL, pixhm1, pixr); if (which == 1) pixWrite("/tmp/lept/livre/ht.150.png", pixht, IFF_PNG); /* Extract non-halftone stuff */ pixnht = pixXor(NULL, pixht, pixr); if (text_flag) pixaAddPix(pixa, pixnht, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/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 (ws_flag) pixaAddPix(pixa, pixi, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/invert.150.png", pixi, 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. */ pix1 = pixMorphCompSequence(pixi, "o80.60", 0); pix2 = pixSubtract(NULL, pixi, pix1); if (ws_flag) pixaAddPix(pixa, pix2, L_COPY); pixDestroy(&pix1); /* Identify vertical whitespace by opening inverted image */ pix3 = pixOpenBrick(NULL, pix2, 5, 1); /* removes thin vertical lines */ pixvws = pixOpenBrick(NULL, pix3, 1, 200); /* gets long vertical lines */ if (text_flag || ws_flag) pixaAddPix(pixa, pixvws, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/vertws.150.png", pixvws, IFF_PNG); pixDestroy(&pix2); pixDestroy(&pix3); /* Get proto (early processed) text line mask. */ /* First close the characters and words in the textlines */ pixm1 = pixCloseSafeBrick(NULL, pixnht, 30, 1); if (text_flag) pixaAddPix(pixa, pixm1, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/textmask1.150.png", pixm1, IFF_PNG); /* Next open back up the vertical whitespace corridors */ pixm2 = pixSubtract(NULL, pixm1, pixvws); if (which == 1) pixWrite("/tmp/lept/livre/textmask2.150.png", pixm2, IFF_PNG); /* Do a small opening to remove noise */ pixOpenBrick(pixm2, pixm2, 3, 3); if (text_flag) pixaAddPix(pixa, pixm2, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/textmask3.150.png", pixm2, IFF_PNG); pixm3 = pixExpandBinaryPower2(pixm2, 2); /* Join pixels vertically to make text block mask */ pixb1 = pixMorphSequence(pixm2, "c1.10 + o4.1", 0); if (block_flag) pixaAddPix(pixa, pixb1, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/textblock1.150.png", pixb1, 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 */ pix1 = pixMorphSequenceByComponent(pixb1, "c30.30 + d3.3", 8, 0, 0, NULL); pixCloseSafeBrick(pix1, pix1, 10, 1); if (block_flag) pixaAddPix(pixa, pix1, L_COPY); pix2 = pixSubtract(NULL, pix1, pixvws); pix3 = pixSelectBySize(pix2, 25, 5, 8, L_SELECT_IF_BOTH, L_SELECT_IF_GTE, NULL); if (block_flag) pixaAddPix(pixa, pix3, L_COPY); if (which == 1) pixWrite("/tmp/lept/livre/textblock2.150.png", pix3, IFF_PNG); pixb2 = pixExpandBinaryPower2(pix3, 2); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); /* Identify the outlines of each textblock */ ptaa = pixGetOuterBordersPtaa(pixb2); pix1 = pixRenderRandomCmapPtaa(pixb2, ptaa, 1, 8, 1); cmap = pixGetColormap(pix1); pixcmapResetColor(cmap, 0, 130, 130, 130); /* set interior to gray */ if (which == 1) pixWrite("/tmp/lept/livre/textblock3.300.png", pix1, IFF_PNG); pixDisplayWithTitle(pix1, 480, 360, "textblock mask with outlines", DFLAG); ptaaDestroy(&ptaa); pixDestroy(&pix1); /* Fill line mask (as seed) into the original */ pix1 = pixSeedfillBinary(NULL, pixm3, pixs, 8); pixOr(pixm3, pixm3, pix1); pixDestroy(&pix1); if (which == 1) pixWrite("/tmp/lept/livre/textmask.300.png", pixm3, IFF_PNG); pixDisplayWithTitle(pixm3, 480, 360, "textline mask 4", DFLAG); /* Fill halftone mask (as seed) into the original */ pix1 = pixSeedfillBinary(NULL, pixhm2, pixs, 8); pixOr(pixhm2, pixhm2, pix1); pixDestroy(&pix1); if (which == 1) pixWrite("/tmp/lept/livre/htmask.300.png", pixhm2, IFF_PNG); pixDisplayWithTitle(pixhm2, 520, 390, "halftonemask 2", DFLAG); /* Find objects that are neither text nor halftones */ pix1 = pixSubtract(NULL, pixs, pixm3); /* remove text pixels */ pixnon = pixSubtract(NULL, pix1, pixhm2); /* remove halftone pixels */ pixDestroy(&pix1); if (which == 1) pixWrite("/tmp/lept/livre/other.300.png", pixnon, IFF_PNG); pixDisplayWithTitle(pixnon, 540, 420, "other stuff", DFLAG); /* Write out b.b. for text line mask and halftone mask components */ boxatm = pixConnComp(pixm3, NULL, 4); boxahm = pixConnComp(pixhm2, NULL, 8); if (which == 1) { boxaWrite("/tmp/lept/livre/textmask.boxa", boxatm); boxaWrite("/tmp/lept/livre/htmask.boxa", boxahm); } pix1 = pixaDisplayTiledAndScaled(pixa, 8, 250, 4, 0, 25, 2); pixDisplay(pix1, 0, 375 * (which - 1)); snprintf(buf, sizeof(buf), "/tmp/lept/livre/segout.%d.png", which); pixWrite(buf, pix1, IFF_PNG); pixDestroy(&pix1); pixaDestroy(&pixa); /* clean up to test with valgrind */ pixDestroy(&pixr); pixDestroy(&pixhs); pixDestroy(&pixm); pixDestroy(&pixhm1); pixDestroy(&pixhm2); pixDestroy(&pixht); pixDestroy(&pixi); pixDestroy(&pixnht); pixDestroy(&pixvws); pixDestroy(&pixm1); pixDestroy(&pixm2); pixDestroy(&pixm3); pixDestroy(&pixb1); pixDestroy(&pixb2); pixDestroy(&pixnon); boxaDestroy(&boxatm); boxaDestroy(&boxahm); return 0; }
/*! * selaAddTJunctions() * * Input: sela (<optional>) * hlsize (length of each line of hits from origin) * mdist (distance of misses from the origin) * norient (number of orientations; max of 8) * debugflag (1 for debug output) * Return: sela with additional sels, or null on error * * Notes: * (1) Adds hitmiss Sels for the T-junction of two lines. * If the lines are very thin, they must be nearly orthogonal * to register. * (2) The number of Sels generated is 4 * @norient. * (3) It is suggested that @hlsize be chosen at least 1 greater * than @mdist. Try values of (@hlsize, @mdist) such as * (6,5), (7,6), (8,7), (9,7), etc. */ SELA * selaAddTJunctions(SELA *sela, l_float32 hlsize, l_float32 mdist, l_int32 norient, l_int32 debugflag) { char name[L_BUF_SIZE]; l_int32 i, j, k, w, xc, yc; l_float64 pi, halfpi, radincr, jang, radang; l_float64 angle[3], dist[3]; PIX *pixc, *pixm, *pixt; PIXA *pixa; PTA *pta1, *pta2, *pta3; SEL *sel; PROCNAME("selaAddTJunctions"); if (hlsize <= 2) return (SELA *)ERROR_PTR("hlsizel not > 1", procName, NULL); if (norient < 1 || norient > 8) return (SELA *)ERROR_PTR("norient not in [1, ... 8]", procName, NULL); if (!sela) { if ((sela = selaCreate(0)) == NULL) return (SELA *)ERROR_PTR("sela not made", procName, NULL); } pi = 3.1415926535; halfpi = 3.1415926535 / 2.0; radincr = halfpi / (l_float32)norient; w = (l_int32)(2.4 * (L_MAX(hlsize, mdist) + 0.5)); if (w % 2 == 0) w++; xc = w / 2; yc = w / 2; pixa = pixaCreate(4 * norient); for (i = 0; i < norient; i++) { for (j = 0; j < 4; j++) { /* 4 orthogonal orientations */ jang = (l_float32)j * halfpi; /* Set the don't cares */ pixc = pixCreate(w, w, 32); pixSetAll(pixc); /* Add the green lines of hits */ pixm = pixCreate(w, w, 1); radang = (l_float32)i * radincr; pta1 = generatePtaLineFromPt(xc, yc, hlsize + 1, jang + radang); pta2 = generatePtaLineFromPt(xc, yc, hlsize + 1, jang + radang + halfpi); pta3 = generatePtaLineFromPt(xc, yc, hlsize + 1, jang + radang + pi); ptaJoin(pta1, pta2, 0, -1); ptaJoin(pta1, pta3, 0, -1); pixRenderPta(pixm, pta1, L_SET_PIXELS); pixPaintThroughMask(pixc, pixm, 0, 0, 0x00ff0000); ptaDestroy(&pta1); ptaDestroy(&pta2); ptaDestroy(&pta3); /* Add red misses between the lines */ angle[0] = radang + jang - halfpi; angle[1] = radang + jang + 0.5 * halfpi; angle[2] = radang + jang + 1.5 * halfpi; dist[0] = 0.8 * mdist; dist[1] = dist[2] = mdist; for (k = 0; k < 3; k++) { pixSetPixel(pixc, xc + (l_int32)(dist[k] * cos(angle[k])), yc + (l_int32)(dist[k] * sin(angle[k])), 0xff000000); } /* Add dark green for origin */ pixSetPixel(pixc, xc, yc, 0x00550000); /* Generate the sel */ sel = selCreateFromColorPix(pixc, NULL); sprintf(name, "sel_cross_%d", 4 * i + j); selaAddSel(sela, sel, name, 0); if (debugflag) { pixt = pixScaleBySampling(pixc, 10.0, 10.0); pixaAddPix(pixa, pixt, L_INSERT); } pixDestroy(&pixm); pixDestroy(&pixc); } } if (debugflag) { l_int32 w; pixaGetPixDimensions(pixa, 0, &w, NULL, NULL); pixt = pixaDisplayTiledAndScaled(pixa, 32, w, 4, 0, 10, 2); pixWriteTempfile("/tmp", "tsel1.png", pixt, IFF_PNG, 0); pixDisplay(pixt, 0, 100); pixDestroy(&pixt); pixt = selaDisplayInPix(sela, 15, 2, 20, 4); pixWriteTempfile("/tmp", "tsel2.png", pixt, IFF_PNG, 0); pixDisplay(pixt, 500, 100); pixDestroy(&pixt); selaWriteStream(stderr, sela); } pixaDestroy(&pixa); return sela; }
int main(int argc, char **argv) { char *filein, *fileout; l_int32 i, j, w, d, nhue, nsat, tilewidth; l_float32 scale, dhue, dsat, delhue, delsat; PIX *pixs, *pixt1, *pixt2, *pixd; PIXA *pixa; static char mainName[] = "modifyhuesat"; if (argc != 7) return ERROR_INT( " Syntax: modifyhuesat filein nhue dhue nsat dsat fileout", mainName, 1); filein = argv[1]; nhue = atoi(argv[2]); dhue = atof(argv[3]); nsat = atoi(argv[4]); dsat = atof(argv[5]); fileout = argv[6]; if (nhue % 2 == 0) { nhue++; fprintf(stderr, "nhue must be odd; raised to %d\n", nhue); } if (nsat % 2 == 0) { nsat++; fprintf(stderr, "nsat must be odd; raised to %d\n", nsat); } if ((pixt1 = pixRead(filein)) == NULL) return ERROR_INT("pixt1 not read", mainName, 1); pixGetDimensions(pixt1, &w, NULL, NULL); scale = 250.0 / (l_float32)w; pixt2 = pixScale(pixt1, scale, scale); pixs = pixConvertTo32(pixt2); pixDestroy(&pixt1); pixDestroy(&pixt2); pixGetDimensions(pixs, &w, NULL, &d); pixa = pixaCreate(nhue * nsat); for (i = 0; i < nsat; i++) { delsat = (i - nsat / 2) * dsat; pixt1 = pixModifySaturation(NULL, pixs, delsat); for (j = 0; j < nhue; j++) { delhue = (j - nhue / 2) * dhue; pixt2 = pixModifyHue(NULL, pixt1, delhue); pixaAddPix(pixa, pixt2, L_INSERT); } pixDestroy(&pixt1); } tilewidth = L_MIN(w, 1500 / nsat); pixd = pixaDisplayTiledAndScaled(pixa, d, tilewidth, nsat, 0, 25, 3); pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixs); pixDestroy(&pixd); pixaDestroy(&pixa); return 0; }
l_int32 main(int argc, char **argv) { l_int32 size, i, rval, gval, bval, yval, uval, vval; l_float32 *a[3], b[3]; L_BMF *bmf; PIX *pixd; PIXA *pixa; /* Explore the range of rgb --> yuv transforms. All rgb * values transform to a valid value of yuv, so when transforming * back we get the same rgb values that we started with. */ pixa = pixaCreate(0); bmf = bmfCreate("fonts", 6); for (gval = 0; gval <= 255; gval += 20) AddTransformsRGB(pixa, bmf, gval); pixd = pixaDisplayTiledAndScaled(pixa, 32, 755, 1, 0, 20, 2); pixDisplay(pixd, 100, 0); pixWrite("/tmp/yuv1.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); /* Now start with all "valid" yuv values, not all of which are * related to a valid rgb value. Our yuv --> rgb transform * clips the rgb components to [0 ... 255], so when transforming * back we get different values whenever the initial yuv * value is out of the rgb gamut. */ pixa = pixaCreate(0); for (yval = 16; yval <= 235; yval += 16) AddTransformsYUV(pixa, bmf, yval); pixd = pixaDisplayTiledAndScaled(pixa, 32, 755, 1, 0, 20, 2); pixDisplay(pixd, 600, 0); pixWrite("/tmp/yuv2.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); bmfDestroy(&bmf); /* --------- Try out a special case by hand, and show that --------- * * ------- the transform matrices we are using are inverses ---------*/ /* First, use our functions for the transform */ fprintf(stderr, "Start with: yval = 143, uval = 79, vval = 103\n"); convertYUVToRGB(143, 79, 103, &rval, &gval, &bval); fprintf(stderr, " ==> rval = %d, gval = %d, bval = %d\n", rval, gval, bval); convertRGBToYUV(rval, gval, bval, &yval, &uval, &vval); fprintf(stderr, " ==> yval = %d, uval = %d, vval = %d\n", yval, uval, vval); /* Next, convert yuv --> rbg by solving for rgb --> yuv transform. * [ a00 a01 a02 ] r = b0 (y - 16) * [ a10 a11 a12 ] * g = b1 (u - 128) * [ a20 a21 a22 ] b = b2 (v - 128) */ b[0] = 143.0 - 16.0; /* y - 16 */ b[1] = 79.0 - 128.0; /* u - 128 */ b[2] = 103.0 - 128.0; /* v - 128 */ for (i = 0; i < 3; i++) a[i] = (l_float32 *)lept_calloc(3, sizeof(l_float32)); a[0][0] = 65.738 / 256.0; a[0][1] = 129.057 / 256.0; a[0][2] = 25.064 / 256.0; a[1][0] = -37.945 / 256.0; a[1][1] = -74.494 / 256.0; a[1][2] = 112.439 / 256.0; a[2][0] = 112.439 / 256.0; a[2][1] = -94.154 / 256.0; a[2][2] = -18.285 / 256.0; fprintf(stderr, "Here's the original matrix: yuv --> rgb:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); gaussjordan(a, b, 3); fprintf(stderr, "\nInput (yuv) = (143,79,103); solve for rgb:\n" "rval = %7.3f, gval = %7.3f, bval = %7.3f\n", b[0], b[1], b[2]); fprintf(stderr, "Here's the inverse matrix: rgb --> yuv:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); /* Now, convert back: rgb --> yuv; * Do this by solving for yuv --> rgb transform. * Use the b[] found previously (the rgb values), and * the a[][] which now holds the rgb --> yuv transform. */ gaussjordan(a, b, 3); fprintf(stderr, "\nInput rgb; solve for yuv:\n" "yval = %7.3f, uval = %7.3f, vval = %7.3f\n", b[0] + 16.0, b[1] + 128.0, b[2] + 128.0); fprintf(stderr, "Inverting the matrix again: yuv --> rgb:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); for (i = 0; i < 3; i++) lept_free(a[i]); return 0; }
/*! * \brief selaAddCrossJunctions() * * \param[in] sela [optional] * \param[in] hlsize length of each line of hits from origin * \param[in] mdist distance of misses from the origin * \param[in] norient number of orientations; max of 8 * \param[in] debugflag 1 for debug output * \return sela with additional sels, or NULL on error * * <pre> * Notes: * (1) Adds hitmiss Sels for the intersection of two lines. * If the lines are very thin, they must be nearly orthogonal * to register. * (2) The number of Sels generated is equal to %norient. * (3) If %norient == 2, this generates 2 Sels of crosses, each with * two perpendicular lines of hits. One Sel has horizontal and * vertical hits; the other has hits along lines at +-45 degrees. * Likewise, if %norient == 3, this generates 3 Sels of crosses * oriented at 30 degrees with each other. * (4) It is suggested that %hlsize be chosen at least 1 greater * than %mdist. Try values of (%hlsize, %mdist) such as * (6,5), (7,6), (8,7), (9,7), etc. * </pre> */ SELA * selaAddCrossJunctions(SELA *sela, l_float32 hlsize, l_float32 mdist, l_int32 norient, l_int32 debugflag) { char name[L_BUF_SIZE]; l_int32 i, j, w, xc, yc; l_float64 pi, halfpi, radincr, radang; l_float64 angle; PIX *pixc, *pixm, *pixt; PIXA *pixa; PTA *pta1, *pta2, *pta3, *pta4; SEL *sel; PROCNAME("selaAddCrossJunctions"); if (hlsize <= 0) return (SELA *)ERROR_PTR("hlsize not > 0", procName, NULL); if (norient < 1 || norient > 8) return (SELA *)ERROR_PTR("norient not in [1, ... 8]", procName, NULL); if (!sela) { if ((sela = selaCreate(0)) == NULL) return (SELA *)ERROR_PTR("sela not made", procName, NULL); } pi = 3.1415926535; halfpi = 3.1415926535 / 2.0; radincr = halfpi / (l_float64)norient; w = (l_int32)(2.2 * (L_MAX(hlsize, mdist) + 0.5)); if (w % 2 == 0) w++; xc = w / 2; yc = w / 2; pixa = pixaCreate(norient); for (i = 0; i < norient; i++) { /* Set the don't cares */ pixc = pixCreate(w, w, 32); pixSetAll(pixc); /* Add the green lines of hits */ pixm = pixCreate(w, w, 1); radang = (l_float32)i * radincr; pta1 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang); pta2 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + halfpi); pta3 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + pi); pta4 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + pi + halfpi); ptaJoin(pta1, pta2, 0, -1); ptaJoin(pta1, pta3, 0, -1); ptaJoin(pta1, pta4, 0, -1); pixRenderPta(pixm, pta1, L_SET_PIXELS); pixPaintThroughMask(pixc, pixm, 0, 0, 0x00ff0000); ptaDestroy(&pta1); ptaDestroy(&pta2); ptaDestroy(&pta3); ptaDestroy(&pta4); /* Add red misses between the lines */ for (j = 0; j < 4; j++) { angle = radang + (j - 0.5) * halfpi; pixSetPixel(pixc, xc + (l_int32)(mdist * cos(angle)), yc + (l_int32)(mdist * sin(angle)), 0xff000000); } /* Add dark green for origin */ pixSetPixel(pixc, xc, yc, 0x00550000); /* Generate the sel */ sel = selCreateFromColorPix(pixc, NULL); sprintf(name, "sel_cross_%d", i); selaAddSel(sela, sel, name, 0); if (debugflag) { pixt = pixScaleBySampling(pixc, 10.0, 10.0); pixaAddPix(pixa, pixt, L_INSERT); } pixDestroy(&pixm); pixDestroy(&pixc); } if (debugflag) { l_int32 w; lept_mkdir("lept/sel"); pixaGetPixDimensions(pixa, 0, &w, NULL, NULL); pixt = pixaDisplayTiledAndScaled(pixa, 32, w, 1, 0, 10, 2); pixWrite("/tmp/lept/sel/xsel1.png", pixt, IFF_PNG); pixDisplay(pixt, 0, 100); pixDestroy(&pixt); pixt = selaDisplayInPix(sela, 15, 2, 20, 1); pixWrite("/tmp/lept/sel/xsel2.png", pixt, IFF_PNG); pixDisplay(pixt, 500, 100); pixDestroy(&pixt); selaWriteStream(stderr, sela); } pixaDestroy(&pixa); return sela; }