Пример #1
0
/*!
 *  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;
}
Пример #2
0
/*!
 *  pixAddWithIndicator()
 *
 *      Input:  pixs (1 bpp pix from which components are added; in-place)
 *              pixa (of connected components, some of which will be put
 *                    into pixs)
 *              na (numa indicator: add components corresponding to 1s)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This complements pixRemoveWithIndicator().   Here, the selected
 *          components are added to pixs.
 */
l_int32
pixAddWithIndicator(PIX   *pixs,
                    PIXA  *pixa,
                    NUMA  *na)
{
l_int32  i, n, ival, x, y, w, h;
BOX     *box;
PIX     *pix;

    PROCNAME("pixAddWithIndicator");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!pixa)
        return ERROR_INT("pixa not defined", procName, 1);
    if (!na)
        return ERROR_INT("na not defined", procName, 1);
    n = pixaGetCount(pixa);
    if (n != numaGetCount(na))
        return ERROR_INT("pixa and na sizes not equal", procName, 1);

    for (i = 0; i < n; i++) {
        numaGetIValue(na, i, &ival);
        if (ival == 1) {
            pix = pixaGetPix(pixa, i, L_CLONE);
            box = pixaGetBox(pixa, i, L_CLONE);
            boxGetGeometry(box, &x, &y, &w, &h);
            pixRasterop(pixs, x, y, w, h, PIX_SRC | PIX_DST, pix, 0, 0);
            boxDestroy(&box);
            pixDestroy(&pix);
        }
    }

    return 0;
}
Пример #3
0
/*!
 *  ptaSortByIndex()
 *
 *      Input:  ptas
 *              naindex (na that maps from the new pta to the input pta)
 *      Return: ptad (sorted), or null on  error
 */
PTA *
ptaSortByIndex(PTA   *ptas,
               NUMA  *naindex)
{
l_int32    i, index, n;
l_float32  x, y;
PTA       *ptad;

    PROCNAME("ptaSortByIndex");

    if (!ptas)
        return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
    if (!naindex)
        return (PTA *)ERROR_PTR("naindex not defined", procName, NULL);

        /* Build up sorted pta using sort index */
    n = numaGetCount(naindex);
    if ((ptad = ptaCreate(n)) == NULL)
        return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
    for (i = 0; i < n; i++) {
        numaGetIValue(naindex, i, &index);
        ptaGetPt(ptas, index, &x, &y);
        ptaAddPt(ptad, x, y);
    }

    return ptad;
}
Пример #4
0
/*!
 *  numaWriteStream()
 *
 *      Input:  stream, na
 *      Return: 0 if OK, 1 on error
 */
l_int32
numaWriteStream(FILE  *fp,
                NUMA  *na)
{
l_int32    i, n;
l_float32  startx, delx;

    PROCNAME("numaWriteStream");

    if (!fp)
        return ERROR_INT("stream not defined", procName, 1);
    if (!na)
        return ERROR_INT("na not defined", procName, 1);

    n = numaGetCount(na);
    fprintf(fp, "\nNuma Version %d\n", NUMA_VERSION_NUMBER);
    fprintf(fp, "Number of numbers = %d\n", n);
    for (i = 0; i < n; i++)
        fprintf(fp, "  [%d] = %f\n", i, na->array[i]);
    fprintf(fp, "\n");

        /* Optional data */
    numaGetParameters(na, &startx, &delx);
    if (startx != 0.0 || delx != 1.0)
        fprintf(fp, "startx = %f, delx = %f\n", startx, delx);

    return 0;
}
Пример #5
0
/*!
 *  ptaaSortByIndex()
 *
 *      Input:  ptaas
 *              naindex (na that maps from the new ptaa to the input ptaa)
 *      Return: ptaad (sorted), or null on error
 */
PTAA *
ptaaSortByIndex(PTAA  *ptaas,
                NUMA  *naindex)
{
l_int32  i, n, index;
PTA     *pta;
PTAA    *ptaad;

    PROCNAME("ptaaSortByIndex");

    if (!ptaas)
        return (PTAA *)ERROR_PTR("ptaas not defined", procName, NULL);
    if (!naindex)
        return (PTAA *)ERROR_PTR("naindex not defined", procName, NULL);

    n = ptaaGetCount(ptaas);
    if (numaGetCount(naindex) != n)
        return (PTAA *)ERROR_PTR("numa and ptaa sizes differ", procName, NULL);
    ptaad = ptaaCreate(n);
    for (i = 0; i < n; i++) {
        numaGetIValue(naindex, i, &index);
        pta = ptaaGetPta(ptaas, index, L_COPY);
        ptaaAddPta(ptaad, pta, L_INSERT);
    }

    return ptaad;
}
Пример #6
0
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;
}
/*!
 * \brief   recogShowPath()
 *
 * \param[in]    recog with LUT's pre-computed
 * \param[in]    select 0 for Viterbi; 1 for rescored
 * \return  pix debug output), or NULL on error
 */
