/*!
 *  recogCreate()
 *
 *      Input:  scalew  (scale all widths to this; use 0 for no scaling)
 *              scaleh  (scale all heights to this; use 0 for no scaling)
 *              templ_type (L_USE_AVERAGE or L_USE_ALL)
 *              threshold (for binarization; typically ~128)
 *              maxyshift (from nominal centroid alignment; typically 0 or 1)
 *      Return: recog, or null on error
 *
 *  Notes:
 *      (1) For a set trained on one font, such as numbers in a book,
 *          it is sensible to set scalew = scaleh = 0.
 *      (2) For a mixed training set, scaling to a fixed height,
 *          such as 32 pixels, but leaving the width unscaled, is effective.
 *      (3) The storage for most of the arrays is allocated when training
 *          is finished.
 */
L_RECOG *
recogCreate(l_int32      scalew,
            l_int32      scaleh,
            l_int32      templ_type,
            l_int32      threshold,
            l_int32      maxyshift)
{
L_RECOG  *recog;
PIXA     *pixa;
PIXAA    *paa;

    PROCNAME("recogCreate");

    if (scalew < 0 || scaleh < 0)
        return (L_RECOG *)ERROR_PTR("invalid scalew or scaleh", procName, NULL);
    if (templ_type != L_USE_AVERAGE && templ_type != L_USE_ALL)
        return (L_RECOG *)ERROR_PTR("invalid templ_type flag", procName, NULL);
    if (threshold < 1 || threshold > 255)
        return (L_RECOG *)ERROR_PTR("invalid threshold", procName, NULL);

    if ((recog = (L_RECOG *)CALLOC(1, sizeof(L_RECOG))) == NULL)
        return (L_RECOG *)ERROR_PTR("rec not made", procName, NULL);
    recog->templ_type = templ_type;
    recog->threshold = threshold;
    recog->scalew = scalew;
    recog->scaleh = scaleh;
    recog->maxyshift = maxyshift;
    recog->asperity_fr = DEFAULT_ASPERITY_FRACT;
    recogSetPadParams(recog, NULL, NULL, NULL, -1, -1, -1);
    recog->bmf = bmfCreate(NULL, 6);
    recog->bmf_size = 6;
    recog->maxarraysize = MAX_EXAMPLES_IN_CLASS;
    recog->index = -1;

        /* Generate the LUTs */
    recog->centtab = makePixelCentroidTab8();
    recog->sumtab = makePixelSumTab8();
    recog->sa_text = sarrayCreate(0);
    recog->dna_tochar = l_dnaCreate(0);

        /* Input default values for min component size for splitting.
         * These are overwritten when pixTrainingFinished() is called. */
    recog->min_splitw = 6;
    recog->min_splith = 6;
    recog->max_splith = 60;

        /* Generate the storage for the unscaled training bitmaps */
    paa = pixaaCreate(recog->maxarraysize);
    pixa = pixaCreate(1);
    pixaaInitFull(paa, pixa);
    pixaDestroy(&pixa);
    recog->pixaa_u = paa;

        /* Generate the storage for debugging */
    recog->pixadb_boot = pixaCreate(2);
    recog->pixadb_split = pixaCreate(2);
    return recog;
}
/*!
 *  pixaaCreateFromPixa()
 *
 *      Input:  pixa
 *              n (number specifying subdivision of pixa)
 *              type (L_CHOOSE_CONSECUTIVE, L_CHOOSE_SKIP_BY)
 *              copyflag (L_CLONE, L_COPY)
 *      Return: pixaa, or null on error
 *
 *  Notes:
 *      (1) This subdivides a pixa into a set of smaller pixa that
 *          are accumulated into a pixaa.
 *      (2) If type == L_CHOOSE_CONSECUTIVE, the first 'n' pix are
 *          put in a pixa and added to pixaa, then the next 'n', etc.
 *          If type == L_CHOOSE_SKIP_BY, the first pixa is made by
 *          aggregating pix[0], pix[n], pix[2*n], etc.
 *      (3) The copyflag specifies if each new pix is a copy or a clone.
 */
