コード例 #1
0
ファイル: pagesegmain.cpp プロジェクト: Kailigithub/tesseract
// Helper to remove an enclosing circle from an image.
// If there isn't one, then the image will most likely get badly mangled.
// The returned pix must be pixDestroyed after use. NULL may be returned
// if the image doesn't meet the trivial conditions that it uses to determine
// success.
static Pix* RemoveEnclosingCircle(Pix* pixs) {
  Pix* pixsi = pixInvert(NULL, pixs);
  Pix* pixc = pixCreateTemplate(pixs);
  pixSetOrClearBorder(pixc, 1, 1, 1, 1, PIX_SET);
  pixSeedfillBinary(pixc, pixc, pixsi, 4);
  pixInvert(pixc, pixc);
  pixDestroy(&pixsi);
  Pix* pixt = pixAnd(NULL, pixs, pixc);
  l_int32 max_count;
  pixCountConnComp(pixt, 8, &max_count);
  // The count has to go up before we start looking for the minimum.
  l_int32 min_count = MAX_INT32;
  Pix* pixout = NULL;
  for (int i = 1; i < kMaxCircleErosions; i++) {
    pixDestroy(&pixt);
    pixErodeBrick(pixc, pixc, 3, 3);
    pixt = pixAnd(NULL, pixs, pixc);
    l_int32 count;
    pixCountConnComp(pixt, 8, &count);
    if (i == 1 || count > max_count) {
      max_count = count;
      min_count = count;
    } else if (i > 1 && count < min_count) {
      min_count = count;
      pixDestroy(&pixout);
      pixout = pixCopy(NULL, pixt);  // Save the best.
    } else if (count >= min_count) {
      break;  // We have passed by the best.
    }
  }
  pixDestroy(&pixt);
  pixDestroy(&pixc);
  return pixout;
}
コード例 #2
0
ファイル: dewarptest2.c プロジェクト: ErfanHasmin/scope-ocr
l_int32 main(int    argc,
             char **argv)
{
l_int32      pageno;
L_DEWARP    *dew1;
L_DEWARPA   *dewa;
PIX         *pixs, *pixn, *pixg, *pixb;
static char  mainName[] = "dewarptest2";
  
    if (argc != 1 && argc != 3)
        return ERROR_INT("Syntax: dewarptest2 [image pageno]", mainName, 1);

    if (argc == 1) {
        pixs = pixRead("cat-35.jpg");
        pageno = 35;
    }
    else {
        pixs = pixRead(argv[1]);
        pageno = atoi(argv[2]);
    }
    if (!pixs)
        return ERROR_INT("image not read", mainName, 1);

    dewa = dewarpaCreate(40, 30, 1, 6, 50);

#if NORMALIZE
        /* Normalize for varying background and binarize */
    pixn = pixBackgroundNormSimple(pixs, NULL, NULL);
    pixg = pixConvertRGBToGray(pixn, 0.5, 0.3, 0.2);
    pixb = pixThresholdToBinary(pixg, 130);
    pixDestroy(&pixn);
#else
        /* Don't normalize; just threshold and clean edges */
    pixg = pixConvertTo8(pixs, 0);
    pixb = pixThresholdToBinary(pixg, 100);
    pixSetOrClearBorder(pixb, 30, 30, 40, 40, PIX_CLR);
#endif

        /* Run the basic functions */
    dew1 = dewarpCreate(pixb, pageno);
    dewarpaInsertDewarp(dewa, dew1);
    dewarpBuildModel(dew1, "/tmp/dewarp_model1.pdf");
    dewarpaApplyDisparity(dewa, pageno, pixg, "/tmp/dewarp_apply1.pdf");

    dewarpaDestroy(&dewa);
    pixDestroy(&pixs);
    pixDestroy(&pixg);
    pixDestroy(&pixb);
    return 0;
}
コード例 #3
0
ファイル: skew_reg.c プロジェクト: mehulsbhatt/MyOCRTEST
int main(int argc,
         char **argv) {
    l_int32 w, h, wd, hd;
    l_float32 deg2rad, angle, conf;
    PIX *pixs, *pixb1, *pixb2, *pixr, *pixf, *pixd, *pixc;
    PIXA *pixa;
    L_REGPARAMS *rp;

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

    deg2rad = 3.1415926535 / 180.;

    pixa = pixaCreate(0);
    pixs = pixRead("feyn.tif");
    pixSetOrClearBorder(pixs, 100, 250, 100, 0, PIX_CLR);
    pixb1 = pixReduceRankBinaryCascade(pixs, 2, 2, 0, 0);
    regTestWritePixAndCheck(rp, pixb1, IFF_PNG);  /* 0 */
    pixDisplayWithTitle(pixb1, 0, 100, NULL, rp->display);

    /* Add a border and locate and deskew a 40 degree rotation */
    pixb2 = pixAddBorder(pixb1, BORDER, 0);
    pixGetDimensions(pixb2, &w, &h, NULL);
    pixSaveTiled(pixb2, pixa, 0.5, 1, 20, 8);
    pixr = pixRotateBySampling(pixb2, w / 2, h / 2,
                               deg2rad * 40., L_BRING_IN_WHITE);
    regTestWritePixAndCheck(rp, pixr, IFF_PNG);  /* 1 */
    pixSaveTiled(pixr, pixa, 0.5, 0, 20, 0);
    pixFindSkewSweepAndSearchScorePivot(pixr, &angle, &conf, NULL, 1, 1,
                                        0.0, 45.0, 2.0, 0.03,
                                        L_SHEAR_ABOUT_CENTER);
    fprintf(stderr, "Should be 40 degrees: angle = %7.3f, conf = %7.3f\n",
            angle, conf);
    pixf = pixRotateBySampling(pixr, w / 2, h / 2,
                               deg2rad * angle, L_BRING_IN_WHITE);
    pixd = pixRemoveBorder(pixf, BORDER);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 2 */
    pixSaveTiled(pixd, pixa, 0.5, 0, 20, 0);
    pixDestroy(&pixr);
    pixDestroy(&pixf);
    pixDestroy(&pixd);

    /* Do a rotation larger than 90 degrees using embedding;
     * Use 2 sets of measurements at 90 degrees to scan the
     * full range of possible rotation angles. */
    pixGetDimensions(pixb1, &w, &h, NULL);
    pixr = pixRotate(pixb1, deg2rad * 37., L_ROTATE_SAMPLING,
                     L_BRING_IN_WHITE, w, h);
    regTestWritePixAndCheck(rp, pixr, IFF_PNG);  /* 3 */
    pixSaveTiled(pixr, pixa, 0.5, 1, 20, 0);
    startTimer();
    pixFindSkewOrthogonalRange(pixr, &angle, &conf, 2, 1,
                               47.0, 1.0, 0.03, 0.0);
    fprintf(stderr, "Orth search time: %7.3f sec\n", stopTimer());
    fprintf(stderr, "Should be about -128 degrees: angle = %7.3f\n", angle);
    pixd = pixRotate(pixr, deg2rad * angle, L_ROTATE_SAMPLING,
                     L_BRING_IN_WHITE, w, h);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 4 */
    pixGetDimensions(pixd, &wd, &hd, NULL);
    pixc = pixCreate(w, h, 1);
    pixRasterop(pixc, 0, 0, w, h, PIX_SRC, pixd, (wd - w) / 2, (hd - h) / 2);
    regTestWritePixAndCheck(rp, pixc, IFF_PNG);  /* 5 */
    pixSaveTiled(pixc, pixa, 0.5, 0, 20, 0);
    pixDestroy(&pixr);
    pixDestroy(&pixf);
    pixDestroy(&pixd);
    pixDestroy(&pixc);

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

    pixDestroy(&pixs);
    pixDestroy(&pixb1);
    pixDestroy(&pixb2);
    pixaDestroy(&pixa);
    return regTestCleanup(rp);
}
コード例 #4
0
ファイル: watershedtest.c プロジェクト: mehulsbhatt/MyOCRTEST
int main(int argc,
         char **argv) {
    l_int32 i, j, w, h, empty;
    l_uint32 redval, greenval;
    l_float32 f;
    L_WSHED *wshed;
    PIX *pixs, *pixc, *pixd;
    PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pix8;
    PIXA *pixac;
    PTA *pta;
    static char mainName[] = "watershedtest";

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

    pixac = pixaCreate(0);
    pixs = pixCreate(500, 500, 8);
    pixGetDimensions(pixs, &w, &h, NULL);
    for (i = 0; i < 500; i++) {
        for (j = 0; j < 500; j++) {
#if 1
            f = 128.0 + 26.3 * sin(0.0438 * (l_float32) i);
            f += 33.4 * cos(0.0712 * (l_float32) i);
            f += 18.6 * sin(0.0561 * (l_float32) j);
            f += 23.6 * cos(0.0327 * (l_float32) j);
#else
            f = 128.0 + 26.3 * sin(0.0238 * (l_float32)i);
            f += 33.4 * cos(0.0312 * (l_float32)i);
            f += 18.6 * sin(0.0261 * (l_float32)j);
            f += 23.6 * cos(0.0207 * (l_float32)j);
#endif
            pixSetPixel(pixs, j, i, (l_int32) f);
        }
    }
    pixSaveTiled(pixs, pixac, 1.0, 1, 10, 32);
    pixWrite("/tmp/pattern.png", pixs, IFF_PNG);
    startTimer();
    pixLocalExtrema(pixs, 0, 0, &pix1, &pix2);
    fprintf(stderr, "Time for extrema: %7.3f\n", stopTimer());
    pixSetOrClearBorder(pix1, 2, 2, 2, 2, PIX_CLR);
    composeRGBPixel(255, 0, 0, &redval);
    composeRGBPixel(0, 255, 0, &greenval);
    pixc = pixConvertTo32(pixs);
    pixPaintThroughMask(pixc, pix2, 0, 0, greenval);
    pixPaintThroughMask(pixc, pix1, 0, 0, redval);
    pixSaveTiled(pixc, pixac, 1.0, 0, 10, 32);
    pixWrite("/tmp/pixc.png", pixc, IFF_PNG);
    pixSaveTiled(pix1, pixac, 1.0, 0, 10, 32);
    pixSelectMinInConnComp(pixs, pix1, &pta, NULL);
/*    ptaWriteStream(stderr, pta, 1); */
    pix3 = pixGenerateFromPta(pta, w, h);
    pixSaveTiled(pix3, pixac, 1.0, 1, 10, 32);

    pix4 = pixConvertTo32(pixs);
    pixPaintThroughMask(pix4, pix3, 0, 0, greenval);
    pixSaveTiled(pix4, pixac, 1.0, 0, 10, 32);
    pix5 = pixRemoveSeededComponents(NULL, pix3, pix1, 8, 2);
    pixSaveTiled(pix5, pixac, 1.0, 0, 10, 32);
    pixZero(pix5, &empty);
    fprintf(stderr, "Is empty?  %d\n", empty);
    pixDestroy(&pix4);
    pixDestroy(&pix5);

    wshed = wshedCreate(pixs, pix3, 10, 0);
    startTimer();
    wshedApply(wshed);
    fprintf(stderr, "Time for wshed: %7.3f\n", stopTimer());
    pix6 = pixaDisplayRandomCmap(wshed->pixad, w, h);
    pixSaveTiled(pix6, pixac, 1.0, 1, 10, 32);
    numaWriteStream(stderr, wshed->nalevels);
    pix7 = wshedRenderFill(wshed);
    pixSaveTiled(pix7, pixac, 1.0, 0, 10, 32);
    pix8 = wshedRenderColors(wshed);
    pixSaveTiled(pix8, pixac, 1.0, 0, 10, 32);
    wshedDestroy(&wshed);

    pixd = pixaDisplay(pixac, 0, 0);
    pixDisplay(pixd, 100, 100);
    pixWrite("/tmp/wshed.png", pixd, IFF_PNG);
    pixDestroy(&pixd);
    pixaDestroy(&pixac);

    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);
    pixDestroy(&pix6);
    pixDestroy(&pix7);
    pixDestroy(&pix8);
    pixDestroy(&pixs);
    pixDestroy(&pixc);
    ptaDestroy(&pta);
    return 0;
}
コード例 #5
0
ファイル: dewarptest2.c プロジェクト: xmarston/BillRecognizer
l_int32 main(int    argc,
             char **argv)
{
l_int32      method, pageno;
L_DEWARP    *dew1;
L_DEWARPA   *dewa;
PIX         *pixs, *pixn, *pixg, *pixb, *pixd;
static char  mainName[] = "dewarptest2";

    if (argc != 2 && argc != 4)
        return ERROR_INT("Syntax: dewarptest2 method [image pageno]",
                         mainName, 1);

    if (argc == 2) {
        pixs = pixRead("cat-35.jpg");
        pageno = 35;
    }
    else {
        pixs = pixRead(argv[2]);
        pageno = atoi(argv[3]);
    }
    if (!pixs)
        return ERROR_INT("image not read", mainName, 1);
    method = atoi(argv[1]);
    lept_mkdir("lept");

    if (method == 1) {  /* Use single page dewarp function */
        dewarpSinglePage(pixs, 1, 100, 1, &pixd, NULL, 1);
        pixDisplay(pixd, 100, 100);
    } else {  /* Break down into multiple steps; require min of only 6 lines */
        dewa = dewarpaCreate(40, 30, 1, 6, 50);
        dewarpaUseBothArrays(dewa, 1);

#if NORMALIZE
            /* Normalize for varying background and binarize */
        pixn = pixBackgroundNormSimple(pixs, NULL, NULL);
        pixg = pixConvertRGBToGray(pixn, 0.5, 0.3, 0.2);
        pixb = pixThresholdToBinary(pixg, 130);
        pixDestroy(&pixn);
#else
            /* Don't normalize; just threshold and clean edges */
        pixg = pixConvertTo8(pixs, 0);
        pixb = pixThresholdToBinary(pixg, 100);
        pixSetOrClearBorder(pixb, 30, 30, 40, 40, PIX_CLR);
#endif

            /* Run the basic functions */
        dew1 = dewarpCreate(pixb, pageno);
        dewarpaInsertDewarp(dewa, dew1);
        dewarpBuildPageModel(dew1, "/tmp/lept/test2_model.pdf");
        dewarpaApplyDisparity(dewa, pageno, pixg, -1, 0, 0, &pixd,
                              "/tmp/lept/test2_apply.pdf");

        dewarpaInfo(stderr, dewa);
        dewarpaDestroy(&dewa);
        pixDestroy(&pixg);
        pixDestroy(&pixb);
    }

    pixDestroy(&pixs);
    pixDestroy(&pixd);
    return 0;
}
コード例 #6
0
ファイル: pageseg.c プロジェクト: Brigadier1-9/node-dv
/*!
 *  pixFindPageForeground()
 *
 *      Input:  pixs (full resolution (any type or depth)
 *              threshold (for binarization; typically about 128)
 *              mindist (min distance of text from border to allow
 *                       cleaning near border; at 2x reduction, this
 *                       should be larger than 50; typically about 70)
 *              erasedist (when conditions are satisfied, erase anything
 *                         within this distance of the edge;
 *                         typically 30 at 2x reduction)
 *              pagenum (use for debugging when called repeatedly; labels
 *                       debug images that are assembled into pdfdir)
 *              showmorph (set to a negative integer to show steps in
 *                         generating masks; this is typically used
 *                         for debugging region extraction)
 *              display (set to 1  to display mask and selected region
 *                       for debugging a single page)
 *              pdfdir (subdirectory of /tmp where images showing the
 *                      result are placed when called repeatedly; use
 *                      null if no output requested)
 *      Return: box (region including foreground, with some pixel noise
 *                   removed), or null if not found
 *
 *  Notes:
 *      (1) This doesn't simply crop to the fg.  It attempts to remove
 *          pixel noise and junk at the edge of the image before cropping.
 *          The input @threshold is used if pixs is not 1 bpp.
 *      (2) There are several debugging options, determined by the
 *          last 4 arguments.
 *      (3) If you want pdf output of results when called repeatedly,
 *          the pagenum arg labels the images written, which go into
 *          /tmp/<pdfdir>/<pagenum>.png.  In that case,
 *          you would clean out the /tmp directory before calling this
 *          function on each page:
 *              lept_rmdir(pdfdir);
 *              lept_mkdir(pdfdir);
 */
