src/jbclass.c
PIX *
pixWordMaskByDilation(PIX      *pixs,
                      l_int32   maxsize,
                      l_int32  *psize)
{
l_int32  i, diffmin, ndiff, imin;
l_int32  ncc[MAX_ALLOWED_DILATION + 1];
BOXA    *boxa;
NUMA    *nacc;
PIX     *pixt1, *pixt2, *pixt3;
PIXA    *pixa;
SEL     *sel;

    PROCNAME("pixWordMaskbyDilation");

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

        /* Find the optimal dilation to create the word mask.
         * Look for successively increasing dilations where the
         * number of connected components doesn't decrease.
         * This is the situation where the components in the
         * word mask should properly cover each word.  Use of
         * 4 cc slightly reduces the likelihood that words from
         * different lines are joined.  */
    diffmin = 1000000;
    pixa = pixaCreate(8);
    pixt1 = pixCopy(NULL, pixs);
    pixaAddPix(pixa, pixt1, L_COPY); 

    if (maxsize <= 0)
        maxsize = 7;  /* default */
    if (maxsize > MAX_ALLOWED_DILATION)
        maxsize = MAX_ALLOWED_DILATION;
    nacc = numaCreate(maxsize);
    for (i = 0; i <= maxsize; i++) {
        if (i == 0)     /* first one not dilated */
            pixt2 = pixCopy(NULL, pixt1); 
        else    /* successive dilation by sel_2h */
            pixt2 = pixMorphSequence(pixt1, "d2.1", 0);
        boxa = pixConnCompBB(pixt2, 4);
        ncc[i] = boxaGetCount(boxa);
        numaAddNumber(nacc, ncc[i]);
        if (i > 0) {
            ndiff = ncc[i - 1] - ncc[i];
#if  DEBUG_PLOT_CC
            fprintf(stderr, "ndiff[%d] = %d\n", i - 1, ndiff);
#endif  /* DEBUG_PLOT_CC */
            if (ndiff < diffmin) {
                imin = i;
                diffmin = ndiff;
            }
        }
        pixaAddPix(pixa, pixt2, L_COPY);
        pixDestroy(&pixt1);
        pixt1 = pixt2;
        boxaDestroy(&boxa);
    }
    pixDestroy(&pixt1);

#if  DEBUG_PLOT_CC
    {GPLOT *gplot;
     NUMA  *naseq;
        naseq = numaMakeSequence(1, 1, numaGetCount(nacc));
        gplot = gplotCreate("/tmp/cc_output", GPLOT_PNG,
                            "Number of cc vs. horizontal dilation",
                            "Sel horiz", "Number of cc");
        gplotAddPlot(gplot, naseq, nacc, GPLOT_LINES, "");
        gplotMakeOutput(gplot);
        gplotDestroy(&gplot);
        numaDestroy(&naseq);
    }
#endif  /* DEBUG_PLOT_CC */

        /* Save the result of the optimal dilation */
    pixt2 = pixaGetPix(pixa, imin, L_CLONE);
    sel = selCreateBrick(1, imin, 0, imin - 1, SEL_HIT);
    pixt3 = pixErode(NULL, pixt2, sel);  /* remove effect of dilation */
    selDestroy(&sel);
    pixDestroy(&pixt2);
    pixaDestroy(&pixa);
    if (psize)
        *psize = imin + 1;

    numaDestroy(&nacc);
    return pixt3;
}
/*!
 *  pixWordMaskByDilation()
 *
 *      Input:  pixs (1 bpp; typ. at 75 to 150 ppi)
 *              maxsize (use 0 for default; not to exceed 14)
 *              &size (<optional return> size of optimal horiz Sel)
 *      Return: pixd (dilated word mask), or null on error
 *
 *  Notes:
 *      (1) For 75 to 150 ppi, the optimal dilation should not exceed 7.
 *          This is the default size chosen if maxsize <= 0.
 *      (2) To run this on images at resolution between 200 and 300, it
 *          is advisable to use a larger maxsize, say between 10 and 14.
 *      (3) The best size for dilating to get word masks is optionally returned.
 */