static PIX *
recogShowPath(L_RECOG  *recog,
              l_int32   select)
{
char       textstr[16];
l_int32    i, n, index, xloc, dely;
l_float32  score;
L_BMF     *bmf;
NUMA      *natempl_s, *nascore_s, *naxloc_s, *nadely_s;
PIX       *pixs, *pix0, *pix1, *pix2, *pix3, *pix4, *pix5;
L_RDID    *did;

    PROCNAME("recogShowPath");

    if (!recog)
        return (PIX *)ERROR_PTR("recog not defined", procName, NULL);
    if ((did = recogGetDid(recog)) == NULL)
        return (PIX *)ERROR_PTR("did not defined", procName, NULL);

    bmf = bmfCreate(NULL, 8);
    pixs = pixScale(did->pixs, 4.0, 4.0);
    pix0 = pixAddBorderGeneral(pixs, 0, 0, 0, 40, 0);
    pix1 = pixConvertTo32(pix0);
    if (select == 0) {  /* Viterbi */
        natempl_s = did->natempl;
        nascore_s = did->nascore;
        naxloc_s = did->naxloc;
        nadely_s = did->nadely;
    } else {  /* rescored */
        natempl_s = did->natempl_r;
        nascore_s = did->nascore_r;
        naxloc_s = did->naxloc_r;
        nadely_s = did->nadely_r;
    }

    n = numaGetCount(natempl_s);
    for (i = 0; i < n; i++) {
        numaGetIValue(natempl_s, i, &index);
        pix2 = pixaGetPix(recog->pixa_u, index, L_CLONE);
        pix3 = pixScale(pix2, 4.0, 4.0);
        pix4 = pixErodeBrick(NULL, pix3, 5, 5);
        pixXor(pix4, pix4, pix3);
        numaGetFValue(nascore_s, i, &score);
        snprintf(textstr, sizeof(textstr), "%5.3f", score);
        pix5 = pixAddTextlines(pix4, bmf, textstr, 1, L_ADD_BELOW);
        numaGetIValue(naxloc_s, i, &xloc);
        numaGetIValue(nadely_s, i, &dely);
        pixPaintThroughMask(pix1, pix5, 4 * xloc, 4 * dely, 0xff000000);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
        pixDestroy(&pix4);
        pixDestroy(&pix5);
    }
    pixDestroy(&pixs);
    pixDestroy(&pix0);
    bmfDestroy(&bmf);
    return pix1;
}
/*!
 *  dewarpaInfo()
 *
 *      Input:  fp
 *              dewa
 *      Return: 0 if OK, 1 on error
 */
l_int32
dewarpaInfo(FILE       *fp,
            L_DEWARPA  *dewa)
{
l_int32    i, n, pageno, nnone, nvsuccess, nvvalid, nhsuccess, nhvalid, nref;
L_DEWARP  *dew;

    PROCNAME("dewarpaInfo");

    if (!fp)
        return ERROR_INT("dewa not defined", procName, 1);
    if (!dewa)
        return ERROR_INT("dewa not defined", procName, 1);

    fprintf(fp, "\nDewarpaInfo: %p\n", dewa);
    fprintf(fp, "nalloc = %d, maxpage = %d\n", dewa->nalloc, dewa->maxpage);
    fprintf(fp, "sampling = %d, redfactor = %d, minlines = %d\n",
            dewa->sampling, dewa->redfactor, dewa->minlines);
    fprintf(fp, "maxdist = %d, useboth = %d\n",
            dewa->maxdist, dewa->useboth);

    dewarpaModelStats(dewa, &nnone, &nvsuccess, &nvvalid,
                      &nhsuccess, &nhvalid, &nref);
    n = numaGetCount(dewa->napages);
    fprintf(stderr, "Total number of pages with a dew = %d\n", n);
    fprintf(stderr, "Number of pages without any models = %d\n", nnone);
    fprintf(stderr, "Number of pages with a vert model = %d\n", nvsuccess);
    fprintf(stderr, "Number of pages with a valid vert model = %d\n", nvvalid);
    fprintf(stderr, "Number of pages with both models = %d\n", nhsuccess);
    fprintf(stderr, "Number of pages with both models valid = %d\n", nhvalid);
    fprintf(stderr, "Number of pages with a ref model = %d\n", nref);

    for (i = 0; i < n; i++) {
        numaGetIValue(dewa->napages, i, &pageno);
        if ((dew = dewarpaGetDewarp(dewa, pageno)) == NULL)
            continue;
        fprintf(stderr, "Page: %d\n", dew->pageno);
        fprintf(stderr, "  hasref = %d, refpage = %d\n",
                dew->hasref, dew->refpage);
        fprintf(stderr, "  nlines = %d\n", dew->nlines);
        fprintf(stderr, "  w = %d, h = %d, nx = %d, ny = %d\n",
                dew->w, dew->h, dew->nx, dew->ny);
        if (dew->sampvdispar)
            fprintf(stderr, "  Vertical disparity builds:\n"
                    "    (min,max,abs-diff) line curvature = (%d,%d,%d)\n",
                    dew->mincurv, dew->maxcurv, dew->maxcurv - dew->mincurv);
        if (dew->samphdispar)
            fprintf(stderr, "  Horizontal disparity builds:\n"
                    "    left edge slope = %d, right edge slope = %d\n"
                    "    (left,right,abs-diff) edge curvature = (%d,%d,%d)\n",
                    dew->leftslope, dew->rightslope, dew->leftcurv,
                    dew->rightcurv, L_ABS(dew->leftcurv - dew->rightcurv));
    }
    return 0;
}
Пример #9
0
/*!
 *  pixGetRunCentersOnLine()
 *
 *      Input:  pixs (1 bpp)
 *              x, y (set one of these to -1; see notes)
 *              minlength (minimum length of acceptable run)
 *      Return: numa of fg runs, or null on error
 *
 *  Notes:
 *      (1) Action: this function computes the fg (black) and bg (white)
 *          pixel runlengths along the specified horizontal or vertical line,
 *          and returns a Numa of the "center" pixels of each fg run
 *          whose length equals or exceeds the minimum length.
 *      (2) This only works on horizontal and vertical lines.
 *      (3) For horizontal runs, set x = -1 and y to the value
 *          for all points along the raster line.  For vertical runs,
 *          set y = -1 and x to the value for all points along the
 *          pixel column.
 *      (4) For horizontal runs, the points in the Numa are the x
 *          values in the center of fg runs that are of length at
 *          least 'minlength'.  For vertical runs, the points in the
 *          Numa are the y values in the center of fg runs, again
 *          of length 'minlength' or greater.
 *      (5) If there are no fg runs along the line that satisfy the
 *          minlength constraint, the returned Numa is empty.  This
 *          is not an error.
 */