PIXAA *
pixaaCreateFromPixa(PIXA    *pixa,
                    l_int32  n,
                    l_int32  type,
                    l_int32  copyflag)
{
l_int32  count, i, j, npixa;
PIX     *pix;
PIXA    *pixat;
PIXAA   *pixaa;

    PROCNAME("pixaaCreateFromPixa");

    if (!pixa)
        return (PIXAA *)ERROR_PTR("pixa not defined", procName, NULL);
    count = pixaGetCount(pixa);
    if (count == 0)
        return (PIXAA *)ERROR_PTR("no pix in pixa", procName, NULL);
    if (n <= 0)
        return (PIXAA *)ERROR_PTR("n must be > 0", procName, NULL);
    if (type != L_CHOOSE_CONSECUTIVE && type != L_CHOOSE_SKIP_BY)
        return (PIXAA *)ERROR_PTR("invalid type", procName, NULL);
    if (copyflag != L_CLONE && copyflag != L_COPY)
        return (PIXAA *)ERROR_PTR("invalid copyflag", procName, NULL);

    if (type == L_CHOOSE_CONSECUTIVE)
        npixa = (count + n - 1) / n;
    else  /* L_CHOOSE_SKIP_BY */
        npixa = L_MIN(n, count);
    pixaa = pixaaCreate(npixa);
    if (type == L_CHOOSE_CONSECUTIVE) {
        for (i = 0; i < count; i++) {
            if (i % n == 0)
                pixat = pixaCreate(n);
            pix = pixaGetPix(pixa, i, copyflag);
            pixaAddPix(pixat, pix, L_INSERT);
            if (i % n == n - 1)
                pixaaAddPixa(pixaa, pixat, L_INSERT);
        }
        if (i % n != 0)
            pixaaAddPixa(pixaa, pixat, L_INSERT);
    }
    else {  /* L_CHOOSE_SKIP_BY */
        for (i = 0; i < npixa; i++) {
            pixat = pixaCreate(count / npixa + 1);
            for (j = i; j < count; j += n) {
                pix = pixaGetPix(pixa, j, copyflag);
                pixaAddPix(pixat, pix, L_INSERT);
            }
            pixaaAddPixa(pixaa, pixat, L_INSERT);
        }
    }

    return pixaa;
}
int main(int    argc,
         char **argv)
{
PIX          *pixs, *pixd;
PIXA         *pixa;
L_REGPARAMS  *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    pixs = pixRead("stampede2.jpg");
    pixa = pixaCreate(0);
    pixSaveTiled(pixs, pixa, 1.0, 1, 20, 8);

    AddTestSet(pixa, pixs, L_SOBEL_EDGE, 18, 40, 40, 0.7, -25, 280, 128);
    AddTestSet(pixa, pixs, L_TWO_SIDED_EDGE, 18, 40, 40, 0.7, -25, 280, 128);
    AddTestSet(pixa, pixs, L_SOBEL_EDGE, 10, 40, 40, 0.7, -15, 305, 128);
    AddTestSet(pixa, pixs, L_TWO_SIDED_EDGE, 10, 40, 40, 0.7, -15, 305, 128);
    AddTestSet(pixa, pixs, L_SOBEL_EDGE, 15, 40, 40, 0.6, -45, 285, 158);
    AddTestSet(pixa, pixs, L_TWO_SIDED_EDGE, 15, 40, 40, 0.6, -45, 285, 158);

    pixDestroy(&pixs);
    pixd = pixaDisplay(pixa, 0, 0);
    regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG);  /* 0 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);

    pixDestroy(&pixd);
    pixaDestroy(&pixa);
    return regTestCleanup(rp);
}
Beispiel #4
0
void
AddTransformsYUV(PIXA    *pixa,
                 L_BMF   *bmf,
                 l_int32  yval)
{
char       textbuf[256];
l_int32    i, j, wpls;
l_uint32  *datas, *lines;
PIX       *pixs, *pixt1, *pixt2, *pixt3, *pixt4;
PIXA      *pixat;

    pixs = pixCreate(225, 225, 32);
    wpls = pixGetWpl(pixs);
    datas = pixGetData(pixs);
    for (i = 0; i < 225; i++) {   /* v */
        lines = datas + i * wpls;
        for (j = 0; j < 225; j++)  /* u */
            composeRGBPixel(yval + 16, j + 16, i + 16, lines + j);
    }

    pixat = pixaCreate(3);
    pixaAddPix(pixat, pixs, L_INSERT);
    pixt1 = pixConvertYUVToRGB(NULL, pixs);
    pixaAddPix(pixat, pixt1, L_INSERT);
    pixt2 = pixConvertRGBToYUV(NULL, pixt1);
    pixaAddPix(pixat, pixt2, L_INSERT);
    pixt3 = pixaDisplayTiledAndScaled(pixat, 32, 225, 3, 0, 20, 2);
    snprintf(textbuf, sizeof(textbuf), "yval = %d", yval);
    pixt4 = pixAddSingleTextblock(pixt3, bmf, textbuf, 0xff000000,
                                  L_ADD_BELOW, NULL);
    pixaAddPix(pixa, pixt4, L_INSERT);
    pixDestroy(&pixt3);
    pixaDestroy(&pixat);
    return;
}
Beispiel #5
0
/*!
 *  pixaReadFilesSA()
 *
 *      Input:  sarray (full pathnames for all files)
 *      Return: pixa, or null on error
 */
PIXA *
pixaReadFilesSA(SARRAY  *sa)
{
char    *str;
l_int32  i, n;
PIX     *pix;
PIXA    *pixa;

    PROCNAME("pixaReadFilesSA");

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

    n = sarrayGetCount(sa);
    pixa = pixaCreate(n);
    for (i = 0; i < n; i++) {
        str = sarrayGetString(sa, i, L_NOCOPY);
        if ((pix = pixRead(str)) == NULL) {
            L_WARNING("pix not read from file %s\n", procName, str);
            continue;
        }
        pixaAddPix(pixa, pix, L_INSERT);
    }

    return pixa;
}
Beispiel #6
0
main(int    argc,
     char **argv)
{
l_int32  i;
PIX     *pix;
PIXA    *pixa;

    for (i = 0; i < NTests; i++)
        GenerateSplitPlot(i);

       /* Read the results back in ...  */
    pixa = pixaCreate(0);
    for (i = 0; i < NTests; i++) {
        sprintf(buf, "/tmp/junkplot.%d.png", i);
	pix = pixRead(buf);
	pixSaveTiled(pix, pixa, 1, 1, 25, 32);
	pixDestroy(&pix);
        sprintf(buf, "/tmp/junkplots.%d.png", i);
	pix = pixRead(buf);
	pixSaveTiled(pix, pixa, 1, 0, 25, 32);
	pixDestroy(&pix);
    }

        /* ... and save into a tiled pix  */
    pix = pixaDisplay(pixa, 0, 0);
    pixWrite("/tmp/junkotsuplot.png", pix, IFF_PNG);
    pixDisplay(pix, 100, 100);
    pixaDestroy(&pixa);
    pixDestroy(&pix);
    return 0;
}
Beispiel #7
0
static void
GetImageMask(PIX         *pixs,
             l_int32      res,
             BOXA       **pboxa,
             const char  *debugfile)
{
PIX   *pix1, *pix2, *pix3, *pix4;
PIXA  *pixa;

    pixSetResolution(pixs, 200, 200);
    pix1 = pixConvertTo1(pixs, 100);
    pix2 = pixGenerateHalftoneMask(pix1, NULL, NULL, NULL);
    pix3 = pixMorphSequence(pix2, "c20.1 + c1.20", 0);
    *pboxa = pixConnComp(pix3, NULL, 8);
    if (debugfile) {
        pixa = pixaCreate(0);
        pixaAddPix(pixa, pixs, L_COPY);
        pixaAddPix(pixa, pix1, L_INSERT);
        pixaAddPix(pixa, pix2, L_INSERT);
        pixaAddPix(pixa, pix3, L_INSERT);
        pix4 = pixaDisplayTiledInRows(pixa, 32, 1800, 0.25, 0, 25, 2);
        pixWrite(debugfile, pix4, IFF_JFIF_JPEG);
        pixDisplay(pix4, 100, 100);
        pixDestroy(&pix4);
        pixaDestroy(&pixa);
    } else {
        pixDestroy(&pix1);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }

    return;
}
Beispiel #8
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;
}
Beispiel #9
0
/*!
 *  pixaSortByIndex()
 * 
 *      Input:  pixas
 *              naindex (na that maps from the new pixa to the input pixa)
 *              copyflag (L_COPY, L_CLONE)
 *      Return: pixad (sorted), or null on error
 */