pixWordMaskByDilation()
Input:  pixs (1 bpp; typ. at 75 to 150 ppi)
maxsize (use 0 for default; not to exceed 14)
&size ( size of optimal horiz Sel)
Return: pixd (dilated word mask), or null on error

(1) For 75 to 150 ppi, the optimal dilation should not exceed 7.
This is the default size chosen if maxsize <= 0.
(2) To run this on images at resolution between 200 and 300, it
is advisable to use a larger maxsize, say between 10 and 14.
(3) The best size for dilating to get word masks is optionally returned.
pixWordMaskByDilation () Input : pixs ( 1 bpp ; typ . at 75 to 150 ppi ) maxsize ( use 0 for default ; not to exceed 14 ) &size ( size of optimal horiz Sel ) Return : pixd ( dilated word mask ) or null on error ( 1 ) For 75 to 150 ppi the optimal dilation should not exceed 7 . This is the default size chosen if maxsize < = 0 . ( 2 ) To run this on images at resolution between 200 and 300 it is advisable to use a larger maxsize say between 10 and 14 . ( 3 ) The best size for dilating to get word masks is optionally returned .
PIX *
pixWordMaskByDilation(PIX      *pixs,
                      l_int32   maxsize,
                      l_int32  *psize)
{
l_int32  i, diffmin, ndiff, imin;
l_int32  ncc[MAX_ALLOWED_DILATION + 1];
BOXA    *boxa;
NUMA    *nacc;
PIX     *pixt1, *pixt2, *pixt3;
PIXA    *pixa;
SEL     *sel;
    PROCNAME("pixWordMaskbyDilation");
    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    diffmin = 1000000;
    pixa = pixaCreate(8);
    pixt1 = pixCopy(NULL, pixs);
    pixaAddPix(pixa, pixt1, L_COPY); 
    if (maxsize <= 0)
        maxsize = 7;  
    if (maxsize > MAX_ALLOWED_DILATION)
        maxsize = MAX_ALLOWED_DILATION;
    nacc = numaCreate(maxsize);
    for (i = 0; i <= maxsize; i++) {
        if (i == 0)     
            pixt2 = pixCopy(NULL, pixt1); 
        else    
            pixt2 = pixMorphSequence(pixt1, "d2.1", 0);
        boxa = pixConnCompBB(pixt2, 4);
        ncc[i] = boxaGetCount(boxa);
        numaAddNumber(nacc, ncc[i]);
        if (i > 0) {
            ndiff = ncc[i - 1] - ncc[i];
#if  DEBUG_PLOT_CC
            fprintf(stderr, "ndiff[%d] = %d\n", i - 1, ndiff);
#endif  
            if (ndiff < diffmin) {
                imin = i;
                diffmin = ndiff;
            }
        }
        pixaAddPix(pixa, pixt2, L_COPY);
        pixDestroy(&pixt1);
        pixt1 = pixt2;
        boxaDestroy(&boxa);
    }
    pixDestroy(&pixt1);
#if  DEBUG_PLOT_CC
    {GPLOT *gplot;
     NUMA  *naseq;
        naseq = numaMakeSequence(1, 1, numaGetCount(nacc));
        gplot = gplotCreate("/tmp/cc_output", GPLOT_PNG,
                            "Number of cc vs. horizontal dilation",
                            "Sel horiz", "Number of cc");
        gplotAddPlot(gplot, naseq, nacc, GPLOT_LINES, "");
        gplotMakeOutput(gplot);
        gplotDestroy(&gplot);
        numaDestroy(&naseq);
    }
#endif  
    pixt2 = pixaGetPix(pixa, imin, L_CLONE);
    sel = selCreateBrick(1, imin, 0, imin - 1, SEL_HIT);
    pixt3 = pixErode(NULL, pixt2, sel);  
    selDestroy(&sel);
    pixDestroy(&pixt2);
    pixaDestroy(&pixa);
    if (psize)
        *psize = imin + 1;
    numaDestroy(&nacc);
    return pixt3;
}
PIX * pixWordMaskByDilation ( PIX * pixs , l_int32 maxsize , l_int32 * psize ) { l_int32 i , diffmin , ndiff , imin ; l_int32 ncc [ MAX_ALLOWED_DILATION + 1 ] ; BOXA * boxa ; NUMA * nacc ; PIX * pixt1 , * pixt2 , * pixt3 ; PIXA * pixa ; SEL * sel ; PROCNAME ( " " ) ; if ( ! pixs ) return ( PIX * ) ERROR_PTR ( " " , procName , NULL ) ; diffmin = 1000000 ; pixa = pixaCreate ( 8 ) ; pixt1 = pixCopy ( NULL , pixs ) ; pixaAddPix ( pixa , pixt1 , L_COPY ) ; if ( maxsize <= 0 ) maxsize = 7 ; if ( maxsize > MAX_ALLOWED_DILATION ) maxsize = MAX_ALLOWED_DILATION ; nacc = numaCreate ( maxsize ) ; for ( i = 0 ; i <= maxsize ; i ++ ) { if ( i == 0 ) pixt2 = pixCopy ( NULL , pixt1 ) ; else pixt2 = pixMorphSequence ( pixt1 , " " , 0 ) ; boxa = pixConnCompBB ( pixt2 , 4 ) ; ncc [ i ] = boxaGetCount ( boxa ) ; numaAddNumber ( nacc , ncc [ i ] ) ; if ( i > 0 ) { ndiff = ncc [ i - 1 ] - ncc [ i ] ; #if DEBUG_PLOT_CC fprintf ( stderr , " \n " , i - 1 , ndiff ) ; #endif if ( ndiff < diffmin ) { imin = i ; diffmin = ndiff ; } } pixaAddPix ( pixa , pixt2 , L_COPY ) ; pixDestroy ( & pixt1 ) ; pixt1 = pixt2 ; boxaDestroy ( & boxa ) ; } pixDestroy ( & pixt1 ) ; #if DEBUG_PLOT_CC { GPLOT * gplot ; NUMA * naseq ; naseq = numaMakeSequence ( 1 , 1 , numaGetCount ( nacc ) ) ; gplot = gplotCreate ( " " , GPLOT_PNG , " " , " " , " " ) ; gplotAddPlot ( gplot , naseq , nacc , GPLOT_LINES , " " ) ; gplotMakeOutput ( gplot ) ; gplotDestroy ( & gplot ) ; numaDestroy ( & naseq ) ; } #endif pixt2 = pixaGetPix ( pixa , imin , L_CLONE ) ; sel = selCreateBrick ( 1 , imin , 0 , imin - 1 , SEL_HIT ) ; pixt3 = pixErode ( NULL , pixt2 , sel ) ; selDestroy ( & sel ) ; pixDestroy ( & pixt2 ) ; pixaDestroy ( & pixa ) ; if ( psize ) * psize = imin + 1 ; numaDestroy ( & nacc ) ; return pixt3 ; }
pixWordMaskByDilation()
      Input:  pixs (1 bpp; typ.
pixWordMaskByDilation () Input : pixs ( 1 bpp ; typ .
/* Find the optimal dilation to create the word mask.
         * Look for successively increasing dilations where the
         * number of connected components doesn't decrease.
         * This is the situation where the components in the
         * word mask should properly cover each word.  Use of
         * 4 cc slightly reduces the likelihood that words from
         * different lines are joined.  */ /* default */ /* first one not dilated */ /* successive dilation by sel_2h */ /* DEBUG_PLOT_CC */ /* DEBUG_PLOT_CC */ /* Save the result of the optimal dilation */ /* remove effect of dilation */