예제 #1
0
파일: pta_reg.c 프로젝트: vkbrad/AndroidOCR
int main(int    argc,
         char **argv)
{
l_int32       i, w, h, nbox, npta, fgcount, bgcount, count;
BOXA         *boxa;
PIX          *pixs, *pixfg, *pixbg, *pixc, *pixb, *pixd;
PIX          *pix1, *pix2, *pix3, *pix4;
PIXA         *pixa;
PTA          *pta;
PTAA         *ptaafg, *ptaabg;
L_REGPARAMS  *rp;

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

    pixs = pixRead("feyn-fract.tif");
    boxa = pixConnComp(pixs, NULL, 8);
    nbox = boxaGetCount(boxa);
    regTestCompareValues(rp, nbox, 464, 0);  /* 0 */

        /* Get fg and bg boundary pixels */
    pixfg = pixMorphSequence(pixs, "e3.3", 0);
    pixXor(pixfg, pixfg, pixs);
    pixCountPixels(pixfg, &fgcount, NULL);
    regTestCompareValues(rp, fgcount, 58764, 0);  /* 1 */

    pixbg = pixMorphSequence(pixs, "d3.3", 0);
    pixXor(pixbg, pixbg, pixs);
    pixCountPixels(pixbg, &bgcount, NULL);
    regTestCompareValues(rp, bgcount, 60335, 0);  /* 2 */

        /* Get ptaa of fg pixels */
    ptaafg = ptaaGetBoundaryPixels(pixs, L_BOUNDARY_FG, 8, NULL, NULL);
    npta = ptaaGetCount(ptaafg);
    regTestCompareValues(rp, npta, nbox, 0);  /* 3 */
    count = 0;
    for (i = 0; i < npta; i++) {
        pta = ptaaGetPta(ptaafg, i, L_CLONE);
        count += ptaGetCount(pta);
        ptaDestroy(&pta);
    }
    regTestCompareValues(rp, fgcount, count, 0);  /* 4 */

        /* Get ptaa of bg pixels.  Note that the number of bg pts
         * is, in general, larger than the number of bg boundary pixels,
         * because bg boundary pixels are shared by two c.c. that
         * are 1 pixel apart. */
    ptaabg = ptaaGetBoundaryPixels(pixs, L_BOUNDARY_BG, 8, NULL, NULL);
    npta = ptaaGetCount(ptaabg);
    regTestCompareValues(rp, npta, nbox, 0);  /* 5 */
    count = 0;
    for (i = 0; i < npta; i++) {
        pta = ptaaGetPta(ptaabg, i, L_CLONE);
        count += ptaGetCount(pta);
        ptaDestroy(&pta);
    }
    regTestCompareValues(rp, count, 60602, 0);  /* 6 */

        /* Render the fg boundary pixels on top of pixs. */
    pixa = pixaCreate(4);
    pixc = pixRenderRandomCmapPtaa(pixs, ptaafg, 0, 0, 0);
    regTestWritePixAndCheck(rp, pixc, IFF_PNG);  /* 7 */
    pixSaveTiledOutline(pixc, pixa, 1.0, 1, 30, 2, 32);
    pixDestroy(&pixc);

        /* Render the bg boundary pixels on top of pixs. */
    pixc = pixRenderRandomCmapPtaa(pixs, ptaabg, 0, 0, 0);
    regTestWritePixAndCheck(rp, pixc, IFF_PNG);  /* 8 */
    pixSaveTiledOutline(pixc, pixa, 1.0, 0, 30, 2, 32);
    pixDestroy(&pixc);

    pixClearAll(pixs);

        /* Render the fg boundary pixels alone. */
    pixc = pixRenderRandomCmapPtaa(pixs, ptaafg, 0, 0, 0);
    regTestWritePixAndCheck(rp, pixc, IFF_PNG);  /* 9 */
    pixSaveTiledOutline(pixc, pixa, 1.0, 1, 30, 2, 32);

        /* Verify that the fg pixels are the same set as we
         * originally started with. */
    pixb = pixConvertTo1(pixc, 255);
    regTestComparePix(rp, pixb, pixfg);  /* 10 */
    pixDestroy(&pixc);
    pixDestroy(&pixb);

        /* Render the bg boundary pixels alone. */
    pixc = pixRenderRandomCmapPtaa(pixs, ptaabg, 0, 0, 0);
    regTestWritePixAndCheck(rp, pixc, IFF_PNG);  /* 11 */
    pixSaveTiledOutline(pixc, pixa, 1.0, 0, 30, 2, 32);

        /* Verify that the bg pixels are the same set as we
         * originally started with. */
    pixb = pixConvertTo1(pixc, 255);
    regTestComparePix(rp, pixb, pixbg);  /* 12 */
    pixDestroy(&pixc);
    pixDestroy(&pixb);

    pixd = pixaDisplay(pixa, 0, 0);
    pixDisplayWithTitle(pixd, 0, 0, NULL, rp->display);
    ptaaDestroy(&ptaafg);
    ptaaDestroy(&ptaabg);
    pixDestroy(&pixs);
    pixDestroy(&pixfg);
    pixDestroy(&pixbg);
    pixDestroy(&pixd);
    pixaDestroy(&pixa);
    boxaDestroy(&boxa);

        /* Test rotation */
    pix1 = pixRead("feyn-word.tif");
    pix2 = pixAddBorderGeneral(pix1, 200, 200, 200, 200, 0);
    pixa = pixaCreate(0);
    pix3 = PtaDisplayRotate(pix2, 0, 0);
    pixaAddPix(pixa, pix3, L_INSERT);
    pix3 = PtaDisplayRotate(pix2, 500, 100);
    pixaAddPix(pixa, pix3, L_INSERT);
    pix3 = PtaDisplayRotate(pix2, 100, 410);
    pixaAddPix(pixa, pix3, L_INSERT);
    pix3 = PtaDisplayRotate(pix2, 500, 410);
    pixaAddPix(pixa, pix3, L_INSERT);
    pix4 = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2);
    regTestWritePixAndCheck(rp, pix4, IFF_PNG);  /* 13 */
    pixDisplayWithTitle(pix4, 800, 0, NULL, rp->display);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix4);
    pixaDestroy(&pixa);

    return regTestCleanup(rp);
}
/*!
 * \brief   recogMakeDecodingArray()
 *
 * \param[in]    recog
 * \param[in]    index of averaged template
 * \param[in]    debug 1 for debug output; 0 otherwise
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) Generates the bit-and sum array for a character template along pixs.
 *      (2) The values are saved in the scoring arrays at the left edge
 *          of the template as it is positioned on pixs.
 * </pre>
 */