PIXA *
pixaSortByIndex(PIXA    *pixas,
                NUMA    *naindex,
                l_int32  copyflag)
{
l_int32  i, n, index;
BOX     *box;
PIX     *pix;
PIXA    *pixad;

    PROCNAME("pixaSortByIndex");

    if (!pixas)
        return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
    if (!naindex)
        return (PIXA *)ERROR_PTR("naindex not defined", procName, NULL);
    if (copyflag != L_CLONE && copyflag != L_COPY)
        return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);

    n = pixaGetCount(pixas);
    pixad = pixaCreate(n);
    for (i = 0; i < n; i++) {
        numaGetIValue(naindex, i, &index);
        pix = pixaGetPix(pixas, index, copyflag);
        box = pixaGetBox(pixas, index, copyflag);
        pixaAddPix(pixad, pix, L_INSERT);
        pixaAddBox(pixad, box, L_INSERT);
    }

    return pixad;
}
Beispiel #10
0
/*!
 * \brief   pixaSetStrokeWidth()
 *
 * \param[in]   pixas  of 1 bpp pix
 * \param[in]   width  set stroke width to this value, in [1 ... 100].
 * \param[in]   thinfirst  1 to thin all pix to a skeleton first; 0 to skip
 * \param[in]   connectivity  4 or 8, to be used if %thinfirst == 1
 * \return  pixa  with all stroke widths being %width, or NULL on error
 *
 * <pre>
 * Notes:
 *      (1) If %thinfirst == 1, thin to a skeleton using the specified
 *          %connectivity.  Use %thinfirst == 0 if all pix in pixas
 *          have already been thinned as far as possible.
 *      (2) The image is dilated to the required %width.  This dilation
 *          is not connectivity preserving, so this is typically
 *          used in a situation where merging of c.c. in the individual
 *          pix is not a problem; e.g., where each pix is a single c.c.
 * </pre>
 */
PIXA *
pixaSetStrokeWidth(PIXA    *pixas,
                   l_int32  width,
                   l_int32  thinfirst,
                   l_int32  connectivity)
{
l_int32  i, n, maxd, same;
PIX     *pix1, *pix2;
PIXA    *pixad;

    PROCNAME("pixaSetStrokeWidth");

    if (!pixas)
        return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
    if (width < 1 || width > 100)
        return (PIXA *)ERROR_PTR("width not in [1 ... 100]", procName, NULL);
    if (connectivity != 4 && connectivity != 8)
        return (PIXA *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
    pixaVerifyDepth(pixas, &same, &maxd);
    if (maxd > 1)
        return (PIXA *)ERROR_PTR("pix are not all 1 bpp", procName, NULL);

    n = pixaGetCount(pixas);
    pixad = pixaCreate(n);
    for (i = 0; i < n; i++) {
        pix1 = pixaGetPix(pixas, i, L_CLONE);
        pix2 = pixSetStrokeWidth(pix1, width, thinfirst, connectivity);
        pixaAddPix(pixad, pix2, L_INSERT);
        pixDestroy(&pix1);
    }

    return pixad;
}
Beispiel #11
0
    /* Reconstruction without compaction */
static PIXA *
ReconstructPixa1(L_PTRA  *papix,
                 L_PTRA  *pabox)
{
l_int32  i, imax, nactual;
BOX     *box;
PIX     *pix;
PIXA    *pixat;

    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "Before removal:  imax = %4d, actual = %4d\n",
            imax, nactual);

    pixat = pixaCreate(imax + 1);
    for (i = 0; i <= imax; i++) {
        pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
        box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
        if (pix) pixaAddPix(pixat, pix, L_INSERT);
        if (box) pixaAddBox(pixat, box, L_INSERT);
    }

    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "After removal:   imax = %4d, actual = %4d\n\n",
            imax, nactual);

    return pixat;
}
static PIXA *
PixSavePlots1(void)
{
PIX    *pixt;
PIXA   *pixa;

    pixa = pixaCreate(8);
    pixt = pixRead("/tmp/rtnan.png");
    pixSaveTiled(pixt, pixa, 1, 1, 20, 8);
    pixDestroy(&pixt);
    pixt = pixRead("/tmp/rtnar.png");
    pixSaveTiled(pixt, pixa, 1, 0, 20, 8);
    pixDestroy(&pixt);
    pixt = pixRead("/tmp/rtnai.png");
    pixSaveTiled(pixt, pixa, 1, 0, 20, 8);
    pixDestroy(&pixt);
    pixt = pixRead("/tmp/rtnarbin.png");
    pixSaveTiled(pixt, pixa, 1, 1, 20, 8);
    pixDestroy(&pixt);
    pixt = pixRead("/tmp/rtnabb.png");
    pixSaveTiled(pixt, pixa, 1, 0, 20, 8);
    pixDestroy(&pixt);
    pixt = pixRead("/tmp/rtnared.png");
    pixSaveTiled(pixt, pixa, 1, 1, 20, 8);
    pixDestroy(&pixt);
    pixt = pixRead("/tmp/rtnagreen.png");
    pixSaveTiled(pixt, pixa, 1, 0, 20, 8);
    pixDestroy(&pixt);
    pixt = pixRead("/tmp/rtnablue.png");
    pixSaveTiled(pixt, pixa, 1, 0, 20, 8);
    pixDestroy(&pixt);
    return pixa;
}
Beispiel #13
0
void
CopyStoreClean(PIXA    *pixas,
               l_int32  nlevels,
               l_int32  ncopies)
{
l_int32  i, j;
PIX     *pix, *pixt;
PIXA    *pixa;
PIXAA   *paa;

    paa = pixaaCreate(0);
    for (i = 0; i < nlevels ; i++) {
        pixa = pixaCreate(0);
        pixaaAddPixa(paa, pixa, L_INSERT);
        pix = pixaGetPix(pixas, i, L_CLONE);
        for (j = 0; j < ncopies; j++) {
            pixt = pixCopy(NULL, pix);
            pixaAddPix(pixa, pixt, L_INSERT);
        }
        pixDestroy(&pix);
    }
    pixaaDestroy(&paa);

    return;
}
Beispiel #14
0
/*!
 *  pixaClipToPix()
 *
 *      Input:  pixas
 *              pixs
 *      Return: pixad, or null on error
 *
 *  Notes:
 *      (1) This is intended for use in situations where pixas
 *          was originally generated from the input pixs.
 *      (2) Returns a pixad where each pix in pixas is ANDed
 *          with its associated region of the input pixs.  This
 *          region is specified by the the box that is associated
 *          with the pix.
 *      (3) In a typical application of this function, pixas has
 *          a set of region masks, so this generates a pixa of
 *          the parts of pixs that correspond to each region
 *          mask component, along with the bounding box for
 *          the region.
 */