BOX *
pixFindPageForeground(PIX         *pixs,
                      l_int32      threshold,
                      l_int32      mindist,
                      l_int32      erasedist,
                      l_int32      pagenum,
                      l_int32      showmorph,
                      l_int32      display,
                      const char  *pdfdir)
{
char     buf[64];
l_int32  flag, nbox, intersects;
l_int32  w, h, bx, by, bw, bh, left, right, top, bottom;
PIX     *pixb, *pixb2, *pixseed, *pixsf, *pixm, *pix1, *pixg2;
BOX     *box, *boxfg, *boxin, *boxd;
BOXA    *ba1, *ba2;

    PROCNAME("pixFindPageForeground");

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

        /* Binarize, downscale by 0.5, remove the noise to generate a seed,
         * and do a seedfill back from the seed into those 8-connected
         * components of the binarized image for which there was at least
         * one seed pixel.  Also clear out any components that are within
         * 10 pixels of the edge at 2x reduction. */
    flag = (showmorph) ? -1 : 0;  /* if showmorph == -1, write intermediate
                                   * images to /tmp/seq_output_1.pdf */
    pixb = pixConvertTo1(pixs, threshold);
    pixb2 = pixScale(pixb, 0.5, 0.5);
    pixseed = pixMorphSequence(pixb2, "o1.2 + c9.9 + o3.5", flag);
    pixsf = pixSeedfillBinary(NULL, pixseed, pixb2, 8);
    pixSetOrClearBorder(pixsf, 10, 10, 10, 10, PIX_SET);
    pixm = pixRemoveBorderConnComps(pixsf, 8);
    if (display) pixDisplay(pixm, 100, 100);

        /* Now, where is the main block of text?  We want to remove noise near
         * the edge of the image, but to do that, we have to be convinced that
         * (1) there is noise and (2) it is far enough from the text block
         * and close enough to the edge.  For each edge, if the block
         * is more than mindist from that edge, then clean 'erasedist'
         * pixels from the edge. */
    pix1 = pixMorphSequence(pixm, "c50.50", flag - 1);
    ba1 = pixConnComp(pix1, NULL, 8);
    ba2 = boxaSort(ba1, L_SORT_BY_AREA, L_SORT_DECREASING, NULL);
    pixGetDimensions(pix1, &w, &h, NULL);
    nbox = boxaGetCount(ba2);
    if (nbox > 1) {
        box = boxaGetBox(ba2, 0, L_CLONE);
        boxGetGeometry(box, &bx, &by, &bw, &bh);
        left = (bx > mindist) ? erasedist : 0;
        right = (w - bx - bw > mindist) ? erasedist : 0;
        top = (by > mindist) ? erasedist : 0;
        bottom = (h - by - bh > mindist) ? erasedist : 0;
        pixSetOrClearBorder(pixm, left, right, top, bottom, PIX_CLR);
        boxDestroy(&box);
    }
    pixDestroy(&pix1);
    boxaDestroy(&ba1);
    boxaDestroy(&ba2);

        /* Locate the foreground region; don't bother cropping */
    pixClipToForeground(pixm, NULL, &boxfg);

        /* Sanity check the fg region.  Make sure it's not confined
         * to a thin boundary on the left and right sides of the image,
         * in which case it is likely to be noise. */
    if (boxfg) {
        boxin = boxCreate(0.1 * w, 0, 0.8 * w, h);
        boxIntersects(boxfg, boxin, &intersects);
        if (!intersects) {
            L_INFO("found only noise on page %d\n", procName, pagenum);
            boxDestroy(&boxfg);
        }
        boxDestroy(&boxin);
    }

    boxd = NULL;
    if (!boxfg) {
        L_INFO("no fg region found for page %d\n", procName, pagenum);
    } else {
        boxAdjustSides(boxfg, boxfg, -2, 2, -2, 2);  /* tiny expansion */
        boxd = boxTransform(boxfg, 0, 0, 2.0, 2.0);

            /* Write image showing box for this page.  This is to be
             * bundled up into a pdf of all the pages, which can be
             * generated by convertFilesToPdf()  */
        if (pdfdir) {
            pixg2 = pixConvert1To4Cmap(pixb);
            pixRenderBoxArb(pixg2, boxd, 3, 255, 0, 0);
            snprintf(buf, sizeof(buf), "/tmp/%s/%05d.png", pdfdir, pagenum);
            if (display) pixDisplay(pixg2, 700, 100);
            pixWrite(buf, pixg2, IFF_PNG);
            pixDestroy(&pixg2);
        }
    }

    pixDestroy(&pixb);
    pixDestroy(&pixb2);
    pixDestroy(&pixseed);
    pixDestroy(&pixsf);
    pixDestroy(&pixm);
    boxDestroy(&boxfg);
    return boxd;
}
コード例 #7
0
ファイル: graymorph.c プロジェクト: ansgri/rsdt-students
/*!
 *  pixErodeGray()
 *
 *      Input:  pixs
 *              hsize  (of Sel; must be odd; origin implicitly in center)
 *              vsize  (ditto)
 *      Return: pixd
 *
 *  Notes:
 *      (1) Sel is a brick with all elements being hits
 *      (2) If hsize = vsize = 1, just returns a copy.
 */