NUMA *
pixGetRunCentersOnLine(PIX     *pixs,
                       l_int32  x,
                       l_int32  y,
                       l_int32  minlength)
{
l_int32   w, h, i, r, nruns, len;
NUMA     *naruns, *nad;

    PROCNAME("pixGetRunCentersOnLine");

    if (!pixs)
        return (NUMA *)ERROR_PTR("pixs not defined", procName, NULL);
    if (pixGetDepth(pixs) != 1)
        return (NUMA *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
    if (x != -1 && y != -1)
        return (NUMA *)ERROR_PTR("x or y must be -1", procName, NULL);
    if (x == -1 && y == -1)
        return (NUMA *)ERROR_PTR("x or y cannot both be -1", procName, NULL);

    if ((nad = numaCreate(0)) == NULL)
        return (NUMA *)ERROR_PTR("nad not made", procName, NULL);
    w = pixGetWidth(pixs);
    h = pixGetHeight(pixs);
    if (x == -1) {  /* horizontal run */
        if (y < 0 || y >= h)
            return nad;
        naruns = pixGetRunsOnLine(pixs, 0, y, w - 1, y);
    }
    else {  /* vertical run */
        if (x < 0 || x >= w)
            return nad;
        naruns = pixGetRunsOnLine(pixs, x, 0, x, h - 1);
    }
    nruns = numaGetCount(naruns);

        /* extract run center values; the first run is always bg */
    r = 0;  /* cumulative distance along line */
    for (i = 0; i < nruns; i++) {
        if (i % 2 == 0) {  /* bg run */
            numaGetIValue(naruns, i, &len);
            r += len;
            continue;
        }
        else {
            numaGetIValue(naruns, i, &len);
            if (len >= minlength)
                numaAddNumber(nad, r + len / 2);
            r += len;
        }
    }

    numaDestroy(&naruns);
    return nad;
}
Пример #10
0
/*
 * Use these variable abbreviations:
 *
 * pap1: distance from left edge to the page
 * txt1: distance from left edge to the text
 * Identify pap1 by (a) 1st downward transition in intensity (nait).
 *                  (b) start of 1st lowpass interval (nail)
 * Identify txt1 by (a) end of 1st lowpass interval (nail)
 *                  (b) first upward transition in reversals (nart)
 *
 * pap2: distance from right edge to beginning of last upward transition,
 *       plus some extra for safety.
 * txt1: distance from right edge to the text
 * Identify pap2 by 1st downward transition in intensity.
 * Identify txt2 by (a) beginning of 1st lowpass interval from bottom
 *                  (b) last downward transition in reversals from bottom
 */
l_int32
GetLeftCut(NUMA *narl,
           NUMA *nart,
           NUMA *nait,
           l_int32 w,
           l_int32 *pleft) {
l_int32  nrl, nrt, nit, start, end, sign, pap1, txt1, del;

    nrl = numaGetCount(narl);
    nrt = numaGetCount(nart);
    nit = numaGetCount(nait);

        /* Check for small max number of reversals or no edge */
    numaGetSpanValues(narl, 0, NULL, &end);
    if (end < 20 || nrl <= 1) {
        *pleft = 0;
        return 0;
    }

        /* Where is text and page, scanning from the left? */
    pap1 = 0;
    txt1 = 0;
    if (nrt >= 4) {  /* beginning of first upward transition */
        numaGetEdgeValues(nart, 0, &start, NULL, NULL);
        txt1 = start;
    }
    if (nit >= 4) {  /* end of first downward trans in (inverse) intensity */
        numaGetEdgeValues(nait, 0, NULL, &end, &sign);
        if (end < txt1 && sign == -1)
            pap1 = end;
        else
            pap1 = 0.5 * txt1;
    }
    del = txt1 - pap1;
    if (del > 20) {
        txt1 -= L_MIN(20, 0.5 * del);
        pap1 += L_MIN(20, 0.5 * del);
    }
    fprintf(stderr, "txt1 = %d, pap1 = %d\n", txt1, pap1);
    *pleft = pap1;
    return 0;
}
/*!
 * \brief   recogRescoreDidResult()
 *
 * \param[in]    recog with LUT's pre-computed
 * \param[out]   ppixdb [optional] debug result; can be null
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) This does correlation matching with all templates using the
 *          viterbi path segmentation.
 * </pre>
 */
static l_int32
recogRescoreDidResult(L_RECOG  *recog,
                      PIX     **ppixdb)
{
l_int32    i, n, w2, h1, templ, x, xloc, dely, index;
char      *text;
l_float32  score;
BOX       *box1;
PIX       *pixs, *pix1;
L_RDID    *did;

    PROCNAME("recogRescoreDidResult");

    if (ppixdb) *ppixdb = NULL;
    if (!recog)
        return ERROR_INT("recog not defined", procName, 1);
    if ((did = recogGetDid(recog)) == NULL)
        return ERROR_INT("did not defined", procName, 1);
    if (did->fullarrays == 0)
        return ERROR_INT("did full arrays not made", procName, 1);
    if ((n = numaGetCount(did->naxloc)) == 0)
        return ERROR_INT("no elements in path", procName, 1);

    pixs = did->pixs;
    h1 = pixGetHeight(pixs);
    for (i = 0; i < n; i++) {
        numaGetIValue(did->natempl, i, &templ);
        numaGetIValue(did->naxloc, i, &xloc);
        numaGetIValue(did->nadely, i, &dely);
        pixaGetPixDimensions(recog->pixa_u, templ, &w2, NULL, NULL);
        /* TODO: try to fix xloc - 4, etc. */
        x = L_MAX(xloc, 0);
        box1 = boxCreate(x, dely, w2, h1);
        pix1 = pixClipRectangle(pixs, box1, NULL);
        recogIdentifyPix(recog, pix1, NULL);
        recogTransferRchToDid(recog, x, dely);
        if (ppixdb) {
            rchExtract(recog->rch, &index, &score, &text,
                       NULL, NULL, NULL, NULL);
            fprintf(stderr, "text = %s, index = %d, score = %5.3f\n",
                    text, index, score);
        }
        pixDestroy(&pix1);
        boxDestroy(&box1);
        LEPT_FREE(text);
    }

/*    numaWriteStream(stderr, recog->did->nadely_r);  */

    if (ppixdb)
        *ppixdb = recogShowPath(recog, 1);

    return 0;
}
Пример #12
0
/*!
 *  numaaGetNumaCount()
 *
 *      Input:  naa
 *              index (of numa in naa)
 *      Return: count of numbers in the referenced numa, or 0 on error.
 */
l_int32
numaaGetNumaCount(NUMAA   *naa,
                  l_int32  index)
{
    PROCNAME("numaaGetNumaCount");

    if (!naa)
        return ERROR_INT("naa not defined", procName, 0);
    if (index < 0 || index >= naa->n)
        return ERROR_INT("invalid index into naa", procName, 0);
    return numaGetCount(naa->numa[index]);
}
void PixelHistogram::ConstructHorizontalCountHist(Pix* pix) {
  Clear();
  Numa* counts = pixCountPixelsByRow(pix, NULL);
  length_ = numaGetCount(counts);
  hist_ = new int[length_];
  for (int i = 0; i < length_; ++i) {
    l_int32 val = 0;
    numaGetIValue(counts, i, &val);
    hist_[i] = val;
  }
  numaDestroy(&counts);
}
Пример #14
0
Numa* numaMakeYNuma(Numa* nax, Numa* nay) {
    l_int32 n = numaGetCount(nax);
    Numa* numaYValues = numaCreate(0);
    for (int i = 0; i < n; i++) {
        l_int32 index;
        l_float32 number;
        numaGetIValue(nax, i, &index);
        
        numaGetFValue(nay, index/nay->delx, &number);
        numaAddNumber(numaYValues, number);
    }
    return numaYValues;
}
Пример #15
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);
}
/*!
 *  dewarpaModelStats()
 *
 *      Input:  dewa
 *              &nnone (<optional return> number without any model)
 *              &nvsuccess (<optional return> number with a vert model)
 *              &nvvalid (<optional return> number with a valid vert model)
 *              &nhsuccess (<optional return> number with both models)
 *              &nhvalid (<optional return> number with both models valid)
 *              &nref (<optional return> number with a reference model)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) A page without a model has no dew.  It most likely failed to
 *          generate a vertical model, and has not been assigned a ref
 *          model from a neighboring page with a valid vertical model.
 *      (2) A page has vsuccess == 1 if there is at least a model of the
 *          vertical disparity.  The model may be invalid, in which case
 *          dewarpaInsertRefModels() will stash it in the cache and
 *          attempt to replace it by a valid ref model.
 *      (3) A vvvalid model is a vertical disparity model whose parameters
 *          satisfy the constraints given in dewarpaSetValidModels().
 *      (4) A page has hsuccess == 1 if both the vertical and horizontal
 *          disparity arrays have been constructed.
 *      (5) An  hvalid model has vertical and horizontal disparity
 *          models whose parameters satisfy the constraints given
 *          in dewarpaSetValidModels().
 *      (6) A page has a ref model if it failed to generate a valid
 *          model but was assigned a vvalid or hvalid model on another
 *          page (within maxdist) by dewarpaInsertRefModel().
 *      (7) This calls dewarpaTestForValidModel(); it ignores the vvalid
 *          and hvalid fields.
 */