PIXA *
pixaClipToPix(PIXA  *pixas,
              PIX   *pixs)
{
l_int32  i, n;
BOX     *box;
PIX     *pix, *pixc;
PIXA    *pixad;

    PROCNAME("pixaClipToPix");

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

    n = pixaGetCount(pixas);
    if ((pixad = pixaCreate(n)) == NULL)
        return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);

    for (i = 0; i < n; i++) {
        pix = pixaGetPix(pixas, i, L_CLONE);
        box = pixaGetBox(pixas, i, L_COPY);
        pixc = pixClipRectangle(pixs, box, NULL);
        pixAnd(pixc, pixc, pix);
        pixaAddPix(pixad, pixc, L_INSERT);
        pixaAddBox(pixad, box, L_INSERT);
        pixDestroy(&pix);
    }

    return pixad;
}
Beispiel #15
0
main(int    argc,
     char **argv)
{
l_int32      w;
PIX         *pixs, *pixt, *pixd;
PIXA        *pixa;
static char  mainName[] = "smoothedge_reg";

    pixs = pixRead("raggededge.png");
    w = pixGetWidth(pixs);
    pixa = pixaCreate(0);
    PixAddEdgeData(pixa, pixs, L_FROM_RIGHT, MIN_JUMP, MIN_REVERSAL);
    PixAddEdgeData(pixa, pixs, L_FROM_LEFT, MIN_JUMP, MIN_REVERSAL);
    pixt = pixRotateOrth(pixs, 1);
    PixAddEdgeData(pixa, pixt, L_FROM_BOTTOM, MIN_JUMP, MIN_REVERSAL);
    PixAddEdgeData(pixa, pixt, L_FROM_TOP, MIN_JUMP, MIN_REVERSAL);
    pixDestroy(&pixt);
    pixt = pixRotateOrth(pixs, 2);
    PixAddEdgeData(pixa, pixt, L_FROM_LEFT, MIN_JUMP, MIN_REVERSAL);
    PixAddEdgeData(pixa, pixt, L_FROM_RIGHT, MIN_JUMP, MIN_REVERSAL);
    pixDestroy(&pixt);
    pixt = pixRotateOrth(pixs, 3);
    PixAddEdgeData(pixa, pixt, L_FROM_TOP, MIN_JUMP, MIN_REVERSAL);
    PixAddEdgeData(pixa, pixt, L_FROM_BOTTOM, MIN_JUMP, MIN_REVERSAL);
    pixDestroy(&pixt);
    pixDestroy(&pixs);

        /* Display at 2x scaling */
    pixd = pixaDisplayTiledAndScaled(pixa, 32, 2 * (w + 10), 2, 0, 25, 2);
    pixWrite("/tmp/junkpixd.png", pixd, IFF_PNG);
    pixDestroy(&pixd);
    pixaDestroy(&pixa);
    return 0;
}
Beispiel #16
0
int main(int    argc,
         char **argv)
{
l_float32    fcolor;
PIX         *pix1, *pix2, *pix3, *pix4;
PIXA        *pixadb;
static char  mainName[] = "find_colorregions";

    lept_mkdir("lept/color");
    pix1 = pixRead("colorpage.030.jpg");
/*    pix1 = pixRead("map.057.jpg"); */

        /* More general method */
    pixadb = pixaCreate(0);
    pixFindColorRegions(pix1, NULL, 4, 200, 60, 10, 90, 0.05,
                        &fcolor, &pix3, &pix4, pixadb);
    fprintf(stderr, "ncolor = %f\n", fcolor);
    if (pix3) pixDisplay(pix3, 0, 800);
    if (pix4) pixDisplay(pix4, 600, 800);

    pix2 = pixaDisplayTiledInColumns(pixadb, 5, 0.3, 20, 2);
    pixDisplay(pix2, 0, 0);
    pixWrite("/tmp/lept/color/result1.png", pix2, IFF_PNG);
    pixDestroy(&pix2);
    pixDestroy(&pix3);
    pixDestroy(&pix4);
    pixaDestroy(&pixadb);

        /* Method for pages with very light background */
    pixadb = pixaCreate(0);
    pixFindColorRegionsLight(pix1, NULL, 4, 60, 230, 40, 20,
                             &fcolor, &pix3, &pix4, pixadb);
    fprintf(stderr, "ncolor = %f\n", fcolor);
    if (pix3) pixDisplay(pix3, 1100, 800);
    if (pix4) pixDisplay(pix4, 1700, 800);

    pix2 = pixaDisplayTiledInColumns(pixadb, 5, 0.3, 20, 2);
    pixDisplay(pix2, 1100, 0);
    pixWrite("/tmp/lept/color/result2.png", pix2, IFF_PNG);
    pixDestroy(&pix2);
    pixDestroy(&pix3);
    pixDestroy(&pix4);
    pixaDestroy(&pixadb);

    pixDestroy(&pix1);
    return 0;
}
Beispiel #17
0
    /* Reconstruction with compaction */
static PIXA *
ReconstructPixa2(L_PTRA  *papix,
                 L_PTRA  *pabox)
{
l_int32  i, imax, nactual;
BOX     *box;
PIX     *pix;
PIXA    *pixat;

    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "Before removal:    imax = %4d, actual = %4d\n",
            imax, nactual);

        /* Remove half */
    pixat = pixaCreate(imax + 1);
    for (i = 0; i <= imax; i++) {
        if (i % 2 == 0) {
            pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
            box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
            if (pix) pixaAddPix(pixat, pix, L_INSERT);
            if (box) pixaAddBox(pixat, box, L_INSERT);
        }
    }

        /* Compact */
    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "Before compaction: imax = %4d, actual = %4d\n",
            imax, nactual);
    ptraCompactArray(papix);
    ptraCompactArray(pabox);
    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "After compaction:  imax = %4d, actual = %4d\n",
            imax, nactual);

        /* Remove the rest (and test compaction with removal) */
    while (1) {
        ptraGetActualCount(papix, &nactual);
        if (nactual == 0) break;

        pix = (PIX *)ptraRemove(papix, 0, L_COMPACTION);
        box = (BOX *)ptraRemove(pabox, 0, L_COMPACTION);
        pixaAddPix(pixat, pix, L_INSERT);
        pixaAddBox(pixat, box, L_INSERT);
    }

    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "After removal:     imax = %4d, actual = %4d\n\n",
            imax, nactual);

    return pixat;
}
Beispiel #18
0
/*!
 *  pixaAddBorderGeneral()
 *
 *      Input:  pixad (can be null or equal to pixas)
 *              pixas (containing pix of all depths; colormap ok)
 *              left, right, top, bot  (number of pixels added)
 *              val   (value of added border pixels)
 *      Return: pixad (with border added to each pix), including on error
 *
 *  Notes:
 *      (1) For binary images:
 *             white:  val = 0
 *             black:  val = 1
 *          For grayscale images:
 *             white:  val = 2 ** d - 1
 *             black:  val = 0
 *          For rgb color images:
 *             white:  val = 0xffffff00
 *             black:  val = 0
 *          For colormapped images, use 'index' found this way:
 *             white: pixcmapGetRankIntensity(cmap, 1.0, &index);
 *             black: pixcmapGetRankIntensity(cmap, 0.0, &index);
 *      (2) For in-place replacement of each pix with a bordered version,
 *          use @pixad = @pixas.  To make a new pixa, use @pixad = NULL.
 *      (3) In both cases, the boxa has sides adjusted as if it were
 *          expanded by the border.
 */