PIX *
pixErodeGray(PIX     *pixs,
             l_int32  hsize,
             l_int32  vsize)
{
l_uint8   *buffer, *minarray;
l_int32    w, h, wplb, wplt;
l_int32    leftpix, rightpix, toppix, bottompix, maxsize;
l_uint32  *datab, *datat;
PIX       *pixb, *pixt, *pixd;

    PROCNAME("pixErodeGray");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    if (pixGetDepth(pixs) != 8)
        return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
    if (hsize < 1 || vsize < 1)
        return (PIX *)ERROR_PTR("hsize or vsize < 1", procName, NULL);
    if ((hsize & 1) == 0 ) {
        L_WARNING("horiz sel size must be odd; increasing by 1", procName);
        hsize++;
    }
    if ((vsize & 1) == 0 ) {
        L_WARNING("vert sel size must be odd; increasing by 1", procName);
        vsize++;
    }

    if (hsize == 1 && vsize == 1)
        return pixCopy(NULL, pixs);

    if (vsize == 1) {  /* horizontal sel */
        leftpix = (hsize + 1) / 2;
        rightpix = (3 * hsize + 1) / 2;
        toppix = 0;
        bottompix = 0;
    }
    else if (hsize == 1) {  /* vertical sel */
        leftpix = 0;
        rightpix = 0;
        toppix = (vsize + 1) / 2;
        bottompix = (3 * vsize + 1) / 2;
    }
    else {
        leftpix = (hsize + 1) / 2;
        rightpix = (3 * hsize + 1) / 2;
        toppix = (vsize + 1) / 2;
        bottompix = (3 * vsize + 1) / 2;
    }

    if ((pixb = pixAddBorderGeneral(pixs,
                leftpix, rightpix, toppix, bottompix, 255)) == NULL)
        return (PIX *)ERROR_PTR("pixb not made", procName, NULL);
    if ((pixt = pixCreateTemplate(pixb)) == NULL)
        return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
    
    pixGetDimensions(pixt, &w, &h, NULL);
    datab = pixGetData(pixb);
    datat = pixGetData(pixt);
    wplb = pixGetWpl(pixb);
    wplt = pixGetWpl(pixt);

    if ((buffer = (l_uint8 *)CALLOC(L_MAX(w, h), sizeof(l_uint8))) == NULL)
        return (PIX *)ERROR_PTR("buffer not made", procName, NULL);
    maxsize = L_MAX(hsize, vsize);
    if ((minarray = (l_uint8 *)CALLOC(2 * maxsize, sizeof(l_uint8))) == NULL)
        return (PIX *)ERROR_PTR("minarray not made", procName, NULL);

    if (vsize == 1)
        erodeGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
                     buffer, minarray);
    else if (hsize == 1)
        erodeGrayLow(datat, w, h, wplt, datab, wplb, vsize, L_VERT,
                     buffer, minarray);
    else {
        erodeGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
                     buffer, minarray);
        pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
                            PIX_SET);
        erodeGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
                     buffer, minarray);
        pixDestroy(&pixt);
        pixt = pixClone(pixb);
    }

    if ((pixd = pixRemoveBorderGeneral(pixt,
                leftpix, rightpix, toppix, bottompix)) == NULL)
        return (PIX *)ERROR_PTR("pixd not made", procName, NULL);

    FREE(buffer);
    FREE(minarray);
    pixDestroy(&pixb);
    pixDestroy(&pixt);
    return pixd;
}
コード例 #8
0
ファイル: dwalinear.3.c プロジェクト: 0359xiaodong/tess-two
/*!
 *  pixFMorphopGen_3()
 *
 *      Input:  pixd (usual 3 choices: null, == pixs, != pixs)
 *              pixs (1 bpp)
 *              operation  (L_MORPH_DILATE, L_MORPH_ERODE,
 *                          L_MORPH_OPEN, L_MORPH_CLOSE)
 *              sel name
 *      Return: pixd
 *
 *  Notes:
 *      (1) This is a dwa operation, and the Sels must be limited in
 *          size to not more than 31 pixels about the origin.
 *      (2) A border of appropriate size (32 pixels, or 64 pixels
 *          for safe closing with asymmetric b.c.) must be added before
 *          this function is called.
 *      (3) This handles all required setting of the border pixels
 *          before erosion and dilation.
 *      (4) The closing operation is safe; no pixels can be removed
 *          near the boundary.
 */