static l_int32
recogMakeDecodingArray(L_RECOG  *recog,
                       l_int32   index,
                       l_int32   debug)
{
l_int32   i, j, w1, h1, w2, h2, nx, ycent2, count, maxcount, maxdely;
l_int32   sum, moment, dely, shifty;
l_int32  *counta, *delya, *ycent1, *arraysum, *arraymoment, *sumtab;
NUMA     *nasum, *namoment;
PIX      *pix1, *pix2, *pix3;
L_RDID   *did;

    PROCNAME("recogMakeDecodingArray");

    if (!recog)
        return ERROR_INT("recog not defined", procName, 1);
    if ((did = recogGetDid(recog)) == NULL)
        return ERROR_INT("did not defined", procName, 1);
    if (index < 0 || index >= did->narray)
        return ERROR_INT("invalid index", procName, 1);

        /* Check that pix1 is large enough for this template. */
    pix1 = did->pixs;  /* owned by did; do not destroy */
    pixGetDimensions(pix1, &w1, &h1, NULL);
    pix2 = pixaGetPix(recog->pixa_u, index, L_CLONE);
    pixGetDimensions(pix2, &w2, &h2, NULL);
    if (w1 < w2) {
        L_INFO("w1 = %d < w2 = %d for index %d\n", procName, w1, w2, index);
        pixDestroy(&pix2);
        return 0;
    }

    nasum = did->nasum;
    namoment = did->namoment;
    ptaGetIPt(recog->pta_u, index, NULL, &ycent2);
    sumtab = recog->sumtab;
    counta = did->counta[index];
    delya = did->delya[index];

        /* Set up the array for ycent1.  This gives the y-centroid location
         * for a window of width w2, starting at location i. */
    nx = w1 - w2 + 1;  /* number of positions w2 can be placed in w1 */
    ycent1 = (l_int32 *)LEPT_CALLOC(nx, sizeof(l_int32));
    arraysum = numaGetIArray(nasum);
    arraymoment = numaGetIArray(namoment);
    for (i = 0, sum = 0, moment = 0; i < w2; i++) {
        sum += arraysum[i];
        moment += arraymoment[i];
    }
    for (i = 0; i < nx - 1; i++) {
        ycent1[i] = (sum == 0) ? ycent2 : (l_float32)moment / (l_float32)sum;
        sum += arraysum[w2 + i] - arraysum[i];
        moment += arraymoment[w2 + i] - arraymoment[i];
    }
    ycent1[nx - 1] = (sum == 0) ? ycent2 : (l_float32)moment / (l_float32)sum;

        /* Compute the bit-and sum between the template pix2 and pix1, at
         * locations where the left side of pix2 goes from 0 to nx - 1
         * in pix1.  Do this around the vertical alignment of the pix2
         * centroid and the windowed pix1 centroid.
         *  (1) Start with pix3 cleared and approximately equal in size to pix1.
         *  (2) Blit the y-shifted pix2 onto pix3.  Then all ON pixels
         *      are within the intersection of pix1 and the shifted pix2.
         *  (3) AND pix1 with pix3. */
    pix3 = pixCreate(w2, h1, 1);
    for (i = 0; i < nx; i++) {
        shifty = (l_int32)(ycent1[i] - ycent2 + 0.5);
        maxcount = 0;
        for (j = -MaxYShift; j <= MaxYShift; j++) {
            pixClearAll(pix3);
            dely = shifty + j;  /* amount pix2 is shifted relative to pix1 */
            pixRasterop(pix3, 0, dely, w2, h2, PIX_SRC, pix2, 0, 0);
            pixRasterop(pix3, 0, 0, w2, h1, PIX_SRC & PIX_DST, pix1, i, 0);
            pixCountPixels(pix3, &count, sumtab);
            if (count > maxcount) {
                maxcount = count;
                maxdely = dely;
            }
        }
        counta[i] = maxcount;
        delya[i] = maxdely;
    }
    did->fullarrays = TRUE;

    pixDestroy(&pix2);
    pixDestroy(&pix3);
    LEPT_FREE(ycent1);
    LEPT_FREE(arraysum);
    LEPT_FREE(arraymoment);
    return 0;
}
예제 #3
0
/*!
 *  pixProjectiveSampled()
 *
 *      Input:  pixs (all depths)
 *              vc  (vector of 8 coefficients for projective transformation)
 *              incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) Brings in either black or white pixels from the boundary.
 *      (2) Retains colormap, which you can do for a sampled transform..
 *      (3) For 8 or 32 bpp, much better quality is obtained by the
 *          somewhat slower pixProjective().  See that function
 *          for relative timings between sampled and interpolated.
 */