PIXA *
pixaAddBorderGeneral(PIXA     *pixad,
                     PIXA     *pixas,
                     l_int32   left,
                     l_int32   right,
                     l_int32   top,
                     l_int32   bot,
                     l_uint32  val)
{
l_int32  i, n, nbox;
BOX     *box;
BOXA    *boxad;
PIX     *pixs, *pixd;

    PROCNAME("pixaAddBorderGeneral");

    if (!pixas)
        return (PIXA *)ERROR_PTR("pixas not defined", procName, pixad);
    if (left < 0 || right < 0 || top < 0 || bot < 0)
        return (PIXA *)ERROR_PTR("negative border added!", procName, pixad);
    if (pixad && (pixad != pixas))
        return (PIXA *)ERROR_PTR("pixad defined but != pixas", procName, pixad);

    n = pixaGetCount(pixas);
    if (!pixad)
        pixad = pixaCreate(n);
    for (i = 0; i < n; i++) {
        pixs = pixaGetPix(pixas, i, L_CLONE);
        pixd = pixAddBorderGeneral(pixs, left, right, top, bot, val);
        if (pixad == pixas)  /* replace */
            pixaReplacePix(pixad, i, pixd, NULL);
        else
            pixaAddPix(pixad, pixd, L_INSERT);
        pixDestroy(&pixs);
    }

    nbox = pixaGetBoxaCount(pixas);
    boxad = pixaGetBoxa(pixad, L_CLONE);
    for (i = 0; i < nbox; i++) {
        if ((box = pixaGetBox(pixas, i, L_COPY)) == NULL) {
            L_WARNING_INT("box %d not found", procName, i);
            break;
        }
        boxAdjustSides(box, box, -left, right, -top, bot);
        if (pixad == pixas)  /* replace */
            boxaReplaceBox(boxad, i, box);
        else
            boxaAddBox(boxad, box, L_INSERT);
    }
    boxaDestroy(&boxad);

    return pixad;
}
Beispiel #19
0
void static
PlotBoxa(L_REGPARAMS  *rp,
         l_int32       index)
{
BOXA  *boxa1, *boxa2;
PIX   *pix1, *pix2, *pix3;
PIXA  *pixa;

    boxa1 = boxaRead(boxafiles[index]);

        /* Read and display initial boxa */
    boxaPlotSizes(boxa1, NULL, NULL, NULL, &pix1);
    boxaPlotSides(boxa1, NULL, NULL, NULL, NULL, NULL, &pix2);
    pixa = pixaCreate(2);
    pixaAddPix(pixa, pix1, L_INSERT);
    pixaAddPix(pixa, pix2, L_INSERT);
    pix3 = pixaDisplayTiledInColumns(pixa, 2, 1.0, 20, 2);
    regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 39, 41, 43 */
    pixDisplayWithTitle(pix3, 0 + 800 * index, 500, NULL, rp->display);
    pixDestroy(&pix3);
    pixaDestroy(&pixa);

        /* Read and display reconciled boxa */
    boxa2 = boxaReconcileSizeByMedian(boxa1, L_CHECK_BOTH, 0.05, 0.04, 1.03,
                                      NULL, NULL, NULL);
    boxaPlotSizes(boxa2, NULL, NULL, NULL, &pix1);
    boxaPlotSides(boxa2, NULL, NULL, NULL, NULL, NULL, &pix2);
    pixa = pixaCreate(2);
    pixaAddPix(pixa, pix1, L_INSERT);
    pixaAddPix(pixa, pix2, L_INSERT);
    pix3 = pixaDisplayTiledInColumns(pixa, 2, 1.0, 20, 2);
    regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 40, 42, 44 */
    pixDisplayWithTitle(pix3, 0 + 800 * index, 920, NULL, rp->display);
    pixDestroy(&pix3);
    pixaDestroy(&pixa);
    boxaDestroy(&boxa1);
    boxaDestroy(&boxa2);
}
Beispiel #20
0
main(int    argc,
     char **argv)
{
    l_int32       i, k, x, y, w, h;
    BOX          *box;
    BOXA         *boxa1, *boxa2;
    PIX          *pix1, *pix2, *pixd;
    PIXA         *pixa;
    L_REGPARAMS  *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    for (k = 0; k < 7; k++) {
        srand(45617);
        pixa = pixaCreate(2);
        boxa1 = boxaCreate(0);
        for (i = 0; i < 500; i++) {
            x = (l_int32)(600.0 * (l_float64)rand() / (l_float64)RAND_MAX);
            y = (l_int32)(600.0 * (l_float64)rand() / (l_float64)RAND_MAX);
            w = (l_int32)
                (1.0 + maxsize[k] * (l_float64)rand() / (l_float64)RAND_MAX);
            h = (l_int32)
                (1.0 + maxsize[k] * (l_float64)rand() / (l_float64)RAND_MAX);
            box = boxCreate(x, y, w, h);
            boxaAddBox(boxa1, box, L_INSERT);
        }

        pix1 = pixCreate(660, 660, 1);
        pixRenderBoxa(pix1, boxa1, 1, L_SET_PIXELS);
        pixaAddPix(pixa, pix1, L_INSERT);
        boxa2 = boxaCombineOverlaps(boxa1);
        pix2 = pixCreate(660, 660, 1);
        pixRenderBoxa(pix2, boxa2, 1, L_SET_PIXELS);
        pixaAddPix(pixa, pix2, L_INSERT);

        pixd = pixaDisplayTiledInRows(pixa, 1, 1500, 1.0, 0, 50, 2);
        pixDisplayWithTitle(pixd, 100, 100 + 100 * k, NULL, rp->display);
        regTestWritePixAndCheck(rp, pixd, IFF_PNG);
        fprintf(stderr, "%d: n_init = %d, n_final = %d\n",
                k, boxaGetCount(boxa1), boxaGetCount(boxa2));
        pixDestroy(&pixd);
        boxaDestroy(&boxa1);
        boxaDestroy(&boxa2);
        pixaDestroy(&pixa);
    }

    regTestCleanup(rp);
    return 0;
}
/*!
 *  pixaCreateFromBoxa()
 *
 *      Input:  pixs
 *              boxa
 *              &cropwarn (<optional return> TRUE if the boxa extent
 *                         is larger than pixs.
 *      Return: pixad, or null on error
 *
 *  Notes:
 *      (1) This simply extracts from pixs the region corresponding to each
 *          box in the boxa.
 *      (2) The 3rd arg is optional.  If the extent of the boxa exceeds the
 *          size of the pixa, so that some boxes are either clipped
 *          or entirely outside the pix, a warning is returned as TRUE.
 *      (3) pixad will have only the properly clipped elements, and
 *          the internal boxa will be correct.
 */