l_int32
dewarpaModelStats(L_DEWARPA  *dewa,
                  l_int32    *pnnone,
                  l_int32    *pnvsuccess,
                  l_int32    *pnvvalid,
                  l_int32    *pnhsuccess,
                  l_int32    *pnhvalid,
                  l_int32    *pnref)
{
l_int32    i, n, pageno, nnone, nvsuccess, nvvalid, nhsuccess, nhvalid, nref;
L_DEWARP  *dew;

    PROCNAME("dewarpaModelStats");

    if (!dewa)
        return ERROR_INT("dewa not defined", procName, 1);

    dewarpaListPages(dewa);
    n = numaGetCount(dewa->napages);
    nnone = nref = nvsuccess = nvvalid = nhsuccess = nhvalid = 0;
    for (i = 0; i < n; i++) {
        numaGetIValue(dewa->napages, i, &pageno);
        dew = dewarpaGetDewarp(dewa, pageno);
        if (!dew) {
            nnone++;
            continue;
        }
        if (dew->hasref == 1)
            nref++;
        if (dew->vsuccess == 1)
            nvsuccess++;
        if (dew->hsuccess == 1)
            nhsuccess++;
        dewarpaTestForValidModel(dewa, dew, 0);
        if (dew->vvalid == 1)
            nvvalid++;
        if (dew->hvalid == 1)
            nhvalid++;
    }

    if (pnnone) *pnnone = nnone;
    if (pnref) *pnref = nref;
    if (pnvsuccess) *pnvsuccess = nvsuccess;
    if (pnvvalid) *pnvvalid = nvvalid;
    if (pnhsuccess) *pnhsuccess = nhsuccess;
    if (pnhvalid) *pnhvalid = nhvalid;
    return 0;
}
Пример #17
0
l_int32
GetRightCut(NUMA *narl,
            NUMA *nart,
            NUMA *nait,
            l_int32 w,
            l_int32 *pright) {
l_int32  nrt, ntrans, start, end, sign, txt2, pap2, found, trans;

    nrt = numaGetCount(nart);

        /* Check for small max number of reversals or no edge */
        /* Where is text and page, scanning from the right?  */
    ntrans = nrt / 3;
    if (ntrans > 1) {
        found = FALSE;
        for (trans = ntrans - 1; trans > 0; --trans) {
            numaGetEdgeValues(nart, trans, &start, &end, &sign);
            if (sign == -1) {  /* end of textblock */
                txt2 = end;
                found = TRUE;
            }
        }
        if (!found) {
            txt2 = w - 1;  /* take the whole thing! */
            pap2 = w - 1;
        } else {  /* found textblock; now find right side of page */
            found = FALSE;
            for (trans = ntrans - 1; trans > 0; --trans) {
                numaGetEdgeValues(nart, trans, &start, &end, &sign);
                if (sign == 1 && start > txt2) {
                    pap2 = start;  /* start of textblock on other page */
                    found = TRUE;
                }
            }
            if (!found) {  /* no text from other page */
                pap2 = w - 1;  /* refine later */
            }
        }
    } else {
        txt2 = w - 1;
        pap2 = w - 1;
    }
    fprintf(stderr, "txt2 = %d, pap2 = %d\n", txt2, pap2);
    *pright = pap2;
    return 0;
}
Пример #18
0
l_int32 count_ones(NUMA  *na, l_int32 nexp, l_int32 index, const char *name)
{
l_int32  i, n, val, sum;

    n = numaGetCount(na);
    sum = 0;
    for (i = 0; i < n; i++) {
        numaGetIValue(na, i, &val);
        if (val == 1) sum++;
    }
    if (!name) return sum;
    if (nexp == sum)
        fprintf(stderr, "Correct: %s[%d]: num. ones: %d\n", name, index, sum);
    else
        fprintf(stderr, "WRONG!: %s[%d]: num. ones: %d\n", name, index, sum);
    return 0;
}
Пример #19
0
/*!
 *  numaConvertToSarray()
 *
 *      Input:  na
 *              size1 (size of conversion field)
 *              size2 (for float conversion: size of field to the right
 *                     of the decimal point)
 *              addzeros (for integer conversion: to add lead zeros)
 *              type (L_INTEGER_VALUE, L_FLOAT_VALUE)
 *      Return: a sarray of the float values converted to strings
 *              representing either integer or float values; or null on error.
 *
 *  Notes:
 *      (1) For integer conversion, size2 is ignored.
 *          For float conversion, addzeroes is ignored.
 */