PIX *
pixProjectiveSampled(PIX        *pixs,
                     l_float32  *vc,
                     l_int32     incolor)
{
l_int32     i, j, w, h, d, x, y, wpls, wpld, color, cmapindex;
l_uint32    val;
l_uint32   *datas, *datad, *lines, *lined;
PIX        *pixd;
PIXCMAP    *cmap;

    PROCNAME("pixProjectiveSampled");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    if (!vc)
        return (PIX *)ERROR_PTR("vc not defined", procName, NULL);
    if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
        return (PIX *)ERROR_PTR("invalid incolor", procName, NULL);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 1 && d != 2 && d != 4 && d != 8 && d != 32)
        return (PIX *)ERROR_PTR("depth not 1, 2, 4, 8 or 16", procName, NULL);

        /* Init all dest pixels to color to be brought in from outside */
    pixd = pixCreateTemplate(pixs);
    if ((cmap = pixGetColormap(pixs)) != NULL) {
        if (incolor == L_BRING_IN_WHITE)
            color = 1;
        else
            color = 0;
        pixcmapAddBlackOrWhite(cmap, color, &cmapindex);
        pixSetAllArbitrary(pixd, cmapindex);
    }
    else {
        if ((d == 1 && incolor == L_BRING_IN_WHITE) ||
            (d > 1 && incolor == L_BRING_IN_BLACK))
            pixClearAll(pixd);
        else
            pixSetAll(pixd);
    }

        /* Scan over the dest pixels */
    datas = pixGetData(pixs);
    wpls = pixGetWpl(pixs);
    datad = pixGetData(pixd);
    wpld = pixGetWpl(pixd);
    for (i = 0; i < h; i++) {
        lined = datad + i * wpld;
        for (j = 0; j < w; j++) {
            projectiveXformSampledPt(vc, j, i, &x, &y);
            if (x < 0 || y < 0 || x >=w || y >= h)
                continue;
            lines = datas + y * wpls;
            if (d == 1) {
                val = GET_DATA_BIT(lines, x);
                SET_DATA_BIT_VAL(lined, j, val);
            }
            else if (d == 8) {
                val = GET_DATA_BYTE(lines, x);
                SET_DATA_BYTE(lined, j, val);
            }
            else if (d == 32) {
                lined[j] = lines[x];
            }
            else if (d == 2) {
                val = GET_DATA_DIBIT(lines, x);
                SET_DATA_DIBIT(lined, j, val);
            }
            else if (d == 4) {
                val = GET_DATA_QBIT(lines, x);
                SET_DATA_QBIT(lined, j, val);
            }
        }
    }

    return pixd;
}