src/ptafunc1.c
PTAA *
ptaaGetBoundaryPixels(PIX     *pixs,
                      l_int32  type,
                      l_int32  connectivity,
                      BOXA   **pboxa,
                      PIXA   **ppixa)
{
l_int32  i, n, w, h, x, y, bw, bh, left, right, top, bot;
BOXA    *boxa;
PIX     *pixt1, *pixt2;
PIXA    *pixa;
PTA     *pta1, *pta2;
PTAA    *ptaa;

    PROCNAME("ptaaGetBoundaryPixels");

    if (pboxa) *pboxa = NULL;
    if (ppixa) *ppixa = NULL;
    if (!pixs || (pixGetDepth(pixs) != 1))
        return (PTAA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
    if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
        return (PTAA *)ERROR_PTR("invalid type", procName, NULL);
    if (connectivity != 4 && connectivity != 8)
        return (PTAA *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);

    pixGetDimensions(pixs, &w, &h, NULL);
    boxa = pixConnComp(pixs, &pixa, connectivity);
    n = boxaGetCount(boxa);
    ptaa = ptaaCreate(0);
    for (i = 0; i < n; i++) {
        pixt1 = pixaGetPix(pixa, i, L_CLONE);
        boxaGetBoxGeometry(boxa, i, &x, &y, &bw, &bh);
        left = right = top = bot = 0;
        if (type == L_BOUNDARY_BG) {
            if (x > 0) left = 1;
            if (y > 0) top = 1;
            if (x + bw < w) right = 1;
            if (y + bh < h) bot = 1;
            pixt2 = pixAddBorderGeneral(pixt1, left, right, top, bot, 0);
        }
        else
            pixt2 = pixClone(pixt1);
        pta1 = ptaGetBoundaryPixels(pixt2, type);
        pta2 = ptaTransform(pta1, x - left, y - top, 1.0, 1.0);
        ptaaAddPta(ptaa, pta2, L_INSERT);
        ptaDestroy(&pta1);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
    }

    if (pboxa)
        *pboxa = boxa;
    else
        boxaDestroy(&boxa);
    if (ppixa)
        *ppixa = pixa;
    else
        pixaDestroy(&pixa);
    return ptaa;
}
/*!
 *  ptaaGetBoundaryPixels()
 *
 *      Input:  pixs (1 bpp)
 *              type (L_BOUNDARY_FG, L_BOUNDARY_BG)
 *              connectivity (4 or 8)
 *              &boxa (<optional return> bounding boxes of the c.c.)
 *              &pixa (<optional return> pixa of the c.c.)
 *      Return: ptaa, or null on error
 *
 *  Notes:
 *      (1) This generates a ptaa of either fg or bg boundary pixels,
 *          where each pta has the boundary pixels for a connected
 *          component.
 *      (2) We can't simply find all the boundary pixels and then select
 *          those within the bounding box of each component, because
 *          bounding boxes can overlap.  It is necessary to extract and
 *          dilate or erode each component separately.  Note also that
 *          special handling is required for bg pixels when the
 *          component touches the pix boundary.
 */
ptaaGetBoundaryPixels()
Input:  pixs (1 bpp)
type (L_BOUNDARY_FG, L_BOUNDARY_BG)
connectivity (4 or 8)
&boxa ( bounding boxes of the c.c.)
&pixa ( pixa of the c.c.)
Return: ptaa, or null on error

(1) This generates a ptaa of either fg or bg boundary pixels,
where each pta has the boundary pixels for a connected
component.
(2) We can't simply find all the boundary pixels and then select
those within the bounding box of each component, because
bounding boxes can overlap.  It is necessary to extract and
dilate or erode each component separately.  Note also that
special handling is required for bg pixels when the
component touches the pix boundary.
ptaaGetBoundaryPixels () Input : pixs ( 1 bpp ) type ( L_BOUNDARY_FG L_BOUNDARY_BG ) connectivity ( 4 or 8 ) &boxa ( bounding boxes of the c . c . ) &pixa ( pixa of the c . c . ) Return : ptaa or null on error ( 1 ) This generates a ptaa of either fg or bg boundary pixels where each pta has the boundary pixels for a connected component . ( 2 ) We can ' t simply find all the boundary pixels and then select those within the bounding box of each component because bounding boxes can overlap . It is necessary to extract and dilate or erode each component separately . Note also that special handling is required for bg pixels when the component touches the pix boundary .
PTAA *
ptaaGetBoundaryPixels(PIX     *pixs,
                      l_int32  type,
                      l_int32  connectivity,
                      BOXA   **pboxa,
                      PIXA   **ppixa)
{
l_int32  i, n, w, h, x, y, bw, bh, left, right, top, bot;
BOXA    *boxa;
PIX     *pixt1, *pixt2;
PIXA    *pixa;
PTA     *pta1, *pta2;
PTAA    *ptaa;
    PROCNAME("ptaaGetBoundaryPixels");
    if (pboxa) *pboxa = NULL;
    if (ppixa) *ppixa = NULL;
    if (!pixs || (pixGetDepth(pixs) != 1))
        return (PTAA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
    if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
        return (PTAA *)ERROR_PTR("invalid type", procName, NULL);
    if (connectivity != 4 && connectivity != 8)
        return (PTAA *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
    pixGetDimensions(pixs, &w, &h, NULL);
    boxa = pixConnComp(pixs, &pixa, connectivity);
    n = boxaGetCount(boxa);
    ptaa = ptaaCreate(0);
    for (i = 0; i < n; i++) {
        pixt1 = pixaGetPix(pixa, i, L_CLONE);
        boxaGetBoxGeometry(boxa, i, &x, &y, &bw, &bh);
        left = right = top = bot = 0;
        if (type == L_BOUNDARY_BG) {
            if (x > 0) left = 1;
            if (y > 0) top = 1;
            if (x + bw < w) right = 1;
            if (y + bh < h) bot = 1;
            pixt2 = pixAddBorderGeneral(pixt1, left, right, top, bot, 0);
        }
        else
            pixt2 = pixClone(pixt1);
        pta1 = ptaGetBoundaryPixels(pixt2, type);
        pta2 = ptaTransform(pta1, x - left, y - top, 1.0, 1.0);
        ptaaAddPta(ptaa, pta2, L_INSERT);
        ptaDestroy(&pta1);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
    }
    if (pboxa)
        *pboxa = boxa;
    else
        boxaDestroy(&boxa);
    if (ppixa)
        *ppixa = pixa;
    else
        pixaDestroy(&pixa);
    return ptaa;
}
PTAA * ptaaGetBoundaryPixels ( PIX * pixs , l_int32 type , l_int32 connectivity , BOXA * * pboxa , PIXA * * ppixa ) { l_int32 i , n , w , h , x , y , bw , bh , left , right , top , bot ; BOXA * boxa ; PIX * pixt1 , * pixt2 ; PIXA * pixa ; PTA * pta1 , * pta2 ; PTAA * ptaa ; PROCNAME ( " " ) ; if ( pboxa ) * pboxa = NULL ; if ( ppixa ) * ppixa = NULL ; if ( ! pixs || ( pixGetDepth ( pixs ) != 1 ) ) return ( PTAA * ) ERROR_PTR ( " " , procName , NULL ) ; if ( type != L_BOUNDARY_FG && type != L_BOUNDARY_BG ) return ( PTAA * ) ERROR_PTR ( " " , procName , NULL ) ; if ( connectivity != 4 && connectivity != 8 ) return ( PTAA * ) ERROR_PTR ( " " , procName , NULL ) ; pixGetDimensions ( pixs , & w , & h , NULL ) ; boxa = pixConnComp ( pixs , & pixa , connectivity ) ; n = boxaGetCount ( boxa ) ; ptaa = ptaaCreate ( 0 ) ; for ( i = 0 ; i < n ; i ++ ) { pixt1 = pixaGetPix ( pixa , i , L_CLONE ) ; boxaGetBoxGeometry ( boxa , i , & x , & y , & bw , & bh ) ; left = right = top = bot = 0 ; if ( type == L_BOUNDARY_BG ) { if ( x > 0 ) left = 1 ; if ( y > 0 ) top = 1 ; if ( x + bw < w ) right = 1 ; if ( y + bh < h ) bot = 1 ; pixt2 = pixAddBorderGeneral ( pixt1 , left , right , top , bot , 0 ) ; } else pixt2 = pixClone ( pixt1 ) ; pta1 = ptaGetBoundaryPixels ( pixt2 , type ) ; pta2 = ptaTransform ( pta1 , x - left , y - top , 1.0 , 1.0 ) ; ptaaAddPta ( ptaa , pta2 , L_INSERT ) ; ptaDestroy ( & pta1 ) ; pixDestroy ( & pixt1 ) ; pixDestroy ( & pixt2 ) ; } if ( pboxa ) * pboxa = boxa ; else boxaDestroy ( & boxa ) ; if ( ppixa ) * ppixa = pixa ; else pixaDestroy ( & pixa ) ; return ptaa ; }
ptaaGetBoundaryPixels()
      Input:  pixs (1 bpp)
              type (L_BOUNDARY_FG, L_BOUNDARY_BG)
              connectivity (4 or 8)
              &boxa (<optional return> bounding boxes of the c.c.)
ptaaGetBoundaryPixels () Input : pixs ( 1 bpp ) type ( L_BOUNDARY_FG L_BOUNDARY_BG ) connectivity ( 4 or 8 ) &boxa ( <optional return > bounding boxes of the c . c . )