SARRAY *
numaConvertToSarray(NUMA    *na,
                    l_int32  size1,
                    l_int32  size2,
                    l_int32  addzeros,
                    l_int32  type)
{
char       fmt[32], strbuf[64];
l_int32    i, n, ival;
l_float32  fval;
SARRAY    *sa;

    PROCNAME("numaConvertToSarray");

    if (!na)
        return (SARRAY *)ERROR_PTR("na not defined", procName, NULL);
    if (type != L_INTEGER_VALUE && type != L_FLOAT_VALUE)
        return (SARRAY *)ERROR_PTR("invalid type", procName, NULL);

    if (type == L_INTEGER_VALUE) {
        if (addzeros)
            snprintf(fmt, sizeof(fmt), "%%0%dd", size1);
        else
            snprintf(fmt, sizeof(fmt), "%%%dd", size1);
    } else {  /* L_FLOAT_VALUE */
        snprintf(fmt, sizeof(fmt), "%%%d.%df", size1, size2);
    }

    n = numaGetCount(na);
    if ((sa = sarrayCreate(n)) == NULL)
        return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);

    for (i = 0; i < n; i++) {
        if (type == L_INTEGER_VALUE) {
            numaGetIValue(na, i, &ival);
            snprintf(strbuf, sizeof(strbuf), fmt, ival);
        } else {  /* L_FLOAT_VALUE */
            numaGetFValue(na, i, &fval);
            snprintf(strbuf, sizeof(strbuf), fmt, fval);
        }
        sarrayAddString(sa, strbuf, L_COPY);
    }

    return sa;
}
Пример #20
0
/*!
 *  mergeLookup()
 *
 *      Input:  wshed
 *              sindex (primary index being changed in the merge)
 *              dindex (index that @sindex will point to after the merge)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) The links are a sparse array of Numas showing current back-links.
 *          The lut gives the current index (of the seed or the minima
 *          for the wshed  in which it is located.
 *      (2) Think of each entry in the lut.  There are two types:
 *             owner:     lut[index] = index
 *             redirect:  lut[index] != index
 *      (3) This is called each time a merge occurs.  It puts the lut
 *          and backlinks in a canonical form after the merge, where
 *          all entries in the lut point to the current "owner", which
 *          has all backlinks.  That is, every "redirect" in the lut
 *          points to an "owner".  The lut always gives the index of
 *          the current owner.
 */
