l_int32 main(int argc, char **argv) { l_int32 i, n, w, h, val; l_uint32 val32; L_AMAP *m; NUMA *na; PIX *pix; PIXCMAP *cmap; RB_TYPE key, value; RB_TYPE *pval; setLeptDebugOK(1); lept_mkdir("lept/map"); pix = pixRead("weasel8.240c.png"); pixGetDimensions(pix, &w, &h, NULL); fprintf(stderr, "Image area in pixels: %d\n", w * h); cmap = pixGetColormap(pix); /* Build the histogram, stored in a map. Then compute * and display the histogram as the number of pixels vs * the colormap index */ m = BuildMapHistogram(pix, 1, FALSE); TestMapIterator1(m, FALSE); TestMapIterator2(m, FALSE); DisplayMapHistogram(m, cmap, "/tmp/lept/map/map1"); l_amapDestroy(&m); /* Ditto, but just with a few pixels */ m = BuildMapHistogram(pix, 14, TRUE); DisplayMapHistogram(m, cmap, "/tmp/lept/map/map2"); l_amapDestroy(&m); /* Do in-order tranversals, using the iterators */ m = BuildMapHistogram(pix, 7, FALSE); TestMapIterator1(m, TRUE); TestMapIterator2(m, TRUE); l_amapDestroy(&m); /* Do in-order tranversals, with iterators and destroying the map */ m = BuildMapHistogram(pix, 7, FALSE); TestMapIterator3(m, TRUE); lept_free(m); m = BuildMapHistogram(pix, 7, FALSE); TestMapIterator4(m, TRUE); lept_free(m); /* Do in-order tranversals, with iterators and reversing the map */ m = BuildMapHistogram(pix, 7, FALSE); TestMapIterator5(m, TRUE); l_amapDestroy(&m); /* Build a histogram the old-fashioned way */ na = pixGetCmapHistogram(pix, 1); numaWrite("/tmp/lept/map/map2.na", na); gplotSimple1(na, GPLOT_PNG, "/tmp/lept/map/map3", NULL); numaDestroy(&na); /* Build a separate map from (rgb) --> colormap index ... */ m = l_amapCreate(L_UINT_TYPE); n = pixcmapGetCount(cmap); for (i = 0; i < n; i++) { pixcmapGetColor32(cmap, i, &val32); key.utype = val32; value.itype = i; l_amapInsert(m, key, value); } /* ... and test the map */ for (i = 0; i < n; i++) { pixcmapGetColor32(cmap, i, &val32); key.utype = val32; pval = l_amapFind(m, key); if (pval && (i != pval->itype)) fprintf(stderr, "i = %d != val = %llx\n", i, pval->itype); } l_amapDestroy(&m); pixDestroy(&pix); /* Build and display a real RGB histogram */ pix = pixRead("wyom.jpg"); m = pixGetColorAmapHistogram(pix, 1); DisplayMapRGBHistogram(m, "/tmp/lept/map/map4"); fprintf(stderr, " Using pixCountRGBColors: %d\n", pixCountRGBColors(pix)); l_amapDestroy(&m); pixDestroy(&pix); return 0; }
l_int32 main(int argc, char **argv) { char buf[64]; BOXA *boxa1, *boxa2, *boxa3, *boxa4; L_DEWARP *dew; L_DEWARPA *dewa; PIX *pixs, *pixn, *pixg, *pixb, *pix2, *pix3, *pix4, *pix5, *pix6; lept_mkdir("lept"); snprintf(buf, sizeof(buf), "cat.%03d.jpg", pageno); pixs = pixRead(buf); dewa = dewarpaCreate(40, 30, 1, 15, 10); dewarpaUseBothArrays(dewa, 1); /* Normalize for varying background and binarize */ pixn = pixBackgroundNormSimple(pixs, NULL, NULL); pixg = pixConvertRGBToGray(pixn, 0.5, 0.3, 0.2); pixb = pixThresholdToBinary(pixg, 130); pixDisplay(pixb, 0, 100); /* Build the model */ dew = dewarpCreate(pixb, pageno); dewarpaInsertDewarp(dewa, dew); if (build_output) { snprintf(buf, sizeof(buf), "/tmp/lept/dewarp_build_%d.pdf", pageno); dewarpBuildPageModel(dew, buf); } else { dewarpBuildPageModel(dew, NULL); } /* Apply the model */ dewarpPopulateFullRes(dew, pixg, 0, 0); if (apply_output) { snprintf(buf, sizeof(buf), "/tmp/lept/dewarp_apply_%d.pdf", pageno); dewarpaApplyDisparity(dewa, pageno, pixb, 200, 0, 0, &pix2, buf); } else { dewarpaApplyDisparity(dewa, pageno, pixb, 200, 0, 0, &pix2, NULL); } pixDisplay(pix2, 200, 100); /* Reverse direction: get the word boxes for the dewarped pix ... */ pixGetWordBoxesInTextlines(pix2, 1, 5, 5, 500, 100, &boxa1, NULL); pix3 = pixConvertTo32(pix2); pixRenderBoxaArb(pix3, boxa1, 2, 255, 0, 0); pixDisplay(pix3, 400, 100); /* ... and map to the word boxes for the input image */ if (map_output) { snprintf(buf, sizeof(buf), "/tmp/lept/dewarp_map1_%d.pdf", pageno); dewarpaApplyDisparityBoxa(dewa, pageno, pix2, boxa1, 0, 0, 0, &boxa2, buf); } else { dewarpaApplyDisparityBoxa(dewa, pageno, pix2, boxa1, 0, 0, 0, &boxa2, NULL); } pix4 = pixConvertTo32(pixb); pixRenderBoxaArb(pix4, boxa2, 2, 0, 255, 0); pixDisplay(pix4, 600, 100); /* Forward direction: get the word boxes for the input pix ... */ pixGetWordBoxesInTextlines(pixb, 1, 5, 5, 500, 100, &boxa3, NULL); pix5 = pixConvertTo32(pixb); pixRenderBoxaArb(pix5, boxa3, 2, 255, 0, 0); pixDisplay(pix5, 800, 100); /* ... and map to the word boxes for the dewarped image */ if (map_output) { snprintf(buf, sizeof(buf), "/tmp/lept/dewarp_map2_%d.pdf", pageno); dewarpaApplyDisparityBoxa(dewa, pageno, pixb, boxa3, 1, 0, 0, &boxa4, buf); } else { dewarpaApplyDisparityBoxa(dewa, pageno, pixb, boxa3, 1, 0, 0, &boxa4, NULL); } pix6 = pixConvertTo32(pix2); pixRenderBoxaArb(pix6, boxa4, 2, 0, 255, 0); pixDisplay(pix6, 1000, 100); dewarpaDestroy(&dewa); pixDestroy(&pixs); pixDestroy(&pixn); pixDestroy(&pixg); pixDestroy(&pixb); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); boxaDestroy(&boxa4); return 0; }
/*! * \brief pixFindBaselines() * * \param[in] pixs 1 bpp, 300 ppi * \param[out] ppta [optional] pairs of pts corresponding to * approx. ends of each text line * \param[in] pixadb for debug output; use NULL to skip * \return na of baseline y values, or NULL on error * * <pre> * Notes: * (1) Input binary image must have text lines already aligned * horizontally. This can be done by either rotating the * image with pixDeskew(), or, if a projective transform * is required, by doing pixDeskewLocal() first. * (2) Input null for &pta if you don't want this returned. * The pta will come in pairs of points (left and right end * of each baseline). * (3) Caution: this will not work properly on text with multiple * columns, where the lines are not aligned between columns. * If there are multiple columns, they should be extracted * separately before finding the baselines. * (4) This function constructs different types of output * for baselines; namely, a set of raster line values and * a set of end points of each baseline. * (5) This function was designed to handle short and long text lines * without using dangerous thresholds on the peak heights. It does * this by combining the differential signal with a morphological * analysis of the locations of the text lines. One can also * combine this data to normalize the peak heights, by weighting * the differential signal in the region of each baseline * by the inverse of the width of the text line found there. * </pre> */ NUMA * pixFindBaselines(PIX *pixs, PTA **ppta, PIXA *pixadb) { l_int32 h, i, j, nbox, val1, val2, ndiff, bx, by, bw, bh; l_int32 imaxloc, peakthresh, zerothresh, inpeak; l_int32 mintosearch, max, maxloc, nloc, locval; l_int32 *array; l_float32 maxval; BOXA *boxa1, *boxa2, *boxa3; GPLOT *gplot; NUMA *nasum, *nadiff, *naloc, *naval; PIX *pix1, *pix2; PTA *pta; PROCNAME("pixFindBaselines"); if (ppta) *ppta = NULL; if (!pixs || pixGetDepth(pixs) != 1) return (NUMA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL); /* Close up the text characters, removing noise */ pix1 = pixMorphSequence(pixs, "c25.1 + e15.1", 0); /* Estimate the resolution */ if (pixadb) pixaAddPix(pixadb, pixScale(pix1, 0.25, 0.25), L_INSERT); /* Save the difference of adjacent row sums. * The high positive-going peaks are the baselines */ if ((nasum = pixCountPixelsByRow(pix1, NULL)) == NULL) { pixDestroy(&pix1); return (NUMA *)ERROR_PTR("nasum not made", procName, NULL); } h = pixGetHeight(pixs); nadiff = numaCreate(h); numaGetIValue(nasum, 0, &val2); for (i = 0; i < h - 1; i++) { val1 = val2; numaGetIValue(nasum, i + 1, &val2); numaAddNumber(nadiff, val1 - val2); } numaDestroy(&nasum); if (pixadb) { /* show the difference signal */ lept_mkdir("lept/baseline"); gplotSimple1(nadiff, GPLOT_PNG, "/tmp/lept/baseline/diff", "Diff Sig"); pix2 = pixRead("/tmp/lept/baseline/diff.png"); pixaAddPix(pixadb, pix2, L_INSERT); } /* Use the zeroes of the profile to locate each baseline. */ array = numaGetIArray(nadiff); ndiff = numaGetCount(nadiff); numaGetMax(nadiff, &maxval, &imaxloc); numaDestroy(&nadiff); /* Use this to begin locating a new peak: */ peakthresh = (l_int32)maxval / PEAK_THRESHOLD_RATIO; /* Use this to begin a region between peaks: */ zerothresh = (l_int32)maxval / ZERO_THRESHOLD_RATIO; naloc = numaCreate(0); naval = numaCreate(0); inpeak = FALSE; for (i = 0; i < ndiff; i++) { if (inpeak == FALSE) { if (array[i] > peakthresh) { /* transition to in-peak */ inpeak = TRUE; mintosearch = i + MIN_DIST_IN_PEAK; /* accept no zeros * between i and mintosearch */ max = array[i]; maxloc = i; } } else { /* inpeak == TRUE; look for max */ if (array[i] > max) { max = array[i]; maxloc = i; mintosearch = i + MIN_DIST_IN_PEAK; } else if (i > mintosearch && array[i] <= zerothresh) { /* leave */ inpeak = FALSE; numaAddNumber(naval, max); numaAddNumber(naloc, maxloc); } } } LEPT_FREE(array); /* If array[ndiff-1] is max, eg. no descenders, baseline at bottom */ if (inpeak) { numaAddNumber(naval, max); numaAddNumber(naloc, maxloc); } if (pixadb) { /* show the raster locations for the peaks */ gplot = gplotCreate("/tmp/lept/baseline/loc", GPLOT_PNG, "Peak locs", "rasterline", "height"); gplotAddPlot(gplot, naloc, naval, GPLOT_POINTS, "locs"); gplotMakeOutput(gplot); gplotDestroy(&gplot); pix2 = pixRead("/tmp/lept/baseline/loc.png"); pixaAddPix(pixadb, pix2, L_INSERT); } numaDestroy(&naval); /* Generate an approximate profile of text line width. * First, filter the boxes of text, where there may be * more than one box for a given textline. */ pix2 = pixMorphSequence(pix1, "r11 + c20.1 + o30.1 +c1.3", 0); if (pixadb) pixaAddPix(pixadb, pix2, L_COPY); boxa1 = pixConnComp(pix2, NULL, 4); pixDestroy(&pix1); pixDestroy(&pix2); if (boxaGetCount(boxa1) == 0) { numaDestroy(&naloc); boxaDestroy(&boxa1); L_INFO("no compnents after filtering\n", procName); return NULL; } boxa2 = boxaTransform(boxa1, 0, 0, 4., 4.); boxa3 = boxaSort(boxa2, L_SORT_BY_Y, L_SORT_INCREASING, NULL); boxaDestroy(&boxa1); boxaDestroy(&boxa2); /* Optionally, find the baseline segments */ pta = NULL; if (ppta) { pta = ptaCreate(0); *ppta = pta; } if (pta) { nloc = numaGetCount(naloc); nbox = boxaGetCount(boxa3); for (i = 0; i < nbox; i++) { boxaGetBoxGeometry(boxa3, i, &bx, &by, &bw, &bh); for (j = 0; j < nloc; j++) { numaGetIValue(naloc, j, &locval); if (L_ABS(locval - (by + bh)) > 25) continue; ptaAddPt(pta, bx, locval); ptaAddPt(pta, bx + bw, locval); break; } } } boxaDestroy(&boxa3); if (pixadb && pta) { /* display baselines */ l_int32 npts, x1, y1, x2, y2; pix1 = pixConvertTo32(pixs); npts = ptaGetCount(pta); for (i = 0; i < npts; i += 2) { ptaGetIPt(pta, i, &x1, &y1); ptaGetIPt(pta, i + 1, &x2, &y2); pixRenderLineArb(pix1, x1, y1, x2, y2, 2, 255, 0, 0); } pixWriteDebug("/tmp/lept/baseline/baselines.png", pix1, IFF_PNG); pixaAddPix(pixadb, pixScale(pix1, 0.25, 0.25), L_INSERT); pixDestroy(&pix1); } return naloc; }
/*! * pixDisplayWithTitle() * * Input: pix (1, 2, 4, 8, 16, 32 bpp) * x, y (location of display frame) * title (<optional> on frame; can be NULL); * dispflag (1 to write, else disabled) * Return: 0 if OK; 1 on error * * Notes: * (1) See notes for pixDisplay(). * (2) This displays the image if dispflag == 1. */ l_int32 pixDisplayWithTitle(PIX *pixs, l_int32 x, l_int32 y, const char *title, l_int32 dispflag) { char *tempname; char buffer[L_BUF_SIZE]; static l_int32 index = 0; /* caution: not .so or thread safe */ l_int32 w, h, d, ignore; l_float32 ratw, rath, ratmin; PIX *pixt; #ifndef _WIN32 l_int32 wt, ht; #else char *pathname; char fullpath[_MAX_PATH]; #endif /* _WIN32 */ PROCNAME("pixDisplayWithTitle"); if (dispflag != 1) return 0; if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (var_DISPLAY_PROG != L_DISPLAY_WITH_XV && var_DISPLAY_PROG != L_DISPLAY_WITH_XLI && var_DISPLAY_PROG != L_DISPLAY_WITH_XZGV && var_DISPLAY_PROG != L_DISPLAY_WITH_IV) return ERROR_INT("no program chosen for display", procName, 1); pixGetDimensions(pixs, &w, &h, &d); if (w <= MAX_DISPLAY_WIDTH && h <= MAX_DISPLAY_HEIGHT) { if (d == 16) /* take MSB */ pixt = pixConvert16To8(pixs, 1); else pixt = pixClone(pixs); } else { ratw = (l_float32)MAX_DISPLAY_WIDTH / (l_float32)w; rath = (l_float32)MAX_DISPLAY_HEIGHT / (l_float32)h; ratmin = L_MIN(ratw, rath); if (ratmin < 0.125 && d == 1) pixt = pixScaleToGray8(pixs); else if (ratmin < 0.25 && d == 1) pixt = pixScaleToGray4(pixs); else if (ratmin < 0.33 && d == 1) pixt = pixScaleToGray3(pixs); else if (ratmin < 0.5 && d == 1) pixt = pixScaleToGray2(pixs); else pixt = pixScale(pixs, ratmin, ratmin); if (!pixt) return ERROR_INT("pixt not made", procName, 1); } if (index == 0) { lept_rmdir("display"); lept_mkdir("display"); } index++; if (pixGetDepth(pixt) < 8 || (w < MAX_SIZE_FOR_PNG && h < MAX_SIZE_FOR_PNG)) { snprintf(buffer, L_BUF_SIZE, "/tmp/display/write.%03d.png", index); pixWrite(buffer, pixt, IFF_PNG); } else { snprintf(buffer, L_BUF_SIZE, "/tmp/display/write.%03d.jpg", index); pixWrite(buffer, pixt, IFF_JFIF_JPEG); } tempname = stringNew(buffer); #ifndef _WIN32 /* Unix */ if (var_DISPLAY_PROG == L_DISPLAY_WITH_XV) { if (title) snprintf(buffer, L_BUF_SIZE, "xv -quit -geometry +%d+%d -name \"%s\" %s &", x, y, title, tempname); else snprintf(buffer, L_BUF_SIZE, "xv -quit -geometry +%d+%d %s &", x, y, tempname); } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XLI) { if (title) snprintf(buffer, L_BUF_SIZE, "xli -dispgamma 1.0 -quiet -geometry +%d+%d -title \"%s\" %s &", x, y, title, tempname); else snprintf(buffer, L_BUF_SIZE, "xli -dispgamma 1.0 -quiet -geometry +%d+%d %s &", x, y, tempname); } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XZGV) { /* no way to display title */ pixGetDimensions(pixt, &wt, &ht, NULL); snprintf(buffer, L_BUF_SIZE, "xzgv --geometry %dx%d+%d+%d %s &", wt + 10, ht + 10, x, y, tempname); } ignore = system(buffer); #else /* _WIN32 */ /* Windows: L_DISPLAY_WITH_IV */ pathname = genPathname(tempname, NULL); _fullpath(fullpath, pathname, sizeof(fullpath)); if (title) snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /pos=(%d,%d) /title=\"%s\"", fullpath, x, y, title); else snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /pos=(%d,%d)", fullpath, x, y); ignore = system(buffer); FREE(pathname); #endif /* _WIN32 */ pixDestroy(&pixt); FREE(tempname); return 0; }
/*! * \brief pixItalicWords() * * \param[in] pixs 1 bpp * \param[in] boxaw [optional] word bounding boxes; can be NULL * \param[in] pixw [optional] word box mask; can be NULL * \param[out] pboxa boxa of italic words * \param[in] debugflag 1 for debug output; 0 otherwise * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) You can input the bounding boxes for the words in one of * two forms: as bounding boxes (%boxaw) or as a word mask with * the word bounding boxes filled (%pixw). For example, * to compute %pixw, you can use pixWordMaskByDilation(). * (2) Alternatively, you can set both of these inputs to NULL, * in which case the word mask is generated here. This is * done by dilating and closing the input image to connect * letters within a word, while leaving the words separated. * The parameters are chosen under the assumption that the * input is 10 to 12 pt text, scanned at about 300 ppi. * (3) sel_ital1 and sel_ital2 detect the right edges that are * nearly vertical, at approximately the angle of italic * strokes. We use the right edge to avoid getting seeds * from lower-case 'y'. The typical italic slant has a smaller * angle with the vertical than the 'W', so in most cases we * will not trigger on the slanted lines in the 'W'. * (4) Note that sel_ital2 is shorter than sel_ital1. It is * more appropriate for a typical font scanned at 200 ppi. * </pre> */ l_int32 pixItalicWords(PIX *pixs, BOXA *boxaw, PIX *pixw, BOXA **pboxa, l_int32 debugflag) { char opstring[32]; l_int32 size; BOXA *boxa; PIX *pixsd, *pixm, *pixd; SEL *sel_ital1, *sel_ital2, *sel_ital3; PROCNAME("pixItalicWords"); if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (!pboxa) return ERROR_INT("&boxa not defined", procName, 1); if (boxaw && pixw) return ERROR_INT("both boxaw and pixw are defined", procName, 1); sel_ital1 = selCreateFromString(str_ital1, 13, 6, NULL); sel_ital2 = selCreateFromString(str_ital2, 10, 6, NULL); sel_ital3 = selCreateFromString(str_ital3, 4, 2, NULL); /* Make the italic seed: extract with HMT; remove noise. * The noise removal close/open is important to exclude * situations where a small slanted line accidentally * matches sel_ital1. */ pixsd = pixHMT(NULL, pixs, sel_ital1); pixClose(pixsd, pixsd, sel_ital3); pixOpen(pixsd, pixsd, sel_ital3); /* Make the word mask. Use input boxes or mask if given. */ size = 0; /* init */ if (boxaw) { pixm = pixCreateTemplate(pixs); pixMaskBoxa(pixm, pixm, boxaw, L_SET_PIXELS); } else if (pixw) { pixm = pixClone(pixw); } else { pixWordMaskByDilation(pixs, NULL, &size, NULL); L_INFO("dilation size = %d\n", procName, size); snprintf(opstring, sizeof(opstring), "d1.5 + c%d.1", size); pixm = pixMorphSequence(pixs, opstring, 0); } /* Binary reconstruction to fill in those word mask * components for which there is at least one seed pixel. */ pixd = pixSeedfillBinary(NULL, pixsd, pixm, 8); boxa = pixConnComp(pixd, NULL, 8); *pboxa = boxa; if (debugflag) { /* Save results at at 2x reduction */ lept_mkdir("lept/ital"); l_int32 res, upper; BOXA *boxat; GPLOT *gplot; NUMA *na; PIXA *pad; PIX *pix1, *pix2, *pix3; pad = pixaCreate(0); boxat = pixConnComp(pixm, NULL, 8); boxaWrite("/tmp/lept/ital/ital.ba", boxat); pixSaveTiledOutline(pixs, pad, 0.5, 1, 20, 2, 32); /* orig */ pixSaveTiledOutline(pixsd, pad, 0.5, 1, 20, 2, 0); /* seed */ pix1 = pixConvertTo32(pixm); pixRenderBoxaArb(pix1, boxat, 3, 255, 0, 0); pixSaveTiledOutline(pix1, pad, 0.5, 1, 20, 2, 0); /* mask + outline */ pixDestroy(&pix1); pixSaveTiledOutline(pixd, pad, 0.5, 1, 20, 2, 0); /* ital mask */ pix1 = pixConvertTo32(pixs); pixRenderBoxaArb(pix1, boxa, 3, 255, 0, 0); pixSaveTiledOutline(pix1, pad, 0.5, 1, 20, 2, 0); /* orig + outline */ pixDestroy(&pix1); pix1 = pixCreateTemplate(pixs); pix2 = pixSetBlackOrWhiteBoxa(pix1, boxa, L_SET_BLACK); pixCopy(pix1, pixs); pix3 = pixDilateBrick(NULL, pixs, 3, 3); pixCombineMasked(pix1, pix3, pix2); pixSaveTiledOutline(pix1, pad, 0.5, 1, 20, 2, 0); /* ital bolded */ pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pix2 = pixaDisplay(pad, 0, 0); pixWrite("/tmp/lept/ital/ital.png", pix2, IFF_PNG); pixDestroy(&pix2); /* Assuming the image represents 6 inches of actual page width, * the pixs resolution is approximately * (width of pixs in pixels) / 6 * and the images have been saved at half this resolution. */ res = pixGetWidth(pixs) / 12; L_INFO("resolution = %d\n", procName, res); l_pdfSetDateAndVersion(0); pixaConvertToPdf(pad, res, 1.0, L_FLATE_ENCODE, 75, "Italic Finder", "/tmp/lept/ital/ital.pdf"); l_pdfSetDateAndVersion(1); pixaDestroy(&pad); boxaDestroy(&boxat); /* Plot histogram of horizontal white run sizes. A small * initial vertical dilation removes most runs that are neither * inter-character nor inter-word. The larger first peak is * from inter-character runs, and the smaller second peak is * from inter-word runs. */ pix1 = pixDilateBrick(NULL, pixs, 1, 15); upper = L_MAX(30, 3 * size); na = pixRunHistogramMorph(pix1, L_RUN_OFF, L_HORIZ, upper); pixDestroy(&pix1); gplot = gplotCreate("/tmp/lept/ital/runhisto", GPLOT_PNG, "Histogram of horizontal runs of white pixels, vs length", "run length", "number of runs"); gplotAddPlot(gplot, NULL, na, GPLOT_LINES, "plot1"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&na); } selDestroy(&sel_ital1); selDestroy(&sel_ital2); selDestroy(&sel_ital3); pixDestroy(&pixsd); pixDestroy(&pixm); pixDestroy(&pixd); return 0; }
main(int argc, char **argv) { l_int32 h; l_float32 scalefactor; BOX *box; BOXA *boxa1, *boxa2; BOXAA *baa; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pix8, *pix9; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; lept_rmdir("segtest"); lept_mkdir("segtest"); baa = boxaaCreate(5); /* Image region input. */ pix1 = pixRead("wet-day.jpg"); pix2 = pixScaleToSize(pix1, WIDTH, 0); pixWrite("/tmp/segtest/0.jpg", pix2, IFF_JFIF_JPEG); regTestCheckFile(rp, "/tmp/segtest/0.jpg"); /* 0 */ box = boxCreate(105, 161, 620, 872); /* image region */ boxa1 = boxaCreate(1); boxaAddBox(boxa1, box, L_INSERT); boxaaAddBoxa(baa, boxa1, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); /* Compute image region at w = 2 * WIDTH */ pix1 = pixRead("candelabrum-11.jpg"); pix2 = pixScaleToSize(pix1, WIDTH, 0); pix3 = pixConvertTo1(pix2, 100); pix4 = pixExpandBinaryPower2(pix3, 2); /* w = 2 * WIDTH */ pix5 = pixGenHalftoneMask(pix4, NULL, NULL, 1); pix6 = pixMorphSequence(pix5, "c20.1 + c1.20", 0); pix7 = pixMaskConnComp(pix6, 8, &boxa1); pix8 = pixReduceBinary2(pix7, NULL); /* back to w = WIDTH */ pix9 = pixBackgroundNormSimple(pix2, pix8, NULL); pixWrite("/tmp/segtest/1.jpg", pix9, IFF_JFIF_JPEG); regTestCheckFile(rp, "/tmp/segtest/1.jpg"); /* 1 */ boxa2 = boxaTransform(boxa1, 0, 0, 0.5, 0.5); /* back to w = WIDTH */ boxaaAddBoxa(baa, boxa2, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); pixDestroy(&pix7); pixDestroy(&pix8); pixDestroy(&pix9); boxaDestroy(&boxa1); /* Use mask to find image region */ pix1 = pixRead("lion-page.00016.jpg"); pix2 = pixScaleToSize(pix1, WIDTH, 0); pixWrite("/tmp/segtest/2.jpg", pix2, IFF_JFIF_JPEG); regTestCheckFile(rp, "/tmp/segtest/2.jpg"); /* 2 */ pix3 = pixRead("lion-mask.00016.tif"); pix4 = pixScaleToSize(pix3, WIDTH, 0); boxa1 = pixConnComp(pix4, NULL, 8); boxaaAddBoxa(baa, boxa1, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); /* Compute image region at full res */ pix1 = pixRead("rabi.png"); scalefactor = (l_float32)WIDTH / (l_float32)pixGetWidth(pix1); pix2 = pixScaleToGray(pix1, scalefactor); pixWrite("/tmp/segtest/3.jpg", pix2, IFF_JFIF_JPEG); regTestCheckFile(rp, "/tmp/segtest/3.jpg"); /* 3 */ pix3 = pixGenHalftoneMask(pix1, NULL, NULL, 0); pix4 = pixMorphSequence(pix3, "c20.1 + c1.20", 0); boxa1 = pixConnComp(pix4, NULL, 8); boxa2 = boxaTransform(boxa1, 0, 0, scalefactor, scalefactor); boxaaAddBoxa(baa, boxa2, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); boxaDestroy(&boxa1); /* Page with no image regions */ pix1 = pixRead("lucasta-47.jpg"); pix2 = pixScaleToSize(pix1, WIDTH, 0); boxa1 = boxaCreate(1); pixWrite("/tmp/segtest/4.jpg", pix2, IFF_JFIF_JPEG); regTestCheckFile(rp, "/tmp/segtest/4.jpg"); /* 4 */ boxaaAddBoxa(baa, boxa1, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); /* Page that is all image */ pix1 = pixRead("map1.jpg"); pix2 = pixScaleToSize(pix1, WIDTH, 0); pixWrite("/tmp/segtest/5.jpg", pix2, IFF_JFIF_JPEG); regTestCheckFile(rp, "/tmp/segtest/5.jpg"); /* 5 */ h = pixGetHeight(pix2); box = boxCreate(0, 0, WIDTH, h); boxa1 = boxaCreate(1); boxaAddBox(boxa1, box, L_INSERT); boxaaAddBoxa(baa, boxa1, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); /* Save the boxaa file */ boxaaWrite("/tmp/segtest/seg.baa", baa); regTestCheckFile(rp, "/tmp/segtest/seg.baa"); /* 6 */ /* Do the conversion */ l_pdfSetDateAndVersion(FALSE); convertSegmentedFilesToPdf("/tmp/segtest", ".jpg", 100, L_G4_ENCODE, 140, baa, 75, 0.6, "Segmentation Test", "/tmp/pdfseg.7.pdf"); regTestCheckFile(rp, "/tmp/pdfseg.7.pdf"); /* 7 */ boxaaDestroy(&baa); return regTestCleanup(rp); }
void TestLeptCpRm(L_REGPARAMS *rp, const char *srctail, const char *newdir, const char *newtail) { char realnewdir[256], newnewdir[256]; char *realtail, *newsrc, *fname; l_int32 nfiles1, nfiles2, nfiles3; SARRAY *sa; /* Remove old version if it exists */ realtail = (newtail) ? stringNew(newtail) : stringNew(srctail); lept_rm(newdir, realtail); makeTempDirname(realnewdir, 256, newdir); if (rp->display) { fprintf(stderr, "\nInput: srctail = %s, newdir = %s, newtail = %s\n", srctail, newdir, newtail); fprintf(stderr, " realnewdir = %s, realtail = %s\n", realnewdir, realtail); } sa = getFilenamesInDirectory(realnewdir); nfiles1 = sarrayGetCount(sa); sarrayDestroy(&sa); /* Copy */ lept_cp(srctail, newdir, newtail, &fname); sa = getFilenamesInDirectory(realnewdir); nfiles2 = sarrayGetCount(sa); if (rp->display) { fprintf(stderr, " File copied to directory: %s\n", realnewdir); fprintf(stderr, " ... with this filename: %s\n", fname); fprintf(stderr, " delta files should be 1: %d\n", nfiles2 - nfiles1); } regTestCompareValues(rp, 1, nfiles2 - nfiles1, 0.0); /* '1' */ sarrayDestroy(&sa); lept_free(fname); /* Remove it */ lept_rm(newdir, realtail); sa = getFilenamesInDirectory(realnewdir); nfiles2 = sarrayGetCount(sa); if (rp->display) { fprintf(stderr, " File removed from directory: %s\n", realnewdir); fprintf(stderr, " delta files should be 0: %d\n", nfiles2 - nfiles1); } regTestCompareValues(rp, 0, nfiles2 - nfiles1, 0.0); /* '2' */ sarrayDestroy(&sa); /* Copy it again ... */ lept_cp(srctail, newdir, newtail, &fname); if (rp->display) fprintf(stderr, " File copied to: %s\n", fname); lept_free(fname); /* move it elsewhere ... */ lept_rmdir("junko"); /* clear out this directory */ lept_mkdir("junko"); newsrc = pathJoin(realnewdir, realtail); lept_mv(newsrc, "junko", NULL, &fname); if (rp->display) { fprintf(stderr, " Move file at: %s\n", newsrc); fprintf(stderr, " ... to: %s\n", fname); } lept_free(fname); lept_free(newsrc); makeTempDirname(newnewdir, 256, "junko"); if (rp->display) fprintf(stderr, " In this directory: %s\n", newnewdir); sa = getFilenamesInDirectory(newnewdir); /* check if it landed ok */ nfiles3 = sarrayGetCount(sa); if (rp->display) fprintf(stderr, " num files should be 1: %d\n", nfiles3); regTestCompareValues(rp, 1, nfiles3, 0.0); /* '3' */ sarrayDestroy(&sa); /* and verify it was removed from the original location */ sa = getFilenamesInDirectory(realnewdir); /* check if it was removed */ nfiles2 = sarrayGetCount(sa); if (rp->display) { fprintf(stderr, " In this directory: %s\n", realnewdir); fprintf(stderr, " delta files should be 0: %d\n", nfiles2 - nfiles1); } regTestCompareValues(rp, 0, nfiles2 - nfiles1, 0.0); /* '4' */ sarrayDestroy(&sa); lept_free(realtail); }
l_int32 main(int argc, char **argv) { l_int32 i, n, ignore; l_float32 a, b, c, d, e; L_DEWARP *dew; FILE *fp; FPIX *fpix; NUMA *nax, *nay, *nafit; PIX *pixs, *pixn, *pixg, *pixb, *pixt1, *pixt2, *pixt3; PIX *pixs2, *pixn2, *pixg2, *pixb2, *pixv, *pixd; PTA *pta, *ptad; PTAA *ptaa1, *ptaa2; pixs = pixRead("1555-7.jpg"); /* Normalize for varying background and binarize */ pixn = pixBackgroundNormSimple(pixs, NULL, NULL); pixg = pixConvertRGBToGray(pixn, 0.5, 0.3, 0.2); pixb = pixThresholdToBinary(pixg, 130); /* Run the basic functions */ dew = dewarpCreate(pixb, 7, 30, 15, 1); dewarpBuildModel(dew, 1); dewarpApplyDisparity(dew, pixg, 1); /* Save the intermediate dewarped images */ pixv = pixRead("/tmp/pixv.png"); pixd = pixRead("/tmp/pixd.png"); /* Normalize another image, that doesn't have enough textlines * to build an accurate model */ pixs2 = pixRead("1555-3.jpg"); pixn2 = pixBackgroundNormSimple(pixs2, NULL, NULL); pixg2 = pixConvertRGBToGray(pixn2, 0.5, 0.3, 0.2); pixb2 = pixThresholdToBinary(pixg2, 130); /* Apply the previous disparity model to this image */ dewarpApplyDisparity(dew, pixg2, 1); dewarpDestroy(&dew); /* Get the textline centers */ const char* const morph2 = "c15.1 + o15.1 + c50.1"; ptaa1 = pixGetTextlineCenters(pixb,morph2, 0); pixt1 = pixCreateTemplate(pixs); pixt2 = pixDisplayPtaa(pixt1, ptaa1); pixWrite("/tmp/textline1.png", pixt2, IFF_PNG); pixDisplayWithTitle(pixt2, 500, 100, "textline centers", 1); pixDestroy(&pixt1); /* Remove short lines */ fprintf(stderr, "Num all lines = %d\n", ptaaGetCount(ptaa1)); ptaa2 = ptaaRemoveShortLines(pixb, ptaa1, 0.8, 0); /* Fit to curve */ n = ptaaGetCount(ptaa2); fprintf(stderr, "Num long lines = %d\n", n); for (i = 0; i < n; i++) { pta = ptaaGetPta(ptaa2, i, L_CLONE); ptaGetArrays(pta, &nax, NULL); #if DO_QUAD ptaGetQuadraticLSF(pta, &a, &b, &c, &nafit); /* fprintf(stderr, "a = %7.3f, b = %7.3f, c = %7.3f\n", a, b, c); */ #elif DO_CUBIC ptaGetCubicLSF(pta, &a, &b, &c, &d, &nafit); /* fprintf(stderr, "a = %7.3f, b = %7.3f, c = %7.3f, d = %7.3f\n", a, b, c, d); */ #elif DO_QUARTIC ptaGetQuarticLSF(pta, &a, &b, &c, &d, &e, &nafit); /* fprintf(stderr, "a = %7.3f, b = %7.3f, c = %7.3f, d = %7.3f, e = %7.3f\n", a, b, c, d, e); */ #endif ptad = ptaCreateFromNuma(nax, nafit); pixDisplayPta(pixt2, pixt2, ptad); ptaDestroy(&pta); ptaDestroy(&ptad); numaDestroy(&nax); numaDestroy(&nafit); } pixDisplayWithTitle(pixt2, 700, 100, "fitted lines superimposed", 1); pixWrite("/tmp/textline2.png", pixt2, IFF_PNG); ptaaDestroy(&ptaa1); ptaaDestroy(&ptaa2); pixDestroy(&pixt2); /* Write out the files to be imaged */ lept_mkdir("junkdir"); pixWrite("/tmp/junkdir/001.jpg", pixs, IFF_JFIF_JPEG); pixWrite("/tmp/junkdir/002.jpg", pixn, IFF_JFIF_JPEG); pixWrite("/tmp/junkdir/003.jpg", pixg, IFF_JFIF_JPEG); pixWrite("/tmp/junkdir/004.png", pixb, IFF_TIFF_G4); pixt1 = pixRead("/tmp/textline1.png"); pixWrite("/tmp/junkdir/005.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixt1 = pixRead("/tmp/textline2.png"); pixWrite("/tmp/junkdir/006.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixt1 = pixRead("/tmp/lines1.png"); pixWrite("/tmp/junkdir/007.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixt1 = pixRead("/tmp/lines2.png"); pixWrite("/tmp/junkdir/008.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixt1 = pixRead("/tmp/vert-contours.png"); pixWrite("/tmp/junkdir/009.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixWrite("/tmp/junkdir/010.png", pixv, IFF_PNG); pixt1 = pixThresholdToBinary(pixv, 130); pixWrite("/tmp/junkdir/011.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixt1 = pixRead("/tmp/horiz-contours.png"); pixWrite("/tmp/junkdir/012.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixWrite("/tmp/junkdir/013.png", pixd, IFF_PNG); pixt1 = pixThresholdToBinary(pixd, 130); pixWrite("/tmp/junkdir/014.png", pixt1, IFF_PNG); pixDestroy(&pixt1); pixWrite("/tmp/junkdir/015.png", pixb, IFF_TIFF_G4); /* (these are for the second image) */ pixWrite("/tmp/junkdir/016.jpg", pixs2, IFF_JFIF_JPEG); pixWrite("/tmp/junkdir/017.png", pixb2, IFF_TIFF_G4); pixt1 = pixRead("/tmp/pixv.png"); pixt2 = pixThresholdToBinary(pixt1, 130); pixWrite("/tmp/junkdir/018.png", pixt2, IFF_PNG); pixDestroy(&pixt1); pixDestroy(&pixt2); pixt1 = pixRead("/tmp/pixd.png"); pixt2 = pixThresholdToBinary(pixt1, 130); pixWrite("/tmp/junkdir/019.png", pixt2, IFF_PNG); pixDestroy(&pixt1); pixDestroy(&pixt2); /* Generate the 19 page ps and pdf files */ convertFilesToPS("/tmp/junkdir", NULL, 135, "/tmp/dewarp.ps"); fprintf(stderr, "ps file made: /tmp/dewarp.ps\n"); ignore = system("ps2pdf /tmp/dewarp.ps /tmp/dewarp.pdf"); fprintf(stderr, "pdf file made: /tmp/dewarp.pdf\n"); pixDestroy(&pixs); pixDestroy(&pixn); pixDestroy(&pixg); pixDestroy(&pixb); pixDestroy(&pixs2); pixDestroy(&pixn2); pixDestroy(&pixg2); pixDestroy(&pixb2); pixDestroy(&pixv); pixDestroy(&pixd); return 0; }
int main(int argc, char **argv) { l_uint8 *array1, *array2; l_int32 i, n1, n2, n3; size_t size1, size2; FILE *fp; BOXA *boxa1, *boxa2; PIX *pixs, *pix1, *pix2, *pix3; PIXA *pixa1; PIXCMAP *cmap; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; pixs = pixRead("feyn.tif"); /* --------------------------------------------------------------- * * Test pixConnComp() and pixCountConnComp(), * * with output to both boxa and pixa * * --------------------------------------------------------------- */ /* First, test with 4-cc */ boxa1= pixConnComp(pixs, &pixa1, 4); n1 = boxaGetCount(boxa1); boxa2= pixConnComp(pixs, NULL, 4); n2 = boxaGetCount(boxa2); pixCountConnComp(pixs, 4, &n3); fprintf(stderr, "Number of 4 c.c.: n1 = %d; n2 = %d, n3 = %d\n", n1, n2, n3); regTestCompareValues(rp, n1, n2, 0); /* 0 */ regTestCompareValues(rp, n1, n3, 0); /* 1 */ regTestCompareValues(rp, n1, 4452, 0); /* 2 */ pix1 = pixaDisplay(pixa1, pixGetWidth(pixs), pixGetHeight(pixs)); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 3 */ regTestComparePix(rp, pixs, pix1); /* 4 */ pixaDestroy(&pixa1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); pixDestroy(&pix1); /* Test with 8-cc */ boxa1= pixConnComp(pixs, &pixa1, 8); n1 = boxaGetCount(boxa1); boxa2= pixConnComp(pixs, NULL, 8); n2 = boxaGetCount(boxa2); pixCountConnComp(pixs, 8, &n3); fprintf(stderr, "Number of 8 c.c.: n1 = %d; n2 = %d, n3 = %d\n", n1, n2, n3); regTestCompareValues(rp, n1, n2, 0); /* 5 */ regTestCompareValues(rp, n1, n3, 0); /* 6 */ regTestCompareValues(rp, n1, 4305, 0); /* 7 */ pix1 = pixaDisplay(pixa1, pixGetWidth(pixs), pixGetHeight(pixs)); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 8 */ regTestComparePix(rp, pixs, pix1); /* 9 */ pixaDestroy(&pixa1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); pixDestroy(&pix1); /* --------------------------------------------------------------- * * Test boxa I/O * * --------------------------------------------------------------- */ lept_mkdir("lept/conn"); boxa1 = pixConnComp(pixs, NULL, 4); fp = lept_fopen("/tmp/lept/conn/boxa1.ba", "wb+"); boxaWriteStream(fp, boxa1); lept_fclose(fp); fp = lept_fopen("/tmp/lept/conn/boxa1.ba", "rb"); boxa2 = boxaReadStream(fp); lept_fclose(fp); fp = lept_fopen("/tmp/lept/conn/boxa2.ba", "wb+"); boxaWriteStream(fp, boxa2); lept_fclose(fp); array1 = l_binaryRead("/tmp/lept/conn/boxa1.ba", &size1); array2 = l_binaryRead("/tmp/lept/conn/boxa2.ba", &size2); regTestCompareStrings(rp, array1, size1, array2, size2); /* 10 */ lept_free(array1); lept_free(array2); boxaDestroy(&boxa1); boxaDestroy(&boxa2); /* --------------------------------------------------------------- * * Just for fun, display each component as a random color in * * cmapped 8 bpp. Background is color 0; it is set to white. * * --------------------------------------------------------------- */ boxa1 = pixConnComp(pixs, &pixa1, 4); pix1 = pixaDisplayRandomCmap(pixa1, pixGetWidth(pixs), pixGetHeight(pixs)); cmap = pixGetColormap(pix1); pixcmapResetColor(cmap, 0, 255, 255, 255); /* reset background to white */ regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 11 */ if (rp->display) pixDisplay(pix1, 100, 0); boxaDestroy(&boxa1); pixDestroy(&pix1); pixaDestroy(&pixa1); pixDestroy(&pixs); /* --------------------------------------------------------------- * * Test iterative covering of connected components by rectangles * * --------------------------------------------------------------- */ pixa1 = pixaCreate(0); pix1 = pixRead("rabi.png"); pix2 = pixReduceRankBinaryCascade(pix1, 1, 1, 1, 0); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 12 - */ pixaAddPix(pixa1, pix2, L_INSERT); for (i = 1; i < 6; i++) { pix3 = pixMakeCoveringOfRectangles(pix2, i); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 13 - 17 */ pixaAddPix(pixa1, pix3, L_INSERT); } pix3 = pixaDisplayTiledInRows(pixa1, 1, 2500, 1.0, 0, 30, 0); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 18 */ pixDisplayWithTitle(pix3, 100, 900, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix3); pixaDestroy(&pixa1); return regTestCleanup(rp); }
int main(int argc, char **argv) { char *fname, *filename; const char *str; char buffer[512]; l_int32 i, npages; size_t length; FILE *fp; NUMA *naflags, *nasizes; PIX *pix, *pix1, *pix2, *pixd; PIXA *pixa; PIXCMAP *cmap; SARRAY *savals, *satypes, *sa; static char mainName[] = "mtifftest"; if (argc != 1) return ERROR_INT(" Syntax: mtifftest", mainName, 1); lept_mkdir("tiff"); #if 1 /* ------------------ Test multipage I/O -------------------*/ /* This puts every image file in the directory with a string * match to "weasel" into a multipage tiff file. * Images with 1 bpp are coded as g4; the others as zip. * It then reads back into a pix and displays. */ writeMultipageTiff(".", "weasel8.", "/tmp/tiff/weasel8.tif"); pixa = pixaReadMultipageTiff("/tmp/tiff/weasel8.tif"); pixd = pixaDisplayTiledInRows(pixa, 1, 1200, 0.5, 0, 15, 4); pixDisplay(pixd, 100, 0); pixDestroy(&pixd); pixd = pixaDisplayTiledInRows(pixa, 8, 1200, 0.8, 0, 15, 4); pixDisplay(pixd, 100, 200); pixDestroy(&pixd); pixd = pixaDisplayTiledInRows(pixa, 32, 1200, 1.2, 0, 15, 4); pixDisplay(pixd, 100, 400); pixDestroy(&pixd); pixaDestroy(&pixa); #endif #if 1 /* ------------ Test single-to-multipage I/O -------------------*/ /* Read the files and generate a multipage tiff file of G4 images. * Then convert that to a G4 compressed and ascii85 encoded PS file. */ sa = getSortedPathnamesInDirectory(".", "weasel4.", 0, 4); sarrayWriteStream(stderr, sa); sarraySort(sa, sa, L_SORT_INCREASING); sarrayWriteStream(stderr, sa); npages = sarrayGetCount(sa); for (i = 0; i < npages; i++) { fname = sarrayGetString(sa, i, 0); filename = genPathname(".", fname); pix1 = pixRead(filename); if (!pix1) continue; pix2 = pixConvertTo1(pix1, 128); if (i == 0) pixWriteTiff("/tmp/tiff/weasel4", pix2, IFF_TIFF_G4, "w+"); else pixWriteTiff("/tmp/tiff/weasel4", pix2, IFF_TIFF_G4, "a"); pixDestroy(&pix1); pixDestroy(&pix2); lept_free(filename); } /* Write it out as a PS file */ convertTiffMultipageToPS("/tmp/tiff/weasel4", "/tmp/tiff/weasel4.ps", NULL, 0.95); sarrayDestroy(&sa); #endif #if 1 /* ------------------ Test multipage I/O -------------------*/ /* Read count of pages in tiff multipage file */ writeMultipageTiff(".", "weasel2", weasel_orig); fp = lept_fopen(weasel_orig, "rb"); if (fileFormatIsTiff(fp)) { tiffGetCount(fp, &npages); fprintf(stderr, " Tiff: %d page\n", npages); } else return ERROR_INT(" file not tiff", mainName, 1); lept_fclose(fp); /* Split into separate page files */ for (i = 0; i < npages + 1; i++) { /* read one beyond to catch error */ if (i == npages) L_INFO("Errors in next 2 lines are intentional!\n", mainName); pix = pixReadTiff(weasel_orig, i); if (!pix) continue; sprintf(buffer, "/tmp/tiff/%03d.tif", i); pixWrite(buffer, pix, IFF_TIFF_ZIP); pixDestroy(&pix); } /* Read separate page files and write reversed file */ for (i = npages - 1; i >= 0; i--) { sprintf(buffer, "/tmp/tiff/%03d.tif", i); pix = pixRead(buffer); if (!pix) continue; if (i == npages - 1) pixWriteTiff(weasel_rev, pix, IFF_TIFF_ZIP, "w+"); else pixWriteTiff(weasel_rev, pix, IFF_TIFF_ZIP, "a"); pixDestroy(&pix); } /* Read reversed file and reverse again */ pixa = pixaCreate(npages); for (i = 0; i < npages; i++) { pix = pixReadTiff(weasel_rev, i); pixaAddPix(pixa, pix, L_INSERT); } for (i = npages - 1; i >= 0; i--) { pix = pixaGetPix(pixa, i, L_CLONE); if (i == npages - 1) pixWriteTiff(weasel_rev_rev, pix, IFF_TIFF_ZIP, "w+"); else pixWriteTiff(weasel_rev_rev, pix, IFF_TIFF_ZIP, "a"); pixDestroy(&pix); } pixaDestroy(&pixa); #endif #if 0 /* ----- test adding custom public tags to a tiff header ----- */ pix = pixRead("feyn.tif"); naflags = numaCreate(10); savals = sarrayCreate(10); satypes = sarrayCreate(10); nasizes = numaCreate(10); /* numaAddNumber(naflags, TIFFTAG_XMLPACKET); */ /* XMP: 700 */ numaAddNumber(naflags, 700); str = "<xmp>This is a Fake XMP packet</xmp>\n<text>Guess what ...?</text>"; length = strlen(str); sarrayAddString(savals, (char *)str, 1); sarrayAddString(satypes, (char *)"char*", 1); numaAddNumber(nasizes, length); /* get it all */ numaAddNumber(naflags, 269); /* DOCUMENTNAME */ sarrayAddString(savals, (char *)"One silly title", 1); sarrayAddString(satypes, (char *)"const char*", 1); numaAddNumber(naflags, 270); /* IMAGEDESCRIPTION */ sarrayAddString(savals, (char *)"One page of text", 1); sarrayAddString(satypes, (char *)"const char*", 1); /* the max sample is used by rendering programs * to scale the dynamic range */ numaAddNumber(naflags, 281); /* MAXSAMPLEVALUE */ sarrayAddString(savals, (char *)"4", 1); sarrayAddString(satypes, (char *)"l_uint16", 1); /* note that date is required to be a 20 byte string */ numaAddNumber(naflags, 306); /* DATETIME */ sarrayAddString(savals, (char *)"2004:10:11 09:35:15", 1); sarrayAddString(satypes, (char *)"const char*", 1); /* note that page number requires 2 l_uint16 input */ numaAddNumber(naflags, 297); /* PAGENUMBER */ sarrayAddString(savals, (char *)"1-412", 1); sarrayAddString(satypes, (char *)"l_uint16-l_uint16", 1); pixWriteTiffCustom("/tmp/tiff/tags.tif", pix, IFF_TIFF_G4, "w", naflags, savals, satypes, nasizes); fprintTiffInfo(stderr, (char *)"/tmp/tiff/tags.tif"); fprintf(stderr, "num flags = %d\n", numaGetCount(naflags)); fprintf(stderr, "num sizes = %d\n", numaGetCount(nasizes)); fprintf(stderr, "num vals = %d\n", sarrayGetCount(savals)); fprintf(stderr, "num types = %d\n", sarrayGetCount(satypes)); numaDestroy(&naflags); numaDestroy(&nasizes); sarrayDestroy(&savals); sarrayDestroy(&satypes); pixDestroy(&pix); #endif return 0; }
int main(int argc, char **argv) { l_int32 i, j; l_int32 w, h, bw, bh, wpls, rval, gval, bval, same; l_uint32 pixel; l_uint32 *lines, *datas; l_float32 sum1, sum2, ave1, ave2, ave3, ave4, diff1, diff2; l_float32 var1, var2, var3; BOX *box1, *box2; NUMA *na, *na1, *na2, *na3, *na4; PIX *pix, *pixs, *pix1, *pix2, *pix3, *pix4, *pix5, *pixg, *pixd; PIXA *pixa; static char mainName[] = "numa2_reg"; if (argc != 1) return ERROR_INT(" Syntax: numa2_reg", mainName, 1); lept_mkdir("lept"); /* -------------------------------------------------------------------* * Numa-windowed stats * * -------------------------------------------------------------------*/ #if DO_ALL na = numaRead("lyra.5.na"); numaWindowedStats(na, 5, &na1, &na2, &na3, &na4); gplotSimple1(na, GPLOT_PNG, "/tmp/lept/numa_lyra6", "Original"); gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/numa_lyra7", "Mean"); gplotSimple1(na2, GPLOT_PNG, "/tmp/lept/numa_lyra8", "Mean Square"); gplotSimple1(na3, GPLOT_PNG, "/tmp/lept/numa_lyra9", "Variance"); gplotSimple1(na4, GPLOT_PNG, "/tmp/lept/numa_lyra10", "RMS Difference"); #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ pixa = pixaCreate(5); pix1 = pixRead("/tmp/lept/numa_lyra6.png"); pix2 = pixRead("/tmp/lept/numa_lyra7.png"); pix3 = pixRead("/tmp/lept/numa_lyra8.png"); pix4 = pixRead("/tmp/lept/numa_lyra9.png"); pix5 = pixRead("/tmp/lept/numa_lyra10.png"); pixSaveTiled(pix1, pixa, 1.0, 1, 25, 32); pixSaveTiled(pix2, pixa, 1.0, 1, 25, 32); pixSaveTiled(pix3, pixa, 1.0, 0, 25, 32); pixSaveTiled(pix4, pixa, 1.0, 1, 25, 32); pixSaveTiled(pix5, pixa, 1.0, 0, 25, 32); pixd = pixaDisplay(pixa, 0, 0); pixDisplay(pixd, 100, 100); pixWrite("/tmp/lept/numa_window.png", pixd, IFF_PNG); numaDestroy(&na); numaDestroy(&na1); numaDestroy(&na2); numaDestroy(&na3); numaDestroy(&na4); pixaDestroy(&pixa); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pixd); #endif /* -------------------------------------------------------------------* * Extraction on a line * * -------------------------------------------------------------------*/ #if DO_ALL /* First, make a pretty image */ w = h = 200; pixs = pixCreate(w, h, 32); wpls = pixGetWpl(pixs); datas = pixGetData(pixs); for (i = 0; i < 200; i++) { lines = datas + i * wpls; for (j = 0; j < 200; j++) { rval = (l_int32)((255. * j) / w + (255. * i) / h); gval = (l_int32)((255. * 2 * j) / w + (255. * 2 * i) / h) % 255; bval = (l_int32)((255. * 4 * j) / w + (255. * 4 * i) / h) % 255; composeRGBPixel(rval, gval, bval, &pixel); lines[j] = pixel; } } pixg = pixConvertTo8(pixs, 0); /* and a grayscale version */ pixWrite("/tmp/lept/numa_pixg.png", pixg, IFF_PNG); pixDisplay(pixg, 450, 100); na1 = pixExtractOnLine(pixg, 20, 20, 180, 20, 1); na2 = pixExtractOnLine(pixg, 40, 30, 40, 170, 1); na3 = pixExtractOnLine(pixg, 20, 170, 180, 30, 1); na4 = pixExtractOnLine(pixg, 20, 190, 180, 10, 1); gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/numa_ext1", "Horizontal"); gplotSimple1(na2, GPLOT_PNG, "/tmp/lept/numa_ext2", "Vertical"); gplotSimple1(na3, GPLOT_PNG, "/tmp/lept/numa_ext3", "Slightly more horizontal than vertical"); gplotSimple1(na4, GPLOT_PNG, "/tmp/lept/numa_ext4", "Slightly more vertical than horizontal"); #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ pixa = pixaCreate(4); pix1 = pixRead("/tmp/lept/numa_ext1.png"); pix2 = pixRead("/tmp/lept/numa_ext2.png"); pix3 = pixRead("/tmp/lept/numa_ext3.png"); pix4 = pixRead("/tmp/lept/numa_ext4.png"); pixSaveTiled(pix1, pixa, 1.0, 1, 25, 32); pixSaveTiled(pix2, pixa, 1.0, 0, 25, 32); pixSaveTiled(pix3, pixa, 1.0, 1, 25, 32); pixSaveTiled(pix4, pixa, 1.0, 0, 25, 32); pixd = pixaDisplay(pixa, 0, 0); pixDisplay(pixd, 100, 500); pixWrite("/tmp/lept/numa_extract.png", pixd, IFF_PNG); numaDestroy(&na1); numaDestroy(&na2); numaDestroy(&na3); numaDestroy(&na4); pixaDestroy(&pixa); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pixs); pixDestroy(&pixg); pixDestroy(&pixd); #endif /* -------------------------------------------------------------------* * Row and column pixel sums * * -------------------------------------------------------------------*/ #if DO_ALL /* Sum by columns in two halves (left and right) */ pixs = pixRead("test8.jpg"); pixGetDimensions(pixs, &w, &h, NULL); box1 = boxCreate(0, 0, w / 2, h); box2 = boxCreate(w / 2, 0, w - 2 / 2, h); na1 = pixAverageByColumn(pixs, box1, L_BLACK_IS_MAX); na2 = pixAverageByColumn(pixs, box2, L_BLACK_IS_MAX); numaJoin(na1, na2, 0, -1); na3 = pixAverageByColumn(pixs, NULL, L_BLACK_IS_MAX); numaSimilar(na1, na3, 0.0, &same); if (same) fprintf(stderr, "Same for columns\n"); else fprintf(stderr, "Error for columns\n"); pix = pixConvertTo32(pixs); pixRenderPlotFromNumaGen(&pix, na3, L_HORIZONTAL_LINE, 3, h / 2, 80, 1, 0xff000000); pixRenderPlotFromNuma(&pix, na3, L_PLOT_AT_BOT, 3, 80, 0xff000000); boxDestroy(&box1); boxDestroy(&box2); numaDestroy(&na1); numaDestroy(&na2); numaDestroy(&na3); /* Sum by rows in two halves (top and bottom) */ box1 = boxCreate(0, 0, w, h / 2); box2 = boxCreate(0, h / 2, w, h - h / 2); na1 = pixAverageByRow(pixs, box1, L_WHITE_IS_MAX); na2 = pixAverageByRow(pixs, box2, L_WHITE_IS_MAX); numaJoin(na1, na2, 0, -1); na3 = pixAverageByRow(pixs, NULL, L_WHITE_IS_MAX); numaSimilar(na1, na3, 0.0, &same); if (same) fprintf(stderr, "Same for rows\n"); else fprintf(stderr, "Error for rows\n"); pixRenderPlotFromNumaGen(&pix, na3, L_VERTICAL_LINE, 3, w / 2, 80, 1, 0x00ff0000); pixRenderPlotFromNuma(&pix, na3, L_PLOT_AT_RIGHT, 3, 80, 0x00ff0000); pixDisplay(pix, 500, 200); boxDestroy(&box1); boxDestroy(&box2); numaDestroy(&na1); numaDestroy(&na2); numaDestroy(&na3); pixDestroy(&pix); /* Average left by rows; right by columns; compare totals */ box1 = boxCreate(0, 0, w / 2, h); box2 = boxCreate(w / 2, 0, w - 2 / 2, h); na1 = pixAverageByRow(pixs, box1, L_WHITE_IS_MAX); na2 = pixAverageByColumn(pixs, box2, L_WHITE_IS_MAX); numaGetSum(na1, &sum1); /* sum of averages of left box */ numaGetSum(na2, &sum2); /* sum of averages of right box */ ave1 = sum1 / h; ave2 = 2.0 * sum2 / w; ave3 = 0.5 * (ave1 + ave2); /* average over both halves */ fprintf(stderr, "ave1 = %8.4f\n", sum1 / h); fprintf(stderr, "ave2 = %8.4f\n", 2.0 * sum2 / w); pixAverageInRect(pixs, NULL, &ave4); /* entire image */ diff1 = ave4 - ave3; diff2 = w * h * ave4 - (0.5 * w * sum1 + h * sum2); if (diff1 < 0.001) fprintf(stderr, "Average diffs are correct\n"); else fprintf(stderr, "Average diffs are wrong: diff1 = %7.5f\n", diff1); if (diff2 < 20) /* float-to-integer roundoff */ fprintf(stderr, "Pixel sums are correct\n"); else fprintf(stderr, "Pixel sums are in error: diff = %7.0f\n", diff2); /* Variance left and right halves. Variance doesn't average * in a simple way, unlike pixel sums. */ pixVarianceInRect(pixs, box1, &var1); /* entire image */ pixVarianceInRect(pixs, box2, &var2); /* entire image */ pixVarianceInRect(pixs, NULL, &var3); /* entire image */ fprintf(stderr, "0.5 * (var1 + var2) = %7.3f, var3 = %7.3f\n", 0.5 * (var1 + var2), var3); boxDestroy(&box1); boxDestroy(&box2); numaDestroy(&na1); numaDestroy(&na2); #endif /* -------------------------------------------------------------------* * Row and column variances * * -------------------------------------------------------------------*/ #if DO_ALL /* Display variance by rows and columns */ box1 = boxCreate(415, 0, 130, 425); boxGetGeometry(box1, NULL, NULL, &bw, &bh); na1 = pixVarianceByRow(pixs, box1); na2 = pixVarianceByColumn(pixs, box1); pix = pixConvertTo32(pixs); pix1 = pixCopy(NULL, pix); pixRenderPlotFromNumaGen(&pix, na1, L_VERTICAL_LINE, 3, 415, 100, 1, 0xff000000); pixRenderPlotFromNumaGen(&pix, na2, L_HORIZONTAL_LINE, 3, bh / 2, 100, 1, 0x00ff0000); pixRenderPlotFromNuma(&pix1, na1, L_PLOT_AT_LEFT, 3, 60, 0x00ff0000); pixRenderPlotFromNuma(&pix1, na1, L_PLOT_AT_MID_VERT, 3, 60, 0x0000ff00); pixRenderPlotFromNuma(&pix1, na1, L_PLOT_AT_RIGHT, 3, 60, 0xff000000); pixRenderPlotFromNuma(&pix1, na2, L_PLOT_AT_TOP, 3, 60, 0x0000ff00); pixRenderPlotFromNuma(&pix1, na2, L_PLOT_AT_MID_HORIZ, 3, 60, 0xff000000); pixRenderPlotFromNuma(&pix1, na2, L_PLOT_AT_BOT, 3, 60, 0x00ff0000); pixDisplay(pix, 500, 900); pixDisplay(pix1, 500, 1000); boxDestroy(&box1); numaDestroy(&na1); numaDestroy(&na2); pixDestroy(&pix); pixDestroy(&pix1); pixDestroy(&pixs); /* Again on a different image */ pix1 = pixRead("boxedpage.jpg"); pix2 = pixConvertTo8(pix1, 0); pixGetDimensions(pix2, &w, &h, NULL); na1 = pixVarianceByRow(pix2, NULL); pix3 = pixConvertTo32(pix1); pixRenderPlotFromNumaGen(&pix3, na1, L_VERTICAL_LINE, 3, 0, 70, 1, 0xff000000); na2 = pixVarianceByColumn(pix2, NULL); pixRenderPlotFromNumaGen(&pix3, na2, L_HORIZONTAL_LINE, 3, bh - 1, 70, 1, 0x00ff0000); pixDisplay(pix3, 1000, 0); numaDestroy(&na1); numaDestroy(&na2); pixDestroy(&pix3); /* Again, with an erosion */ pix3 = pixErodeGray(pix2, 3, 21); pixDisplay(pix3, 1400, 0); na1 = pixVarianceByRow(pix3, NULL); pix4 = pixConvertTo32(pix1); pixRenderPlotFromNumaGen(&pix4, na1, L_VERTICAL_LINE, 3, 30, 70, 1, 0xff000000); na2 = pixVarianceByColumn(pix3, NULL); pixRenderPlotFromNumaGen(&pix4, na2, L_HORIZONTAL_LINE, 3, bh - 1, 70, 1, 0x00ff0000); pixDisplay(pix4, 1000, 550); numaDestroy(&na1); numaDestroy(&na2); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); #endif /* -------------------------------------------------------------------* * Windowed variance along a line * * -------------------------------------------------------------------*/ #if DO_ALL pix1 = pixRead("boxedpage.jpg"); pix2 = pixConvertTo8(pix1, 0); pixGetDimensions(pix2, &w, &h, NULL); pix3 = pixCopy(NULL, pix1); /* Plot along horizontal line */ pixWindowedVarianceOnLine(pix2, L_HORIZONTAL_LINE, h / 2 - 30, 0, w, 5, &na1); pixRenderPlotFromNumaGen(&pix1, na1, L_HORIZONTAL_LINE, 3, h / 2 - 30, 80, 1, 0xff000000); pixRenderPlotFromNuma(&pix3, na1, L_PLOT_AT_TOP, 3, 60, 0x00ff0000); pixRenderPlotFromNuma(&pix3, na1, L_PLOT_AT_BOT, 3, 60, 0x0000ff00); /* Plot along vertical line */ pixWindowedVarianceOnLine(pix2, L_VERTICAL_LINE, 0.78 * w, 0, h, 5, &na2); pixRenderPlotFromNumaGen(&pix1, na2, L_VERTICAL_LINE, 3, 0.78 * w, 60, 1, 0x00ff0000); pixRenderPlotFromNuma(&pix3, na2, L_PLOT_AT_LEFT, 3, 60, 0xff000000); pixRenderPlotFromNuma(&pix3, na2, L_PLOT_AT_RIGHT, 3, 60, 0x00ff0000); pixDisplay(pix1, 1000, 1000); pixDisplay(pix3, 1500, 1000); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); numaDestroy(&na1); numaDestroy(&na2); #endif return 0; }
int main(int argc, char **argv) { char *filename; l_int32 w, h, type, maxboxes; l_float32 ovlap; BOX *box; BOXA *boxa, *boxat, *boxad; PIX *pix, *pixt, *pixs, *pixd; static char mainName[] = "partitiontest"; if (argc != 3 && argc != 5) return ERROR_INT("syntax: partitiontest <fname> type [maxboxes ovlap]", mainName, 1); filename = argv[1]; type = atoi(argv[2]); if (type == L_SORT_BY_WIDTH) fprintf(stderr, "Sorting by width:\n"); else if (type == L_SORT_BY_HEIGHT) fprintf(stderr, "Sorting by height:\n"); else if (type == L_SORT_BY_MAX_DIMENSION) fprintf(stderr, "Sorting by maximum dimension:\n"); else if (type == L_SORT_BY_MIN_DIMENSION) fprintf(stderr, "Sorting by minimum dimension:\n"); else if (type == L_SORT_BY_PERIMETER) fprintf(stderr, "Sorting by perimeter:\n"); else if (type == L_SORT_BY_AREA) fprintf(stderr, "Sorting by area:\n"); else { fprintf(stderr, "Use one of the following for 'type':\n" " 5: L_SORT_BY_WIDTH\n" " 6: L_SORT_BY_HEIGHT\n" " 7: L_SORT_BY_MIN_DIMENSION\n" " 8: L_SORT_BY_MAX_DIMENSION\n" " 9: L_SORT_BY_PERIMETER\n" " 10: L_SORT_BY_AREA\n"); return ERROR_INT("invalid type: see source", mainName, 1); } if (argc == 5) { maxboxes = atoi(argv[3]); ovlap = atof(argv[4]); } else { maxboxes = 100; ovlap = 0.2; } pixDisplayWrite(NULL, -1); lept_mkdir("lept/part"); pix = pixRead(filename); pixs = pixConvertTo1(pix, 128); pixDilateBrick(pixs, pixs, 5, 5); boxa = pixConnComp(pixs, NULL, 4); pixGetDimensions(pixs, &w, &h, NULL); box = boxCreate(0, 0, w, h); startTimer(); boxaPermuteRandom(boxa, boxa); boxat = boxaSelectBySize(boxa, 500, 500, L_SELECT_IF_BOTH, L_SELECT_IF_LT, NULL); boxad = boxaGetWhiteblocks(boxat, box, type, maxboxes, ovlap, 200, 0.15, 20000); fprintf(stderr, "Time: %7.3f sec\n", stopTimer()); boxaWriteStream(stderr, boxad); pixDisplayWrite(pixs, REDUCTION); /* Display box outlines in a single color in a cmapped image */ pixd = pixDrawBoxa(pixs, boxad, 7, 0xe0708000); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixd); /* Display box outlines in a single color in an RGB image */ pixt = pixConvertTo8(pixs, FALSE); pixd = pixDrawBoxa(pixt, boxad, 7, 0x40a0c000); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixt); pixDestroy(&pixd); /* Display box outlines with random colors in a cmapped image */ pixd = pixDrawBoxaRandom(pixs, boxad, 7); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixd); /* Display box outlines with random colors in an RGB image */ pixt = pixConvertTo8(pixs, FALSE); pixd = pixDrawBoxaRandom(pixt, boxad, 7); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixt); pixDestroy(&pixd); /* Display boxes in the same color in a cmapped image */ pixd = pixPaintBoxa(pixs, boxad, 0x60e0a000); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixd); /* Display boxes in the same color in an RGB image */ pixt = pixConvertTo8(pixs, FALSE); pixd = pixPaintBoxa(pixt, boxad, 0xc030a000); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixt); pixDestroy(&pixd); /* Display boxes in random colors in a cmapped image */ pixd = pixPaintBoxaRandom(pixs, boxad); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixd); /* Display boxes in random colors in an RGB image */ pixt = pixConvertTo8(pixs, FALSE); pixd = pixPaintBoxaRandom(pixt, boxad); pixDisplayWrite(pixd, REDUCTION); pixDestroy(&pixt); pixDestroy(&pixd); fprintf(stderr, "Writing to: /tmp/lept/part/partition.pdf\n"); pixDisplayMultiple(150, 1.0, "/tmp/lept/part/partition.pdf"); pixDestroy(&pix); pixDestroy(&pixs); boxDestroy(&box); boxaDestroy(&boxa); boxaDestroy(&boxat); boxaDestroy(&boxad); return 0; }
int main(int argc, char **argv) { PIX *pixs; l_int32 d; static char mainName[] = "scaletest2"; if (argc != 2) return ERROR_INT(" Syntax: scaletest2 filein", mainName, 1); if ((pixs = pixRead(argv[1])) == NULL) return ERROR_INT("pixs not made", mainName, 1); d = pixGetDepth(pixs); lept_mkdir("lept/scale"); #if 1 /* Integer scale-to-gray functions */ if (d == 1) { PIX *pixd; pixd = pixScaleToGray2(pixs); pixWrite("/tmp/lept/scale/s2g_2x", pixd, IFF_PNG); pixDestroy(&pixd); pixd = pixScaleToGray3(pixs); pixWrite("/tmp/lept/scale/s2g_3x", pixd, IFF_PNG); pixDestroy(&pixd); pixd = pixScaleToGray4(pixs); pixWrite("/tmp/lept/scale/s2g_4x", pixd, IFF_PNG); pixDestroy(&pixd); pixd = pixScaleToGray6(pixs); pixWrite("/tmp/lept/scale/s2g_6x", pixd, IFF_PNG); pixDestroy(&pixd); pixd = pixScaleToGray8(pixs); pixWrite("/tmp/lept/scale/s2g_8x", pixd, IFF_PNG); pixDestroy(&pixd); pixd = pixScaleToGray16(pixs); pixWrite("/tmp/lept/scale/s2g_16x", pixd, IFF_PNG); pixDestroy(&pixd); } #endif #if 1 /* Various non-integer scale-to-gray, compared with * with different ways of getting similar results */ if (d == 1) { PIX *pixt, *pixd; pixd = pixScaleToGray8(pixs); pixWrite("/tmp/lept/scale/s2g_8.png", pixd, IFF_PNG); pixDestroy(&pixd); pixd = pixScaleToGray(pixs, 0.124); pixWrite("/tmp/lept/scale/s2g_124.png", pixd, IFF_PNG); pixDestroy(&pixd); pixd = pixScaleToGray(pixs, 0.284); pixWrite("/tmp/lept/scale/s2g_284.png", pixd, IFF_PNG); pixDestroy(&pixd); pixt = pixScaleToGray4(pixs); pixd = pixScaleBySampling(pixt, 284./250., 284./250.); pixWrite("/tmp/lept/scale/s2g_284.2.png", pixd, IFF_PNG); pixDestroy(&pixt); pixDestroy(&pixd); pixt = pixScaleToGray4(pixs); pixd = pixScaleGrayLI(pixt, 284./250., 284./250.); pixWrite("/tmp/lept/scale/s2g_284.3.png", pixd, IFF_PNG); pixDestroy(&pixt); pixDestroy(&pixd); pixt = pixScaleBinary(pixs, 284./250., 284./250.); pixd = pixScaleToGray4(pixt); pixWrite("/tmp/lept/scale/s2g_284.4.png", pixd, IFF_PNG); pixDestroy(&pixt); pixDestroy(&pixd); pixt = pixScaleToGray4(pixs); pixd = pixScaleGrayLI(pixt, 0.49, 0.49); pixWrite("/tmp/lept/scale/s2g_42.png", pixd, IFF_PNG); pixDestroy(&pixt); pixDestroy(&pixd); pixt = pixScaleToGray4(pixs); pixd = pixScaleSmooth(pixt, 0.49, 0.49); pixWrite("/tmp/lept/scale/s2g_4sm.png", pixd, IFF_PNG); pixDestroy(&pixt); pixDestroy(&pixd); pixt = pixScaleBinary(pixs, .16/.125, .16/.125); pixd = pixScaleToGray8(pixt); pixWrite("/tmp/lept/scale/s2g_16.png", pixd, IFF_PNG); pixDestroy(&pixt); pixDestroy(&pixd); pixd = pixScaleToGray(pixs, .16); pixWrite("/tmp/lept/scale/s2g_16.2.png", pixd, IFF_PNG); pixDestroy(&pixd); } #endif #if 1 /* Antialiased (smoothed) reduction, along with sharpening */ if (d != 1) { PIX *pixt1, *pixt2; startTimer(); pixt1 = pixScaleSmooth(pixs, 0.154, 0.154); fprintf(stderr, "fast scale: %5.3f sec\n", stopTimer()); pixDisplayWithTitle(pixt1, 0, 0, "smooth scaling", DISPLAY); pixWrite("/tmp/lept/scale/smooth1.png", pixt1, IFF_PNG); pixt2 = pixUnsharpMasking(pixt1, 1, 0.3); pixWrite("/tmp/lept/scale/smooth2.png", pixt2, IFF_PNG); pixDisplayWithTitle(pixt2, 200, 0, "sharp scaling", DISPLAY); pixDestroy(&pixt1); pixDestroy(&pixt2); } #endif #if 1 /* Test a large range of scale-to-gray reductions */ if (d == 1) { l_int32 i; l_float32 scale; PIX *pixd; for (i = 2; i < 15; i++) { scale = 1. / (l_float32)i; startTimer(); pixd = pixScaleToGray(pixs, scale); fprintf(stderr, "Time for scale %7.3f: %7.3f sec\n", scale, stopTimer()); pixDisplayWithTitle(pixd, 75 * i, 100, "scaletogray", DISPLAY); pixDestroy(&pixd); } for (i = 8; i < 14; i++) { scale = 1. / (l_float32)(2 * i); startTimer(); pixd = pixScaleToGray(pixs, scale); fprintf(stderr, "Time for scale %7.3f: %7.3f sec\n", scale, stopTimer()); pixDisplayWithTitle(pixd, 100 * i, 600, "scaletogray", DISPLAY); pixDestroy(&pixd); } } #endif #if 1 /* Test the same range of scale-to-gray mipmap reductions */ if (d == 1) { l_int32 i; l_float32 scale; PIX *pixd; for (i = 2; i < 15; i++) { scale = 1. / (l_float32)i; startTimer(); pixd = pixScaleToGrayMipmap(pixs, scale); fprintf(stderr, "Time for scale %7.3f: %7.3f sec\n", scale, stopTimer()); pixDisplayWithTitle(pixd, 75 * i, 100, "scale mipmap", DISPLAY); pixDestroy(&pixd); } for (i = 8; i < 12; i++) { scale = 1. / (l_float32)(2 * i); startTimer(); pixd = pixScaleToGrayMipmap(pixs, scale); fprintf(stderr, "Time for scale %7.3f: %7.3f sec\n", scale, stopTimer()); pixDisplayWithTitle(pixd, 100 * i, 600, "scale mipmap", DISPLAY); pixDestroy(&pixd); } } #endif #if 1 /* Test several methods for antialiased reduction, * along with sharpening */ if (d != 1) { PIX *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6, *pixt7; l_float32 SCALING = 0.27; l_int32 SIZE = 7; l_int32 smooth; l_float32 FRACT = 1.0; smooth = SIZE / 2; startTimer(); pixt1 = pixScaleSmooth(pixs, SCALING, SCALING); fprintf(stderr, "fast scale: %5.3f sec\n", stopTimer()); pixDisplayWithTitle(pixt1, 0, 0, "smooth scaling", DISPLAY); pixWrite("/tmp/lept/scale/sm_1.png", pixt1, IFF_PNG); pixt2 = pixUnsharpMasking(pixt1, 1, 0.3); pixDisplayWithTitle(pixt2, 150, 0, "sharpened scaling", DISPLAY); startTimer(); pixt3 = pixBlockconv(pixs, smooth, smooth); pixt4 = pixScaleBySampling(pixt3, SCALING, SCALING); fprintf(stderr, "slow scale: %5.3f sec\n", stopTimer()); pixDisplayWithTitle(pixt4, 200, 200, "sampled scaling", DISPLAY); pixWrite("/tmp/lept/scale/sm_2.png", pixt4, IFF_PNG); startTimer(); pixt5 = pixUnsharpMasking(pixs, smooth, FRACT); pixt6 = pixBlockconv(pixt5, smooth, smooth); pixt7 = pixScaleBySampling(pixt6, SCALING, SCALING); fprintf(stderr, "very slow scale + sharp: %5.3f sec\n", stopTimer()); pixDisplayWithTitle(pixt7, 500, 200, "sampled scaling", DISPLAY); pixWrite("/tmp/lept/scale/sm_3.jpg", pixt7, IFF_JFIF_JPEG); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); pixDestroy(&pixt5); pixDestroy(&pixt6); pixDestroy(&pixt7); } #endif #if 1 /* Test the color scaling function, comparing the * special case of scaling factor 2.0 with the * general case. */ if (d == 32) { PIX *pix1, *pix2, *pixd; NUMA *nar, *nag, *nab, *naseq; GPLOT *gplot; startTimer(); pix1 = pixScaleColorLI(pixs, 2.00001, 2.0); fprintf(stderr, " Time with regular LI: %7.3f\n", stopTimer()); pixWrite("/tmp/lept/scale/color1.jpg", pix1, IFF_JFIF_JPEG); startTimer(); pix2 = pixScaleColorLI(pixs, 2.0, 2.0); fprintf(stderr, " Time with 2x LI: %7.3f\n", stopTimer()); pixWrite("/tmp/lept/scale/color2.jpg", pix2, IFF_JFIF_JPEG); pixd = pixAbsDifference(pix1, pix2); pixGetColorHistogram(pixd, 1, &nar, &nag, &nab); naseq = numaMakeSequence(0., 1., 256); gplot = gplotCreate("/tmp/lept/scale/c_absdiff", GPLOT_PNG, "Number vs diff", "diff", "number"); gplotSetScaling(gplot, GPLOT_LOG_SCALE_Y); gplotAddPlot(gplot, naseq, nar, GPLOT_POINTS, "red"); gplotAddPlot(gplot, naseq, nag, GPLOT_POINTS, "green"); gplotAddPlot(gplot, naseq, nab, GPLOT_POINTS, "blue"); gplotMakeOutput(gplot); l_fileDisplay("/tmp/lept/scale/c_absdiff.png", 0, 100); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pixd); numaDestroy(&naseq); numaDestroy(&nar); numaDestroy(&nag); numaDestroy(&nab); gplotDestroy(&gplot); } #endif #if 1 /* Test the gray LI scaling function, comparing the * special cases of scaling factor 2.0 and 4.0 with the * general case */ if (d == 8 || d == 32) { PIX *pixt, *pix0, *pix1, *pix2, *pixd; NUMA *nagray, *naseq; GPLOT *gplot; if (d == 8) pixt = pixClone(pixs); else pixt = pixConvertRGBToGray(pixs, 0.33, 0.34, 0.33); pix0 = pixScaleGrayLI(pixt, 0.5, 0.5); #if 1 startTimer(); pix1 = pixScaleGrayLI(pix0, 2.00001, 2.0); fprintf(stderr, " Time with regular LI 2x: %7.3f\n", stopTimer()); startTimer(); pix2 = pixScaleGrayLI(pix0, 2.0, 2.0); fprintf(stderr, " Time with 2x LI: %7.3f\n", stopTimer()); #else startTimer(); pix1 = pixScaleGrayLI(pix0, 4.00001, 4.0); fprintf(stderr, " Time with regular LI 4x: %7.3f\n", stopTimer()); startTimer(); pix2 = pixScaleGrayLI(pix0, 4.0, 4.0); fprintf(stderr, " Time with 2x LI: %7.3f\n", stopTimer()); #endif pixWrite("/tmp/lept/scale/gray1", pix1, IFF_JFIF_JPEG); pixWrite("/tmp/lept/scale/gray2", pix2, IFF_JFIF_JPEG); pixd = pixAbsDifference(pix1, pix2); nagray = pixGetGrayHistogram(pixd, 1); naseq = numaMakeSequence(0., 1., 256); gplot = gplotCreate("/tmp/lept/scale/g_absdiff", GPLOT_PNG, "Number vs diff", "diff", "number"); gplotSetScaling(gplot, GPLOT_LOG_SCALE_Y); gplotAddPlot(gplot, naseq, nagray, GPLOT_POINTS, "gray"); gplotMakeOutput(gplot); l_fileDisplay("/tmp/lept/scale/g_absdiff.png", 750, 100); pixDestroy(&pixt); pixDestroy(&pix0); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pixd); numaDestroy(&naseq); numaDestroy(&nagray); gplotDestroy(&gplot); } #endif pixDestroy(&pixs); return 0; }
int main(int argc, char **argv) { char *str1, *str2, *pngname; l_int32 i; size_t size1, size2; l_float32 x, y1, y2, pi; GPLOT *gplot1, *gplot2, *gplot3, *gplot4, *gplot5; NUMA *nax, *nay1, *nay2; static char mainName[] = "plottest"; if (argc != 1) return ERROR_INT(" Syntax: plottest", mainName, 1); lept_mkdir("lept/plot"); /* Generate plot data */ nax = numaCreate(0); nay1 = numaCreate(0); nay2 = numaCreate(0); pi = 3.1415926535; for (i = 0; i < 180; i++) { x = (pi / 180.) * i; y1 = (l_float32)sin(2.4 * x); y2 = (l_float32)cos(2.4 * x); numaAddNumber(nax, x); numaAddNumber(nay1, y1); numaAddNumber(nay2, y2); } /* Show the plot */ gplot1 = gplotCreate("/tmp/lept/plot/set1", GPLOT_OUTPUT, "Example plots", "theta", "f(theta)"); gplotAddPlot(gplot1, nax, nay1, GPLOT_STYLE, "sin (2.4 * theta)"); gplotAddPlot(gplot1, nax, nay2, GPLOT_STYLE, "cos (2.4 * theta)"); gplotMakeOutput(gplot1); /* Also save the plot to png */ gplot1->outformat = GPLOT_PNG; pngname = genPathname("/tmp/lept/plot", "set1.png"); stringReplace(&gplot1->outname, pngname); gplotMakeOutput(gplot1); l_fileDisplay("/tmp/lept/plot/set1.png", 100, 100, 1.0); lept_free(pngname); /* Test gplot serialization */ gplotWrite("/tmp/lept/plot/plot1.gp", gplot1); if ((gplot2 = gplotRead("/tmp/lept/plot/plot1.gp")) == NULL) return ERROR_INT("gplotRead failure!", mainName, 1); gplotWrite("/tmp/lept/plot/plot2.gp", gplot2); /* Are the two written gplot files the same? */ str1 = (char *)l_binaryRead("/tmp/lept/plot/plot1.gp", &size1); str2 = (char *)l_binaryRead("/tmp/lept/plot/plot2.gp", &size2); if (size1 != size2) fprintf(stderr, "Error: size1 = %lu, size2 = %lu\n", (unsigned long)size1, (unsigned long)size2); else fprintf(stderr, "Correct: size1 = size2 = %lu\n", (unsigned long)size1); if (strcmp(str1, str2)) fprintf(stderr, "Error: str1 != str2\n"); else fprintf(stderr, "Correct: str1 == str2\n"); lept_free(str1); lept_free(str2); /* Read from file and regenerate the plot */ gplot3 = gplotRead("/tmp/lept/plot/plot2.gp"); stringReplace(&gplot3->title , "Example plots regen"); gplot3->outformat = GPLOT_PNG; gplotMakeOutput(gplot3); /* Build gplot but do not make the output formatted stuff */ gplot4 = gplotCreate("/tmp/lept/plot/set2", GPLOT_OUTPUT, "Example plots 2", "theta", "f(theta)"); gplotAddPlot(gplot4, nax, nay1, GPLOT_STYLE, "sin (2.4 * theta)"); gplotAddPlot(gplot4, nax, nay2, GPLOT_STYLE, "cos (2.4 * theta)"); /* Write, read back, and generate the plot */ gplotWrite("/tmp/lept/plot/plot4.gp", gplot4); if ((gplot5 = gplotRead("/tmp/lept/plot/plot4.gp")) == NULL) return ERROR_INT("gplotRead failure!", mainName, 1); gplotMakeOutput(gplot5); l_fileDisplay("/tmp/lept/plot/set2.png", 750, 100, 1.0); gplotDestroy(&gplot1); gplotDestroy(&gplot2); gplotDestroy(&gplot3); gplotDestroy(&gplot4); gplotDestroy(&gplot5); numaDestroy(&nax); numaDestroy(&nay1); numaDestroy(&nay2); return 0; }
int main(int argc, char **argv) { l_int32 w, h, ystart, yend, y, ymax, ymid, i, window, sum1, sum2, rankx; l_uint32 uval; l_float32 ave, rankval, maxvar, variance, norm, conf, angle, radangle; NUMA *na1; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7; PIXA *pixa; static char mainName[] = "findbinding"; if (argc != 1) return ERROR_INT(" Syntax: findbinding", mainName, 1); lept_mkdir("lept/binding"); pixa = pixaCreate(0); pix1 = pixRead("binding-example.45.jpg"); pix2 = pixConvertTo8(pix1, 0); /* Find the skew angle */ pix3 = pixConvertTo1(pix2, 150); pixFindSkewSweepAndSearch(pix3, &angle, &conf, 2, 2, 7.0, 1.0, 0.01); fprintf(stderr, "angle = %f, conf = %f\n", angle, conf); /* Deskew, bringing in black pixels at the edges */ if (L_ABS(angle) < 0.1 || conf < 1.5) { pix4 = pixClone(pix2); } else { radangle = 3.1416 * angle / 180.0; pix4 = pixRotate(pix2, radangle, L_ROTATE_AREA_MAP, L_BRING_IN_BLACK, 0, 0); } /* Rotate 90 degrees to make binding horizontal */ pix5 = pixRotateOrth(pix4, 1); /* Sort pixels in each row by their gray value. * Dark pixels on the left, light ones on the right. */ pix6 = pixRankRowTransform(pix5); pixDisplay(pix5, 0, 0); pixDisplay(pix6, 550, 0); pixaAddPix(pixa, pix4, L_COPY); pixaAddPix(pixa, pix5, L_COPY); pixaAddPix(pixa, pix6, L_COPY); /* Make an a priori estimate of the y-interval within which the * binding will be found. The search will be done in this interval. */ pixGetDimensions(pix6, &w, &h, NULL); ystart = 0.25 * h; yend = 0.75 * h; /* Choose a very light rank value; close to white, which * corresponds to a column in pix6 near the right side. */ rankval = 0.98; rankx = (l_int32)(w * rankval); /* Investigate variance in a small window (vertical, size = 5) * of the pixels in that column. These are the %rankval * pixels in each raster of pix6. Find the y-location of * maximum variance. */ window = 5; norm = 1.0 / window; maxvar = 0.0; na1 = numaCreate(0); numaSetParameters(na1, ystart, 1); for (y = ystart; y <= yend; y++) { sum1 = sum2 = 0; for (i = 0; i < window; i++) { pixGetPixel(pix6, rankx, y + i, &uval); sum1 += uval; sum2 += uval * uval; } ave = norm * sum1; variance = norm * sum2 - ave * ave; numaAddNumber(na1, variance); ymid = y + window / 2; if (variance > maxvar) { maxvar = variance; ymax = ymid; } } /* Plot the windowed variance as a function of the y-value * of the window location */ fprintf(stderr, "maxvar = %f, ymax = %d\n", maxvar, ymax); gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/binding/root", NULL); pix7 = pixRead("/tmp/lept/binding/root.png"); pixDisplay(pix7, 0, 800); pixaAddPix(pixa, pix7, L_COPY); /* Superimpose the variance plot over the image. * The variance peak is at the binding. */ pixRenderPlotFromNumaGen(&pix5, na1, L_VERTICAL_LINE, 3, w - 120, 100, 1, 0x0000ff00); pixDisplay(pix5, 1050, 0); pixaAddPix(pixa, pix5, L_COPY); /* Bundle the results up in a pdf */ fprintf(stderr, "Writing pdf output file: /tmp/lept/binding/binding.pdf\n"); pixaConvertToPdf(pixa, 45, 1.0, 0, 0, "Binding locator", "/tmp/lept/binding/binding.pdf"); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); pixDestroy(&pix7); pixaDestroy(&pixa); numaDestroy(&na1); return 0; }
/*! * pixDisplayWriteFormat() * * Input: pix (1, 2, 4, 8, 16, 32 bpp) * reduction (-1 to reset/erase; 0 to disable; * otherwise this is a reduction factor) * format (IFF_PNG or IFF_JFIF_JPEG) * Return: 0 if OK; 1 on error * * Notes: * (1) This writes files if reduction > 0. These can be displayed using * pixDisplayMultiple("/tmp/display/file*"); * (2) All previously written files can be erased by calling with * reduction < 0; the value of pixs is ignored. * (3) If reduction > 1 and depth == 1, this does a scale-to-gray * reduction. * (4) This function uses a static internal variable to number * output files written by a single process. Behavior * with a shared library may be unpredictable. * (5) Output file format is as follows: * format == IFF_JFIF_JPEG: * png if d < 8 or d == 16 or if the output pix * has a colormap. Otherwise, output is jpg. * format == IFF_PNG: * png (lossless) on all images. * (6) For 16 bpp, the choice of full dynamic range with log scale * is the best for displaying these images. Alternative outputs are * pix8 = pixMaxDynamicRange(pixt, L_LINEAR_SCALE); * pix8 = pixConvert16To8(pixt, 0); // low order byte * pix8 = pixConvert16To8(pixt, 1); // high order byte */ l_int32 pixDisplayWriteFormat(PIX *pixs, l_int32 reduction, l_int32 format) { char buf[L_BUF_SIZE]; char *fname; l_float32 scale; PIX *pixt, *pix8; static l_int32 index = 0; /* caution: not .so or thread safe */ PROCNAME("pixDisplayWriteFormat"); if (reduction == 0) return 0; if (reduction < 0) { index = 0; /* reset; this will cause erasure at next call to write */ return 0; } if (format != IFF_JFIF_JPEG && format != IFF_PNG) return ERROR_INT("invalid format", procName, 1); if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (index == 0) { lept_rmdir("display"); lept_mkdir("display"); } index++; if (reduction == 1) { pixt = pixClone(pixs); } else { scale = 1. / (l_float32)reduction; if (pixGetDepth(pixs) == 1) pixt = pixScaleToGray(pixs, scale); else pixt = pixScale(pixs, scale, scale); } if (pixGetDepth(pixt) == 16) { pix8 = pixMaxDynamicRange(pixt, L_LOG_SCALE); snprintf(buf, L_BUF_SIZE, "file.%03d.png", index); fname = genPathname("/tmp/display", buf); pixWrite(fname, pix8, IFF_PNG); pixDestroy(&pix8); } else if (pixGetDepth(pixt) < 8 || pixGetColormap(pixt) || format == IFF_PNG) { snprintf(buf, L_BUF_SIZE, "file.%03d.png", index); fname = genPathname("/tmp/display", buf); pixWrite(fname, pixt, IFF_PNG); } else { snprintf(buf, L_BUF_SIZE, "file.%03d.jpg", index); fname = genPathname("/tmp/display", buf); pixWrite(fname, pixt, format); } FREE(fname); pixDestroy(&pixt); return 0; }
int main(int argc, char **argv) { l_uint8 *data1, *data2; l_int32 i, same, w, h, width, success, nba; size_t size1, size2; l_float32 diffarea, diffxor, scalefact; BOX *box; BOXA *boxa1, *boxa2, *boxa3; BOXAA *baa1, *baa2, *baa3; PIX *pix1, *pix2, *pix3, *pixdb; PIXA *pixa1, *pixa2; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; lept_mkdir("lept/boxa"); /* Make a boxa and display its contents */ boxa1 = boxaCreate(6); box = boxCreate(60, 60, 40, 20); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(120, 50, 20, 50); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(50, 140, 46, 60); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(166, 130, 64, 28); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(64, 224, 44, 34); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(117, 206, 26, 74); boxaAddBox(boxa1, box, L_INSERT); pix1 = DisplayBoxa(boxa1); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 0 */ pixDisplayWithTitle(pix1, 0, 0, NULL, rp->display); pixDestroy(&pix1); boxaCompareRegions(boxa1, boxa1, 100, &same, &diffarea, &diffxor, NULL); regTestCompareValues(rp, 1, same, 0.0); /* 1 */ regTestCompareValues(rp, 0.0, diffarea, 0.0); /* 2 */ regTestCompareValues(rp, 0.0, diffxor, 0.0); /* 3 */ boxa2 = boxaTransform(boxa1, -13, -13, 1.0, 1.0); boxaCompareRegions(boxa1, boxa2, 10, &same, &diffarea, &diffxor, NULL); regTestCompareValues(rp, 1, same, 0.0); /* 4 */ regTestCompareValues(rp, 0.0, diffarea, 0.0); /* 5 */ regTestCompareValues(rp, 0.0, diffxor, 0.0); /* 6 */ boxaDestroy(&boxa2); boxa2 = boxaReconcileEvenOddHeight(boxa1, L_ADJUST_TOP_AND_BOT, 6, L_ADJUST_CHOOSE_MIN, 1.0, 0); pix1 = DisplayBoxa(boxa2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 7 */ pixDisplayWithTitle(pix1, 200, 0, NULL, rp->display); pixDestroy(&pix1); boxaCompareRegions(boxa1, boxa2, 10, &same, &diffarea, &diffxor, &pixdb); regTestCompareValues(rp, 1, same, 0.0); /* 8 */ regTestCompareValues(rp, 0.053, diffarea, 0.002); /* 9 */ regTestCompareValues(rp, 0.240, diffxor, 0.002); /* 10 */ regTestWritePixAndCheck(rp, pixdb, IFF_PNG); /* 11 */ pixDisplayWithTitle(pixdb, 400, 0, NULL, rp->display); pixDestroy(&pixdb); boxaDestroy(&boxa1); boxaDestroy(&boxa2); /* Input is a fairly clean boxa */ boxa1 = boxaRead("boxa1.ba"); boxa2 = boxaReconcileEvenOddHeight(boxa1, L_ADJUST_TOP, 80, L_ADJUST_CHOOSE_MIN, 1.05, 1); width = 100; boxaGetExtent(boxa2, &w, &h, NULL); scalefact = (l_float32)width / (l_float32)w; boxa3 = boxaTransform(boxa2, 0, 0, scalefact, scalefact); pix1 = boxaDisplayTiled(boxa3, NULL, 1500, 2, 1.0, 0, 3, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 12 */ pixDisplayWithTitle(pix1, 600, 0, NULL, rp->display); pixDestroy(&pix1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); /* Input is an unsmoothed and noisy boxa */ boxa1 = boxaRead("boxa2.ba"); boxa2 = boxaReconcileEvenOddHeight(boxa1, L_ADJUST_TOP, 80, L_ADJUST_CHOOSE_MIN, 1.05, 1); width = 100; boxaGetExtent(boxa2, &w, &h, NULL); scalefact = (l_float32)width / (l_float32)w; boxa3 = boxaTransform(boxa2, 0, 0, scalefact, scalefact); pix1 = boxaDisplayTiled(boxa3, NULL, 1500, 2, 1.0, 0, 3, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 13 */ pixDisplayWithTitle(pix1, 800, 0, NULL, rp->display); pixDestroy(&pix1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); /* Input is an unsmoothed and noisy boxa */ boxa1 = boxaRead("boxa2.ba"); boxa2 = boxaSmoothSequenceMedian(boxa1, 10, L_SUB_ON_LOC_DIFF, 80, 20, 1); boxa3 = boxaSmoothSequenceMedian(boxa1, 10, L_SUB_ON_SIZE_DIFF, 80, 20, 1); boxaPlotSides(boxa1, "initial", NULL, NULL, NULL, NULL, &pix1); boxaPlotSides(boxa2, "side_smoothing", NULL, NULL, NULL, NULL, &pix2); boxaPlotSides(boxa3, "size_smoothing", NULL, NULL, NULL, NULL, &pix3); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 14 */ regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 15 */ regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 16 */ pixDisplayWithTitle(pix1, 1300, 0, NULL, rp->display); pixDisplayWithTitle(pix2, 1300, 500, NULL, rp->display); pixDisplayWithTitle(pix3, 1300, 1000, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); /* Input is a boxa smoothed with a median window filter */ boxa1 = boxaRead("boxa3.ba"); boxa2 = boxaReconcileEvenOddHeight(boxa1, L_ADJUST_TOP, 80, L_ADJUST_CHOOSE_MIN, 1.05, 1); width = 100; boxaGetExtent(boxa2, &w, &h, NULL); scalefact = (l_float32)width / (l_float32)w; boxa3 = boxaTransform(boxa2, 0, 0, scalefact, scalefact); pix1 = boxaDisplayTiled(boxa3, NULL, 1500, 2, 1.0, 0, 3, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 17 */ pixDisplayWithTitle(pix1, 1000, 0, NULL, rp->display); pixDestroy(&pix1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); /* Test serialized boxa I/O to and from memory */ data1 = l_binaryRead("boxa2.ba", &size1); boxa1 = boxaReadMem(data1, size1); boxaWriteMem(&data2, &size2, boxa1); boxa2 = boxaReadMem(data2, size2); boxaWrite("/tmp/lept/boxa/boxa1.ba", boxa1); boxaWrite("/tmp/lept/boxa/boxa2.ba", boxa2); filesAreIdentical("/tmp/lept/boxa/boxa1.ba", "/tmp/lept/boxa/boxa2.ba", &same); regTestCompareValues(rp, 1, same, 0.0); /* 18 */ boxaDestroy(&boxa1); boxaDestroy(&boxa2); lept_free(data1); lept_free(data2); /* ----------- Test pixaDisplayBoxaa() ------------ */ pixa1 = pixaReadBoth("showboxes.pac"); baa1 = boxaaRead("showboxes1.baa"); baa2 = boxaaTranspose(baa1); baa3 = boxaaTranspose(baa2); nba = boxaaGetCount(baa1); success = TRUE; for (i = 0; i < nba; i++) { boxa1 = boxaaGetBoxa(baa1, i, L_CLONE); boxa2 = boxaaGetBoxa(baa3, i, L_CLONE); boxaEqual(boxa1, boxa2, 0, NULL, &same); boxaDestroy(&boxa1); boxaDestroy(&boxa2); if (!same) success = FALSE; } /* Check that the transpose is reversible */ regTestCompareValues(rp, 1, success, 0.0); /* 19 */ pixa2 = pixaDisplayBoxaa(pixa1, baa2, L_DRAW_RGB, 2); pix1 = pixaDisplayTiledInRows(pixa2, 32, 1400, 1.0, 0, 10, 0); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 20 */ pixDisplayWithTitle(pix1, 0, 600, NULL, rp->display); fprintf(stderr, "Writing to: /tmp/lept/boxa/show.pdf\n"); l_pdfSetDateAndVersion(FALSE); pixaConvertToPdf(pixa2, 75, 1.0, 0, 0, NULL, "/tmp/lept/boxa/show.pdf"); regTestCheckFile(rp, "/tmp/lept/boxa/show.pdf"); /* 21 */ pixDestroy(&pix1); pixaDestroy(&pixa1); pixaDestroy(&pixa2); boxaaDestroy(&baa1); boxaaDestroy(&baa2); boxaaDestroy(&baa3); return regTestCleanup(rp); }
/*! * pixDisplayWithTitle() * * Input: pix (1, 2, 4, 8, 16, 32 bpp) * x, y (location of display frame) * title (<optional> on frame; can be NULL); * dispflag (1 to write, else disabled) * Return: 0 if OK; 1 on error * * Notes: * (1) See notes for pixDisplay(). * (2) This displays the image if dispflag == 1. */ l_int32 pixDisplayWithTitle(PIX *pixs, l_int32 x, l_int32 y, const char *title, l_int32 dispflag) { char *tempname; char buffer[L_BUF_SIZE]; static l_int32 index = 0; /* caution: not .so or thread safe */ l_int32 w, h, d, spp, maxheight, opaque, threeviews, ignore; l_float32 ratw, rath, ratmin; PIX *pix0, *pix1, *pix2; PIXCMAP *cmap; #ifndef _WIN32 l_int32 wt, ht; #else char *pathname; char fullpath[_MAX_PATH]; #endif /* _WIN32 */ PROCNAME("pixDisplayWithTitle"); if (dispflag != 1) return 0; if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (var_DISPLAY_PROG != L_DISPLAY_WITH_XZGV && var_DISPLAY_PROG != L_DISPLAY_WITH_XLI && var_DISPLAY_PROG != L_DISPLAY_WITH_XV && var_DISPLAY_PROG != L_DISPLAY_WITH_IV && var_DISPLAY_PROG != L_DISPLAY_WITH_OPEN) { return ERROR_INT("no program chosen for display", procName, 1); } /* Display with three views if either spp = 4 or if colormapped * and the alpha component is not fully opaque */ opaque = TRUE; if ((cmap = pixGetColormap(pixs)) != NULL) pixcmapIsOpaque(cmap, &opaque); spp = pixGetSpp(pixs); threeviews = (spp == 4 || !opaque) ? TRUE : FALSE; /* If colormapped and not opaque, remove the colormap to RGBA */ if (!opaque) pix0 = pixRemoveColormap(pixs, REMOVE_CMAP_WITH_ALPHA); else pix0 = pixClone(pixs); /* Scale if necessary; this will also remove a colormap */ pixGetDimensions(pix0, &w, &h, &d); maxheight = (threeviews) ? MAX_DISPLAY_HEIGHT / 3 : MAX_DISPLAY_HEIGHT; if (w <= MAX_DISPLAY_WIDTH && h <= maxheight) { if (d == 16) /* take MSB */ pix1 = pixConvert16To8(pix0, 1); else pix1 = pixClone(pix0); } else { ratw = (l_float32)MAX_DISPLAY_WIDTH / (l_float32)w; rath = (l_float32)maxheight / (l_float32)h; ratmin = L_MIN(ratw, rath); if (ratmin < 0.125 && d == 1) pix1 = pixScaleToGray8(pix0); else if (ratmin < 0.25 && d == 1) pix1 = pixScaleToGray4(pix0); else if (ratmin < 0.33 && d == 1) pix1 = pixScaleToGray3(pix0); else if (ratmin < 0.5 && d == 1) pix1 = pixScaleToGray2(pix0); else pix1 = pixScale(pix0, ratmin, ratmin); } pixDestroy(&pix0); if (!pix1) return ERROR_INT("pix1 not made", procName, 1); /* Generate the three views if required */ if (threeviews) pix2 = pixDisplayLayersRGBA(pix1, 0xffffff00, 0); else pix2 = pixClone(pix1); if (index == 0) { lept_rmdir("disp"); lept_mkdir("disp"); } index++; if (pixGetDepth(pix2) < 8 || (w < MAX_SIZE_FOR_PNG && h < MAX_SIZE_FOR_PNG)) { snprintf(buffer, L_BUF_SIZE, "/tmp/disp/write.%03d.png", index); pixWrite(buffer, pix2, IFF_PNG); } else { snprintf(buffer, L_BUF_SIZE, "/tmp/disp/write.%03d.jpg", index); pixWrite(buffer, pix2, IFF_JFIF_JPEG); } tempname = genPathname(buffer, NULL); #ifndef _WIN32 /* Unix */ if (var_DISPLAY_PROG == L_DISPLAY_WITH_XZGV) { /* no way to display title */ pixGetDimensions(pix2, &wt, &ht, NULL); snprintf(buffer, L_BUF_SIZE, "xzgv --geometry %dx%d+%d+%d %s &", wt + 10, ht + 10, x, y, tempname); } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XLI) { if (title) { snprintf(buffer, L_BUF_SIZE, "xli -dispgamma 1.0 -quiet -geometry +%d+%d -title \"%s\" %s &", x, y, title, tempname); } else { snprintf(buffer, L_BUF_SIZE, "xli -dispgamma 1.0 -quiet -geometry +%d+%d %s &", x, y, tempname); } } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XV) { if (title) { snprintf(buffer, L_BUF_SIZE, "xv -quit -geometry +%d+%d -name \"%s\" %s &", x, y, title, tempname); } else { snprintf(buffer, L_BUF_SIZE, "xv -quit -geometry +%d+%d %s &", x, y, tempname); } } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_OPEN) { snprintf(buffer, L_BUF_SIZE, "open %s &", tempname); } ignore = system(buffer); #else /* _WIN32 */ /* Windows: L_DISPLAY_WITH_IV */ pathname = genPathname(tempname, NULL); _fullpath(fullpath, pathname, sizeof(fullpath)); if (title) { snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /pos=(%d,%d) /title=\"%s\"", fullpath, x, y, title); } else { snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /pos=(%d,%d)", fullpath, x, y); } ignore = system(buffer); FREE(pathname); #endif /* _WIN32 */ pixDestroy(&pix1); pixDestroy(&pix2); FREE(tempname); return 0; }
int main(int argc, char **argv) { l_int32 i, n, binsize, binstart, nbins; l_float32 pi, val, angle, xval, yval, x0, y0, rank, startval, fbinsize; l_float32 minval, maxval, meanval, median, variance, rankval; GPLOT *gplot; NUMA *na, *nahisto, *nax, *nay, *nap, *nasx, *nasy; NUMA *nadx, *nady, *nafx, *nafy, *na1, *na2, *na3, *na4; PIX *pixs, *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pixd; PIXA *pixa; static char mainName[] = "numa1_reg"; if (argc != 1) return ERROR_INT(" Syntax: numa1_reg", mainName, 1); lept_mkdir("lept/numa1"); /* -------------------------------------------------------------------* * Histograms * * -------------------------------------------------------------------*/ #if DO_ALL pi = 3.1415926535; na = numaCreate(5000); for (i = 0; i < 500000; i++) { angle = 0.02293 * i * pi; val = (l_float32)(999. * sin(angle)); numaAddNumber(na, val); } nahisto = numaMakeHistogramClipped(na, 6, 2000); nbins = numaGetCount(nahisto); nax = numaMakeSequence(0, 1, nbins); gplot = gplotCreate("/tmp/lept/numa1/histo1", GPLOT_PNG, "example histo 1", "i", "histo[i]"); gplotAddPlot(gplot, nax, nahisto, GPLOT_LINES, "sine"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nax); numaDestroy(&nahisto); nahisto = numaMakeHistogram(na, 1000, &binsize, &binstart); nbins = numaGetCount(nahisto); nax = numaMakeSequence(binstart, binsize, nbins); fprintf(stderr, " binsize = %d, binstart = %d\n", binsize, binstart); gplot = gplotCreate("/tmp/lept/numa1/histo2", GPLOT_PNG, "example histo 2", "i", "histo[i]"); gplotAddPlot(gplot, nax, nahisto, GPLOT_LINES, "sine"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nax); numaDestroy(&nahisto); nahisto = numaMakeHistogram(na, 1000, &binsize, NULL); nbins = numaGetCount(nahisto); nax = numaMakeSequence(0, binsize, nbins); fprintf(stderr, " binsize = %d, binstart = %d\n", binsize, 0); gplot = gplotCreate("/tmp/lept/numa1/histo3", GPLOT_PNG, "example histo 3", "i", "histo[i]"); gplotAddPlot(gplot, nax, nahisto, GPLOT_LINES, "sine"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nax); numaDestroy(&nahisto); nahisto = numaMakeHistogramAuto(na, 1000); nbins = numaGetCount(nahisto); numaGetParameters(nahisto, &startval, &fbinsize); nax = numaMakeSequence(startval, fbinsize, nbins); fprintf(stderr, " binsize = %7.4f, binstart = %8.3f\n", fbinsize, startval); gplot = gplotCreate("/tmp/lept/numa1/histo4", GPLOT_PNG, "example histo 4", "i", "histo[i]"); gplotAddPlot(gplot, nax, nahisto, GPLOT_LINES, "sine"); gplotMakeOutput(gplot); gplotDestroy(&gplot); pixa = pixaCreate(4); pix1 = pixRead("/tmp/lept/numa1/histo1.png"); pix2 = pixRead("/tmp/lept/numa1/histo2.png"); pix3 = pixRead("/tmp/lept/numa1/histo3.png"); pix4 = pixRead("/tmp/lept/numa1/histo4.png"); pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); pixaAddPix(pixa, pix3, L_INSERT); pixaAddPix(pixa, pix4, L_INSERT); pixd = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 20, 2); pixDisplay(pixd, 600, 0); pixWrite("/tmp/lept/numa1/histo.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); numaDestroy(&nax); numaDestroy(&nahisto); numaGetStatsUsingHistogram(na, 2000, &minval, &maxval, &meanval, &variance, &median, 0.80, &rankval, &nahisto); fprintf(stderr, "Sin histogram: \n" " min val = %7.2f -- should be -999.00\n" " max val = %7.2f -- should be 999.00\n" " mean val = %7.2f -- should be 0.06\n" " median = %7.2f -- should be 0.30\n" " rmsdev = %7.2f -- should be 706.41\n" " rank val = %7.2f -- should be 808.15\n", minval, maxval, meanval, median, sqrt((l_float64)variance), rankval); numaHistogramGetRankFromVal(nahisto, 808.15, &rank); fprintf(stderr, " rank = %7.3f -- should be 0.800\n", rank); numaDestroy(&nahisto); numaDestroy(&na); #endif /* -------------------------------------------------------------------* * Interpolation * * -------------------------------------------------------------------*/ #if DO_ALL /* Test numaInterpolateEqxInterval() */ pixs = pixRead("test8.jpg"); na = pixGetGrayHistogramMasked(pixs, NULL, 0, 0, 1); /* numaWriteStream(stderr, na); */ nasy = numaGetPartialSums(na); gplotSimple1(nasy, GPLOT_PNG, "/tmp/lept/numa1/int1", "partial sums"); gplotSimple1(na, GPLOT_PNG, "/tmp/lept/numa1/int2", "simple test"); numaInterpolateEqxInterval(0.0, 1.0, na, L_LINEAR_INTERP, 0.0, 255.0, 15, &nax, &nay); gplot = gplotCreate("/tmp/lept/numa1/int3", GPLOT_PNG, "test interpolation", "pix val", "num pix"); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, "plot 1"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&na); numaDestroy(&nasy); numaDestroy(&nax); numaDestroy(&nay); pixDestroy(&pixs); #endif #if DO_ALL /* Test numaInterpolateArbxInterval() */ pixs = pixRead("test8.jpg"); na = pixGetGrayHistogramMasked(pixs, NULL, 0, 0, 1); nasy = numaGetPartialSums(na); numaInsertNumber(nasy, 0, 0.0); nasx = numaMakeSequence(0.0, 1.0, 257); /* gplotSimple1(nasy, GPLOT_PNG, "/tmp/numa/nasy", "partial sums"); */ numaInterpolateArbxInterval(nasx, nasy, L_LINEAR_INTERP, 10.0, 250.0, 23, &nax, &nay); gplot = gplotCreate("/tmp/lept/numa1/int4", GPLOT_PNG, "arbx interpolation", "pix val", "cum num pix"); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, "plot 1"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&na); numaDestroy(&nasx); numaDestroy(&nasy); numaDestroy(&nax); numaDestroy(&nay); pixDestroy(&pixs); #endif #if DO_ALL /* Test numaInterpolateArbxVal() */ pixs = pixRead("test8.jpg"); na = pixGetGrayHistogramMasked(pixs, NULL, 0, 0, 1); nasy = numaGetPartialSums(na); numaInsertNumber(nasy, 0, 0.0); nasx = numaMakeSequence(0.0, 1.0, 257); /* gplotSimple1(nasy, GPLOT_PNG, "/tmp/numa/nasy", "partial sums"); */ nax = numaMakeSequence(15.0, (250.0 - 15.0) / 23.0, 24); n = numaGetCount(nax); nay = numaCreate(n); for (i = 0; i < n; i++) { numaGetFValue(nax, i, &xval); numaInterpolateArbxVal(nasx, nasy, L_QUADRATIC_INTERP, xval, &yval); numaAddNumber(nay, yval); } gplot = gplotCreate("/tmp/lept/numa1/int5", GPLOT_PNG, "arbx interpolation", "pix val", "cum num pix"); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, "plot 1"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&na); numaDestroy(&nasx); numaDestroy(&nasy); numaDestroy(&nax); numaDestroy(&nay); pixDestroy(&pixs); #endif #if DO_ALL /* Test interpolation */ nasx = numaRead("testangle.na"); nasy = numaRead("testscore.na"); gplot = gplotCreate("/tmp/lept/numa1/int6", GPLOT_PNG, "arbx interpolation", "angle", "score"); numaInterpolateArbxInterval(nasx, nasy, L_LINEAR_INTERP, -2.00, 0.0, 50, &nax, &nay); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, "linear"); numaDestroy(&nax); numaDestroy(&nay); numaInterpolateArbxInterval(nasx, nasy, L_QUADRATIC_INTERP, -2.00, 0.0, 50, &nax, &nay); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, "quadratic"); numaDestroy(&nax); numaDestroy(&nay); gplotMakeOutput(gplot); gplotDestroy(&gplot); gplot = gplotCreate("/tmp/lept/numa1/int7", GPLOT_PNG, "arbx interpolation", "angle", "score"); numaInterpolateArbxInterval(nasx, nasy, L_LINEAR_INTERP, -1.2, -0.8, 50, &nax, &nay); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, "quadratic"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaFitMax(nay, &yval, nax, &xval); fprintf(stderr, "max = %f at loc = %f\n", yval, xval); pixa = pixaCreate(7); pix1 = pixRead("/tmp/lept/numa1/int1.png"); pix2 = pixRead("/tmp/lept/numa1/int2.png"); pix3 = pixRead("/tmp/lept/numa1/int3.png"); pix4 = pixRead("/tmp/lept/numa1/int4.png"); pix5 = pixRead("/tmp/lept/numa1/int5.png"); pix6 = pixRead("/tmp/lept/numa1/int6.png"); pix7 = pixRead("/tmp/lept/numa1/int7.png"); pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); pixaAddPix(pixa, pix3, L_INSERT); pixaAddPix(pixa, pix4, L_INSERT); pixaAddPix(pixa, pix5, L_INSERT); pixaAddPix(pixa, pix6, L_INSERT); pixaAddPix(pixa, pix7, L_INSERT); pixd = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 20, 2); pixDisplay(pixd, 100, 900); pixWrite("/tmp/lept/numa1/int.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); numaDestroy(&nasx); numaDestroy(&nasy); numaDestroy(&nax); numaDestroy(&nay); #endif /* -------------------------------------------------------------------* * Integration and differentiation * * -------------------------------------------------------------------*/ #if DO_ALL /* Test integration and differentiation */ nasx = numaRead("testangle.na"); nasy = numaRead("testscore.na"); /* ---------- Plot the derivative ---------- */ numaDifferentiateInterval(nasx, nasy, -2.0, 0.0, 50, &nadx, &nady); gplot = gplotCreate("/tmp/lept/numa1/diff1", GPLOT_PNG, "derivative", "angle", "slope"); gplotAddPlot(gplot, nadx, nady, GPLOT_LINES, "derivative"); gplotMakeOutput(gplot); gplotDestroy(&gplot); /* ---------- Plot the original function ----------- */ /* and the integral of the derivative; the two */ /* should be approximately the same. */ gplot = gplotCreate("/tmp/lept/numa1/diff2", GPLOT_PNG, "integ-diff", "angle", "val"); numaInterpolateArbxInterval(nasx, nasy, L_LINEAR_INTERP, -2.00, 0.0, 50, &nafx, &nafy); gplotAddPlot(gplot, nafx, nafy, GPLOT_LINES, "function"); n = numaGetCount(nadx); numaGetFValue(nafx, 0, &x0); numaGetFValue(nafy, 0, &y0); nay = numaCreate(n); /* (Note: this tests robustness of the integrator: we go from * i = 0, and choose to have only 1 point in the interpolation * there, which is too small and causes the function to bomb out.) */ fprintf(stderr, "We must get a 'npts < 2' error here:\n"); for (i = 0; i < n; i++) { numaGetFValue(nadx, i, &xval); numaIntegrateInterval(nadx, nady, x0, xval, 2 * i + 1, &yval); numaAddNumber(nay, y0 + yval); } gplotAddPlot(gplot, nafx, nay, GPLOT_LINES, "anti-derivative"); gplotMakeOutput(gplot); gplotDestroy(&gplot); pixa = pixaCreate(2); pix1 = pixRead("/tmp/lept/numa1/diff1.png"); pix2 = pixRead("/tmp/lept/numa1/diff2.png"); pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); pixd = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 20, 2); pixDisplay(pixd, 100, 450); pixWrite("/tmp/lept/numa1/diff.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); numaDestroy(&nasx); numaDestroy(&nasy); numaDestroy(&nafx); numaDestroy(&nafy); numaDestroy(&nadx); numaDestroy(&nady); numaDestroy(&nay); #endif /* -------------------------------------------------------------------* * Rank extraction * * -------------------------------------------------------------------*/ #if DO_ALL /* Rank extraction with interpolation */ pixs = pixRead("test8.jpg"); nasy= pixGetGrayHistogramMasked(pixs, NULL, 0, 0, 1); numaMakeRankFromHistogram(0.0, 1.0, nasy, 350, &nax, &nay); gplot = gplotCreate("/tmp/lept/numa1/rank1", GPLOT_PNG, "test rank extractor", "pix val", "rank val"); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, "plot 1"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nasy); numaDestroy(&nax); numaDestroy(&nay); pixDestroy(&pixs); #endif #if DO_ALL /* Rank extraction, point by point */ pixs = pixRead("test8.jpg"); nap = numaCreate(200); pixGetRankValueMasked(pixs, NULL, 0, 0, 2, 0.0, &val, &na); for (i = 0; i < 101; i++) { rank = 0.01 * i; numaHistogramGetValFromRank(na, rank, &val); numaAddNumber(nap, val); } gplotSimple1(nap, GPLOT_PNG, "/tmp/lept/numa1/rank2", "rank value"); pixa = pixaCreate(2); pix1 = pixRead("/tmp/lept/numa1/rank1.png"); pix2 = pixRead("/tmp/lept/numa1/rank2.png"); pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); pixd = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 20, 2); pixDisplay(pixd, 100, 0); pixWrite("/tmp/lept/numa1/rank.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); numaDestroy(&na); numaDestroy(&nap); pixDestroy(&pixs); #endif /* -------------------------------------------------------------------* * Numa-morphology * * -------------------------------------------------------------------*/ #if DO_ALL na = numaRead("lyra.5.na"); gplotSimple1(na, GPLOT_PNG, "/tmp/lept/numa1/lyra1", "Original"); na1 = numaErode(na, 21); gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/numa1/lyra2", "Erosion"); na2 = numaDilate(na, 21); gplotSimple1(na2, GPLOT_PNG, "/tmp/lept/numa1/lyra3", "Dilation"); na3 = numaOpen(na, 21); gplotSimple1(na3, GPLOT_PNG, "/tmp/lept/numa1/lyra4", "Opening"); na4 = numaClose(na, 21); gplotSimple1(na4, GPLOT_PNG, "/tmp/lept/numa1/lyra5", "Closing"); pixa = pixaCreate(2); pix1 = pixRead("/tmp/lept/numa1/lyra1.png"); pix2 = pixRead("/tmp/lept/numa1/lyra2.png"); pix3 = pixRead("/tmp/lept/numa1/lyra3.png"); pix4 = pixRead("/tmp/lept/numa1/lyra4.png"); pix5 = pixRead("/tmp/lept/numa1/lyra5.png"); pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); pixaAddPix(pixa, pix3, L_INSERT); pixaAddPix(pixa, pix4, L_INSERT); pixaAddPix(pixa, pix5, L_INSERT); pixd = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 20, 2); pixDisplay(pixd, 600, 450); pixWrite("/tmp/lept/numa1/morph.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); numaDestroy(&na); numaDestroy(&na1); numaDestroy(&na2); numaDestroy(&na3); numaDestroy(&na4); pixaDestroy(&pixa); #endif return 0; }
int main(int argc, char **argv) { l_int32 i, w, h, d, rotflag; PIX *pixs, *pixt, *pixd; l_float32 angle, deg2rad, pops, ang; char *filein, *fileout; static char mainName[] = "rotatetest1"; if (argc != 4) return ERROR_INT(" Syntax: rotatetest1 filein angle fileout", mainName, 1); filein = argv[1]; angle = atof(argv[2]); fileout = argv[3]; deg2rad = 3.1415926535 / 180.; lept_mkdir("lept/rotate"); if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pix not made", mainName, 1); if (pixGetDepth(pixs) == 1) { pixt = pixScaleToGray3(pixs); pixDestroy(&pixs); pixs = pixAddBorderGeneral(pixt, 1, 0, 1, 0, 255); pixDestroy(&pixt); } pixGetDimensions(pixs, &w, &h, &d); fprintf(stderr, "w = %d, h = %d\n", w, h); #if 0 /* repertory of rotation operations to choose from */ pixd = pixRotateAM(pixs, deg2rad * angle, L_BRING_IN_WHITE); pixd = pixRotateAMColor(pixs, deg2rad * angle, 0xffffff00); pixd = pixRotateAMColorFast(pixs, deg2rad * angle, 255); pixd = pixRotateAMCorner(pixs, deg2rad * angle, L_BRING_IN_WHITE); pixd = pixRotateShear(pixs, w /2, h / 2, deg2rad * angle, L_BRING_IN_WHITE); pixd = pixRotate3Shear(pixs, w /2, h / 2, deg2rad * angle, L_BRING_IN_WHITE); pixRotateShearIP(pixs, w / 2, h / 2, deg2rad * angle); pixd = pixs; #endif #if 0 /* timing of shear rotation */ for (i = 0; i < NITERS; i++) { pixd = pixRotateShear(pixs, (i * w) / NITERS, (i * h) / NITERS, deg2rad * angle, L_BRING_IN_WHITE); pixDisplay(pixd, 100 + 20 * i, 100 + 20 * i); pixDestroy(&pixd); } #endif #if 0 /* timing of in-place shear rotation */ for (i = 0; i < NITERS; i++) { pixRotateShearIP(pixs, w/2, h/2, deg2rad * angle, L_BRING_IN_WHITE); /* pixRotateShearCenterIP(pixs, deg2rad * angle, L_BRING_IN_WHITE); */ pixDisplay(pixs, 100 + 20 * i, 100 + 20 * i); } pixd = pixs; if (pixGetDepth(pixd) == 1) pixWrite(fileout, pixd, IFF_PNG); else pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixs); #endif #if 0 /* timing of various rotation operations (choose) */ startTimer(); w = pixGetWidth(pixs); h = pixGetHeight(pixs); for (i = 0; i < NTIMES; i++) { pixd = pixRotateShearCenter(pixs, deg2rad * angle, L_BRING_IN_WHITE); pixDestroy(&pixd); } pops = (l_float32)(w * h * NTIMES / 1000000.) / stopTimer(); fprintf(stderr, "vers. 1, mpops: %f\n", pops); startTimer(); w = pixGetWidth(pixs); h = pixGetHeight(pixs); for (i = 0; i < NTIMES; i++) { pixRotateShearIP(pixs, w/2, h/2, deg2rad * angle, L_BRING_IN_WHITE); } pops = (l_float32)(w * h * NTIMES / 1000000.) / stopTimer(); fprintf(stderr, "shear, mpops: %f\n", pops); pixWrite(fileout, pixs, IFF_PNG); for (i = 0; i < NTIMES; i++) { pixRotateShearIP(pixs, w/2, h/2, -deg2rad * angle, L_BRING_IN_WHITE); } pixWrite("/usr/tmp/junkout", pixs, IFF_PNG); #endif #if 0 /* area-mapping rotation operations */ pixd = pixRotateAM(pixs, deg2rad * angle, L_BRING_IN_WHITE); /* pixd = pixRotateAMColorFast(pixs, deg2rad * angle, 255); */ if (pixGetDepth(pixd) == 1) pixWrite(fileout, pixd, IFF_PNG); else pixWrite(fileout, pixd, IFF_JFIF_JPEG); #endif #if 0 /* compare the standard area-map color rotation with * the fast area-map color rotation, on a pixel basis */ { PIX *pix1, *pix2; NUMA *nar, *nag, *nab, *naseq; GPLOT *gplot; startTimer(); pix1 = pixRotateAMColor(pixs, 0.12, 0xffffff00); fprintf(stderr, " standard color rotate: %7.2f sec\n", stopTimer()); pixWrite("/tmp/lept/rotate/color1.jpg", pix1, IFF_JFIF_JPEG); startTimer(); pix2 = pixRotateAMColorFast(pixs, 0.12, 0xffffff00); fprintf(stderr, " fast color rotate: %7.2f sec\n", stopTimer()); pixWrite("/tmp/lept/rotate/color2.jpg", pix2, IFF_JFIF_JPEG); pixd = pixAbsDifference(pix1, pix2); pixGetColorHistogram(pixd, 1, &nar, &nag, &nab); naseq = numaMakeSequence(0., 1., 256); gplot = gplotCreate("/tmp/lept/rotate/absdiff", GPLOT_PNG, "Number vs diff", "diff", "number"); gplotAddPlot(gplot, naseq, nar, GPLOT_POINTS, "red"); gplotAddPlot(gplot, naseq, nag, GPLOT_POINTS, "green"); gplotAddPlot(gplot, naseq, nab, GPLOT_POINTS, "blue"); gplotMakeOutput(gplot); l_fileDisplay("/tmp/lept/rotate/absdiff.png", 100, 100, 1.0); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pixd); numaDestroy(&nar); numaDestroy(&nag); numaDestroy(&nab); numaDestroy(&naseq); gplotDestroy(&gplot); } #endif /* Do a succession of 180 7-degree rotations in a cw * direction, and unwind the result with another set in * a ccw direction. Although there is a considerable amount * of distortion after successive rotations, after all * 360 rotations, the resulting image is restored to * its original pristine condition! */ #if 1 rotflag = L_ROTATE_AREA_MAP; /* rotflag = L_ROTATE_SHEAR; */ /* rotflag = L_ROTATE_SAMPLING; */ ang = 7.0 * deg2rad; pixGetDimensions(pixs, &w, &h, NULL); pixd = pixRotate(pixs, ang, rotflag, L_BRING_IN_WHITE, w, h); pixWrite("/tmp/lept/rotate/rot7.png", pixd, IFF_PNG); for (i = 1; i < 180; i++) { pixs = pixd; pixd = pixRotate(pixs, ang, rotflag, L_BRING_IN_WHITE, w, h); if ((i % 30) == 0) pixDisplay(pixd, 600, 0); pixDestroy(&pixs); } pixWrite("/tmp/lept/rotate/spin.png", pixd, IFF_PNG); pixDisplay(pixd, 0, 0); for (i = 0; i < 180; i++) { pixs = pixd; pixd = pixRotate(pixs, -ang, rotflag, L_BRING_IN_WHITE, w, h); if (i && (i % 30) == 0) pixDisplay(pixd, 600, 500); pixDestroy(&pixs); } pixWrite("/tmp/lept/rotate/unspin.png", pixd, IFF_PNG); pixDisplay(pixd, 0, 500); pixDestroy(&pixd); #endif return 0; }
l_int32 main(int argc, char **argv) { l_int32 exists; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; fprintf(stderr, " ===================================================\n"); fprintf(stderr, " =================== Test pathJoin() ===============\n"); fprintf(stderr, " ===================================================\n"); TestPathJoin(rp, "/a/b//c///d//", "//e//f//g//", "/a/b/c/d/e/f/g"); /* 0 */ TestPathJoin(rp, "/tmp/", "junk//", "/tmp/junk"); /* 1 */ TestPathJoin(rp, "//tmp/", "junk//", "/tmp/junk"); /* 2 */ TestPathJoin(rp, "tmp/", "//junk//", "tmp/junk"); /* 3 */ TestPathJoin(rp, "tmp/", "junk/////", "tmp/junk"); /* 4 */ TestPathJoin(rp, "/tmp/", "///", "/tmp"); /* 5 */ TestPathJoin(rp, "////", NULL, "/"); /* 6 */ TestPathJoin(rp, "//", "/junk//", "/junk"); /* 7 */ TestPathJoin(rp, NULL, "/junk//", "/junk"); /* 8 */ TestPathJoin(rp, NULL, "//junk//", "/junk"); /* 9 */ TestPathJoin(rp, NULL, "junk//", "junk"); /* 10 */ TestPathJoin(rp, NULL, "//", "/"); /* 11 */ TestPathJoin(rp, NULL, NULL, ""); /* 12 */ TestPathJoin(rp, "", "", ""); /* 13 */ TestPathJoin(rp, "/", "", "/"); /* 14 */ TestPathJoin(rp, "", "//", "/"); /* 15 */ TestPathJoin(rp, "", "a", "a"); /* 16 */ fprintf(stderr, "The next 3 joins properly give error messages:\n"); fprintf(stderr, "join: .. + a --> NULL\n"); pathJoin("..", "a"); /* returns NULL */ fprintf(stderr, "join: %s + .. --> NULL\n", "/tmp"); pathJoin("/tmp", ".."); /* returns NULL */ fprintf(stderr, "join: ./ + .. --> NULL\n"); pathJoin("./", ".."); /* returns NULL */ fprintf(stderr, "\n ===================================================\n"); fprintf(stderr, " ======= Test lept_rmdir() and lept_mkdir()) =======\n"); fprintf(stderr, " ===================================================\n"); lept_rmdir("junkfiles"); lept_direxists("/tmp/junkfiles", &exists); if (rp->display) fprintf(stderr, "directory removed?: %d\n", !exists); regTestCompareValues(rp, 0, exists, 0.0); /* 17 */ lept_mkdir("junkfiles"); lept_direxists("/tmp/junkfiles", &exists); if (rp->display) fprintf(stderr, "directory made?: %d\n", exists); regTestCompareValues(rp, 1, exists, 0.0); /* 18 */ fprintf(stderr, "\n ===================================================\n"); fprintf(stderr, " ======= Test lept_mv(), lept_cp(), lept_rm() ======\n"); fprintf(stderr, " ==================================================="); TestLeptCpRm(rp, "weasel2.png", NULL, NULL); /* 19 - 22 */ TestLeptCpRm(rp, "weasel2.png", "junkfiles", NULL); /* 23 - 26 */ TestLeptCpRm(rp, "weasel2.png", NULL, "new_weasel2.png"); /* 27 - 30 */ TestLeptCpRm(rp, "weasel2.png", "junkfiles", "new_weasel2.png"); /* 31-34 */ fprintf(stderr, "\n ===================================================\n"); fprintf(stderr, " =============== Test genPathname() ================\n"); fprintf(stderr, " ===================================================\n"); TestGenPathname(rp, "what/", NULL, "what"); /* 35 */ TestGenPathname(rp, "what", "abc", "what/abc"); /* 36 */ TestGenPathname(rp, NULL, "abc/def", "abc/def"); /* 37 */ TestGenPathname(rp, "", "abc/def", "abc/def"); /* 38 */ #ifndef _WIN32 /* unix only */ TestGenPathname(rp, "/tmp", NULL, "/tmp"); /* 39 */ TestGenPathname(rp, "/tmp/", NULL, "/tmp"); /* 40 */ TestGenPathname(rp, "/tmp/junk", NULL, "/tmp/junk"); /* 41 */ TestGenPathname(rp, "/tmp/junk/abc", NULL, "/tmp/junk/abc"); /* 42 */ TestGenPathname(rp, "/tmp/junk/", NULL, "/tmp/junk"); /* 43 */ TestGenPathname(rp, "/tmp/junk", "abc", "/tmp/junk/abc"); /* 44 */ #endif /* !_WIN32 */ return regTestCleanup(rp); }
/*! * \brief regTestSetup() * * \param[in] argc from invocation; can be either 1 or 2 * \param[in] argv to regtest: %argv[1] is one of these: * "generate", "compare", "display" * \param[out] prp all regression params * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) Call this function with the args to the reg test. The first arg * is the name of the reg test. There are three cases: * Case 1: * There is either only one arg, or the second arg is "compare". * This is the mode in which you run a regression test * (or a set of them), looking for failures and logging * the results to a file. The output, which includes * logging of all reg test failures plus a SUCCESS or * FAILURE summary for each test, is appended to the file * "/tmp/lept/reg_results.txt. For this case, as in Case 2, * the display field in rp is set to FALSE, preventing * image display. * Case 2: * The second arg is "generate". This will cause * generation of new golden files for the reg test. * The results of the reg test are not recorded, and * the display field in rp is set to FALSE. * Case 3: * The second arg is "display". The test will run and * files will be written. Comparisons with golden files * will not be carried out, so the only notion of success * or failure is with tests that do not involve golden files. * The display field in rp is TRUE, and this is used by * pixDisplayWithTitle(). * (2) See regutils.h for examples of usage. * </pre> */ l_int32 regTestSetup(l_int32 argc, char **argv, L_REGPARAMS **prp) { char *testname, *vers; char errormsg[64]; L_REGPARAMS *rp; PROCNAME("regTestSetup"); if (argc != 1 && argc != 2) { snprintf(errormsg, sizeof(errormsg), "Syntax: %s [ [compare] | generate | display ]", argv[0]); return ERROR_INT(errormsg, procName, 1); } if ((testname = getRootNameFromArgv0(argv[0])) == NULL) return ERROR_INT("invalid root", procName, 1); if ((rp = (L_REGPARAMS *)LEPT_CALLOC(1, sizeof(L_REGPARAMS))) == NULL) { LEPT_FREE(testname); return ERROR_INT("rp not made", procName, 1); } *prp = rp; rp->testname = testname; rp->index = -1; /* increment before each test */ /* Initialize to true. A failure in any test is registered * as a failure of the regression test. */ rp->success = TRUE; /* Make sure the lept/regout subdirectory exists */ lept_mkdir("lept/regout"); /* Only open a stream to a temp file for the 'compare' case */ if (argc == 1 || !strcmp(argv[1], "compare")) { rp->mode = L_REG_COMPARE; rp->tempfile = genPathname("/tmp/lept/regout", "regtest_output.txt"); rp->fp = fopenWriteStream(rp->tempfile, "wb"); if (rp->fp == NULL) { rp->success = FALSE; return ERROR_INT("stream not opened for tempfile", procName, 1); } } else if (!strcmp(argv[1], "generate")) { rp->mode = L_REG_GENERATE; lept_mkdir("lept/golden"); } else if (!strcmp(argv[1], "display")) { rp->mode = L_REG_DISPLAY; rp->display = TRUE; } else { LEPT_FREE(rp); snprintf(errormsg, sizeof(errormsg), "Syntax: %s [ [generate] | compare | display ]", argv[0]); return ERROR_INT(errormsg, procName, 1); } /* Print out test name and both the leptonica and * image libarary versions */ fprintf(stderr, "\n################ %s_reg ###############\n", rp->testname); vers = getLeptonicaVersion(); fprintf(stderr, "%s\n", vers); LEPT_FREE(vers); vers = getImagelibVersions(); fprintf(stderr, "%s\n", vers); LEPT_FREE(vers); rp->tstart = startTimerNested(); return 0; }
/*! * ioFormatTest() * * Input: filename (input file) * Return: 0 if OK; 1 on error or if the test fails * * Notes: * (1) This writes and reads a set of output files losslessly * in different formats to /tmp/format/, and tests that the * result before and after is unchanged. * (2) This should work properly on input images of any depth, * with and without colormaps. * (3) All supported formats are tested for bmp, png, tiff and * non-ascii pnm. Ascii pnm also works (but who'd ever want * to use it?) We allow 2 bpp bmp, although it's not * supported elsewhere. And we don't support reading * 16 bpp png, although this can be turned on in pngio.c. * (4) This silently skips png or tiff testing if HAVE_LIBPNG * or HAVE_LIBTIFF are 0, respectively. */ l_int32 ioFormatTest(const char *filename) { l_int32 w, h, d, depth, equal, problems; l_float32 diff; BOX *box; PIX *pixs, *pixc, *pix1, *pix2; PIXCMAP *cmap; PROCNAME("ioFormatTest"); if (!filename) return ERROR_INT("filename not defined", procName, 1); /* Read the input file and limit the size */ if ((pix1 = pixRead(filename)) == NULL) return ERROR_INT("pix1 not made", procName, 1); pixGetDimensions(pix1, &w, &h, NULL); if (w > 250 && h > 250) { /* take the central 250 x 250 region */ box = boxCreate(w / 2 - 125, h / 2 - 125, 250, 250); pixs = pixClipRectangle(pix1, box, NULL); boxDestroy(&box); } else { pixs = pixClone(pix1); } pixDestroy(&pix1); lept_mkdir("lept"); /* Note that the reader automatically removes colormaps * from 1 bpp BMP images, but not from 8 bpp BMP images. * Therefore, if our 8 bpp image initially doesn't have a * colormap, we are going to need to remove it from any * pix read from a BMP file. */ pixc = pixClone(pixs); /* laziness */ /* This does not test the alpha layer pixels, because most * formats don't support it. Remove any alpha. */ if (pixGetSpp(pixc) == 4) pixSetSpp(pixc, 3); cmap = pixGetColormap(pixc); /* colormap; can be NULL */ d = pixGetDepth(pixc); problems = FALSE; /* ----------------------- BMP -------------------------- */ /* BMP works for 1, 2, 4, 8 and 32 bpp images. * It always writes colormaps for 1 and 8 bpp, so we must * remove it after readback if the input image doesn't have * a colormap. Although we can write/read 2 bpp BMP, nobody * else can read them! */ if (d == 1 || d == 8) { L_INFO("write/read bmp\n", procName); pixWrite(FILE_BMP, pixc, IFF_BMP); pix1 = pixRead(FILE_BMP); if (!cmap) pix2 = pixRemoveColormap(pix1, REMOVE_CMAP_BASED_ON_SRC); else pix2 = pixClone(pix1); pixEqual(pixc, pix2, &equal); if (!equal) { L_INFO(" **** bad bmp image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); pixDestroy(&pix2); } if (d == 2 || d == 4 || d == 32) { L_INFO("write/read bmp\n", procName); pixWrite(FILE_BMP, pixc, IFF_BMP); pix1 = pixRead(FILE_BMP); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad bmp image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); } /* ----------------------- PNG -------------------------- */ #if HAVE_LIBPNG /* PNG works for all depths, but here, because we strip * 16 --> 8 bpp on reading, we don't test png for 16 bpp. */ if (d != 16) { L_INFO("write/read png\n", procName); pixWrite(FILE_PNG, pixc, IFF_PNG); pix1 = pixRead(FILE_PNG); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad png image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); } #endif /* HAVE_LIBPNG */ /* ----------------------- TIFF -------------------------- */ #if HAVE_LIBTIFF /* TIFF works for 1, 2, 4, 8, 16 and 32 bpp images. * Because 8 bpp tiff always writes 256 entry colormaps, the * colormap sizes may be different for 8 bpp images with * colormap; we are testing if the image content is the same. * Likewise, the 2 and 4 bpp tiff images with colormaps * have colormap sizes 4 and 16, rsp. This test should * work properly on the content, regardless of the number * of color entries in pixc. */ /* tiff uncompressed works for all pixel depths */ L_INFO("write/read uncompressed tiff\n", procName); pixWrite(FILE_TIFF, pixc, IFF_TIFF); pix1 = pixRead(FILE_TIFF); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad tiff uncompressed image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); /* tiff lzw works for all pixel depths */ L_INFO("write/read lzw compressed tiff\n", procName); pixWrite(FILE_LZW, pixc, IFF_TIFF_LZW); pix1 = pixRead(FILE_LZW); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad tiff lzw compressed image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); /* tiff adobe deflate (zip) works for all pixel depths */ L_INFO("write/read zip compressed tiff\n", procName); pixWrite(FILE_ZIP, pixc, IFF_TIFF_ZIP); pix1 = pixRead(FILE_ZIP); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad tiff zip compressed image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); /* tiff g4, g3, rle and packbits work for 1 bpp */ if (d == 1) { L_INFO("write/read g4 compressed tiff\n", procName); pixWrite(FILE_G4, pixc, IFF_TIFF_G4); pix1 = pixRead(FILE_G4); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad tiff g4 image ****\n", procName); problems = TRUE; } pixDestroy(&pix1); L_INFO("write/read g3 compressed tiff\n", procName); pixWrite(FILE_G3, pixc, IFF_TIFF_G3); pix1 = pixRead(FILE_G3); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad tiff g3 image ****\n", procName); problems = TRUE; } pixDestroy(&pix1); L_INFO("write/read rle compressed tiff\n", procName); pixWrite(FILE_RLE, pixc, IFF_TIFF_RLE); pix1 = pixRead(FILE_RLE); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad tiff rle image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); L_INFO("write/read packbits compressed tiff\n", procName); pixWrite(FILE_PB, pixc, IFF_TIFF_PACKBITS); pix1 = pixRead(FILE_PB); pixEqual(pixc, pix1, &equal); if (!equal) { L_INFO(" **** bad tiff packbits image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); } #endif /* HAVE_LIBTIFF */ /* ----------------------- PNM -------------------------- */ /* pnm works for 1, 2, 4, 8, 16 and 32 bpp. * pnm doesn't have colormaps, so when we write colormapped * pix out as pnm, the colormap is removed. Thus for the test, * we must remove the colormap from pixc before testing. */ L_INFO("write/read pnm\n", procName); pixWrite(FILE_PNM, pixc, IFF_PNM); pix1 = pixRead(FILE_PNM); if (cmap) pix2 = pixRemoveColormap(pixc, REMOVE_CMAP_BASED_ON_SRC); else pix2 = pixClone(pixc); pixEqual(pix1, pix2, &equal); if (!equal) { L_INFO(" **** bad pnm image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); pixDestroy(&pix2); /* ----------------------- GIF -------------------------- */ #if HAVE_LIBGIF /* GIF works for only 1 and 8 bpp, colormapped */ if (d != 8 || !cmap) pix1 = pixConvertTo8(pixc, 1); else pix1 = pixClone(pixc); L_INFO("write/read gif\n", procName); pixWrite(FILE_GIF, pix1, IFF_GIF); pix2 = pixRead(FILE_GIF); pixEqual(pix1, pix2, &equal); if (!equal) { L_INFO(" **** bad gif image: d = %d ****\n", procName, d); problems = TRUE; } pixDestroy(&pix1); pixDestroy(&pix2); #endif /* HAVE_LIBGIF */ /* ----------------------- JPEG ------------------------- */ #if HAVE_LIBJPEG /* JPEG works for only 8 bpp gray and rgb */ if (cmap || d > 8) pix1 = pixConvertTo32(pixc); else pix1 = pixConvertTo8(pixc, 0); depth = pixGetDepth(pix1); L_INFO("write/read jpeg\n", procName); pixWrite(FILE_JPG, pix1, IFF_JFIF_JPEG); pix2 = pixRead(FILE_JPG); if (depth == 8) { pixCompareGray(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff, NULL, NULL); } else { pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff, NULL, NULL); } if (diff > 8.0) { L_INFO(" **** bad jpeg image: d = %d, diff = %5.2f ****\n", procName, depth, diff); problems = TRUE; } pixDestroy(&pix1); pixDestroy(&pix2); #endif /* HAVE_LIBJPEG */ /* ----------------------- WEBP ------------------------- */ #if HAVE_LIBWEBP /* WEBP works for rgb and rgba */ if (cmap || d <= 16) pix1 = pixConvertTo32(pixc); else pix1 = pixClone(pixc); depth = pixGetDepth(pix1); L_INFO("write/read webp\n", procName); pixWrite(FILE_WEBP, pix1, IFF_WEBP); pix2 = pixRead(FILE_WEBP); pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff, NULL, NULL); if (diff > 5.0) { L_INFO(" **** bad webp image: d = %d, diff = %5.2f ****\n", procName, depth, diff); problems = TRUE; } pixDestroy(&pix1); pixDestroy(&pix2); #endif /* HAVE_LIBWEBP */ /* ----------------------- JP2K ------------------------- */ #if HAVE_LIBJP2K /* JP2K works for only 8 bpp gray, rgb and rgba */ if (cmap || d > 8) pix1 = pixConvertTo32(pixc); else pix1 = pixConvertTo8(pixc, 0); depth = pixGetDepth(pix1); L_INFO("write/read jp2k\n", procName); pixWrite(FILE_JP2K, pix1, IFF_JP2); pix2 = pixRead(FILE_JP2K); if (depth == 8) { pixCompareGray(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff, NULL, NULL); } else { pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff, NULL, NULL); } fprintf(stderr, "diff = %7.3f\n", diff); if (diff > 7.0) { L_INFO(" **** bad jp2k image: d = %d, diff = %5.2f ****\n", procName, depth, diff); problems = TRUE; } pixDestroy(&pix1); pixDestroy(&pix2); #endif /* HAVE_LIBJP2K */ if (problems == FALSE) L_INFO("All formats read and written OK!\n", procName); pixDestroy(&pixc); pixDestroy(&pixs); return problems; }
int main(int argc, char **argv) { l_uint8 *data; l_int32 w, h, n1, n2, n, i, minval, maxval; l_int32 ncolors, rval, gval, bval, equal; l_int32 *rmap, *gmap, *bmap; l_uint32 color; l_float32 gamma; BOX *box; FILE *fp; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6; PIX *pixs, *pixb, *pixg, *pixc, *pixd; PIX *pixg2, *pixcs1, *pixcs2, *pixd1, *pixd2; PIXA *pixa, *pixa2, *pixa3; PIXCMAP *cmap, *cmap2; RGBA_QUAD *cta; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* ------------------------ (1) ----------------------------*/ /* Blend with a white background */ pix1 = pixRead("books_logo.png"); pixDisplayWithTitle(pix1, 100, 0, NULL, rp->display); pix2 = pixAlphaBlendUniform(pix1, 0xffffff00); pixDisplayWithTitle(pix2, 100, 150, NULL, rp->display); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 0 */ regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 1 */ /* Generate an alpha layer based on the white background */ pix3 = pixSetAlphaOverWhite(pix2); pixSetSpp(pix3, 3); /* without alpha */ pixWrite("/tmp/lept/regout/alphaops.2.png", pix3, IFF_PNG); regTestCheckFile(rp, "/tmp/lept/regout/alphaops.2.png"); /* 2 */ pixSetSpp(pix3, 4); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 3, with alpha */ pixDisplayWithTitle(pix3, 100, 300, NULL, rp->display); /* Render on a light yellow background */ pix4 = pixAlphaBlendUniform(pix3, 0xffffe000); regTestWritePixAndCheck(rp, pix4, IFF_PNG); /* 4 */ pixDisplayWithTitle(pix4, 100, 450, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); /* ------------------------ (2) ----------------------------*/ lept_mkdir("lept/alpha"); /* Make the transparency (alpha) layer. * pixs is the mask. We turn it into a transparency (alpha) * layer by converting to 8 bpp. A small convolution fuzzes * the mask edges so that you don't see the pixels. */ pixs = pixRead("feyn-fract.tif"); pixGetDimensions(pixs, &w, &h, NULL); pixg = pixConvert1To8(NULL, pixs, 0, 255); pixg2 = pixBlockconvGray(pixg, NULL, 1, 1); regTestWritePixAndCheck(rp, pixg2, IFF_JFIF_JPEG); /* 5 */ pixDisplayWithTitle(pixg2, 0, 0, "alpha", rp->display); /* Make the viewable image. * pixc is the image that we see where the alpha layer is * opaque -- i.e., greater than 0. Scale it to the same * size as the mask. To visualize what this will look like * when displayed over a black background, create the black * background image, pixb, and do the blending with pixcs1 * explicitly using the alpha layer pixg2. */ pixc = pixRead("tetons.jpg"); pixcs1 = pixScaleToSize(pixc, w, h); regTestWritePixAndCheck(rp, pixcs1, IFF_JFIF_JPEG); /* 6 */ pixDisplayWithTitle(pixcs1, 300, 0, "viewable", rp->display); pixb = pixCreateTemplate(pixcs1); /* black */ pixd1 = pixBlendWithGrayMask(pixb, pixcs1, pixg2, 0, 0); regTestWritePixAndCheck(rp, pixd1, IFF_JFIF_JPEG); /* 7 */ pixDisplayWithTitle(pixd1, 600, 0, "alpha-blended 1", rp->display); /* Embed the alpha layer pixg2 into the color image pixc. * Write it out as is. Then clean pixcs1 (to 0) under the fully * transparent part of the alpha layer, and write that result * out as well. */ pixSetRGBComponent(pixcs1, pixg2, L_ALPHA_CHANNEL); pixWrite("/tmp/lept/alpha/cs1.png", pixcs1, IFF_PNG); pixcs2 = pixSetUnderTransparency(pixcs1, 0, 0); pixWrite("/tmp/lept/alpha/cs2.png", pixcs2, IFF_PNG); /* What will this look like over a black background? * Do the blending explicitly and display. It should * look identical to the blended result pixd1 before cleaning. */ pixd2 = pixBlendWithGrayMask(pixb, pixcs2, pixg2, 0, 0); regTestWritePixAndCheck(rp, pixd2, IFF_JFIF_JPEG); /* 8 */ pixDisplayWithTitle(pixd2, 0, 400, "alpha blended 2", rp->display); /* Read the two images back, ignoring the transparency layer. * The uncleaned image will come back identical to pixcs1. * However, the cleaned image will be black wherever * the alpha layer was fully transparent. It will * look the same when viewed through the alpha layer, * but have much better compression. */ pix1 = pixRead("/tmp/lept/alpha/cs1.png"); /* just pixcs1 */ pix2 = pixRead("/tmp/lept/alpha/cs2.png"); /* cleaned under transparent */ n1 = nbytesInFile("/tmp/lept/alpha/cs1.png"); n2 = nbytesInFile("/tmp/lept/alpha/cs2.png"); fprintf(stderr, " Original: %d bytes\n Cleaned: %d bytes\n", n1, n2); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 9 */ regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 10 */ pixDisplayWithTitle(pix1, 300, 400, "without alpha", rp->display); pixDisplayWithTitle(pix2, 600, 400, "cleaned under transparent", rp->display); pixa = pixaCreate(0); pixSaveTiled(pixg2, pixa, 1.0, 1, 20, 32); pixSaveTiled(pixcs1, pixa, 1.0, 1, 20, 0); pixSaveTiled(pix1, pixa, 1.0, 0, 20, 0); pixSaveTiled(pixd1, pixa, 1.0, 1, 20, 0); pixSaveTiled(pixd2, pixa, 1.0, 0, 20, 0); pixSaveTiled(pix2, pixa, 1.0, 1, 20, 0); pixd = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 11 */ pixDisplayWithTitle(pixd, 200, 200, "composite", rp->display); pixWrite("/tmp/lept/alpha/composite.png", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixs); pixDestroy(&pixb); pixDestroy(&pixg); pixDestroy(&pixg2); pixDestroy(&pixc); pixDestroy(&pixcs1); pixDestroy(&pixcs2); pixDestroy(&pixd); pixDestroy(&pixd1); pixDestroy(&pixd2); pixDestroy(&pix1); pixDestroy(&pix2); /* ------------------------ (3) ----------------------------*/ color = 0xffffa000; gamma = 1.0; minval = 0; maxval = 200; box = boxCreate(0, 85, 600, 100); pixa = pixaCreate(6); pix1 = pixRead("blend-green1.jpg"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-green2.png"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-green3.png"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-orange.jpg"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-yellow.jpg"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-red.png"); pixaAddPix(pixa, pix1, L_INSERT); n = pixaGetCount(pixa); pixa2 = pixaCreate(n); pixa3 = pixaCreate(n); for (i = 0; i < n; i++) { pix1 = pixaGetPix(pixa, i, L_CLONE); pix2 = DoBlendTest(pix1, box, color, gamma, minval, maxval, 1); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 12, 14, ... 22 */ pixDisplayWithTitle(pix2, 150 * i, 0, NULL, rp->display); pixaAddPix(pixa2, pix2, L_INSERT); pix2 = DoBlendTest(pix1, box, color, gamma, minval, maxval, 2); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 13, 15, ... 23 */ pixDisplayWithTitle(pix2, 150 * i, 200, NULL, rp->display); pixaAddPix(pixa3, pix2, L_INSERT); pixDestroy(&pix1); } if (rp->display) { pixaConvertToPdf(pixa2, 0, 0.75, L_FLATE_ENCODE, 0, "blend 1 test", "/tmp/lept/alpha/blend1.pdf"); pixaConvertToPdf(pixa3, 0, 0.75, L_FLATE_ENCODE, 0, "blend 2 test", "/tmp/lept/alpha/blend2.pdf"); } pixaDestroy(&pixa); pixaDestroy(&pixa2); pixaDestroy(&pixa3); boxDestroy(&box); /* ------------------------ (4) ----------------------------*/ /* Use one image as the alpha component for a second image */ pix1 = pixRead("test24.jpg"); pix2 = pixRead("marge.jpg"); pix3 = pixScale(pix2, 1.9, 2.2); pix4 = pixConvertTo8(pix3, 0); pixSetRGBComponent(pix1, pix4, L_ALPHA_CHANNEL); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 24 */ pixDisplayWithTitle(pix1, 600, 0, NULL, rp->display); /* Set the alpha value in a colormap to bval */ pix5 = pixOctreeColorQuant(pix1, 128, 0); cmap = pixGetColormap(pix5); pixcmapToArrays(cmap, &rmap, &gmap, &bmap, NULL); n = pixcmapGetCount(cmap); for (i = 0; i < n; i++) { pixcmapGetColor(cmap, i, &rval, &gval, &bval); cta = (RGBA_QUAD *)cmap->array; cta[i].alpha = bval; } /* Test binary serialization/deserialization of colormap with alpha */ pixcmapSerializeToMemory(cmap, 4, &ncolors, &data); cmap2 = pixcmapDeserializeFromMemory(data, 4, ncolors); CmapEqual(cmap, cmap2, &equal); regTestCompareValues(rp, TRUE, equal, 0.0); /* 25 */ pixcmapDestroy(&cmap2); lept_free(data); /* Test ascii serialization/deserialization of colormap with alpha */ fp = fopenWriteStream("/tmp/lept/alpha/cmap.4", "w"); pixcmapWriteStream(fp, cmap); fclose(fp); fp = fopenReadStream("/tmp/lept/alpha/cmap.4"); cmap2 = pixcmapReadStream(fp); fclose(fp); CmapEqual(cmap, cmap2, &equal); regTestCompareValues(rp, TRUE, equal, 0.0); /* 26 */ pixcmapDestroy(&cmap2); /* Test r/w for cmapped pix with non-opaque alpha */ pixDisplayWithTitle(pix5, 900, 0, NULL, rp->display); regTestWritePixAndCheck(rp, pix5, IFF_PNG); /* 27 */ pixWrite("/tmp/lept/alpha/fourcomp.png", pix5, IFF_PNG); pix6 = pixRead("/tmp/lept/alpha/fourcomp.png"); regTestComparePix(rp, pix5, pix6); /* 28 */ pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); lept_free(rmap); lept_free(gmap); lept_free(bmap); return regTestCleanup(rp); }
int main(int argc, char **argv) { char *selname; l_int32 i, j, nsels, sx, sy; l_float32 fact, time; GPLOT *gplot; NUMA *na1, *na2, *na3, *na4, *nac1, *nac2, *nac3, *nac4, *nax; PIX *pixs, *pixt; PIXA *pixa; SEL *sel; SELA *selalinear; static char mainName[] = "dwamorph2_reg"; if (argc != 1) return ERROR_INT(" Syntax: dwamorph2_reg", mainName, 1); pixs = pixRead("feyn-fract.tif"); pixt = pixCreateTemplate(pixs); selalinear = selaAddDwaLinear(NULL); nsels = selaGetCount(selalinear); fact = 1000. / (l_float32)NTIMES; /* converts to time in msec */ na1 = numaCreate(64); na2 = numaCreate(64); na3 = numaCreate(64); na4 = numaCreate(64); lept_mkdir("lept/morph"); /* --------- dilation ----------*/ for (i = 0; i < nsels / 2; i++) { sel = selaGetSel(selalinear, i); selGetParameters(sel, &sy, &sx, NULL, NULL); selname = selGetName(sel); fprintf(stderr, " %d .", i); startTimer(); for (j = 0; j < NTIMES; j++) pixDilate(pixt, pixs, sel); time = fact * stopTimer(); numaAddNumber(na1, time); startTimer(); for (j = 0; j < NTIMES; j++) pixDilateCompBrick(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na2, time); startTimer(); for (j = 0; j < NTIMES; j++) pixMorphDwa_3(pixt, pixs, L_MORPH_DILATE, selname); time = fact * stopTimer(); numaAddNumber(na3, time); startTimer(); for (j = 0; j < NTIMES; j++) pixDilateCompBrickDwa(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na4, time); } nax = numaMakeSequence(2, 1, nsels / 2); nac1 = numaWindowedMean(na1, HALFWIDTH); nac2 = numaWindowedMean(na2, HALFWIDTH); nac3 = numaWindowedMean(na3, HALFWIDTH); nac4 = numaWindowedMean(na4, HALFWIDTH); gplot = gplotCreate("/tmp/lept/morph/dilate", GPLOT_PNG, "Dilation time vs sel size", "size", "time (ms)"); gplotAddPlot(gplot, nax, nac1, GPLOT_LINES, "linear rasterop"); gplotAddPlot(gplot, nax, nac2, GPLOT_LINES, "composite rasterop"); gplotAddPlot(gplot, nax, nac3, GPLOT_LINES, "linear dwa"); gplotAddPlot(gplot, nax, nac4, GPLOT_LINES, "composite dwa"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nac1); numaDestroy(&nac2); numaDestroy(&nac3); numaDestroy(&nac4); /* --------- erosion ----------*/ numaEmpty(na1); numaEmpty(na2); numaEmpty(na3); numaEmpty(na4); for (i = 0; i < nsels / 2; i++) { sel = selaGetSel(selalinear, i); selGetParameters(sel, &sy, &sx, NULL, NULL); selname = selGetName(sel); fprintf(stderr, " %d .", i); startTimer(); for (j = 0; j < NTIMES; j++) pixErode(pixt, pixs, sel); time = fact * stopTimer(); numaAddNumber(na1, time); startTimer(); for (j = 0; j < NTIMES; j++) pixErodeCompBrick(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na2, time); startTimer(); for (j = 0; j < NTIMES; j++) pixMorphDwa_3(pixt, pixs, L_MORPH_ERODE, selname); time = fact * stopTimer(); numaAddNumber(na3, time); startTimer(); for (j = 0; j < NTIMES; j++) pixErodeCompBrickDwa(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na4, time); } nac1 = numaWindowedMean(na1, HALFWIDTH); nac2 = numaWindowedMean(na2, HALFWIDTH); nac3 = numaWindowedMean(na3, HALFWIDTH); nac4 = numaWindowedMean(na4, HALFWIDTH); gplot = gplotCreate("/tmp/lept/morph/erode", GPLOT_PNG, "Erosion time vs sel size", "size", "time (ms)"); gplotAddPlot(gplot, nax, nac1, GPLOT_LINES, "linear rasterop"); gplotAddPlot(gplot, nax, nac2, GPLOT_LINES, "composite rasterop"); gplotAddPlot(gplot, nax, nac3, GPLOT_LINES, "linear dwa"); gplotAddPlot(gplot, nax, nac4, GPLOT_LINES, "composite dwa"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nac1); numaDestroy(&nac2); numaDestroy(&nac3); numaDestroy(&nac4); /* --------- opening ----------*/ numaEmpty(na1); numaEmpty(na2); numaEmpty(na3); numaEmpty(na4); for (i = 0; i < nsels / 2; i++) { sel = selaGetSel(selalinear, i); selGetParameters(sel, &sy, &sx, NULL, NULL); selname = selGetName(sel); fprintf(stderr, " %d .", i); startTimer(); for (j = 0; j < NTIMES; j++) pixOpen(pixt, pixs, sel); time = fact * stopTimer(); numaAddNumber(na1, time); startTimer(); for (j = 0; j < NTIMES; j++) pixOpenCompBrick(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na2, time); startTimer(); for (j = 0; j < NTIMES; j++) pixMorphDwa_3(pixt, pixs, L_MORPH_OPEN, selname); time = fact * stopTimer(); numaAddNumber(na3, time); startTimer(); for (j = 0; j < NTIMES; j++) pixOpenCompBrickDwa(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na4, time); } nac1 = numaWindowedMean(na1, HALFWIDTH); nac2 = numaWindowedMean(na2, HALFWIDTH); nac3 = numaWindowedMean(na3, HALFWIDTH); nac4 = numaWindowedMean(na4, HALFWIDTH); gplot = gplotCreate("/tmp/lept/morph/open", GPLOT_PNG, "Opening time vs sel size", "size", "time (ms)"); gplotAddPlot(gplot, nax, nac1, GPLOT_LINES, "linear rasterop"); gplotAddPlot(gplot, nax, nac2, GPLOT_LINES, "composite rasterop"); gplotAddPlot(gplot, nax, nac3, GPLOT_LINES, "linear dwa"); gplotAddPlot(gplot, nax, nac4, GPLOT_LINES, "composite dwa"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nac1); numaDestroy(&nac2); numaDestroy(&nac3); numaDestroy(&nac4); /* --------- closing ----------*/ numaEmpty(na1); numaEmpty(na2); numaEmpty(na3); numaEmpty(na4); for (i = 0; i < nsels / 2; i++) { sel = selaGetSel(selalinear, i); selGetParameters(sel, &sy, &sx, NULL, NULL); selname = selGetName(sel); fprintf(stderr, " %d .", i); startTimer(); for (j = 0; j < NTIMES; j++) pixClose(pixt, pixs, sel); time = fact * stopTimer(); numaAddNumber(na1, time); startTimer(); for (j = 0; j < NTIMES; j++) pixCloseCompBrick(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na2, time); startTimer(); for (j = 0; j < NTIMES; j++) pixMorphDwa_3(pixt, pixs, L_MORPH_CLOSE, selname); time = fact * stopTimer(); numaAddNumber(na3, time); startTimer(); for (j = 0; j < NTIMES; j++) pixCloseCompBrickDwa(pixt, pixs, sx, sy); time = fact * stopTimer(); numaAddNumber(na4, time); } nac1 = numaWindowedMean(na1, HALFWIDTH); nac2 = numaWindowedMean(na2, HALFWIDTH); nac3 = numaWindowedMean(na3, HALFWIDTH); nac4 = numaWindowedMean(na4, HALFWIDTH); gplot = gplotCreate("/tmp/lept/morph/close", GPLOT_PNG, "Closing time vs sel size", "size", "time (ms)"); gplotAddPlot(gplot, nax, nac1, GPLOT_LINES, "linear rasterop"); gplotAddPlot(gplot, nax, nac2, GPLOT_LINES, "composite rasterop"); gplotAddPlot(gplot, nax, nac3, GPLOT_LINES, "linear dwa"); gplotAddPlot(gplot, nax, nac4, GPLOT_LINES, "composite dwa"); gplotMakeOutput(gplot); #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ gplotDestroy(&gplot); numaDestroy(&nac1); numaDestroy(&nac2); numaDestroy(&nac3); numaDestroy(&nac4); numaDestroy(&na1); numaDestroy(&na2); numaDestroy(&na3); numaDestroy(&na4); numaDestroy(&nax); selaDestroy(&selalinear); pixDestroy(&pixt); pixDestroy(&pixs); /* Display the results together */ pixa = pixaCreate(0); pixs = pixRead("/tmp/lept/morph/dilate.png"); pixaAddPix(pixa, pixs, L_INSERT); pixs = pixRead("/tmp/lept/morph/erode.png"); pixaAddPix(pixa, pixs, L_INSERT); pixs = pixRead("/tmp/lept/morph/open.png"); pixaAddPix(pixa, pixs, L_INSERT); pixs = pixRead("/tmp/lept/morph/close.png"); pixaAddPix(pixa, pixs, L_INSERT); pixt = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 40, 3); pixWrite("/tmp/lept/morph/timings.png", pixt, IFF_PNG); pixDisplay(pixt, 100, 100); pixDestroy(&pixt); pixaDestroy(&pixa); return 0; }
int main(int argc, char **argv) { l_uint8 *data1, *data2; l_int32 i, same, w, h, width, success, nba; size_t size1, size2; l_float32 diffarea, diffxor, scalefact; BOX *box; BOXA *boxa1, *boxa2, *boxa3; BOXAA *baa1, *baa2, *baa3; PIX *pix1, *pixdb; PIXA *pixa1, *pixa2; static char mainName[] = "boxa1_reg"; if (argc != 1) return ERROR_INT(" Syntax: boxa1_reg", mainName, 1); lept_mkdir("lept/boxa"); /* Make a boxa and display its contents */ boxa1 = boxaCreate(6); box = boxCreate(60, 60, 40, 20); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(120, 50, 20, 50); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(50, 140, 46, 60); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(166, 130, 64, 28); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(64, 224, 44, 34); boxaAddBox(boxa1, box, L_INSERT); box = boxCreate(117, 206, 26, 74); boxaAddBox(boxa1, box, L_INSERT); pix1 = DisplayBoxa(boxa1); pixDisplay(pix1, 100, 100); pixDestroy(&pix1); boxaCompareRegions(boxa1, boxa1, 100, &same, &diffarea, &diffxor, NULL); fprintf(stderr, "same = %d, diffarea = %5.3f, diffxor = %5.3f\n", same, diffarea, diffxor); boxa2 = boxaTransform(boxa1, -13, -13, 1.0, 1.0); boxaCompareRegions(boxa1, boxa2, 10, &same, &diffarea, &diffxor, NULL); fprintf(stderr, "same = %d, diffarea = %5.3f, diffxor = %5.3f\n", same, diffarea, diffxor); boxaDestroy(&boxa2); boxa2 = boxaReconcileEvenOddHeight(boxa1, L_ADJUST_TOP_AND_BOT, 6, L_ADJUST_CHOOSE_MIN, 1.0, 0); pix1 = DisplayBoxa(boxa2); pixDisplay(pix1, 100, 500); pixDestroy(&pix1); boxaCompareRegions(boxa1, boxa2, 10, &same, &diffarea, &diffxor, &pixdb); fprintf(stderr, "same = %d, diffarea = %5.3f, diffxor = %5.3f\n", same, diffarea, diffxor); pixDisplay(pixdb, 700, 100); pixDestroy(&pixdb); boxaDestroy(&boxa1); boxaDestroy(&boxa2); /* Input is a fairly clean boxa */ boxa1 = boxaRead("boxa1.ba"); boxa2 = boxaReconcileEvenOddHeight(boxa1, L_ADJUST_TOP, 80, L_ADJUST_CHOOSE_MIN, 1.05, 1); width = 100; boxaGetExtent(boxa2, &w, &h, NULL); scalefact = (l_float32)width / (l_float32)w; boxa3 = boxaTransform(boxa2, 0, 0, scalefact, scalefact); pix1 = boxaDisplayTiled(boxa3, NULL, 1500, 2, 1.0, 0, 3, 2); pixDisplay(pix1, 0, 100); pixWrite("/tmp/lept/boxa/pix1.png", pix1, IFF_PNG); pixDestroy(&pix1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); /* Input is an unsmoothed and noisy boxa */ boxa1 = boxaRead("boxa2.ba"); boxa2 = boxaReconcileEvenOddHeight(boxa1, L_ADJUST_TOP, 80, L_ADJUST_CHOOSE_MIN, 1.05, 1); width = 100; boxaGetExtent(boxa2, &w, &h, NULL); scalefact = (l_float32)width / (l_float32)w; boxa3 = boxaTransform(boxa2, 0, 0, scalefact, scalefact); pix1 = boxaDisplayTiled(boxa3, NULL, 1500, 2, 1.0, 0, 3, 2); pixDisplay(pix1, 500, 100); pixWrite("/tmp/lept/boxa/pix2.png", pix1, IFF_PNG); pixDestroy(&pix1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); /* Input is a boxa smoothed with a median window filter */ boxa1 = boxaRead("boxa3.ba"); boxa2 = boxaReconcileEvenOddHeight(boxa1, L_ADJUST_TOP, 80, L_ADJUST_CHOOSE_MIN, 1.05, 1); width = 100; boxaGetExtent(boxa2, &w, &h, NULL); scalefact = (l_float32)width / (l_float32)w; boxa3 = boxaTransform(boxa2, 0, 0, scalefact, scalefact); pix1 = boxaDisplayTiled(boxa3, NULL, 1500, 2, 1.0, 0, 3, 2); pixDisplay(pix1, 1000, 100); pixWrite("/tmp/lept/boxa/pix3.png", pix1, IFF_PNG); pixDestroy(&pix1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); /* Test serialized boxa I/O to and from memory */ data1 = l_binaryRead("boxa2.ba", &size1); boxa1 = boxaReadMem(data1, size1); boxaWriteMem(&data2, &size2, boxa1); boxa2 = boxaReadMem(data2, size2); boxaWrite("/tmp/lept/boxa/boxa1.ba", boxa1); boxaWrite("/tmp/lept/boxa/boxa2.ba", boxa2); filesAreIdentical("/tmp/lept/boxa/boxa1.ba", "/tmp/lept/boxa/boxa2.ba", &same); if (same) fprintf(stderr, "Good: boxes files are identical\n"); else fprintf(stderr, "Bad: boxes files differ\n"); boxaDestroy(&boxa1); boxaDestroy(&boxa2); lept_free(data1); lept_free(data2); /* Test pixaDisplayBoxaa() */ pixa1 = pixaReadBoth("showboxes.pac"); baa1 = boxaaRead("showboxes1.baa"); baa2 = boxaaTranspose(baa1); baa3 = boxaaTranspose(baa2); nba = boxaaGetCount(baa1); success = TRUE; for (i = 0; i < nba; i++) { boxa1 = boxaaGetBoxa(baa1, i, L_CLONE); boxa2 = boxaaGetBoxa(baa3, i, L_CLONE); boxaEqual(boxa1, boxa2, 0, NULL, &same); boxaDestroy(&boxa1); boxaDestroy(&boxa2); if (!same) success = FALSE; } if (success) fprintf(stderr, "Good: transpose is reversible\n"); else fprintf(stderr, "Bad: transpose failed\n"); pixa2 = pixaDisplayBoxaa(pixa1, baa2, L_DRAW_RGB, 2); pix1 = pixaDisplayTiledInRows(pixa2, 32, 1400, 1.0, 0, 10, 0); pixDisplay(pix1, 0, 600); fprintf(stderr, "Writing to: /tmp/lept/boxa/show.pdf\n"); pixaConvertToPdf(pixa2, 75, 1.0, 0, 0, NULL, "/tmp/lept/boxa/show.pdf"); pixDestroy(&pix1); pixaDestroy(&pixa1); pixaDestroy(&pixa2); boxaaDestroy(&baa1); boxaaDestroy(&baa2); boxaaDestroy(&baa3); return 0; }
int main(int argc, char **argv) { char *str; l_uint8 *data1, *data2; l_int32 i, n, same1, same2; size_t size1, size2, slice, total, start, end; FILE *fp; L_DNA *da; SARRAY *sa; L_BYTEA *lba1, *lba2, *lba3, *lba4, *lba5; static char mainName[] = "byteatest"; if (argc != 1) return ERROR_INT("syntax: byteatest", mainName, 1); lept_mkdir("bytea"); /* Test basic init, join and split */ lba1 = l_byteaInitFromFile("feyn.tif"); lba2 = l_byteaInitFromFile("test24.jpg"); size1 = l_byteaGetSize(lba1); size2 = l_byteaGetSize(lba2); l_byteaJoin(lba1, &lba2); lba3 = l_byteaInitFromMem(lba1->data, size1); lba4 = l_byteaInitFromMem(lba1->data + size1, size2); /* Split by hand */ l_binaryWrite("/tmp/bytea/junk1.dat", "w", lba3->data, lba3->size); l_binaryWrite("/tmp/bytea/junk2.dat", "w", lba4->data, lba4->size); filesAreIdentical("feyn.tif", "/tmp/bytea/junk1.dat", &same1); filesAreIdentical("test24.jpg", "/tmp/bytea/junk2.dat", &same2); if (same1 && same2) fprintf(stderr, "OK for join file\n"); else fprintf(stderr, "Error: files are different!\n"); /* Split by function */ l_byteaSplit(lba1, size1, &lba5); l_binaryWrite("/tmp/bytea/junk3.dat", "w", lba1->data, lba1->size); l_binaryWrite("/tmp/bytea/junk4.dat", "w", lba5->data, lba5->size); filesAreIdentical("feyn.tif", "/tmp/bytea/junk3.dat", &same1); filesAreIdentical("test24.jpg", "/tmp/bytea/junk4.dat", &same2); if (same1 && same2) fprintf(stderr, "OK for split file\n"); else fprintf(stderr, "Error: files are different!\n"); l_byteaDestroy(&lba1); l_byteaDestroy(&lba2); l_byteaDestroy(&lba3); l_byteaDestroy(&lba4); l_byteaDestroy(&lba5); /* Test appending with strings */ data1 = l_binaryRead("kernel_reg.c", &size1); sa = sarrayCreateLinesFromString((char *)data1, 1); lba1 = l_byteaCreate(0); n = sarrayGetCount(sa); for (i = 0; i < n; i++) { str = sarrayGetString(sa, i, L_NOCOPY); l_byteaAppendString(lba1, str); l_byteaAppendString(lba1, (char *)"\n"); } data2 = l_byteaGetData(lba1, &size2); l_binaryWrite("/tmp/bytea/junk5.dat", "w", data2, size2); filesAreIdentical("kernel_reg.c", "/tmp/bytea/junk5.dat", &same1); if (same1) fprintf(stderr, "OK for appended string data\n"); else fprintf(stderr, "Error: appended string data is different!\n"); lept_free(data1); sarrayDestroy(&sa); l_byteaDestroy(&lba1); /* Test appending with binary data */ slice = 1000; total = nbytesInFile("breviar-a38.jp2"); lba1 = l_byteaCreate(100); n = 1 + total / slice; fprintf(stderr, "******************************************************\n"); fprintf(stderr, "* Testing error checking: ignore two reported errors *\n"); for (i = 0, start = 0; i <= n; i++, start += slice) { data1 = l_binaryReadSelect("breviar-a38.jp2", start, slice, &size1); l_byteaAppendData(lba1, data1, size1); lept_free(data1); } fprintf(stderr, "******************************************************\n"); data2 = l_byteaGetData(lba1, &size2); l_binaryWrite("/tmp/bytea/junk6.dat", "w", data2, size2); filesAreIdentical("breviar-a38.jp2", "/tmp/bytea/junk6.dat", &same1); if (same1) fprintf(stderr, "OK for appended binary data\n"); else fprintf(stderr, "Error: appended binary data is different!\n"); l_byteaDestroy(&lba1); /* Test search */ convertToPdf("test24.jpg", L_JPEG_ENCODE, 0, "/tmp/bytea/junk7.pdf", 0, 0, 100, NULL, NULL, 0); lba1 = l_byteaInitFromFile("/tmp/bytea/junk7.pdf"); l_byteaFindEachSequence(lba1, (l_uint8 *)" 0 obj\n", 7, &da); /* l_dnaWriteStream(stderr, da); */ n = l_dnaGetCount(da); if (n == 6) fprintf(stderr, "OK for search: found 6 instances\n"); else fprintf(stderr, "Error in search: found %d instances, not 6\n", n); l_byteaDestroy(&lba1); l_dnaDestroy(&da); /* Test write to file */ lba1 = l_byteaInitFromFile("feyn.tif"); fp = lept_fopen("/tmp/bytea/junk8.dat", "wb"); size1 = l_byteaGetSize(lba1); for (start = 0; start < size1; start += 1000) { end = L_MIN(start + 1000 - 1, size1 - 1); l_byteaWriteStream(fp, lba1, start, end); } lept_fclose(fp); filesAreIdentical("feyn.tif", "/tmp/bytea/junk8.dat", &same1); if (same1) fprintf(stderr, "OK for written binary data\n"); else fprintf(stderr, "Error: written binary data is different!\n"); l_byteaDestroy(&lba1); return 0; }
int main(int argc, char **argv) { char buffer[512]; char *tempfile1, *tempfile2; l_uint8 *data; l_int32 i, j, w, h, seq, ret, same; size_t nbytes; const char *title; BOX *box; BOXA *boxa1, *boxa2; L_BYTEA *ba; L_PDF_DATA *lpd; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6; PIX *pixs, *pixt, *pixg, *pixgc, *pixc; static char mainName[] = "pdfiotest"; if (argc != 1) return ERROR_INT("syntax: pdfiotest", mainName, 1); l_pdfSetDateAndVersion(0); lept_mkdir("pdf"); #if 1 /* --------------- Single image tests ------------------- */ fprintf(stderr, "\n*** Writing single images as pdf files\n"); convertToPdf("weasel2.4c.png", L_FLATE_ENCODE, 0, "/tmp/pdf/file01.pdf", 0, 0, 72, "weasel2.4c.png", NULL, 0); convertToPdf("test24.jpg", L_JPEG_ENCODE, 0, "/tmp/pdf/file02.pdf", 0, 0, 72, "test24.jpg", NULL, 0); convertToPdf("feyn.tif", L_G4_ENCODE, 0, "/tmp/pdf/file03.pdf", 0, 0, 300, "feyn.tif", NULL, 0); pixs = pixRead("feyn.tif"); pixConvertToPdf(pixs, L_G4_ENCODE, 0, "/tmp/pdf/file04.pdf", 0, 0, 300, "feyn.tif", NULL, 0); pixDestroy(&pixs); pixs = pixRead("test24.jpg"); pixConvertToPdf(pixs, L_JPEG_ENCODE, 5, "/tmp/pdf/file05.pdf", 0, 0, 72, "test24.jpg", NULL, 0); pixDestroy(&pixs); pixs = pixRead("feyn.tif"); pixt = pixScaleToGray2(pixs); pixWrite("/tmp/pdf/feyn8.png", pixt, IFF_PNG); convertToPdf("/tmp/pdf/feyn8.png", L_JPEG_ENCODE, 0, "/tmp/pdf/file06.pdf", 0, 0, 150, "feyn8.png", NULL, 0); pixDestroy(&pixs); pixDestroy(&pixt); convertToPdf("weasel4.16g.png", L_FLATE_ENCODE, 0, "/tmp/pdf/file07.pdf", 0, 0, 30, "weasel4.16g.png", NULL, 0); pixs = pixRead("test24.jpg"); pixg = pixConvertTo8(pixs, 0); box = boxCreate(100, 100, 100, 100); pixc = pixClipRectangle(pixs, box, NULL); pixgc = pixClipRectangle(pixg, box, NULL); pixWrite("/tmp/pdf/pix32.jpg", pixc, IFF_JFIF_JPEG); pixWrite("/tmp/pdf/pix8.jpg", pixgc, IFF_JFIF_JPEG); convertToPdf("/tmp/pdf/pix32.jpg", L_FLATE_ENCODE, 0, "/tmp/pdf/file08.pdf", 0, 0, 72, "pix32.jpg", NULL, 0); convertToPdf("/tmp/pdf/pix8.jpg", L_FLATE_ENCODE, 0, "/tmp/pdf/file09.pdf", 0, 0, 72, "pix8.jpg", NULL, 0); pixDestroy(&pixs); pixDestroy(&pixg); pixDestroy(&pixc); pixDestroy(&pixgc); boxDestroy(&box); #endif #if 1 /* --------------- Multiple image tests ------------------- */ fprintf(stderr, "\n*** Writing multiple images as single page pdf files\n"); pix1 = pixRead("feyn-fract.tif"); pix2 = pixRead("weasel8.240c.png"); /* l_pdfSetDateAndVersion(0); */ /* First, write the 1 bpp image through the mask onto the weasels */ for (i = 0; i < 5; i++) { for (j = 0; j < 10; j++) { seq = (i == 0 && j == 0) ? L_FIRST_IMAGE : L_NEXT_IMAGE; title = (i == 0 && j == 0) ? "feyn-fract.tif" : NULL; pixConvertToPdf(pix2, L_FLATE_ENCODE, 0, NULL, 100 * j, 100 * i, 70, title, &lpd, seq); } } pixConvertToPdf(pix1, L_G4_ENCODE, 0, "/tmp/pdf/file10.pdf", 0, 0, 80, NULL, &lpd, L_LAST_IMAGE); /* Now, write the 1 bpp image over the weasels */ l_pdfSetG4ImageMask(0); for (i = 0; i < 5; i++) { for (j = 0; j < 10; j++) { seq = (i == 0 && j == 0) ? L_FIRST_IMAGE : L_NEXT_IMAGE; title = (i == 0 && j == 0) ? "feyn-fract.tif" : NULL; pixConvertToPdf(pix2, L_FLATE_ENCODE, 0, NULL, 100 * j, 100 * i, 70, title, &lpd, seq); } } pixConvertToPdf(pix1, L_G4_ENCODE, 0, "/tmp/pdf/file11.pdf", 0, 0, 80, NULL, &lpd, L_LAST_IMAGE); l_pdfSetG4ImageMask(1); pixDestroy(&pix1); pixDestroy(&pix2); #endif #if 1 /* -------- pdf convert segmented with no image regions -------- */ fprintf(stderr, "\n*** Writing segmented images without image regions\n"); pix1 = pixRead("rabi.png"); pix2 = pixScaleToGray2(pix1); pixWrite("/tmp/pdf/rabi8.jpg", pix2, IFF_JFIF_JPEG); pix3 = pixThresholdTo4bpp(pix2, 16, 1); pixWrite("/tmp/pdf/rabi4.png", pix3, IFF_PNG); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); /* 1 bpp input */ convertToPdfSegmented("rabi.png", 300, L_G4_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file12.pdf"); convertToPdfSegmented("rabi.png", 300, L_JPEG_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file13.pdf"); convertToPdfSegmented("rabi.png", 300, L_FLATE_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file14.pdf"); /* 8 bpp input, no cmap */ convertToPdfSegmented("/tmp/pdf/rabi8.jpg", 150, L_G4_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file15.pdf"); convertToPdfSegmented("/tmp/pdf/rabi8.jpg", 150, L_JPEG_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file16.pdf"); convertToPdfSegmented("/tmp/pdf/rabi8.jpg", 150, L_FLATE_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file17.pdf"); /* 4 bpp input, cmap */ convertToPdfSegmented("/tmp/pdf/rabi4.png", 150, L_G4_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file18.pdf"); convertToPdfSegmented("/tmp/pdf/rabi4.png", 150, L_JPEG_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file19.pdf"); convertToPdfSegmented("/tmp/pdf/rabi4.png", 150, L_FLATE_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/pdf/file20.pdf"); #endif #if 1 /* ---------- pdf convert segmented with image regions ---------- */ fprintf(stderr, "\n*** Writing segmented images with image regions\n"); /* Get the image region(s) for rabi.png. There are two * small bogus regions at the top, but we'll keep them for * the demonstration. */ pix1 = pixRead("rabi.png"); pixSetResolution(pix1, 300, 300); pixGetDimensions(pix1, &w, &h, NULL); pix2 = pixGenHalftoneMask(pix1, NULL, NULL, 0); pix3 = pixMorphSequence(pix2, "c20.1 + c1.20", 0); boxa1 = pixConnComp(pix3, NULL, 8); boxa2 = boxaTransform(boxa1, 0, 0, 0.5, 0.5); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); /* 1 bpp input */ convertToPdfSegmented("rabi.png", 300, L_G4_ENCODE, 128, boxa1, 0, 0.25, NULL, "/tmp/pdf/file21.pdf"); convertToPdfSegmented("rabi.png", 300, L_JPEG_ENCODE, 128, boxa1, 0, 0.25, NULL, "/tmp/pdf/file22.pdf"); convertToPdfSegmented("rabi.png", 300, L_FLATE_ENCODE, 128, boxa1, 0, 0.25, NULL, "/tmp/pdf/file23.pdf"); /* 8 bpp input, no cmap */ convertToPdfSegmented("/tmp/pdf/rabi8.jpg", 150, L_G4_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/pdf/file24.pdf"); convertToPdfSegmented("/tmp/pdf/rabi8.jpg", 150, L_JPEG_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/pdf/file25.pdf"); convertToPdfSegmented("/tmp/pdf/rabi8.jpg", 150, L_FLATE_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/pdf/file26.pdf"); /* 4 bpp input, cmap */ convertToPdfSegmented("/tmp/pdf/rabi4.png", 150, L_G4_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/pdf/file27.pdf"); convertToPdfSegmented("/tmp/pdf/rabi4.png", 150, L_JPEG_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/pdf/file28.pdf"); convertToPdfSegmented("/tmp/pdf/rabi4.png", 150, L_FLATE_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/pdf/file29.pdf"); /* 4 bpp input, cmap, data output */ data = NULL; convertToPdfDataSegmented("/tmp/pdf/rabi4.png", 150, L_G4_ENCODE, 128, boxa2, 0, 0.5, NULL, &data, &nbytes); l_binaryWrite("/tmp/pdf/file30.pdf", "w", data, nbytes); lept_free(data); convertToPdfDataSegmented("/tmp/pdf/rabi4.png", 150, L_JPEG_ENCODE, 128, boxa2, 0, 0.5, NULL, &data, &nbytes); l_binaryWrite("/tmp/pdf/file31.pdf", "w", data, nbytes); lept_free(data); convertToPdfDataSegmented("/tmp/pdf/rabi4.png", 150, L_FLATE_ENCODE, 128, boxa2, 0, 0.5, NULL, &data, &nbytes); l_binaryWrite("/tmp/pdf/file32.pdf", "w", data, nbytes); lept_free(data); boxaDestroy(&boxa1); boxaDestroy(&boxa2); #endif #if 1 /* -------- pdf convert segmented from color image -------- */ fprintf(stderr, "\n*** Writing color segmented images\n"); pix1 = pixRead("candelabrum-11.jpg"); pix2 = pixScale(pix1, 3.0, 3.0); pixWrite("/tmp/pdf/candelabrum3.jpg", pix2, IFF_JFIF_JPEG); GetImageMask(pix2, 200, &boxa1, "/tmp/pdf/seg1.jpg"); convertToPdfSegmented("/tmp/pdf/candelabrum3.jpg", 200, L_G4_ENCODE, 100, boxa1, 0, 0.25, NULL, "/tmp/pdf/file33.pdf"); convertToPdfSegmented("/tmp/pdf/candelabrum3.jpg", 200, L_JPEG_ENCODE, 100, boxa1, 0, 0.25, NULL, "/tmp/pdf/file34.pdf"); convertToPdfSegmented("/tmp/pdf/candelabrum3.jpg", 200, L_FLATE_ENCODE, 100, boxa1, 0, 0.25, NULL, "/tmp/pdf/file35.pdf"); pixDestroy(&pix1); pixDestroy(&pix2); boxaDestroy(&boxa1); pix1 = pixRead("lion-page.00016.jpg"); pix2 = pixScale(pix1, 3.0, 3.0); pixWrite("/tmp/pdf/lion16.jpg", pix2, IFF_JFIF_JPEG); pix3 = pixRead("lion-mask.00016.tif"); boxa1 = pixConnComp(pix3, NULL, 8); boxa2 = boxaTransform(boxa1, 0, 0, 3.0, 3.0); convertToPdfSegmented("/tmp/pdf/lion16.jpg", 200, L_G4_ENCODE, 190, boxa2, 0, 0.5, NULL, "/tmp/pdf/file36.pdf"); convertToPdfSegmented("/tmp/pdf/lion16.jpg", 200, L_JPEG_ENCODE, 190, boxa2, 0, 0.5, NULL, "/tmp/pdf/file37.pdf"); convertToPdfSegmented("/tmp/pdf/lion16.jpg", 200, L_FLATE_ENCODE, 190, boxa2, 0, 0.5, NULL, "/tmp/pdf/file38.pdf"); /* Quantize the non-image part and flate encode. * This is useful because it results in a smaller file than * when you flate-encode the un-quantized non-image regions. */ pix4 = pixScale(pix3, 3.0, 3.0); /* higher res mask, for combining */ pix5 = QuantizeNonImageRegion(pix2, pix4, 12); pixWrite("/tmp/pdf/lion16-quant.png", pix5, IFF_PNG); convertToPdfSegmented("/tmp/pdf/lion16-quant.png", 200, L_FLATE_ENCODE, 190, boxa2, 0, 0.5, NULL, "/tmp/pdf/file39.pdf"); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); boxaDestroy(&boxa1); boxaDestroy(&boxa2); #endif #if 1 /* ------------------ Test multipage pdf generation ----------------- */ fprintf(stderr, "\n*** Writing multipage pdfs from single page pdfs\n"); /* Generate a multi-page pdf from all these files */ startTimer(); concatenatePdf("/tmp/pdf", "file", "/tmp/pdf/cat_lept.pdf"); fprintf(stderr, "All files have been concatenated: /tmp/pdf/cat_lept.pdf\n" "Concatenation time: %7.3f\n", stopTimer()); #endif #if 1 /* -------------------- Test corruption recovery ------------------- */ /* Put two good pdf files in a directory */ lept_mkdir("good"); lept_cp("testfile1.pdf", "good", NULL, NULL); lept_cp("testfile2.pdf", "good", NULL, NULL); concatenatePdf("/tmp/good", "file", "/tmp/pdf/good.pdf"); /* Make a version with the pdf id removed, so that it is not * recognized as a pdf */ ba = l_byteaInitFromFile("testfile2.pdf"); data = l_byteaGetData(ba, &nbytes); l_binaryWrite("testfile0.notpdf.pdf", "w", data + 10, nbytes - 10); /* Make a version with a corrupted trailer */ if (data) data[2297] = '2'; /* munge trailer object 6: change 458 --> 428 */ l_binaryWrite("testfile2.bad.pdf", "w", data, nbytes); /* Put these two bad files, along with a good file, in a directory */ lept_mkdir("bad"); lept_mv("testfile0.notpdf.pdf", "bad", NULL, NULL); lept_cp("testfile1.pdf", "bad", NULL, NULL); lept_mv("testfile2.bad.pdf", "bad", NULL, NULL); l_byteaDestroy(&ba); /* Run concat on the bad files. In the /tmp/bad/ directory, * the "not pdf" file should be ignored, and the corrupted pdf * file should be properly parsed, so the resulting * concatenated files should be identical. */ fprintf(stderr, "\nWe attempt to build from the bad directory\n"); concatenatePdf("/tmp/bad", "file", "/tmp/pdf/bad.pdf"); filesAreIdentical("/tmp/pdf/good.pdf", "/tmp/pdf/bad.pdf", &same); if (same) fprintf(stderr, "Fixed: files are the same\n" "Attempt succeeded\n\n"); else fprintf(stderr, "Busted: files are different\n"); /* pdftk fails because the first file is not a pdf */ fprintf(stderr, "pdftk attempts to build from the bad directory\n"); tempfile1 = genPathname("/tmp/bad", "*.pdf"); tempfile2 = genPathname("/tmp", "pdftk.bad.pdf"); snprintf(buffer, sizeof(buffer), "pdftk %s output %s", tempfile1, tempfile2); ret = system(buffer); /* pdftk */ lept_free(tempfile1); lept_free(tempfile2); fprintf(stderr, "Attempt failed\n\n"); #endif #if 1 fprintf(stderr, "\n*** pdftk writes multipage pdfs from images\n"); tempfile1 = genPathname("/tmp/pdf", "file*.pdf"); tempfile2 = genPathname("/tmp/pdf", "cat_pdftk.pdf"); snprintf(buffer, sizeof(buffer), "pdftk %s output %s", tempfile1, tempfile2); ret = system(buffer); /* pdftk */ lept_free(tempfile1); lept_free(tempfile2); #endif #if 1 /* -- Test simple interface for generating multi-page pdf from images -- */ fprintf(stderr, "\n*** Writing multipage pdfs from images\n"); /* Put four image files in a directory. They will be encoded thus: * file1.png: flate (8 bpp, only 10 colors) * file2.jpg: dct (8 bpp, 256 colors because of the jpeg encoding) * file3.tif: g4 (1 bpp) * file4.jpg: dct (32 bpp) */ lept_mkdir("image"); pix1 = pixRead("feyn.tif"); pix2 = pixRead("rabi.png"); pix3 = pixScaleToGray3(pix1); pix4 = pixScaleToGray3(pix2); pix5 = pixScale(pix1, 0.33, 0.33); pix6 = pixRead("test24.jpg"); pixWrite("/tmp/image/file1.png", pix3, IFF_PNG); /* 10 colors */ pixWrite("/tmp/image/file2.jpg", pix4, IFF_JFIF_JPEG); /* 256 colors */ pixWrite("/tmp/image/file3.tif", pix5, IFF_TIFF_G4); pixWrite("/tmp/image/file4.jpg", pix6, IFF_JFIF_JPEG); startTimer(); convertFilesToPdf("/tmp/image", "file", 100, 0.8, 0, 75, "4 file test", "/tmp/pdf/fourimages.pdf"); fprintf(stderr, "4-page pdf generated: /tmp/pdf/fourimages.pdf\n" "Time: %7.3f\n", stopTimer()); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); #endif return 0; }
/*! * \brief pixGetLocalSkewAngles() * * \param[in] pixs 1 bpp * \param[in] nslices the number of horizontal overlapping slices; must * be larger than 1 and not exceed 20; 0 for default * \param[in] redsweep sweep reduction factor: 1, 2, 4 or 8; * use 0 for default value * \param[in] redsearch search reduction factor: 1, 2, 4 or 8, and not * larger than redsweep; use 0 for default value * \param[in] sweeprange half the full range, assumed about 0; in degrees; * use 0.0 for default value * \param[in] sweepdelta angle increment of sweep; in degrees; * use 0.0 for default value * \param[in] minbsdelta min binary search increment angle; in degrees; * use 0.0 for default value * \param[out] pa [optional] slope of skew as fctn of y * \param[out] pb [optional] intercept at y=0 of skew as fctn of y * \param[in] debug 1 for generating plot of skew angle vs. y; 0 otherwise * \return naskew, or NULL on error * * <pre> * Notes: * (1) The local skew is measured in a set of overlapping strips. * We then do a least square linear fit parameters to get * the slope and intercept parameters a and b in * skew-angle = a * y + b (degrees) * for the local skew as a function of raster line y. * This is then used to make naskew, which can be interpreted * as the computed skew angle (in degrees) at the left edge * of each raster line. * (2) naskew can then be used to find the baselines of text, because * each text line has a baseline that should intersect * the left edge of the image with the angle given by this * array, evaluated at the raster line of intersection. * </pre> */ NUMA * pixGetLocalSkewAngles(PIX *pixs, l_int32 nslices, l_int32 redsweep, l_int32 redsearch, l_float32 sweeprange, l_float32 sweepdelta, l_float32 minbsdelta, l_float32 *pa, l_float32 *pb, l_int32 debug) { l_int32 w, h, hs, i, ystart, yend, ovlap, npts; l_float32 angle, conf, ycenter, a, b; BOX *box; GPLOT *gplot; NUMA *naskew, *nax, *nay; PIX *pix; PTA *pta; PROCNAME("pixGetLocalSkewAngles"); if (!pixs || pixGetDepth(pixs) != 1) return (NUMA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL); if (nslices < 2 || nslices > 20) nslices = DEFAULT_SLICES; if (redsweep < 1 || redsweep > 8) redsweep = DEFAULT_SWEEP_REDUCTION; if (redsearch < 1 || redsearch > redsweep) redsearch = DEFAULT_BS_REDUCTION; if (sweeprange == 0.0) sweeprange = DEFAULT_SWEEP_RANGE; if (sweepdelta == 0.0) sweepdelta = DEFAULT_SWEEP_DELTA; if (minbsdelta == 0.0) minbsdelta = DEFAULT_MINBS_DELTA; pixGetDimensions(pixs, &w, &h, NULL); hs = h / nslices; ovlap = (l_int32)(OVERLAP_FRACTION * hs); pta = ptaCreate(nslices); for (i = 0; i < nslices; i++) { ystart = L_MAX(0, hs * i - ovlap); yend = L_MIN(h - 1, hs * (i + 1) + ovlap); ycenter = (l_float32)(ystart + yend) / 2; box = boxCreate(0, ystart, w, yend - ystart + 1); pix = pixClipRectangle(pixs, box, NULL); pixFindSkewSweepAndSearch(pix, &angle, &conf, redsweep, redsearch, sweeprange, sweepdelta, minbsdelta); if (conf > MIN_ALLOWED_CONFIDENCE) ptaAddPt(pta, ycenter, angle); pixDestroy(&pix); boxDestroy(&box); } /* Do linear least squares fit */ if ((npts = ptaGetCount(pta)) < 2) { ptaDestroy(&pta); return (NUMA *)ERROR_PTR("can't fit skew", procName, NULL); } ptaGetLinearLSF(pta, &a, &b, NULL); if (pa) *pa = a; if (pb) *pb = b; /* Make skew angle array as function of raster line */ naskew = numaCreate(h); for (i = 0; i < h; i++) { angle = a * i + b; numaAddNumber(naskew, angle); } if (debug) { lept_mkdir("lept/baseline"); ptaGetArrays(pta, &nax, &nay); gplot = gplotCreate("/tmp/lept/baseline/skew", GPLOT_PNG, "skew as fctn of y", "y (in raster lines from top)", "angle (in degrees)"); gplotAddPlot(gplot, NULL, naskew, GPLOT_POINTS, "linear lsf"); gplotAddPlot(gplot, nax, nay, GPLOT_POINTS, "actual data pts"); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nax); numaDestroy(&nay); } ptaDestroy(&pta); return naskew; }
l_int32 main(int argc, char **argv) { l_int32 i, w, h, n, val, ne, no, nbins, minw, maxw, minh, maxh; l_int32 mine, mino, maxe, maxo; l_int32 w_diff, h_diff, median_w_diff, median_h_diff; l_int32 noutw, nouth; l_float32 medwe, medhe, medwo, medho; BOXA *boxa1, *boxa2, *boxae, *boxao; NUMA *na1, *nawe, *nahe, *nawo, *naho; NUMA *nadiffw, *nadiffh; /* diff from median w and h */ NUMA *naiw, *naih; /* indicator arrays for small outlier dimensions */ NUMA *narbwe, *narbhe, *narbwo, *narbho; /* rank-binned w and h */ PIX *pix1; PIXA *pixa1; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; lept_mkdir("lept/boxa"); boxa1 = boxaRead("boxa4.ba"); /* Fill invalid boxes */ n = boxaGetCount(boxa1); na1 = boxaFindInvalidBoxes(boxa1); if (na1) boxa2 = boxaFillSequence(boxa1, L_USE_SAME_PARITY_BOXES, 0); else boxa2 = boxaCopy(boxa1, L_CLONE); boxaDestroy(&boxa1); /* Get the widths and heights for even and odd parity */ boxaSplitEvenOdd(boxa2, 0, &boxae, &boxao); boxaGetSizes(boxae, &nawe, &nahe); boxaGetSizes(boxao, &nawo, &naho); boxaDestroy(&boxa2); /* Find the medians */ numaGetMedian(nawe, &medwe); numaGetMedian(nahe, &medhe); numaGetMedian(nawo, &medwo); numaGetMedian(naho, &medho); /* Find the median even/odd differences for width and height */ median_w_diff = L_ABS(medwe - medwo); median_h_diff = L_ABS(medhe - medho); regTestCompareValues(rp, 210, median_w_diff, 0.0); /* 0 */ regTestCompareValues(rp, 15, median_h_diff, 0.0); /* 1 */ if (rp->display) { fprintf(stderr, "diff of e/o median widths = %d\n", median_w_diff); fprintf(stderr, "diff of e/o median heights = %d\n", median_h_diff); } /* Find the differences of box width and height from the median */ nadiffw = numaMakeConstant(0, n); nadiffh = numaMakeConstant(0, n); ne = numaGetCount(nawe); no = numaGetCount(nawo); for (i = 0; i < ne; i++) { numaGetIValue(nawe, i, &val); numaSetValue(nadiffw, 2 * i, L_ABS(val - medwe)); numaGetIValue(nahe, i, &val); numaSetValue(nadiffh, 2 * i, L_ABS(val - medhe)); } for (i = 0; i < no; i++) { numaGetIValue(nawo, i, &val); numaSetValue(nadiffw, 2 * i + 1, L_ABS(val - medwo)); numaGetIValue(naho, i, &val); numaSetValue(nadiffh, 2 * i + 1, L_ABS(val - medho)); } /* Don't count invalid boxes; set the diffs to 0 for them */ if (na1) { for (i = 0; i < n; i++) { numaGetIValue(na1, i, &val); if (val == 1) { numaSetValue(nadiffw, i, 0); numaSetValue(nadiffh, i, 0); } } } /* Make an indicator array for boxes that differ from the * median by more than a threshold value for outliers */ naiw = numaMakeThresholdIndicator(nadiffw, 90, L_SELECT_IF_GT); naih = numaMakeThresholdIndicator(nadiffh, 90, L_SELECT_IF_GT); numaGetCountRelativeToZero(naiw, L_GREATER_THAN_ZERO, &noutw); numaGetCountRelativeToZero(naih, L_GREATER_THAN_ZERO, &nouth); regTestCompareValues(rp, 24, noutw, 0.0); /* 2 */ regTestCompareValues(rp, 0, nouth, 0.0); /* 3 */ if (rp->display) fprintf(stderr, "num width outliers = %d, num height outliers = %d\n", noutw, nouth); numaDestroy(&nadiffw); numaDestroy(&nadiffh); numaDestroy(&naiw); numaDestroy(&naih); /* Find the rank bins for width and height */ nbins = L_MAX(5, ne / 50); // up to 50 pages/bin numaGetRankBinValues(nawe, nbins, NULL, &narbwe); numaGetRankBinValues(nawo, nbins, NULL, &narbwo); numaGetRankBinValues(nahe, nbins, NULL, &narbhe); numaGetRankBinValues(naho, nbins, NULL, &narbho); numaDestroy(&nawe); numaDestroy(&nawo); numaDestroy(&nahe); numaDestroy(&naho); /* Find min and max binned widths and heights; get the max diffs */ numaGetIValue(narbwe, 0, &mine); numaGetIValue(narbwe, nbins - 1, &maxe); numaGetIValue(narbwo, 0, &mino); numaGetIValue(narbwo, nbins - 1, &maxo); minw = L_MIN(mine, mino); maxw = L_MAX(maxe, maxo); w_diff = maxw - minw; numaGetIValue(narbhe, 0, &mine); numaGetIValue(narbhe, nbins - 1, &maxe); numaGetIValue(narbho, 0, &mino); numaGetIValue(narbho, nbins - 1, &maxo); minh = L_MIN(mine, mino); maxh = L_MAX(maxe, maxo); h_diff = maxh - minh; numaDestroy(&narbwe); numaDestroy(&narbhe); numaDestroy(&narbwo); numaDestroy(&narbho); regTestCompareValues(rp, 409, w_diff, 0.0); /* 4 */ regTestCompareValues(rp, 49, h_diff, 0.0); /* 5 */ if (rp->display) fprintf(stderr, "Binned rank results: w_diff = %d, h_diff = %d\n", w_diff, h_diff); /* Plot the results */ if (noutw > 0 || nouth > 0) { pixa1 = pixaCreate(2); boxaPlotSizes(boxae, "even", NULL, NULL, &pix1); pixaAddPix(pixa1, pix1, L_INSERT); boxaPlotSizes(boxao, "odd", NULL, NULL, &pix1); pixaAddPix(pixa1, pix1, L_INSERT); pix1 = pixaDisplayTiledInRows(pixa1, 32, 1500, 1.0, 0, 30, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 6 */ pixDisplayWithTitle(pix1, 100, 100, NULL, rp->display); pixDestroy(&pix1); pixaDestroy(&pixa1); } boxaDestroy(&boxae); boxaDestroy(&boxao); return regTestCleanup(rp); }