PIXA *
pixaCreateFromBoxa(PIX      *pixs,
                   BOXA     *boxa,
                   l_int32  *pcropwarn)
{
l_int32  i, n, w, h, wbox, hbox, cropwarn;
BOX     *box, *boxc;
PIX     *pixd;
PIXA    *pixad;

    PROCNAME("pixaCreateFromBoxa");

    if (!pixs)
        return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
    if (!boxa)
        return (PIXA *)ERROR_PTR("boxa not defined", procName, NULL);

    n = boxaGetCount(boxa);
    if ((pixad = pixaCreate(n)) == NULL)
        return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);

    boxaGetExtent(boxa, &wbox, &hbox, NULL);
    pixGetDimensions(pixs, &w, &h, NULL);
    cropwarn = FALSE;
    if (wbox > w || hbox > h)
        cropwarn = TRUE;
    if (pcropwarn)
        *pcropwarn = cropwarn;

    for (i = 0; i < n; i++) {
        box = boxaGetBox(boxa, i, L_COPY);
        if (cropwarn) {  /* if box is outside pixs, pixd is NULL */
            pixd = pixClipRectangle(pixs, box, &boxc);  /* may be NULL */
            if (pixd) {
                pixaAddPix(pixad, pixd, L_INSERT);
                pixaAddBox(pixad, boxc, L_INSERT);
            }
            boxDestroy(&box);
        }
        else {
            pixd = pixClipRectangle(pixs, box, NULL);
            pixaAddPix(pixad, pixd, L_INSERT);
            pixaAddBox(pixad, box, L_INSERT);
        }
    }

    return pixad;
}
main(int    argc,
     char **argv)
{
char          buf[256];
l_int32       i, j, k, index, conn, depth, bc;
BOX          *box;
PIX          *pix, *pixs, *pixd;
PIXA         *pixa;
L_REGPARAMS  *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    pix = pixRead("feyn.tif");
    box = boxCreate(383, 338, 1480, 1050);
    pixs = pixClipRectangle(pix, box, NULL);
    regTestWritePixAndCheck(rp, pixs, IFF_PNG);  /* 0 */
	    
    for (i = 0; i < 2; i++) {
        conn = 4 + 4 * i;
        for (j = 0; j < 2; j++) {
            depth = 8 + 8 * j;
            for (k = 0; k < 2; k++) {
                bc = k + 1;
                index = 4 * i + 2 * j + k;
                fprintf(stderr, "Set %d\n", index);
                if (DEBUG) {
                    fprintf(stderr, "%d: conn = %d, depth = %d, bc = %d\n",
                            rp->index + 1, conn, depth, bc);
                }
                pixa = pixaCreate(0);
                pixSaveTiled(pixs, pixa, 1, 1, 20, 8);
                TestDistance(pixa, pixs, conn, depth, bc, rp);
                pixd = pixaDisplay(pixa, 0, 0);
                pixDisplayWithTitle(pixd, 0, 0, NULL, rp->display);
                pixaDestroy(&pixa);
                pixDestroy(&pixd);
            }
        }
    }

    boxDestroy(&box);
    pixDestroy(&pix);
    pixDestroy(&pixs);
    regTestCleanup(rp);
    return 0;
}
/*!
 *  pixaSplitPix()
 *
 *      Input:  pixs  (with individual components on a lattice)
 *              nx   (number of mosaic cells horizontally)
 *              ny   (number of mosaic cells vertically)
 *              borderwidth  (of added border on all sides)
 *              bordercolor  (in our RGBA format: 0xrrggbbaa)
 *      Return: pixa, or null on error
 *
 *  Notes:
 *      (1) This is a variant on pixaCreateFromPix(), where we
 *          simply divide the image up into (approximately) equal
 *          subunits.  If you want the subimages to have essentially
 *          the same aspect ratio as the input pix, use nx = ny.
 *      (2) If borderwidth is 0, we ignore the input bordercolor and
 *          redefine it to white.
 *      (3) The bordercolor is always used to initialize each tiled pix,
 *          so that if the src is clipped, the unblitted part will
 *          be this color.  This avoids 1 pixel wide black stripes at the
 *          left and lower edges.
 */
PIXA *
pixaSplitPix(PIX      *pixs,
             l_int32   nx,
             l_int32   ny,
             l_int32   borderwidth,
             l_uint32  bordercolor)
{
l_int32  w, h, d, cellw, cellh, i, j;
PIX     *pixt;
PIXA    *pixa;

    PROCNAME("pixaSplitPix");

    if (!pixs)
        return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
    if (nx <= 0 || ny <= 0)
        return (PIXA *)ERROR_PTR("nx and ny must be > 0", procName, NULL);
    borderwidth = L_MAX(0, borderwidth);

    if ((pixa = pixaCreate(nx * ny)) == NULL)
        return (PIXA *)ERROR_PTR("pixa not made", procName, NULL);
    pixGetDimensions(pixs, &w, &h, &d);
    cellw = (w + nx - 1) / nx;  /* round up */
    cellh = (h + ny - 1) / ny;

    for (i = 0; i < ny; i++) {
        for (j = 0; j < nx; j++) {
            if ((pixt = pixCreate(cellw + 2 * borderwidth,
                                  cellh + 2 * borderwidth, d)) == NULL)
                return (PIXA *)ERROR_PTR("pixt not made", procName, NULL);
            pixCopyColormap(pixt, pixs);
            if (borderwidth == 0) {  /* initialize full image to white */
                if (d == 1)
                    pixClearAll(pixt);
                else
                    pixSetAll(pixt);
            }
            else
                pixSetAllArbitrary(pixt, bordercolor);
            pixRasterop(pixt, borderwidth, borderwidth, cellw, cellh,
                        PIX_SRC, pixs, j * cellw, i * cellh);
            pixaAddPix(pixa, pixt, L_INSERT);
        }
    }

    return pixa;
}
/*!
 *  pixaReadStream()
 *
 *      Input:  stream
 *      Return: pixa, or null on error
 */