static l_int32
mergeLookup(L_WSHED  *wshed,
            l_int32   sindex,
            l_int32   dindex)
{
l_int32   i, n, size, index;
l_int32  *lut;
NUMA     *na;
NUMA    **links;

    PROCNAME("mergeLookup");

    if (!wshed)
        return ERROR_INT("wshed not defined", procName, 1);
    size = wshed->arraysize;
    if (sindex < 0 || sindex >= size)
        return ERROR_INT("invalid sindex", procName, 1);
    if (dindex < 0 || dindex >= size)
        return ERROR_INT("invalid dindex", procName, 1);

        /* Redirect links in the lut */
    n = 0;
    links = wshed->links;
    lut = wshed->lut;
    if ((na = links[sindex]) != NULL) {
        n = numaGetCount(na);
        for (i = 0; i < n; i++) {
            numaGetIValue(na, i, &index);
            lut[index] = dindex;
        }
    }
    lut[sindex] = dindex;

        /* Shift the backlink arrays from sindex to dindex.
         * sindex should have no backlinks because all entries in the
         * lut that were previously pointing to it have been redirected
         * to dindex. */
    if (!links[dindex])
        links[dindex] = numaCreate(n);
    numaJoin(links[dindex], links[sindex], 0, -1);
    numaAddNumber(links[dindex], sindex);
    numaDestroy(&links[sindex]);

    return 0;
}
Пример #21
0
/*!
 *  kernelCreateFromString()
 *
 *      Input:  height, width
 *              cy, cx   (origin)
 *              kdata
 *      Return: kernel of the given size, or null on error
 *
 *  Notes:
 *      (1) The data is an array of chars, in row-major order, giving
 *          space separated integers in the range [-255 ... 255].
 *      (2) The only other formatting limitation is that you must
 *          leave space between the last number in each row and
 *          the double-quote.  If possible, it's also nice to have each
 *          line in the string represent a line in the kernel; e.g.,
 *              static const char *kdata =
 *                  " 20   50   20 "
 *                  " 70  140   70 "
 *                  " 20   50   20 ";
 */