PIX *
pixFMorphopGen_3(PIX     *pixd,
                 PIX     *pixs,
                 l_int32  operation,
                 char    *selname)
{
l_int32    i, index, found, w, h, wpls, wpld, bordercolor, erodeop, borderop;
l_uint32  *datad, *datas, *datat;
PIX       *pixt;

    PROCNAME("pixFMorphopGen_3");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
    if (pixGetDepth(pixs) != 1)
        return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);

        /* Get boundary colors to use */
    bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
    if (bordercolor == 1)
        erodeop = PIX_SET;
    else
        erodeop = PIX_CLR;

    found = FALSE;
    for (i = 0; i < NUM_SELS_GENERATED; i++) {
        if (strcmp(selname, SEL_NAMES[i]) == 0) {
            found = TRUE;
            index = 2 * i;
            break;
        }
    }
    if (found == FALSE)
        return (PIX *)ERROR_PTR("sel index not found", procName, pixd);

    if (!pixd) {
        if ((pixd = pixCreateTemplate(pixs)) == NULL)
            return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
    }
    else  /* for in-place or pre-allocated */
        pixResizeImageData(pixd, pixs);
    wpls = pixGetWpl(pixs);
    wpld = pixGetWpl(pixd);

        /* The images must be surrounded, in advance, with a border of
         * size 32 pixels (or 64, for closing), that we'll read from.
         * Fabricate a "proper" image as the subimage within the 32
         * pixel border, having the following parameters:  */
    w = pixGetWidth(pixs) - 64;
    h = pixGetHeight(pixs) - 64;
    datas = pixGetData(pixs) + 32 * wpls + 1;
    datad = pixGetData(pixd) + 32 * wpld + 1;

    if (operation == L_MORPH_DILATE || operation == L_MORPH_ERODE) {
        borderop = PIX_CLR;
        if (operation == L_MORPH_ERODE) {
            borderop = erodeop;
            index++;
        }
        if (pixd == pixs) {  /* in-place; generate a temp image */
            if ((pixt = pixCopy(NULL, pixs)) == NULL)
                return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
            datat = pixGetData(pixt) + 32 * wpls + 1;
            pixSetOrClearBorder(pixt, 32, 32, 32, 32, borderop);
            fmorphopgen_low_3(datad, w, h, wpld, datat, wpls, index);
            pixDestroy(&pixt);
        }
        else { /* not in-place */
            pixSetOrClearBorder(pixs, 32, 32, 32, 32, borderop);
            fmorphopgen_low_3(datad, w, h, wpld, datas, wpls, index);
        }
    }
    else {  /* opening or closing; generate a temp image */
        if ((pixt = pixCreateTemplate(pixs)) == NULL)
            return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
        datat = pixGetData(pixt) + 32 * wpls + 1;
        if (operation == L_MORPH_OPEN) {
            pixSetOrClearBorder(pixs, 32, 32, 32, 32, erodeop);
            fmorphopgen_low_3(datat, w, h, wpls, datas, wpls, index+1);
            pixSetOrClearBorder(pixt, 32, 32, 32, 32, PIX_CLR);
            fmorphopgen_low_3(datad, w, h, wpld, datat, wpls, index);
        }
        else {  /* closing */
            pixSetOrClearBorder(pixs, 32, 32, 32, 32, PIX_CLR);
            fmorphopgen_low_3(datat, w, h, wpls, datas, wpls, index);
            pixSetOrClearBorder(pixt, 32, 32, 32, 32, erodeop);
            fmorphopgen_low_3(datad, w, h, wpld, datat, wpls, index+1);
        }
        pixDestroy(&pixt);
    }

    return pixd;
}
コード例 #9
0
ファイル: watershed_reg.c プロジェクト: chewi/leptonica
void
DoWatershed(L_REGPARAMS  *rp,
            PIX          *pixs)
{
l_uint8   *data;
size_t     size;
l_int32    w, h, empty;
l_uint32   redval, greenval;
L_WSHED   *wshed;
PIX       *pixc, *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pix8, *pix9;
PIXA      *pixa;
PTA       *pta;

        /* Find local extrema */
    pixa = pixaCreate(0);
    pixGetDimensions(pixs, &w, &h, NULL);
    regTestWritePixAndCheck(rp, pixs, IFF_PNG);  /* 0 */
    pixSaveTiled(pixs, pixa, 1.0, 1, 10, 32);
    startTimer();
    pixLocalExtrema(pixs, 0, 0, &pix1, &pix2);
    fprintf(stderr, "Time for extrema: %7.3f\n", stopTimer());
    pixSetOrClearBorder(pix1, 2, 2, 2, 2, PIX_CLR);
    composeRGBPixel(255, 0, 0, &redval);
    composeRGBPixel(0, 255, 0, &greenval);
    pixc = pixConvertTo32(pixs);
    pixPaintThroughMask(pixc, pix2, 0, 0, greenval);
    pixPaintThroughMask(pixc, pix1, 0, 0, redval);
    regTestWritePixAndCheck(rp, pixc, IFF_PNG);  /* 1 */
    pixSaveTiled(pixc, pixa, 1.0, 0, 10, 32);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 2 */
    pixSaveTiled(pix1, pixa, 1.0, 0, 10, 32);

        /* Generate seeds for watershed */
    pixSelectMinInConnComp(pixs, pix1, &pta, NULL);
    pix3 = pixGenerateFromPta(pta, w, h);
    regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 3 */
    pixSaveTiled(pix3, pixa, 1.0, 1, 10, 32);
    pix4 = pixConvertTo32(pixs);
    pixPaintThroughMask(pix4, pix3, 0, 0, greenval);
    regTestWritePixAndCheck(rp, pix4, IFF_PNG);  /* 4 */
    pixSaveTiled(pix4, pixa, 1.0, 0, 10, 32);
    pix5 = pixRemoveSeededComponents(NULL, pix3, pix1, 8, 2);
    regTestWritePixAndCheck(rp, pix5, IFF_PNG);  /* 5 */
    pixSaveTiled(pix5, pixa, 1.0, 0, 10, 32);
    pixZero(pix5, &empty);
    regTestCompareValues(rp, 1, empty, 0.0);  /* 6 */

        /* Make and display watershed */
    wshed = wshedCreate(pixs, pix3, 10, 0);
    startTimer();
    wshedApply(wshed);
    fprintf(stderr, "Time for wshed: %7.3f\n", stopTimer());
    pix6 = pixaDisplayRandomCmap(wshed->pixad, w, h);
    regTestWritePixAndCheck(rp, pix6, IFF_PNG);  /* 7 */
    pixSaveTiled(pix6, pixa, 1.0, 1, 10, 32);
    numaWriteMem(&data, &size, wshed->nalevels);
    regTestWriteDataAndCheck(rp, data, size, "na");  /* 8 */
    pix7 = wshedRenderFill(wshed);
    regTestWritePixAndCheck(rp, pix7, IFF_PNG);  /* 9 */
    pixSaveTiled(pix7, pixa, 1.0, 0, 10, 32);
    pix8 = wshedRenderColors(wshed);
    regTestWritePixAndCheck(rp, pix8, IFF_PNG);  /* 10 */
    pixSaveTiled(pix8, pixa, 1.0, 0, 10, 32);
    wshedDestroy(&wshed);

    pix9 = pixaDisplay(pixa, 0, 0);
    regTestWritePixAndCheck(rp, pix9, IFF_PNG);  /* 11 */
    pixDisplayWithTitle(pix9, 100, 100, NULL, rp->display);

    lept_free(data);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);
    pixDestroy(&pix4);
    pixDestroy(&pix5);
    pixDestroy(&pix6);
    pixDestroy(&pix7);
    pixDestroy(&pix8);
    pixDestroy(&pix9);
    pixDestroy(&pixc);
    pixaDestroy(&pixa);
    ptaDestroy(&pta);
}