int main(int argc, char **argv) { l_int32 w, d, tilewidth; PIX *pixs; PIXA *pixa, *pixad1, *pixad2; PIXAA *pixaa1, *pixaa2; static char mainName[] = "pixaatest"; if (argc != 1) return ERROR_INT(" Syntax: pixaatest", mainName, 1); /* Read in file, split it into a set of tiles, and generate a pdf. * Two things to note for these tiny images: * (1) If you use dct format (jpeg) for each image instead of * flate (lossless), the quantization will be apparent. * (2) If the resolution in pixaConvertToPdf() is above 50, and * you add a red boundary, you will see errors in the boundary * width. */ pixs = pixRead("test24.jpg"); pixGetDimensions(pixs, &w, NULL, &d); pixa = pixaSplitPix(pixs, nx, ny, 0, 0); /* pixa = pixaSplitPix(pixs, nx, ny, 2, 0xff000000); */ /* red border */ pixWrite("/tmp/junk0", pixa->pix[0], IFF_PNG); pixWrite("/tmp/junk9", pixa->pix[9], IFF_PNG); pixaConvertToPdf(pixa, 50, 1.0, 0, 95, "individual", "/tmp/junkout0.pdf"); /* Generate two pixaa by sampling the pixa, and write them to file */ pixaa1 = pixaaCreateFromPixa(pixa, nx, L_CHOOSE_CONSECUTIVE, L_CLONE); pixaa2 = pixaaCreateFromPixa(pixa, nx, L_CHOOSE_SKIP_BY, L_CLONE); pixaaWrite("/tmp/pixaa1.paa", pixaa1); pixaaWrite("/tmp/pixaa2.paa", pixaa2); pixaDestroy(&pixa); pixaaDestroy(&pixaa1); pixaaDestroy(&pixaa2); /* Read each pixaa from file; tile/scale into a pixa */ pixaa1 = pixaaRead("/tmp/pixaa1.paa"); pixaa2 = pixaaRead("/tmp/pixaa2.paa"); tilewidth = w / nx; pixad1 = pixaaDisplayTiledAndScaled(pixaa1, d, tilewidth, ncols, 0, 10, 0); pixad2 = pixaaDisplayTiledAndScaled(pixaa2, d, tilewidth, ncols, 0, 10, 0); /* Generate a pdf from each pixa */ pixaConvertToPdf(pixad1, 50, 1.0, 0, 75, "consecutive", "/tmp/junkout1.pdf"); pixaConvertToPdf(pixad2, 50, 1.0, 0, 75, "skip_by", "/tmp/junkout2.pdf"); /* Write each pixa to a set of files, and generate a PS */ pixaWriteFiles("/tmp/junksplit1.", pixad1, IFF_JFIF_JPEG); pixaWriteFiles("/tmp/junksplit2.", pixad2, IFF_JFIF_JPEG); convertFilesToPS("/tmp", "junksplit1", 40, "/tmp/junkout1.ps"); convertFilesToPS("/tmp", "junksplit2", 40, "/tmp/junkout2.ps"); pixDestroy(&pixs); pixaaDestroy(&pixaa1); pixaaDestroy(&pixaa2); pixaDestroy(&pixad1); pixaDestroy(&pixad2); return 0; }
/*! * recogaWritePixaa() * * Input: filename * recoga * Return: 0 if OK, 1 on error * * Notes: * (1) For each recognizer, this generates a pixa of all the * unscaled images. They are combined into a pixaa for * the set of recognizers. Each pix has has its character * string in the pix text field. * (2) As a side-effect, the character class label is written * into each pix in recog. */ l_int32 recogaWritePixaa(const char *filename, L_RECOGA *recoga) { l_int32 i; PIXA *pixa; PIXAA *paa; L_RECOG *recog; PROCNAME("recogaWritePixaa"); if (!filename) return ERROR_INT("filename not defined", procName, 1); if (!recoga) return ERROR_INT("recoga not defined", procName, 1); paa = pixaaCreate(recoga->n); for (i = 0; i < recoga->n; i++) { recog = recogaGetRecog(recoga, i); recogAddCharstrLabels(recog); pixa = pixaaFlattenToPixa(recog->pixaa_u, NULL, L_CLONE); pixaaAddPixa(paa, pixa, L_INSERT); } pixaaWrite(filename, paa); pixaaDestroy(&paa); return 0; }
main(int argc, char **argv) { char *filein, *fileout; l_int32 w, h, d, w2, h2, i, ncols; l_float32 angle, conf; BOX *box; BOXA *boxa, *boxas, *boxad, *boxa2; NUMA *numa; PIX *pixs, *pixt, *pixb, *pixb2, *pixd; PIX *pixtlm, *pixvws; PIX *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6; PIXA *pixam, *pixac, *pixad, *pixat; PIXAA *pixaa, *pixaa2; PTA *pta; SEL *selsplit; static char mainName[] = "textlinemask"; if (argc != 3) exit(ERROR_INT(" Syntax: textlinemask filein fileout", mainName, 1)); filein = argv[1]; fileout = argv[2]; pixDisplayWrite(NULL, -1); /* init debug output */ if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); pixGetDimensions(pixs, &w, &h, &d); /* Binarize input */ if (d == 8) pixt = pixThresholdToBinary(pixs, 128); else if (d == 1) pixt = pixClone(pixs); else { fprintf(stderr, "depth is %d\n", d); exit(1); } /* Deskew */ pixb = pixFindSkewAndDeskew(pixt, 1, &angle, &conf); pixDestroy(&pixt); fprintf(stderr, "Skew angle: %7.2f degrees; %6.2f conf\n", angle, conf); pixDisplayWrite(pixb, DEBUG_OUTPUT); #if 1 /* Use full image morphology to find columns, at 2x reduction. * This only works for very simple layouts where each column * of text extends the full height of the input image. * pixam has a pix component over each column. */ pixb2 = pixReduceRankBinary2(pixb, 2, NULL); pixt1 = pixMorphCompSequence(pixb2, "c5.500", 0); boxa = pixConnComp(pixt1, &pixam, 8); ncols = boxaGetCount(boxa); fprintf(stderr, "Num columns: %d\n", ncols); pixDisplayWrite(pixt1, DEBUG_OUTPUT); /* Use selective region-based morphology to get the textline mask. */ pixad = pixaMorphSequenceByRegion(pixb2, pixam, "c100.3", 0, 0); pixGetDimensions(pixb2, &w2, &h2, NULL); if (DEBUG_OUTPUT) { pixt2 = pixaDisplay(pixad, w2, h2); pixDisplayWrite(pixt2, DEBUG_OUTPUT); pixDestroy(&pixt2); } /* Some of the lines may be touching, so use a HMT to split the * lines in each column, and use a pixaa to save the results. */ selsplit = selCreateFromString(seltext, 17, 7, "selsplit"); pixaa = pixaaCreate(ncols); for (i = 0; i < ncols; i++) { pixt3 = pixaGetPix(pixad, i, L_CLONE); box = pixaGetBox(pixad, i, L_COPY); pixt4 = pixHMT(NULL, pixt3, selsplit); pixXor(pixt4, pixt4, pixt3); boxa2 = pixConnComp(pixt4, &pixac, 8); pixaaAddPixa(pixaa, pixac, L_INSERT); pixaaAddBox(pixaa, box, L_INSERT); if (DEBUG_OUTPUT) { pixt5 = pixaDisplayRandomCmap(pixac, 0, 0); pixDisplayWrite(pixt5, DEBUG_OUTPUT); fprintf(stderr, "Num textlines in col %d: %d\n", i, boxaGetCount(boxa2)); pixDestroy(&pixt5); } pixDestroy(&pixt3); pixDestroy(&pixt4); boxaDestroy(&boxa2); } /* Visual output */ if (DEBUG_OUTPUT) { pixDisplayMultiple("/tmp/junk_write_display*"); pixat = pixaReadFiles("/tmp", "junk_write_display"); pixt5 = selDisplayInPix(selsplit, 31, 2); pixaAddPix(pixat, pixt5, L_INSERT); pixt6 = pixaDisplayTiledAndScaled(pixat, 32, 400, 3, 0, 35, 3); pixWrite(fileout, pixt6, IFF_PNG); pixaDestroy(&pixat); pixDestroy(&pixt6); } /* Test pixaa I/O */ pixaaWrite("/tmp/junkpixaa", pixaa); pixaa2 = pixaaRead("/tmp/junkpixaa"); pixaaWrite("/tmp/junkpixaa2", pixaa2); /* Test pixaa display */ pixd = pixaaDisplay(pixaa, w2, h2); pixWrite("/tmp/junkdisplay", pixd, IFF_PNG); pixDestroy(&pixd); /* Cleanup */ pixDestroy(&pixb2); pixDestroy(&pixt1); pixaDestroy(&pixam); pixaDestroy(&pixad); pixaaDestroy(&pixaa); pixaaDestroy(&pixaa2); boxaDestroy(&boxa); selDestroy(&selsplit); #endif #if 0 /* Use the baseline finder; not really what is needed */ numa = pixFindBaselines(pixb, &pta, 1); #endif #if 0 /* Use the textline mask function; parameters are not quite right */ pixb2 = pixReduceRankBinary2(pixb, 2, NULL); pixtlm = pixGenTextlineMask(pixb2, &pixvws, NULL, 1); pixDisplay(pixtlm, 0, 100); pixDisplay(pixvws, 500, 100); pixDestroy(&pixb2); pixDestroy(&pixtlm); pixDestroy(&pixvws); #endif #if 0 /* Use the Breuel whitespace partition method; slow and we would * still need to work to extract the fg regions. */ pixb2 = pixReduceRankBinary2(pixb, 2, NULL); boxas = pixConnComp(pixb2, NULL, 8); boxad = boxaGetWhiteblocks(boxas, NULL, L_SORT_BY_HEIGHT, 3, 0.1, 200, 0.2, 0); pixd = pixDrawBoxa(pixb2, boxad, 7, 0xe0708000); pixDisplay(pixd, 100, 500); pixDestroy(&pixb2); pixDestroy(&pixd); boxaDestroy(&boxas); boxaDestroy(&boxad); #endif #if 0 /* Use morphology to find columns and then selective * region-based morphology to get the textline mask. * This is for display; we really want to get a pixa of the * specific textline masks. */ startTimer(); pixb2 = pixReduceRankBinary2(pixb, 2, NULL); pixt1 = pixMorphCompSequence(pixb2, "c5.500", 0); /* column mask */ pixt2 = pixMorphSequenceByRegion(pixb2, pixt1, "c100.3", 8, 0, 0, &boxa); fprintf(stderr, "time = %7.3f sec\n", stopTimer()); pixDisplay(pixt1, 100, 500); pixDisplay(pixt2, 800, 500); pixDestroy(&pixb2); pixDestroy(&pixt1); pixDestroy(&pixt2); boxaDestroy(&boxa); #endif pixDestroy(&pixs); pixDestroy(&pixb); exit(0); }
int main(int argc, char **argv) { l_int32 w, h, d, w2, h2, i, ncols, ret; l_float32 angle, conf; BOX *box; BOXA *boxa, *boxa2; PIX *pix, *pixs, *pixb, *pixb2, *pixd; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6; PIXA *pixam; /* mask with a single component over each column */ PIXA *pixac, *pixad, *pixat; PIXAA *pixaa, *pixaa2; SEL *selsplit; static char mainName[] = "arabic_lines"; if (argc != 1) return ERROR_INT(" Syntax: arabic_lines", mainName, 1); pixDisplayWrite(NULL, -1); /* init debug output */ /* Binarize input */ pixs = pixRead("arabic.png"); pixGetDimensions(pixs, &w, &h, &d); pix = pixConvertTo1(pixs, 128); /* Deskew */ pixb = pixFindSkewAndDeskew(pix, 1, &angle, &conf); pixDestroy(&pix); fprintf(stderr, "Skew angle: %7.2f degrees; %6.2f conf\n", angle, conf); pixDisplayWrite(pixb, 1); /* Use full image morphology to find columns, at 2x reduction. This only works for very simple layouts where each column of text extends the full height of the input image. */ pixb2 = pixReduceRankBinary2(pixb, 2, NULL); pix1 = pixMorphCompSequence(pixb2, "c5.500", 0); boxa = pixConnComp(pix1, &pixam, 8); ncols = boxaGetCount(boxa); fprintf(stderr, "Num columns: %d\n", ncols); pixDisplayWrite(pix1, 1); /* Use selective region-based morphology to get the textline mask. */ pixad = pixaMorphSequenceByRegion(pixb2, pixam, "c100.3", 0, 0); pixGetDimensions(pixb2, &w2, &h2, NULL); pix2 = pixaDisplay(pixad, w2, h2); pixDisplayWrite(pix2, 1); pixDestroy(&pix2); /* Some of the lines may be touching, so use a HMT to split the lines in each column, and use a pixaa to save the results. */ selsplit = selCreateFromString(seltext, 17, 7, "selsplit"); pixaa = pixaaCreate(ncols); for (i = 0; i < ncols; i++) { pix3 = pixaGetPix(pixad, i, L_CLONE); box = pixaGetBox(pixad, i, L_COPY); pix4 = pixHMT(NULL, pix3, selsplit); pixXor(pix4, pix4, pix3); boxa2 = pixConnComp(pix4, &pixac, 8); pixaaAddPixa(pixaa, pixac, L_INSERT); pixaaAddBox(pixaa, box, L_INSERT); pix5 = pixaDisplayRandomCmap(pixac, 0, 0); pixDisplayWrite(pix5, 1); fprintf(stderr, "Num textlines in col %d: %d\n", i, boxaGetCount(boxa2)); pixDestroy(&pix5); pixDestroy(&pix3); pixDestroy(&pix4); boxaDestroy(&boxa2); } /* Visual output */ ret = system("gthumb /tmp/display/file* &"); pixat = pixaReadFiles("/tmp/display", "file"); pix5 = selDisplayInPix(selsplit, 31, 2); pixaAddPix(pixat, pix5, L_INSERT); pix6 = pixaDisplayTiledAndScaled(pixat, 32, 400, 3, 0, 35, 3); pixWrite("/tmp/result.png", pix6, IFF_PNG); pixaDestroy(&pixat); pixDestroy(&pix6); /* Test pixaa I/O */ pixaaWrite("/tmp/pixaa", pixaa); pixaa2 = pixaaRead("/tmp/pixaa"); pixaaWrite("/tmp/pixaa2", pixaa2); /* Test pixaa display */ pixd = pixaaDisplay(pixaa, w2, h2); pixWrite("/tmp/textlines.png", pixd, IFF_PNG); pixDestroy(&pixd); /* Cleanup */ pixDestroy(&pixb2); pixDestroy(&pix1); pixaDestroy(&pixam); pixaDestroy(&pixad); pixaaDestroy(&pixaa); pixaaDestroy(&pixaa2); boxaDestroy(&boxa); selDestroy(&selsplit); pixDestroy(&pixs); pixDestroy(&pixb); return 0; }
int main(int argc, char **argv) { char buf[8]; l_int32 i, n, h; l_float32 scalefact; BOXA *boxa; PIX *pixs, *pix, *pixt1, *pixt2; PIXA *pixa, *pixas, *pixad; PIXAA *pixaa; static char mainName[] = "digitprep1"; if (argc != 1) { ERROR_INT(" Syntax: digitprep1", mainName, 1); return 1; } if ((pixs = pixRead("barcode-digits.png")) == NULL) return ERROR_INT("pixs not read", mainName, 1); /* Extract the digits and scale to HEIGHT */ boxa = pixConnComp(pixs, &pixa, 8); pixas = pixaSort(pixa, L_SORT_BY_X, L_SORT_INCREASING, NULL, L_CLONE); n = pixaGetCount(pixas); /* Move the last ("0") to the first position */ pixt1 = pixaGetPix(pixas, n - 1, L_CLONE); pixaInsertPix(pixas, 0, pixt1, NULL); pixaRemovePix(pixas, n); /* Make the output scaled pixa */ pixad = pixaCreate(n); for (i = 0; i < n; i++) { pixt1 = pixaGetPix(pixas, i, L_CLONE); pixGetDimensions(pixt1, NULL, &h, NULL); scalefact = HEIGHT / (l_float32)h; pixt2 = pixScale(pixt1, scalefact, scalefact); if (pixGetHeight(pixt2) != 32) return ERROR_INT("height not 32!", mainName, 1); sprintf(buf, "%d", i); pixSetText(pixt2, buf); pixaAddPix(pixad, pixt2, L_INSERT); pixDestroy(&pixt1); } /* Save in a pixaa, with 1 pix in each pixa */ pixaa = pixaaCreateFromPixa(pixad, 1, L_CHOOSE_CONSECUTIVE, L_CLONE); pixaaWrite("junkdigits.pixaa", pixaa); /* Show result */ pixt1 = pixaaDisplayByPixa(pixaa, 20, 20, 1000); pixDisplay(pixt1, 100, 100); pixDestroy(&pixt1); boxaDestroy(&boxa); pixaDestroy(&pixa); pixaDestroy(&pixas); pixaDestroy(&pixad); pixaaDestroy(&pixaa); return 0; }