L_KERNEL *
kernelCreateFromString(l_int32      h,
                       l_int32      w,
                       l_int32      cy,
                       l_int32      cx,
                       const char  *kdata)
{
l_int32    n, i, j, index;
l_float32  val;
L_KERNEL  *kel;
NUMA      *na;

    PROCNAME("kernelCreateFromString");

    if (h < 1)
        return (L_KERNEL *)ERROR_PTR("height must be > 0", procName, NULL);
    if (w < 1)
        return (L_KERNEL *)ERROR_PTR("width must be > 0", procName, NULL);
    if (cy < 0 || cy >= h)
        return (L_KERNEL *)ERROR_PTR("cy invalid", procName, NULL);
    if (cx < 0 || cx >= w)
        return (L_KERNEL *)ERROR_PTR("cx invalid", procName, NULL);

    kel = kernelCreate(h, w);
    kernelSetOrigin(kel, cy, cx);
    na = parseStringForNumbers(kdata, " \t\n");
    n = numaGetCount(na);
    if (n != w * h) {
        numaDestroy(&na);
	fprintf(stderr, "w = %d, h = %d, num ints = %d\n", w, h, n);
        return (L_KERNEL *)ERROR_PTR("invalid integer data", procName, NULL);
    }

    index = 0;
    for (i = 0; i < h; i++) {
        for (j = 0; j < w; j++) {
            numaGetFValue(na, index, &val);
            kernelSetElement(kel, i, j, val);
	    index++;
        }
    }

    numaDestroy(&na);
    return kel;
}
Пример #22
0
/*!
 * \brief   pixFindDifferentialSquareSum()
 *
 * \param[in]    pixs
 * \param[out]   psum  result
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) At the top and bottom, we skip:
 *           ~ at least one scanline
 *           ~ not more than 10% of the image height
 *           ~ not more than 5% of the image width
 * </pre>
 */
l_int32
pixFindDifferentialSquareSum(PIX        *pixs,
                             l_float32  *psum)
{
l_int32    i, n;
l_int32    w, h, skiph, skip, nskip;
l_float32  val1, val2, diff, sum;
NUMA      *na;

    PROCNAME("pixFindDifferentialSquareSum");

    if (!psum)
        return ERROR_INT("&sum not defined", procName, 1);
    *psum = 0.0;
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);

        /* Generate a number array consisting of the sum
         * of pixels in each row of pixs */
    if ((na = pixCountPixelsByRow(pixs, NULL)) == NULL)
        return ERROR_INT("na not made", procName, 1);

        /* Compute the number of rows at top and bottom to omit.
         * We omit these to avoid getting a spurious signal from
         * the top and bottom of a (nearly) all black image. */
    w = pixGetWidth(pixs);
    h = pixGetHeight(pixs);
    skiph = (l_int32)(0.05 * w);  /* skip for max shear of 0.025 radians */
    skip = L_MIN(h / 10, skiph);  /* don't remove more than 10% of image */
    nskip = L_MAX(skip / 2, 1);  /* at top & bot; skip at least one line */

        /* Sum the squares of differential row sums, on the
         * allowed rows.  Note that nskip must be >= 1. */
    n = numaGetCount(na);
    sum = 0.0;
    for (i = nskip; i < n - nskip; i++) {
        numaGetFValue(na, i - 1, &val1);
        numaGetFValue(na, i, &val2);
        diff = val2 - val1;
        sum += diff * diff;
    }
    numaDestroy(&na);
    *psum = sum;
    return 0;
}
Пример #23
0
/*!
 *  numaAddNumber()
 *
 *      Input:  na
 *              val  (float or int to be added; stored as a float)
 *      Return: 0 if OK, 1 on error
 */
l_int32
numaAddNumber(NUMA      *na,
              l_float32  val)
{
l_int32  n;

    PROCNAME("numaAddNumber");

    if (!na)
        return ERROR_INT("na not defined", procName, 1);

    n = numaGetCount(na);
    if (n >= na->nalloc)
        numaExtendArray(na);
    na->array[n] = val;
    na->n++;
    return 0;
}
Пример #24
0
/*!
 *  numaReplaceNumber()
 *
 *      Input:  na
 *              index (element to be replaced)
 *              val (new value to replace old one)
 *      Return: 0 if OK, 1 on error
 */
l_int32
numaReplaceNumber(NUMA      *na,
                  l_int32    index,
                  l_float32  val)
{
l_int32  n;

    PROCNAME("numaReplaceNumber");

    if (!na)
        return ERROR_INT("na not defined", procName, 1);
    n = numaGetCount(na);
    if (index < 0 || index >= n)
        return ERROR_INT("index not in {0...n - 1}", procName, 1);

    na->array[index] = val;
    return 0;
}
Пример #25
0
/*!
 *  pixaSort2dByIndex()
 * 
 *      Input:  pixas
 *              naa (numaa that maps from the new pixaa to the input pixas)
 *              copyflag (L_CLONE or L_COPY)
 *      Return: pixaa (sorted), or null on error
 */
PIXAA *
pixaSort2dByIndex(PIXA    *pixas,
                  NUMAA   *naa,
                  l_int32  copyflag)
{
l_int32  pixtot, ntot, i, j, n, nn, index;
BOX     *box;
NUMA    *na;
PIX     *pix;
PIXA    *pixa;
PIXAA   *pixaa;

    PROCNAME("pixaSort2dByIndex");

    if (!pixas)
        return (PIXAA *)ERROR_PTR("pixas not defined", procName, NULL);
    if (!naa)
        return (PIXAA *)ERROR_PTR("naindex not defined", procName, NULL);

        /* Check counts */
    ntot = numaaGetNumberCount(naa);
    pixtot = pixaGetCount(pixas);
    if (ntot != pixtot)
        return (PIXAA *)ERROR_PTR("element count mismatch", procName, NULL);

    n = numaaGetCount(naa);
    pixaa = pixaaCreate(n);
    for (i = 0; i < n; i++) {
        na = numaaGetNuma(naa, i, L_CLONE);
        nn = numaGetCount(na);
        pixa = pixaCreate(nn);
        for (j = 0; j < nn; j++) {
            numaGetIValue(na, j, &index);
            pix = pixaGetPix(pixas, index, copyflag);
            box = pixaGetBox(pixas, index, copyflag);
            pixaAddPix(pixa, pix, L_INSERT);
            pixaAddBox(pixa, box, L_INSERT);
        }
        pixaaAddPixa(pixaa, pixa, L_INSERT);
        numaDestroy(&na);
    }

    return pixaa;
}
Пример #26
0
/*!
 *  numaRemoveNumber()
 *
 *      Input:  na
 *              index (element to be removed)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This shifts na[i] --> na[i - 1] for all i > index.
 *      (2) It should not be used repeatedly on large arrays,
 *          because the function is O(n).
 */