PIXA *
pixaReadStream(FILE  *fp)
{
l_int32  n, i, xres, yres, version;
l_int32  ignore;
BOXA    *boxa;
PIX     *pix;
PIXA    *pixa;

    PROCNAME("pixaReadStream");

#if  !HAVE_LIBPNG  /* defined in environ.h */
    return (PIXA *)ERROR_PTR("no libpng: can't read data", procName, NULL);
#else

    if (!fp)
        return (PIXA *)ERROR_PTR("stream not defined", procName, NULL);

    if (fscanf(fp, "\nPixa Version %d\n", &version) != 1)
        return (PIXA *)ERROR_PTR("not a pixa file", procName, NULL);
    if (version != PIXA_VERSION_NUMBER)
        return (PIXA *)ERROR_PTR("invalid pixa version", procName, NULL);
    if (fscanf(fp, "Number of pix = %d\n", &n) != 1)
        return (PIXA *)ERROR_PTR("not a pixa file", procName, NULL);

    if ((pixa = pixaCreate(n)) == NULL)
        return (PIXA *)ERROR_PTR("pixa not made", procName, NULL);
    if ((boxa = boxaReadStream(fp)) == NULL)
        return (PIXA *)ERROR_PTR("boxa not made", procName, NULL);
    boxaDestroy(&pixa->boxa);
    pixa->boxa = boxa;

    for (i = 0; i < n; i++) {
        if ((fscanf(fp, " pix[%d]: xres = %d, yres = %d\n",
              &ignore, &xres, &yres)) != 3)
            return (PIXA *)ERROR_PTR("res reading", procName, NULL);
        if ((pix = pixReadStreamPng(fp)) == NULL)
            return (PIXA *)ERROR_PTR("pix not read", procName, NULL);
        pixSetXRes(pix, xres);
        pixSetYRes(pix, yres);
        pixaAddPix(pixa, pix, L_INSERT);
    }

    return pixa;

#endif  /* !HAVE_LIBPNG */
}
Beispiel #25
0
int main(int    argc,
         char **argv)
{
SEL         *sel1, *sel2, *sel3, *sel4;
SELA        *sela;
PIX         *pix, *pixd;
PIXA        *pixa;
static char  mainName[] = "flipselgen";

    if (argc != 1)
        return ERROR_INT(" Syntax: flipselgen", mainName, 1);

    sela = selaCreate(0);
    sel1 = selCreateFromString(textsel1, 5, 6, "flipsel1");
    sel2 = selCreateFromString(textsel2, 5, 6, "flipsel2");
    sel3 = selCreateFromString(textsel3, 5, 6, "flipsel3");
    sel4 = selCreateFromString(textsel4, 5, 6, "flipsel4");
    selaAddSel(sela, sel1, NULL, 0);
    selaAddSel(sela, sel2, NULL, 0);
    selaAddSel(sela, sel3, NULL, 0);
    selaAddSel(sela, sel4, NULL, 0);

    pixa = pixaCreate(4);
    pix = selDisplayInPix(sel1, 23, 2);
    pixDisplayWithTitle(pix, 100, 100, "sel1", DFLAG);
    pixaAddPix(pixa, pix, L_INSERT);
    pix = selDisplayInPix(sel2, 23, 2);
    pixDisplayWithTitle(pix, 275, 100, "sel2", DFLAG);
    pixaAddPix(pixa, pix, L_INSERT);
    pix = selDisplayInPix(sel3, 23, 2);
    pixDisplayWithTitle(pix, 450, 100, "sel3", DFLAG);
    pixaAddPix(pixa, pix, L_INSERT);
    pix = selDisplayInPix(sel4, 23, 2);
    pixDisplayWithTitle(pix, 625, 100, "sel4", DFLAG);
    pixaAddPix(pixa, pix, L_INSERT);

    pixd = pixaDisplayTiled(pixa, 800, 0, 15);
    pixDisplayWithTitle(pixd, 100, 300, "allsels", DFLAG);
    pixDestroy(&pixd);
    pixaDestroy(&pixa);

    if (fhmtautogen(sela, INDEX, NULL))
        return ERROR_INT(" Generation failed", mainName, 1);

    selaDestroy(&sela);
    return 0;
}
Beispiel #26
0
/*!
 * \brief   fpixaDisplayQuadtree()
 *
 * \param[in]    fpixa     mean, variance or root variance
 * \param[in]    factor    replication factor at lowest level
 * \param[in]    fontsize  4, ... 20
 * \return  pixd 8 bpp, mosaic of quadtree images, or NULL on error
 *
 * <pre>
 * Notes:
 *      (1) The mean and root variance fall naturally in the 8 bpp range,
 *          but the variance is typically outside the range.  This
 *          function displays 8 bpp pix clipped to 255, so the image
 *          pixels will mostly be 255 (white).
 * </pre>
 */
PIX *
fpixaDisplayQuadtree(FPIXA   *fpixa,
                     l_int32  factor,
                     l_int32  fontsize)
{
char       buf[256];
l_int32    nlevels, i, mag, w;
L_BMF     *bmf;
FPIX      *fpix;
PIX       *pixt1, *pixt2, *pixt3, *pixt4, *pixd;
PIXA      *pixat;

    PROCNAME("fpixaDisplayQuadtree");

    if (!fpixa)
        return (PIX *)ERROR_PTR("fpixa not defined", procName, NULL);

    if ((nlevels = fpixaGetCount(fpixa)) == 0)
        return (PIX *)ERROR_PTR("pixas empty", procName, NULL);

    if ((bmf = bmfCreate(NULL, fontsize)) == NULL)
        L_ERROR("bmf not made; text will not be added", procName);
    pixat = pixaCreate(nlevels);
    for (i = 0; i < nlevels; i++) {
        fpix = fpixaGetFPix(fpixa, i, L_CLONE);
        pixt1 = fpixConvertToPix(fpix, 8, L_CLIP_TO_ZERO, 0);
        mag = factor * (1 << (nlevels - i - 1));
        pixt2 = pixExpandReplicate(pixt1, mag);
        pixt3 = pixConvertTo32(pixt2);
        snprintf(buf, sizeof(buf), "Level %d\n", i);
        pixt4 = pixAddSingleTextblock(pixt3, bmf, buf, 0xff000000,
                                      L_ADD_BELOW, NULL);
        pixaAddPix(pixat, pixt4, L_INSERT);
        fpixDestroy(&fpix);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
        pixDestroy(&pixt3);
    }
    w = pixGetWidth(pixt4);
    pixd = pixaDisplayTiledInRows(pixat, 32, nlevels * (w + 80), 1.0, 0, 30, 2);

    pixaDestroy(&pixat);
    bmfDestroy(&bmf);
    return pixd;
}
Beispiel #27
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;
}
Beispiel #28
0
/*!
 * \brief   recogAddAllSamples()
 *
 * \param[in]    precog  addr of recog
 * \param[in]    paa     pixaa from previously trained recog
 * \param[in]    debug
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) On error, the input recog is destroyed.
 *      (2) This is used with the serialization routine recogRead(),
 *          where each pixa in the pixaa represents a set of characters
 *          in a different class.  Before calling this function, we have
 *          verified that the number of character classes, given by the
 *          setsize field in %recog, equals the number of pixa in the paa.
 *          The character labels for each set are in the sa_text field.
 * </pre>
 */
