/*! * numaaTruncate() * * Input: naa * Return: 0 if OK, 1 on error * * Notes: * (1) This identifies the largest index containing a numa that * has any numbers within it, destroys all numa beyond that * index, and resets the count. */ l_int32 numaaTruncate(NUMAA *naa) { l_int32 i, n, nn; NUMA *na; PROCNAME("numaaTruncate"); if (!naa) return ERROR_INT("naa not defined", procName, 1); n = numaaGetCount(naa); for (i = n - 1; i >= 0; i--) { na = numaaGetNuma(naa, i, L_CLONE); if (!na) continue; nn = numaGetCount(na); numaDestroy(&na); if (nn == 0) numaDestroy(&naa->numa[i]); else break; } naa->n = i + 1; return 0; }
/*! * pixaSelectByWidthHeightRatio() * * Input: pixas * thresh (threshold ratio of width/height) * type (L_SELECT_IF_LT, L_SELECT_IF_GT, * L_SELECT_IF_LTE, L_SELECT_IF_GTE) * &changed (<optional return> 1 if changed; 0 if clone returned) * Return: pixad, or null on error * * Notes: * (1) Returns a pixa clone if no components are removed. * (2) Uses pix and box clones in the new pixa. * (3) This filters components based on the width-to-height ratio * of each pix. * (4) Use L_SELECT_IF_LT or L_SELECT_IF_LTE to save components * with less than the threshold ratio, and * L_SELECT_IF_GT or L_SELECT_IF_GTE to remove them. */ PIXA * pixaSelectByWidthHeightRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged) { NUMA *na, *nai; PIXA *pixad; PROCNAME("pixaSelectByWidthHeightRatio"); if (!pixas) return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL); if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT && type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE) return (PIXA *)ERROR_PTR("invalid type", procName, NULL); /* Compute component ratios. */ na = pixaFindWidthHeightRatio(pixas); /* Generate indicator array for elements to be saved. */ nai = numaMakeThresholdIndicator(na, thresh, type); numaDestroy(&na); /* Filter to get output */ pixad = pixaSelectWithIndicator(pixas, nai, pchanged); numaDestroy(&nai); return pixad; }
/*! * pixcmapGetRankIntensity() * * Input: cmap * rankval (0.0 for darkest, 1.0 for lightest color) * &index (<return> the index into the colormap that * corresponds to the rank intensity color) * Return: 0 if OK, 1 on error */ l_int32 pixcmapGetRankIntensity(PIXCMAP *cmap, l_float32 rankval, l_int32 *pindex) { l_int32 n, i, rval, gval, bval, rankindex; NUMA *na, *nasort; PROCNAME("pixcmapGetRankIntensity"); if (!pindex) return ERROR_INT("&index not defined", procName, 1); *pindex = 0; if (!cmap) return ERROR_INT("cmap not defined", procName, 1); if (rankval < 0.0 || rankval > 1.0) return ERROR_INT("rankval not in [0.0 ... 1.0]", procName, 1); n = pixcmapGetCount(cmap); na = numaCreate(n); for (i = 0; i < n; i++) { pixcmapGetColor(cmap, i, &rval, &gval, &bval); numaAddNumber(na, rval + gval + bval); } nasort = numaGetSortIndex(na, L_SORT_INCREASING); rankindex = (l_int32)(rankval * (n - 1) + 0.5); numaGetIValue(nasort, rankindex, pindex); numaDestroy(&na); numaDestroy(&nasort); return 0; }
/*! * dewarpaListPages() * * Input: dewa (populated with dewarp structs for pages) * Return: 0 if OK, 1 on error (list of page numbers), or null on error * * Notes: * (1) This generates two numas, stored in the dewarpa, that give: * (a) the page number for each dew that has a page model. * (b) the page number for each dew that has either a page * model or a reference model. * It can be called at any time. * (2) It is called by the dewarpa serializer before writing. */ l_int32 dewarpaListPages(L_DEWARPA *dewa) { l_int32 i; L_DEWARP *dew; NUMA *namodels, *napages; PROCNAME("dewarpaListPages"); if (!dewa) return ERROR_INT("dewa not defined", procName, 1); numaDestroy(&dewa->namodels); numaDestroy(&dewa->napages); namodels = numaCreate(dewa->maxpage + 1); napages = numaCreate(dewa->maxpage + 1); dewa->namodels = namodels; dewa->napages = napages; for (i = 0; i <= dewa->maxpage; i++) { if ((dew = dewarpaGetDewarp(dewa, i)) != NULL) { if (dew->hasref == 0) numaAddNumber(namodels, dew->pageno); numaAddNumber(napages, dew->pageno); } } return 0; }
/*! * boxaEqual() * * Input: boxa1 * boxa2 * maxdist * &naindex (<optional return> index array of correspondences * &same (<return> 1 if equal; 0 otherwise) * Return 0 if OK, 1 on error * * Notes: * (1) The two boxa are the "same" if they contain the same * boxes and each box is within @maxdist of its counterpart * in their positions within the boxa. This allows for * small rearrangements. Use 0 for maxdist if the boxa * must be identical. * (2) This applies only to geometry and ordering; refcounts * are not considered. * (3) @maxdist allows some latitude in the ordering of the boxes. * For the boxa to be the "same", corresponding boxes must * be within @maxdist of each other. Note that for large * @maxdist, we should use a hash function for efficiency. * (4) naindex[i] gives the position of the box in boxa2 that * corresponds to box i in boxa1. It is only returned if the * boxa are equal. */ l_int32 boxaEqual(BOXA *boxa1, BOXA *boxa2, l_int32 maxdist, NUMA **pnaindex, l_int32 *psame) { l_int32 i, j, n, jstart, jend, found, samebox; l_int32 *countarray; BOX *box1, *box2; NUMA *na; PROCNAME("boxaEqual"); if (pnaindex) *pnaindex = NULL; if (!psame) return ERROR_INT("&same not defined", procName, 1); *psame = 0; if (!boxa1 || !boxa2) return ERROR_INT("boxa1 and boxa2 not both defined", procName, 1); n = boxaGetCount(boxa1); if (n != boxaGetCount(boxa2)) return 0; countarray = (l_int32 *)CALLOC(n, sizeof(l_int32)); na = numaMakeConstant(0.0, n); for (i = 0; i < n; i++) { box1 = boxaGetBox(boxa1, i, L_CLONE); jstart = L_MAX(0, i - maxdist); jend = L_MIN(n-1, i + maxdist); found = FALSE; for (j = jstart; j <= jend; j++) { box2 = boxaGetBox(boxa2, j, L_CLONE); boxEqual(box1, box2, &samebox); if (samebox && countarray[j] == 0) { countarray[j] = 1; numaReplaceNumber(na, i, j); found = TRUE; boxDestroy(&box2); break; } boxDestroy(&box2); } boxDestroy(&box1); if (!found) { numaDestroy(&na); FREE(countarray); return 0; } } *psame = 1; if (pnaindex) *pnaindex = na; else numaDestroy(&na); FREE(countarray); return 0; }
/*! * dewarpMinimize() * * Input: dew * Return: 0 if OK, 1 on error * * Notes: * (1) This removes all data that is not needed for serialization. * It keeps the subsampled disparity array(s), so the full * resolution arrays can be reconstructed. */ l_int32 dewarpMinimize(L_DEWARP *dew) { L_DEWARP *dewt; PROCNAME("dewarpMinimize"); if (!dew) return ERROR_INT("dew not defined", procName, 1); /* If dew is a ref, minimize the actual dewarp */ if (dew->hasref) dewt = dewarpaGetDewarp(dew->dewa, dew->refpage); else dewt = dew; if (!dewt) return ERROR_INT("dewt not found", procName, 1); pixDestroy(&dewt->pixs); fpixDestroy(&dewt->fullvdispar); fpixDestroy(&dewt->fullhdispar); numaDestroy(&dewt->namidys); numaDestroy(&dewt->nacurves); return 0; }
/*! * dewarpDestroy() * * Input: &dew (<will be set to null before returning>) * Return: void */ void dewarpDestroy(L_DEWARP **pdew) { L_DEWARP *dew; PROCNAME("dewarpDestroy"); if (pdew == NULL) { L_WARNING("ptr address is null!", procName); return; } if ((dew = *pdew) == NULL) return; pixDestroy(&dew->pixs); pixDestroy(&dew->pixd); fpixDestroy(&dew->sampvdispar); fpixDestroy(&dew->samphdispar); fpixDestroy(&dew->fullvdispar); fpixDestroy(&dew->fullhdispar); numaDestroy(&dew->naflats); numaDestroy(&dew->nacurves); FREE(dew); *pdew = NULL; return; }
/*! * boxaGetRankSize() * * Input: boxa * fract (use 0.0 for smallest, 1.0 for largest) * Return: box (with rank values for x, y, w, h), or null on error * or if the boxa is empty (has no valid boxes) * * Notes: * (1) This function does not assume that all boxes in the boxa are valid * (2) The four box parameters are sorted independently. * For rank order, the width and height are sorted in increasing * order. But what does it mean to sort x and y in "rank order"? * If the boxes are of comparable size and somewhat * aligned (e.g., from multiple images), it makes some sense * to give a "rank order" for x and y by sorting them in * decreasing order. But in general, the interpretation of a rank * order on x and y is highly application dependent. In summary: * - x and y are sorted in decreasing order * - w and h are sorted in increasing order */ BOX * boxaGetRankSize(BOXA *boxa, l_float32 fract) { l_float32 xval, yval, wval, hval; NUMA *nax, *nay, *naw, *nah; BOX *box; PROCNAME("boxaGetRankSize"); if (!boxa) return (BOX *)ERROR_PTR("boxa not defined", procName, NULL); if (fract < 0.0 || fract > 1.0) return (BOX *)ERROR_PTR("fract not in [0.0 ... 1.0]", procName, NULL); if (boxaGetValidCount(boxa) == 0) return (BOX *)ERROR_PTR("no valid boxes in boxa", procName, NULL); boxaExtractAsNuma(boxa, &nax, &nay, &naw, &nah, 0); /* valid boxes only */ numaGetRankValue(nax, 1.0 - fract, NULL, 1, &xval); numaGetRankValue(nay, 1.0 - fract, NULL, 1, &yval); numaGetRankValue(naw, fract, NULL, 1, &wval); numaGetRankValue(nah, fract, NULL, 1, &hval); box = boxCreate((l_int32)xval, (l_int32)yval, (l_int32)wval, (l_int32)hval); numaDestroy(&nax); numaDestroy(&nay); numaDestroy(&naw); numaDestroy(&nah); return box; }
/*! * ptaaRemoveShortLines() * * Input: pixs (1 bpp) * ptaas (input lines) * fract (minimum fraction of longest line to keep) * debugflag * Return: ptaad (containing only lines of sufficient length), * or null on error */ PTAA * ptaaRemoveShortLines(PIX *pixs, PTAA *ptaas, l_float32 fract, l_int32 debugflag) { l_int32 w, n, i, index, maxlen, len; l_float32 minx, maxx; NUMA *na, *naindex; PIX *pixt1, *pixt2; PTA *pta; PTAA *ptaad; PROCNAME("ptaaRemoveShortLines"); if (!pixs || pixGetDepth(pixs) != 1) return (PTAA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL); if (!ptaas) return (PTAA *)ERROR_PTR("ptaas undefined", procName, NULL); pixGetDimensions(pixs, &w, NULL, NULL); n = ptaaGetCount(ptaas); ptaad = ptaaCreate(n); na = numaCreate(n); for (i = 0; i < n; i++) { pta = ptaaGetPta(ptaas, i, L_CLONE); ptaGetRange(pta, &minx, &maxx, NULL, NULL); numaAddNumber(na, maxx - minx + 1); ptaDestroy(&pta); } /* Sort by length and find all that are long enough */ naindex = numaGetSortIndex(na, L_SORT_DECREASING); numaGetIValue(naindex, 0, &index); numaGetIValue(na, index, &maxlen); if (maxlen < 0.5 * w) L_WARNING("lines are relatively short", procName); pta = ptaaGetPta(ptaas, index, L_CLONE); ptaaAddPta(ptaad, pta, L_INSERT); for (i = 1; i < n; i++) { numaGetIValue(naindex, i, &index); numaGetIValue(na, index, &len); if (len < fract * maxlen) break; pta = ptaaGetPta(ptaas, index, L_CLONE); ptaaAddPta(ptaad, pta, L_INSERT); } if (debugflag) { pixt1 = pixCopy(NULL, pixs); pixt2 = pixDisplayPtaa(pixt1, ptaad); pixDisplayWithTitle(pixt2, 0, 200, "pix4", 1); pixDestroy(&pixt1); pixDestroy(&pixt2); } numaDestroy(&na); numaDestroy(&naindex); return ptaad; }
static l_int32 GenerateSplitPlot(l_int32 i) { char title[256]; l_int32 split; l_float32 ave1, ave2, num1, num2, maxnum, maxscore; GPLOT *gplot; NUMA *na1, *na2, *nascore, *nax, *nay; PIX *pixs, *pixd; /* Generate */ na1 = MakeGaussian(gaussmean1[i], gaussstdev1[i], gaussfract1[i]); na2 = MakeGaussian(gaussmean2[i], gaussstdev1[i], 1.0 - gaussfract1[i]); numaArithOp(na1, na1, na2, L_ARITH_ADD); /* Otsu splitting */ numaSplitDistribution(na1, 0.08, &split, &ave1, &ave2, &num1, &num2, &nascore); fprintf(stderr, "split = %d, ave1 = %6.1f, ave2 = %6.1f\n", split, ave1, ave2); fprintf(stderr, "num1 = %8.0f, num2 = %8.0f\n", num1, num2); /* Prepare for plotting a vertical line at the split point */ nax = numaMakeConstant(split, 2); numaGetMax(na1, &maxnum, NULL); nay = numaMakeConstant(0, 2); numaReplaceNumber(nay, 1, (l_int32)(0.5 * maxnum)); /* Plot the input histogram with the split location */ sprintf(buf, "/tmp/junkplot.%d", i); sprintf(title, "Plot %d", i); gplot = gplotCreate(buf, GPLOT_PNG, "Histogram: mixture of 2 gaussians", "Grayscale value", "Number of pixels"); gplotAddPlot(gplot, NULL, na1, GPLOT_LINES, title); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, NULL); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&na1); numaDestroy(&na2); /* Plot the score function */ sprintf(buf, "/tmp/junkplots.%d", i); sprintf(title, "Plot %d", i); gplot = gplotCreate(buf, GPLOT_PNG, "Otsu score function for splitting", "Grayscale value", "Score"); gplotAddPlot(gplot, NULL, nascore, GPLOT_LINES, title); numaGetMax(nascore, &maxscore, NULL); numaReplaceNumber(nay, 1, maxscore); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, NULL); gplotMakeOutput(gplot); gplotDestroy(&gplot); numaDestroy(&nax); numaDestroy(&nay); numaDestroy(&nascore); return 0; }
int main(int argc, char **argv) { char *filein, *fileout; char bigbuf[512]; l_int32 iplot, same; l_float32 gam; l_float64 gamma[] = {.5, 1.0, 1.5, 2.0, 2.5, -1.0}; GPLOT *gplot; NUMA *na, *nax; PIX *pixs, *pixd; static char mainName[] = "gammatest"; if (argc != 4) return ERROR_INT(" Syntax: gammatest filein gam fileout", mainName, 1); lept_mkdir("lept/gamma"); filein = argv[1]; gam = atof(argv[2]); fileout = argv[3]; if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); startTimer(); pixd = pixGammaTRC(NULL, pixs, gam, MINVAL, MAXVAL); fprintf(stderr, "Time for gamma: %7.3f sec\n", stopTimer()); pixGammaTRC(pixs, pixs, gam, MINVAL, MAXVAL); pixEqual(pixs, pixd, &same); if (!same) fprintf(stderr, "Error in pixGammaTRC!\n"); pixWrite(fileout, pixs, IFF_JFIF_JPEG); pixDestroy(&pixs); na = numaGammaTRC(gam, MINVAL, MAXVAL); gplotSimple1(na, GPLOT_PNG, "/tmp/lept/gamma/trc", "gamma trc"); l_fileDisplay("/tmp/lept/gamma/trc.png", 100, 100, 1.0); numaDestroy(&na); /* Plot gamma TRC maps */ gplot = gplotCreate("/tmp/lept/gamma/corr", GPLOT_PNG, "Mapping function for gamma correction", "value in", "value out"); nax = numaMakeSequence(0.0, 1.0, 256); for (iplot = 0; gamma[iplot] >= 0.0; iplot++) { na = numaGammaTRC(gamma[iplot], 30, 215); sprintf(bigbuf, "gamma = %3.1f", gamma[iplot]); gplotAddPlot(gplot, nax, na, GPLOT_LINES, bigbuf); numaDestroy(&na); } gplotMakeOutput(gplot); gplotDestroy(&gplot); l_fileDisplay("/tmp/lept/gamma/corr.png", 100, 100, 1.0); numaDestroy(&nax); return 0; }
/*! * recogDestroy() * * Input: &recog (<will be set to null before returning>) * Return: void * * Notes: * (1) If a recog has a parent, the parent owns it. A recogDestroy() * will fail if there is a parent. */ void recogDestroy(L_RECOG **precog) { L_RECOG *recog; PROCNAME("recogDestroy"); if (!precog) { L_WARNING("ptr address is null\n", procName); return; } if ((recog = *precog) == NULL) return; if (recogGetParent(recog) != NULL) { L_ERROR("recog has parent; can't be destroyed\n", procName); return; } FREE(recog->bootdir); FREE(recog->bootpattern); FREE(recog->bootpath); FREE(recog->centtab); FREE(recog->sumtab); FREE(recog->fname); sarrayDestroy(&recog->sa_text); l_dnaDestroy(&recog->dna_tochar); pixaaDestroy(&recog->pixaa_u); pixaDestroy(&recog->pixa_u); ptaaDestroy(&recog->ptaa_u); ptaDestroy(&recog->pta_u); numaDestroy(&recog->nasum_u); numaaDestroy(&recog->naasum_u); pixaaDestroy(&recog->pixaa); pixaDestroy(&recog->pixa); ptaaDestroy(&recog->ptaa); ptaDestroy(&recog->pta); numaDestroy(&recog->nasum); numaaDestroy(&recog->naasum); pixaDestroy(&recog->pixa_tr); pixaDestroy(&recog->pixadb_ave); pixaDestroy(&recog->pixa_id); pixDestroy(&recog->pixdb_ave); pixDestroy(&recog->pixdb_range); pixaDestroy(&recog->pixadb_boot); pixaDestroy(&recog->pixadb_split); FREE(recog->fontdir); bmfDestroy(&recog->bmf); rchDestroy(&recog->rch); rchaDestroy(&recog->rcha); recogDestroyDid(recog); FREE(recog); *precog = NULL; return; }
Pix* stats(Pix* pix){ Numa* histo = pixGetGrayHistogram(pix, 4); Numa* norm = numaNormalizeHistogram(histo, 1); l_float32 mean, median, variance, stdd; numaGetHistogramStats(histo, 0, 1, &mean, &median, NULL, &variance); stdd = sqrt(variance); printf("stats: mean = %.2f, stdd = %.2f\n", mean, stdd); numaDestroy(&histo); numaDestroy(&norm); return pixClone(pix); }
int main(int argc, char **argv) { char *filein, *fileout; char bigbuf[512]; l_int32 iplot; l_float32 factor; /* scaled width of atan curve */ l_float32 fact[] = {.2, 0.4, 0.6, 0.8, 1.0, -1.0}; GPLOT *gplot; NUMA *na, *nax; PIX *pixs; static char mainName[] = "contrasttest"; if (argc != 4) return ERROR_INT(" Syntax: contrasttest filein factor fileout", mainName, 1); lept_mkdir("lept/contrast"); filein = argv[1]; factor = atof(argv[2]); fileout = argv[3]; if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); na = numaContrastTRC(factor); gplotSimple1(na, GPLOT_PNG, "/tmp/lept/contrast/trc1", "contrast trc"); l_fileDisplay("/tmp/lept/contrast/trc1.png", 0, 100, 1.0); numaDestroy(&na); /* Plot contrast TRC maps */ nax = numaMakeSequence(0.0, 1.0, 256); gplot = gplotCreate("/tmp/lept/contrast/trc2", GPLOT_PNG, "Atan mapping function for contrast enhancement", "value in", "value out"); for (iplot = 0; fact[iplot] >= 0.0; iplot++) { na = numaContrastTRC(fact[iplot]); sprintf(bigbuf, "factor = %3.1f", fact[iplot]); gplotAddPlot(gplot, nax, na, GPLOT_LINES, bigbuf); numaDestroy(&na); } gplotMakeOutput(gplot); gplotDestroy(&gplot); l_fileDisplay("/tmp/lept/contrast/trc2.png", 600, 100, 1.0); numaDestroy(&nax); /* Apply the input contrast enhancement */ pixContrastTRC(pixs, pixs, factor); pixWrite(fileout, pixs, IFF_PNG); pixDestroy(&pixs); return 0; }
main(int argc, char **argv) { char *filein; l_int32 i, j, w, h, d, sampling; l_float32 rank, rval; l_uint32 val; NUMA *na, *nah, *nar, *nav; PIX *pix; static char mainName[] = "numaranktest"; if (argc != 3) exit(ERROR_INT(" Syntax: numaranktest filein sampling", mainName, 1)); filein = argv[1]; sampling = atoi(argv[2]); if ((pix = pixRead(filein)) == NULL) exit(ERROR_INT("pix not made", mainName, 1)); pixGetDimensions(pix, &w, &h, &d); if (d != 8) return ERROR_INT("d != 8 bpp", mainName, 1); na = numaCreate(0); for (i = 0; i < h; i += sampling) { for (j = 0; j < w; j += sampling) { pixGetPixel(pix, j, i, &val); numaAddNumber(na, val); } } nah = numaMakeHistogramClipped(na, BIN_SIZE, 255); nar = numaCreate(0); for (rval = 0.0; rval < 256.0; rval += 2.56) { numaHistogramGetRankFromVal(nah, rval, &rank); numaAddNumber(nar, rank); } gplotSimple1(nar, GPLOT_X11, "/tmp/junkroot1", "rank vs val"); nav = numaCreate(0); for (rank = 0.0; rank <= 1.0; rank += 0.01) { numaHistogramGetValFromRank(nah, rank, &rval); numaAddNumber(nav, rval); } gplotSimple1(nav, GPLOT_X11, "/tmp/junkroot2", "val vs rank"); pixDestroy(&pix); numaDestroy(&na); numaDestroy(&nah); numaDestroy(&nar); numaDestroy(&nav); return 0; }
main(int argc, char **argv) { l_int32 i, ival, n; l_float32 f, val; GPLOT *gplot; NUMA *na1, *na2, *na3; PIX *pixt; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* Generate a 1D signal and plot it */ na1 = numaCreate(500); for (i = 0; i < 500; i++) { f = 48.3 * sin(0.13 * (l_float32)i); f += 63.4 * cos(0.21 * (l_float32)i); numaAddNumber(na1, f); } gplot = gplotCreate("/tmp/extrema", GPLOT_PNG, "Extrema test", "x", "y"); gplotAddPlot(gplot, NULL, na1, GPLOT_LINES, "plot 1"); /* Find the local min and max and plot them */ na2 = numaFindExtrema(na1, 38.3); n = numaGetCount(na2); na3 = numaCreate(n); for (i = 0; i < n; i++) { numaGetIValue(na2, i, &ival); numaGetFValue(na1, ival, &val); numaAddNumber(na3, val); } gplotAddPlot(gplot, na2, na3, GPLOT_POINTS, "plot 2"); gplotMakeOutput(gplot); #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ regTestCheckFile(rp, "/tmp/extrema.png"); /* 0 */ pixt = pixRead("/tmp/extrema.png"); pixDisplayWithTitle(pixt, 100, 100, "Extrema test", rp->display); pixDestroy(&pixt); gplotDestroy(&gplot); numaDestroy(&na1); numaDestroy(&na2); numaDestroy(&na3); return regTestCleanup(rp); }
/*! * \brief pixColorSegmentClean() * * \param[in] pixs 8 bpp, colormapped * \param[in] selsize for closing * \param[in] countarray ptr to array containing the number of pixels * found in each color in the colormap * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) This operation is in-place. * (2) This is phase 3 of color segmentation. It is the first * part of a two-step noise removal process. Colors with a * large population are closed first; this operation absorbs * small sets of intercolated pixels of a different color. * </pre> */ l_ok pixColorSegmentClean(PIX *pixs, l_int32 selsize, l_int32 *countarray) { l_int32 i, ncolors, val; l_uint32 val32; NUMA *na, *nasi; PIX *pixt1, *pixt2; PIXCMAP *cmap; PROCNAME("pixColorSegmentClean"); if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (pixGetDepth(pixs) != 8) return ERROR_INT("pixs not 8 bpp", procName, 1); if ((cmap = pixGetColormap(pixs)) == NULL) return ERROR_INT("cmap not found", procName, 1); if (!countarray) return ERROR_INT("countarray not defined", procName, 1); if (selsize <= 1) return 0; /* nothing to do */ /* Sort colormap indices in decreasing order of pixel population */ ncolors = pixcmapGetCount(cmap); na = numaCreate(ncolors); for (i = 0; i < ncolors; i++) numaAddNumber(na, countarray[i]); nasi = numaGetSortIndex(na, L_SORT_DECREASING); numaDestroy(&na); if (!nasi) return ERROR_INT("nasi not made", procName, 1); /* For each color, in order of decreasing population, * do a closing and absorb the added pixels. Note that * if the closing removes pixels at the border, they'll * still appear in the xor and will be properly (re)set. */ for (i = 0; i < ncolors; i++) { numaGetIValue(nasi, i, &val); pixt1 = pixGenerateMaskByValue(pixs, val, 1); pixt2 = pixCloseSafeCompBrick(NULL, pixt1, selsize, selsize); pixXor(pixt2, pixt2, pixt1); /* pixels to be added to type 'val' */ pixcmapGetColor32(cmap, val, &val32); pixSetMasked(pixs, pixt2, val32); /* add them */ pixDestroy(&pixt1); pixDestroy(&pixt2); } numaDestroy(&nasi); return 0; }
/*! * pixcmapContrastTRC() * * Input: colormap * factor (generally between 0.0 (no enhancement) * and 1.0, but can be larger than 1.0) * Return: 0 if OK; 1 on error * * Notes: * - in-place transform * - see pixContrastTRC() and numaContrastTRC() in enhance.c for * description and use of transform */ l_int32 pixcmapContrastTRC(PIXCMAP *cmap, l_float32 factor) { l_int32 i, ncolors, rval, gval, bval, trval, tgval, tbval; NUMA *nac; PROCNAME("pixcmapContrastTRC"); if (!cmap) return ERROR_INT("cmap not defined", procName, 1); if (factor < 0.0) { L_WARNING("factor must be >= 0.0; setting to 0.0", procName); factor = 0.0; } if ((nac = numaContrastTRC(factor)) == NULL) return ERROR_INT("nac not made", procName, 1); ncolors = pixcmapGetCount(cmap); for (i = 0; i < ncolors; i++) { pixcmapGetColor(cmap, i, &rval, &gval, &bval); numaGetIValue(nac, rval, &trval); numaGetIValue(nac, gval, &tgval); numaGetIValue(nac, bval, &tbval); pixcmapResetColor(cmap, i, trval, tgval, tbval); } numaDestroy(&nac); return 0; }
/*! * \brief pixaModifyStrokeWidth() * * \param[in] pixas of 1 bpp pix * \param[out] targetw desired width for strokes in each pix * \return pixa with modified stroke widths, or NULL on error */ PIXA * pixaModifyStrokeWidth(PIXA *pixas, l_float32 targetw) { l_int32 i, n, same, maxd; l_float32 width; NUMA *na; PIX *pix1, *pix2; PIXA *pixad; PROCNAME("pixaModifyStrokeWidth"); if (!pixas) return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL); if (targetw < 1) return (PIXA *)ERROR_PTR("target width < 1", procName, NULL); pixaVerifyDepth(pixas, &same, &maxd); if (maxd > 1) return (PIXA *)ERROR_PTR("pix not all 1 bpp", procName, NULL); na = pixaFindStrokeWidth(pixas, 0.1, NULL, 0); n = pixaGetCount(pixas); pixad = pixaCreate(n); for (i = 0; i < n; i++) { pix1 = pixaGetPix(pixas, i, L_CLONE); numaGetFValue(na, i, &width); pix2 = pixModifyStrokeWidth(pix1, width, targetw); pixaAddPix(pixad, pix2, L_INSERT); pixDestroy(&pix1); } numaDestroy(&na); return pixad; }
/*! * \brief boxaSelectByWHRatio() * * \param[in] boxas * \param[in] ratio width/height threshold value * \param[in] relation L_SELECT_IF_LT, L_SELECT_IF_GT, * L_SELECT_IF_LTE, L_SELECT_IF_GTE * \param[out] pchanged [optional] 1 if changed; 0 if clone returned * \return boxad filtered set, or NULL on error * * <pre> * Notes: * (1) Uses box copies in the new boxa. * (2) To keep narrow components, use relation = L_SELECT_IF_LT or * L_SELECT_IF_LTE. * To keep wide components, use relation = L_SELECT_IF_GT or * L_SELECT_IF_GTE. * </pre> */ BOXA * boxaSelectByWHRatio(BOXA *boxas, l_float32 ratio, l_int32 relation, l_int32 *pchanged) { BOXA *boxad; NUMA *na; PROCNAME("boxaSelectByWHRatio"); if (pchanged) *pchanged = FALSE; if (!boxas) return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL); if (boxaGetCount(boxas) == 0) { L_WARNING("boxas is empty\n", procName); return boxaCopy(boxas, L_COPY); } if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT && relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE) return (BOXA *)ERROR_PTR("invalid relation", procName, NULL); /* Compute the indicator array for saving components */ na = boxaMakeWHRatioIndicator(boxas, ratio, relation); /* Filter to get output */ boxad = boxaSelectWithIndicator(boxas, na, pchanged); numaDestroy(&na); return boxad; }
static void DisplayMapHistogram(L_AMAP *m, PIXCMAP *cmap, const char *rootname) { char buf[128]; l_int32 i, n, ival; l_uint32 val32; NUMA *na; RB_TYPE key; RB_TYPE *pval; n = pixcmapGetCount(cmap); na = numaCreate(n); for (i = 0; i < n; i++) { pixcmapGetColor32(cmap, i, &val32); key.utype = val32; pval = l_amapFind(m, key); if (pval) { ival = pval->itype; numaAddNumber(na, ival); } } gplotSimple1(na, GPLOT_PNG, rootname, NULL); snprintf(buf, sizeof(buf), "%s.png", rootname); l_fileDisplay(buf, 700, 0, 1.0); numaDestroy(&na); return; }
/*! * wshedRenderFill() * * Input: wshed * Return: pixd (initial image with all basins filled), or null on error */ PIX * wshedRenderFill(L_WSHED *wshed) { l_int32 i, n, level, bx, by; NUMA *na; PIX *pix, *pixd; PIXA *pixa; PROCNAME("wshedRenderFill"); if (!wshed) return (PIX *) ERROR_PTR("wshed not defined", procName, NULL); wshedBasins(wshed, &pixa, &na); pixd = pixCopy(NULL, wshed->pixs); n = pixaGetCount(pixa); for (i = 0; i < n; i++) { pix = pixaGetPix(pixa, i, L_CLONE); pixaGetBoxGeometry(pixa, i, &bx, &by, NULL, NULL); numaGetIValue(na, i, &level); pixPaintThroughMask(pixd, pix, bx, by, level); pixDestroy(&pix); } pixaDestroy(&pixa); numaDestroy(&na); return pixd; }
static void DisplayMapHistogram(L_AMAP *m, PIXCMAP *cmap, const char *rootname) { l_int32 i, n, ival; l_uint32 val32; NUMA *na; RB_TYPE key; RB_TYPE *pval; n = pixcmapGetCount(cmap); na = numaCreate(n); for (i = 0; i < n; i++) { pixcmapGetColor32(cmap, i, &val32); key.utype = val32; pval = l_amapFind(m, key); if (pval) { ival = pval->itype; numaAddNumber(na, ival); } } /* numaWrite("/tmp/lept/map/map.na", na); */ gplotSimple1(na, GPLOT_X11, rootname, NULL); numaDestroy(&na); return; }
jfloatArray Java_com_googlecode_eyesfree_textdetect_HydrogenTextDetector_nativeGetTextConfs( JNIEnv *env, jclass clazz, jlong nativePtr) { if (DEBUG_MODE) LOGV(__FUNCTION__); HydrogenTextDetector *ptr = (HydrogenTextDetector *) nativePtr; NUMA *confs = ptr->GetTextConfs(); l_int32 count = numaGetCount(confs); jfloatArray ret = env->NewFloatArray(count); l_float32 nval; jfloat jval; if (ret != NULL) { for (int i = 0; i < count; i++) { numaGetFValue(confs, i, &nval); jval = (jfloat) nval; env->SetFloatArrayRegion(ret, i, 1, &jval); } } numaDestroy(&confs); return ret; }
/*! * numaaWriteStream() * * Input: stream, naa * Return: 0 if OK, 1 on error */ l_int32 numaaWriteStream(FILE *fp, NUMAA *naa) { l_int32 i, n; NUMA *na; PROCNAME("numaaWriteStream"); if (!fp) return ERROR_INT("stream not defined", procName, 1); if (!naa) return ERROR_INT("naa not defined", procName, 1); n = numaaGetCount(naa); fprintf(fp, "\nNumaa Version %d\n", NUMA_VERSION_NUMBER); fprintf(fp, "Number of numa = %d\n\n", n); for (i = 0; i < n; i++) { if ((na = numaaGetNuma(naa, i, L_CLONE)) == NULL) return ERROR_INT("na not found", procName, 1); fprintf(fp, "Numa[%d]:", i); numaWriteStream(fp, na); numaDestroy(&na); } return 0; }
/*! * pixaSelectBySize() * * Input: pixas * width, height (threshold dimensions) * type (L_SELECT_WIDTH, L_SELECT_HEIGHT, * L_SELECT_IF_EITHER, L_SELECT_IF_BOTH) * relation (L_SELECT_IF_LT, L_SELECT_IF_GT, * L_SELECT_IF_LTE, L_SELECT_IF_GTE) * &changed (<optional return> 1 if changed; 0 otherwise) * Return: pixad, or null on error * * Notes: * (1) The args specify constraints on the size of the * components that are kept. * (2) Uses pix and box clones in the new pixa. * (3) If the selection type is L_SELECT_WIDTH, the input * height is ignored, and v.v. * (4) To keep small components, use relation = L_SELECT_IF_LT or * L_SELECT_IF_LTE. * To keep large components, use relation = L_SELECT_IF_GT or * L_SELECT_IF_GTE. */ PIXA * pixaSelectBySize(PIXA *pixas, l_int32 width, l_int32 height, l_int32 type, l_int32 relation, l_int32 *pchanged) { BOXA *boxa; NUMA *na; PIXA *pixad; PROCNAME("pixaSelectBySize"); if (!pixas) return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL); if (type != L_SELECT_WIDTH && type != L_SELECT_HEIGHT && type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH) return (PIXA *)ERROR_PTR("invalid type", procName, NULL); if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT && relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE) return (PIXA *)ERROR_PTR("invalid relation", procName, NULL); /* Compute the indicator array for saving components */ boxa = pixaGetBoxa(pixas, L_CLONE); na = boxaMakeSizeIndicator(boxa, width, height, type, relation); boxaDestroy(&boxa); /* Filter to get output */ pixad = pixaSelectWithIndicator(pixas, na, pchanged); numaDestroy(&na); return pixad; }
/*! * ptaSort() * * Input: ptas * sorttype (L_SORT_BY_X, L_SORT_BY_Y) * sortorder (L_SORT_INCREASING, L_SORT_DECREASING) * &naindex (<optional return> index of sorted order into * original array) * Return: ptad (sorted version of ptas), or null on error */ PTA * ptaSort(PTA *ptas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex) { PTA *ptad; NUMA *naindex; PROCNAME("ptaSort"); if (pnaindex) *pnaindex = NULL; if (!ptas) return (PTA *)ERROR_PTR("ptas not defined", procName, NULL); if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y) return (PTA *)ERROR_PTR("invalid sort type", procName, NULL); if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING) return (PTA *)ERROR_PTR("invalid sort order", procName, NULL); if (ptaGetSortIndex(ptas, sorttype, sortorder, &naindex) != 0) return (PTA *)ERROR_PTR("naindex not made", procName, NULL); ptad = ptaSortByIndex(ptas, naindex); if (pnaindex) *pnaindex = naindex; else numaDestroy(&naindex); if (!ptad) return (PTA *)ERROR_PTR("ptad not made", procName, NULL); return ptad; }
/*! * gplotDestroy() * * Input: &gplot (<to be nulled>) * Return: void */ void gplotDestroy(GPLOT **pgplot) { GPLOT *gplot; PROCNAME("gplotDestroy"); if (pgplot == NULL) { L_WARNING("ptr address is null!\n", procName); return; } if ((gplot = *pgplot) == NULL) return; FREE(gplot->rootname); FREE(gplot->cmdname); sarrayDestroy(&gplot->cmddata); sarrayDestroy(&gplot->datanames); sarrayDestroy(&gplot->plotdata); sarrayDestroy(&gplot->plottitles); numaDestroy(&gplot->plotstyles); FREE(gplot->outname); if (gplot->title) FREE(gplot->title); if (gplot->xlabel) FREE(gplot->xlabel); if (gplot->ylabel) FREE(gplot->ylabel); FREE(gplot); *pgplot = NULL; return; }
/*! * gplotSimpleXYN() * * Input: nax (<optional>; can be NULL) * naay (numaa of arrays to plot against @nax) * outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11, * GPLOT_LATEX) * outroot (root of output files) * title (<optional>) * Return: 0 if OK, 1 on error * * Notes: * (1) This gives line plots of each Numa in @naa against nax, * generated in the specified output format. The title is optional. * (2) @nax is optional. If NULL, each Numa array is plotted against * the array index. * (3) When calling these simple plot functions more than once, use * different @outroot to avoid overwriting the output files. */ l_int32 gplotSimpleXYN(NUMA *nax, NUMAA *naay, l_int32 outformat, const char *outroot, const char *title) { l_int32 i, n; GPLOT *gplot; NUMA *nay; PROCNAME("gplotSimpleXYN"); if (!naay) return ERROR_INT("naay not defined", procName, 1); if ((n = numaaGetCount(naay)) == 0) return ERROR_INT("no numa in array", procName, 1); if (outformat != GPLOT_PNG && outformat != GPLOT_PS && outformat != GPLOT_EPS && outformat != GPLOT_X11 && outformat != GPLOT_LATEX) return ERROR_INT("invalid outformat", procName, 1); if (!outroot) return ERROR_INT("outroot not specified", procName, 1); if ((gplot = gplotCreate(outroot, outformat, title, NULL, NULL)) == 0) return ERROR_INT("gplot not made", procName, 1); for (i = 0; i < n; i++) { nay = numaaGetNuma(naay, i, L_CLONE); gplotAddPlot(gplot, nax, nay, GPLOT_LINES, NULL); numaDestroy(&nay); } gplotMakeOutput(gplot); gplotDestroy(&gplot); return 0; }
/*! * dewarpMinimize() * * Input: dew * Return: 0 if OK, 1 on error * * Notes: * (1) This removes all data that is not needed for serialization. * It keeps the subsampled disparity array(s), so the full * resolution arrays can be reconstructed. */ l_int32 dewarpMinimize(L_DEWARP *dew) { PROCNAME("dewarpMinimize"); if (!dew) return ERROR_INT("dew not defined", procName, 1); pixDestroy(&dew->pixs); pixDestroy(&dew->pixd); fpixDestroy(&dew->fullvdispar); fpixDestroy(&dew->fullhdispar); numaDestroy(&dew->naflats); numaDestroy(&dew->nacurves); return 0; }