l_int32
numaRemoveNumber(NUMA    *na,
                 l_int32  index)
{
l_int32  i, n;

    PROCNAME("numaRemoveNumber");

    if (!na)
        return ERROR_INT("na not defined", procName, 1);
    n = numaGetCount(na);
    if (index < 0 || index >= n)
        return ERROR_INT("index not in {0...n - 1}", procName, 1);

    for (i = index + 1; i < n; i++)
        na->array[i - 1] = na->array[i];
    na->n--;
    return 0;
}
Пример #27
0
int
register_mappings (const JBDATA * data, struct mapping **in_maps)
{
  int i;
  /* Register mappings for each component */
  l_int32 ncomp = numaGetCount (data->naclass);

  *in_maps = malloc_guarded (ncomp * sizeof (struct mapping));
  struct mapping *maps = *in_maps;
  for (i = 0; i < ncomp; i++)
    {
      maps[i].used = 0;
    }

  unsigned char code_point = first_code_point ();
  int font_num = 0;

  for (i = 0; i < data->nclass; i++)
    {
      l_int32 iclass = i;

      if (maps[iclass].used)
	continue;

      maps[iclass].iclass = iclass;
      maps[iclass].font_num = font_num;
      maps[iclass].code_point = code_point;
      maps[iclass].used = 1;

      if (code_point == max_code_point ())
	{
	  code_point = first_code_point ();
	  font_num++;
	}
      else
	{
	  code_point = next_code_point (code_point);
	}
    }
  printf ("%d fonts\n", font_num + 1);

  return font_num + 1;
}
Пример #28
0
/*!
 *  numaConvertToDna
 *
 *      Input:  na
 *      Return: da, or null on error
 */
L_DNA *
numaConvertToDna(NUMA  *na)
{
l_int32    i, n;
l_float32  val;
L_DNA     *da;

    PROCNAME("numaConvertToDna");

    if (!na)
        return (L_DNA *)ERROR_PTR("na not defined", procName, NULL);

    n = numaGetCount(na);
    da = l_dnaCreate(n);
    for (i = 0; i < n; i++) {
        numaGetFValue(na, i, &val);
        l_dnaAddNumber(da, val);
    }
    return da;
}
Пример #29
0
/*!
 *  numaaGetNumberCount()
 *
 *      Input:  naa
 *      Return: count (total number of numbers in the numaa),
 *                     or 0 if no numbers or on error
 */
l_int32
numaaGetNumberCount(NUMAA  *naa)
{
NUMA    *na;
l_int32  n, sum, i;

    PROCNAME("numaaGetNumberCount");

    if (!naa)
        return ERROR_INT("naa not defined", procName, 0);

    n = numaaGetCount(naa);
    for (sum = 0, i = 0; i < n; i++) {
        na = numaaGetNuma(naa, i, L_CLONE);
        sum += numaGetCount(na);
        numaDestroy(&na);
    }

    return sum;
}
Пример #30
0
/*!
 *  pixaSelectWithIndicator()
 *
 *      Input:  pixas
 *              na (indicator numa)
 *              &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) The indicator numa has values 0 (ignore) and 1 (accept).
 */
PIXA *
pixaSelectWithIndicator(PIXA     *pixas,
                        NUMA     *na,
                        l_int32  *pchanged)
{
l_int32  i, n, ival, nsave;
BOX     *box;
PIX     *pixt;
PIXA    *pixad;

    PROCNAME("pixaSelectWithIndicator");

    if (!pixas)
        return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
    if (!na)
        return (PIXA *)ERROR_PTR("na not defined", procName, NULL);

    nsave = 0;
    n = numaGetCount(na);
    for (i = 0; i < n; i++) {
        numaGetIValue(na, i, &ival);
        if (ival == 1) nsave++;
    }

    if (nsave == n) {
        if (pchanged) *pchanged = FALSE;
        return pixaCopy(pixas, L_CLONE);
    }
    if (pchanged) *pchanged = TRUE;
    pixad = pixaCreate(nsave);
    for (i = 0; i < n; i++) {
        numaGetIValue(na, i, &ival);
        if (ival == 0) continue;
        pixt = pixaGetPix(pixas, i, L_CLONE);
        box = pixaGetBox(pixas, i, L_CLONE);
        pixaAddPix(pixad, pixt, L_INSERT);
        pixaAddBox(pixad, box, L_INSERT);
    }

    return pixad;
}