static l_int32
recogAddAllSamples(L_RECOG  **precog,
                   PIXAA     *paa,
                   l_int32    debug)
{
char     *text;
l_int32   i, j, nc, ns;
PIX      *pix;
PIXA     *pixa, *pixa1;
L_RECOG  *recog;

    PROCNAME("recogAddAllSamples");

    if (!precog)
        return ERROR_INT("&recog not defined", procName, 1);
    if ((recog = *precog) == NULL)
        return ERROR_INT("recog not defined", procName, 1);
    if (!paa) {
        recogDestroy(&recog);
        return ERROR_INT("paa not defined", procName, 1);
    }

    nc = pixaaGetCount(paa, NULL);
    for (i = 0; i < nc; i++) {
        pixa = pixaaGetPixa(paa, i, L_CLONE);
        ns = pixaGetCount(pixa);
        text = sarrayGetString(recog->sa_text, i, L_NOCOPY);
        pixa1 = pixaCreate(ns);
        pixaaAddPixa(recog->pixaa_u, pixa1, L_INSERT);
        for (j = 0; j < ns; j++) {
            pix = pixaGetPix(pixa, j, L_CLONE);
            if (debug) fprintf(stderr, "pix[%d,%d]: text = %s\n", i, j, text);
            pixaaAddPix(recog->pixaa_u, i, pix, NULL, L_INSERT);
        }
        pixaDestroy(&pixa);
    }

    recogTrainingFinished(&recog, 0, -1, -1.0);  /* For second parameter,
                                             see comment in recogRead() */
    if (!recog)
        return ERROR_INT("bad templates; recog destroyed", procName, 1);
    return 0;
}
Beispiel #29
0
/*!
 *  pixaaFlattenToPixa()
 *
 *      Input:  pixaa
 *              &naindex  (<optional return> the pixa index in the pixaa)
 *              copyflag  (L_COPY or L_CLONE)
 *      Return: pixa, or null on error
 *
 *  Notes:
 *      (1) This 'flattens' the pixaa to a pixa, taking the pix in
 *          order in the first pixa, then the second, etc.
 *      (2) If &naindex is defined, we generate a Numa that gives, for
 *          each pix in the pixaa, the index of the pixa to which it belongs.
 */
PIXA *
pixaaFlattenToPixa(PIXAA   *pixaa,
                   NUMA   **pnaindex,
                   l_int32  copyflag)
{
l_int32  i, j, m, n;
BOX     *box;
NUMA    *naindex;
PIX     *pix;
PIXA    *pixa, *pixat;

    PROCNAME("pixaaFlattenToPixa");

    if (pnaindex) *pnaindex = NULL;
    if (!pixaa)
        return (PIXA *)ERROR_PTR("pixaa not defined", procName, NULL);
    if (copyflag != L_COPY && copyflag != L_CLONE)
        return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);

    if (pnaindex) {
        naindex = numaCreate(0);
        *pnaindex = naindex;
    }

    n = pixaaGetCount(pixaa);
    pixa = pixaCreate(n);
    for (i = 0; i < n; i++) {
        pixat = pixaaGetPixa(pixaa, i, L_CLONE);
        m = pixaGetCount(pixat);
        for (j = 0; j < m; j++) {
            pix = pixaGetPix(pixat, j, copyflag);
            box = pixaGetBox(pixat, j, copyflag);
            pixaAddPix(pixa, pix, L_INSERT);
            pixaAddBox(pixa, box, L_INSERT);
            if (pnaindex)
                numaAddNumber(naindex, i);  /* save 'row' number */
        }
        pixaDestroy(&pixat);
    }

    return pixa;
}
/*!
 * \brief   recogDecode()
 *
 * \param[in]    recog with LUT's pre-computed
 * \param[in]    pixs typically of multiple touching characters, 1 bpp
 * \param[in]    nlevels of templates; 2 for now
 * \param[out]   ppixdb [optional] debug result; can be null
 * \return  0 if OK, 1 on error
 */
l_int32
recogDecode(L_RECOG  *recog,
            PIX      *pixs,
            l_int32   nlevels,
            PIX     **ppixdb)
{
l_int32  debug;
PIX     *pixt;
PIXA    *pixa;

    PROCNAME("recogDecode");

    if (ppixdb) *ppixdb = NULL;
    if (!recog)
        return ERROR_INT("recog not defined", procName, 1);
    if (!pixs || pixGetDepth(pixs) != 1)
        return ERROR_INT("pixs not defined or not 1 bpp", procName, 1);
    if (!recog->train_done)
        return ERROR_INT("training not finished", procName, 1);
    if (nlevels != 2)
        return ERROR_INT("nlevels != 2 (for now)", procName, 1);

    pixa = (ppixdb) ? pixaCreate(2) : NULL;
    debug = (ppixdb) ? 1 : 0;
    if (recogMakeDecodingArrays(recog, pixs, debug))
        return ERROR_INT("error making arrays", procName, 1);

    recogSetChannelParams(recog, nlevels);

    if (recogRunViterbi(recog, &pixt))
        return ERROR_INT("error in viterbi", procName, 1);
    if (ppixdb) pixaAddPix(pixa, pixt, L_INSERT);

    if (recogRescoreDidResult(recog, &pixt))
        return ERROR_INT("error in rescoring", procName, 1);
    if (ppixdb) pixaAddPix(pixa, pixt, L_INSERT);

    *ppixdb = pixaDisplayTiledInRows(pixa, 32, 2 * pixGetWidth(pixt) + 100,
                                     1.0, 0, 30, 2);
    pixaDestroy(&pixa);
    return 0;
}