Leptonica  1.82.0
Image processing and image analysis suite
boxfunc3.c File Reference
#include "allheaders.h"

Go to the source code of this file.

Macros

#define DEBUG_SPLIT   0
 

Functions

static l_int32 pixSearchForRectangle (PIX *pixs, BOX *boxs, l_int32 minsum, l_int32 skipdist, l_int32 delta, l_int32 maxbg, l_int32 sideflag, BOXA *boxat, NUMA *nascore)
 
PIXpixMaskConnComp (PIX *pixs, l_int32 connectivity, BOXA **pboxa)
 
PIXpixMaskBoxa (PIX *pixd, PIX *pixs, BOXA *boxa, l_int32 op)
 
PIXpixPaintBoxa (PIX *pixs, BOXA *boxa, l_uint32 val)
 
PIXpixSetBlackOrWhiteBoxa (PIX *pixs, BOXA *boxa, l_int32 op)
 
PIXpixPaintBoxaRandom (PIX *pixs, BOXA *boxa)
 
PIXpixBlendBoxaRandom (PIX *pixs, BOXA *boxa, l_float32 fract)
 
PIXpixDrawBoxa (PIX *pixs, BOXA *boxa, l_int32 width, l_uint32 val)
 
PIXpixDrawBoxaRandom (PIX *pixs, BOXA *boxa, l_int32 width)
 
PIXboxaaDisplay (PIX *pixs, BOXAA *baa, l_int32 linewba, l_int32 linewb, l_uint32 colorba, l_uint32 colorb, l_int32 w, l_int32 h)
 
PIXApixaDisplayBoxaa (PIXA *pixas, BOXAA *baa, l_int32 colorflag, l_int32 width)
 
BOXApixSplitIntoBoxa (PIX *pixs, l_int32 minsum, l_int32 skipdist, l_int32 delta, l_int32 maxbg, l_int32 maxcomps, l_int32 remainder)
 
BOXApixSplitComponentIntoBoxa (PIX *pix, BOX *box, l_int32 minsum, l_int32 skipdist, l_int32 delta, l_int32 maxbg, l_int32 maxcomps, l_int32 remainder)
 
BOXAmakeMosaicStrips (l_int32 w, l_int32 h, l_int32 direction, l_int32 size)
 
l_ok boxaCompareRegions (BOXA *boxa1, BOXA *boxa2, l_int32 areathresh, l_int32 *pnsame, l_float32 *pdiffarea, l_float32 *pdiffxor, PIX **ppixdb)
 
BOXpixSelectLargeULComp (PIX *pixs, l_float32 areaslop, l_int32 yslop, l_int32 connectivity)
 
BOXboxaSelectLargeULBox (BOXA *boxas, l_float32 areaslop, l_int32 yslop)
 

Detailed Description

     Boxa/Boxaa painting into pix
          PIX             *pixMaskConnComp()
          PIX             *pixMaskBoxa()
          PIX             *pixPaintBoxa()
          PIX             *pixSetBlackOrWhiteBoxa()
          PIX             *pixPaintBoxaRandom()
          PIX             *pixBlendBoxaRandom()
          PIX             *pixDrawBoxa()
          PIX             *pixDrawBoxaRandom()
          PIX             *boxaaDisplay()
          PIXA            *pixaDisplayBoxaa()
     Split mask components into Boxa
          BOXA            *pixSplitIntoBoxa()
          BOXA            *pixSplitComponentIntoBoxa()
          static l_int32   pixSearchForRectangle()
     Represent horizontal or vertical mosaic strips
          BOXA            *makeMosaicStrips()
     Comparison between boxa
          l_int32          boxaCompareRegions()
     Reliable selection of a single large box
          BOX             *pixSelectLargeULComp()
          BOX             *boxaSelectLargeULBox()
 See summary in pixPaintBoxa() of various ways to paint and draw
 boxes on images.

Definition in file boxfunc3.c.

Function Documentation

◆ boxaaDisplay()

PIX* boxaaDisplay ( PIX pixs,
BOXAA baa,
l_int32  linewba,
l_int32  linewb,
l_uint32  colorba,
l_uint32  colorb,
l_int32  w,
l_int32  h 
)

boxaaDisplay()

Parameters
[in]pixs[optional] 1 bpp
[in]baaboxaa, typically from a 2d sort
[in]linewbaline width to display outline of each boxa
[in]linewbline width to display outline of each box
[in]colorbacolor to display boxa
[in]colorbcolor to display box
[in]wwidth of outupt pix; use 0 if determined by pixs or baa
[in]hheight of outupt pix; use 0 if determined by pixs or baa
Returns
0 if OK, 1 on error
Notes:
     (1) If pixs exists, this renders the boxes over an 8 bpp version
         of it.  Otherwise, it renders the boxes over an empty image
         with a white background.
     (2) If pixs exists, the dimensions of pixd are the same,
         and input values of w and h are ignored.
         If pixs is NULL, the dimensions of pixd are determined by
  • w and h if both are > 0, or
  • the minimum size required using all boxes in baa.
 

Definition at line 637 of file boxfunc3.c.

References boxaaGetExtent(), pixConvertTo8(), and pixGetDimensions().

◆ boxaCompareRegions()

l_ok boxaCompareRegions ( BOXA boxa1,
BOXA boxa2,
l_int32  areathresh,
l_int32 *  pnsame,
l_float32 *  pdiffarea,
l_float32 *  pdiffxor,
PIX **  ppixdb 
)

boxaCompareRegions()

Parameters
[in]boxa1,boxa2
[in]areathreshminimum area of boxes to be considered
[out]pnsametrue if same number of boxes
[out]pdiffareafractional difference in total area
[out]pdiffxor[optional] fractional difference in xor of regions
[out]ppixdb[optional] debug pix showing two boxa
Returns
0 if OK, 1 on error
Notes:
     (1) This takes 2 boxa, removes all boxes smaller than a given area,
         and compares the remaining boxes between the boxa.
     (2) The area threshold is introduced to help remove noise from
         small components.  Any box with a smaller value of w * h
         will be removed from consideration.
     (3) The xor difference is the most stringent test, requiring alignment
         of the corresponding boxes.  It is also more computationally
         intensive and is optionally returned.  Alignment is to the
         UL corner of each region containing all boxes, as given by
         boxaGetExtent().
     (4) Both fractional differences are with respect to the total
         area in the two boxa.  They range from 0.0 to 1.0.
         A perfect match has value 0.0.  If both boxa are empty,
         we return 0.0; if one is empty we return 1.0.
     (5) An example input might be the rectangular regions of a
         segmentation mask for text or images from two pages.

Definition at line 1390 of file boxfunc3.c.

References boxaDestroy(), boxaGetArea(), boxaGetCount(), boxaGetExtent(), boxaSelectByArea(), boxaTransform(), boxDestroy(), boxGetGeometry(), L_INSERT, L_NEG_SLOPE_LINE, L_POS_SLOPE_LINE, L_SELECT_IF_GTE, L_SET_PIXELS, makePixelSumTab8(), pixaAddPix(), pixaCreate(), pixaDestroy(), pixaDisplayTiledInRows(), pixAnd(), pixCountPixels(), pixCreate(), pixDestroy(), pixMaskBoxa(), pixPaintThroughMask(), pixRenderHashBoxaBlend(), pixSetAll(), and pixXor().

◆ boxaSelectLargeULBox()

BOX* boxaSelectLargeULBox ( BOXA boxas,
l_float32  areaslop,
l_int32  yslop 
)

boxaSelectLargeULBox()

Parameters
[in]boxas1 bpp
[in]areaslopfraction near but less than 1.0
[in]yslopnumber of pixels in y direction
Returns
box, or NULL on error
Notes:
     (1) See usage notes in pixSelectLargeULComp().

Definition at line 1575 of file boxfunc3.c.

References boxaAddBox(), boxaCreate(), boxaDestroy(), boxaGetBox(), boxaGetBoxGeometry(), boxaGetCount(), boxaSort(), L_COPY, L_INSERT, L_SORT_BY_AREA, L_SORT_BY_Y, L_SORT_DECREASING, and L_SORT_INCREASING.

Referenced by pixSelectLargeULComp().

◆ makeMosaicStrips()

BOXA* makeMosaicStrips ( l_int32  w,
l_int32  h,
l_int32  direction,
l_int32  size 
)

makeMosaicStrips()

Parameters
[in]w,h
[in]directionL_SCAN_HORIZONTAL or L_SCAN_VERTICAL
[in]sizeof strips in the scan direction
Returns
boxa, or NULL on error
Notes:
     (1) For example, this can be used to generate a pixa of
         vertical strips of width 10 from an image, using:
            pixGetDimensions(pix, &w, &h, NULL);
            boxa = makeMosaicStrips(w, h, L_SCAN_HORIZONTAL, 10);
            pixa = pixClipRectangles(pix, boxa);
         All strips except the last will be the same width.  The
         last strip will have width w % 10.

Definition at line 1311 of file boxfunc3.c.

References boxaAddBox(), boxaCreate(), boxCreate(), L_INSERT, L_SCAN_HORIZONTAL, and L_SCAN_VERTICAL.

◆ pixaDisplayBoxaa()

PIXA* pixaDisplayBoxaa ( PIXA pixas,
BOXAA baa,
l_int32  colorflag,
l_int32  width 
)

pixaDisplayBoxaa()

Parameters
[in]pixasany depth, can be cmapped
[in]baaboxes to draw on input pixa
[in]colorflagL_DRAW_RED, L_DRAW_GREEN, etc
[in]widththickness of lines
Returns
pixa with box outlines drawn on each pix, or NULL on error
Notes:
     (1) All pix in pixas that are not rgb are converted to rgb.
     (2) Each boxa in baa contains boxes that will be drawn on
         the corresponding pix in pixas.
     (3) The color of the boxes drawn on each pix are selected with
         colorflag:
           * For red, green or blue: use L_DRAW_RED, etc.
           * For sequential r, g, b: use L_DRAW_RGB
           * For random colors: use L_DRAW_RANDOM

Definition at line 719 of file boxfunc3.c.

References boxaaGetBoxa(), boxaaGetCount(), boxaDestroy(), boxaGetBox(), boxaGetCount(), boxDestroy(), composeRGBPixel(), extractRGBValues(), L_CLONE, L_COPY, L_DRAW_BLUE, L_DRAW_GREEN, L_DRAW_RANDOM, L_DRAW_RED, L_DRAW_RGB, L_INSERT, pixaAddPix(), pixaCreate(), pixaGetCount(), pixaGetPix(), and pixRenderBoxArb().

◆ pixBlendBoxaRandom()

PIX* pixBlendBoxaRandom ( PIX pixs,
BOXA boxa,
l_float32  fract 
)

pixBlendBoxaRandom()

Parameters
[in]pixsany depth; can be cmapped
[in]boxaof boxes, to blend/paint
[in]fractof box color to use
Returns
pixd 32 bpp, with blend/painted boxes, or NULL on error
Notes:
     (1) pixs is converted to 32 bpp.
     (2) This differs from pixPaintBoxaRandom(), in that the
         colors here are blended with the color of pixs.
     (3) We use up to 254 different colors for painting the regions.
     (4) If boxes overlap, the final color depends only on the last
         rect that is used.

Definition at line 438 of file boxfunc3.c.

References boxaGetBox(), boxaGetCount(), boxDestroy(), composeRGBPixel(), L_CLONE, pixBlendInRect(), pixcmapCreateRandom(), pixcmapDestroy(), pixcmapGetColor(), pixConvertTo32(), and pixCopy().

◆ pixDrawBoxa()

PIX* pixDrawBoxa ( PIX pixs,
BOXA boxa,
l_int32  width,
l_uint32  val 
)

pixDrawBoxa()

Parameters
[in]pixsany depth; can be cmapped
[in]boxaof boxes, to draw
[in]widthof lines
[in]valrgba color to draw
Returns
pixd with outlines of boxes added, or NULL on error
Notes:
     (1) If pixs is 1 bpp or is colormapped, it is converted to 8 bpp
         and the boxa is drawn using a colormap; otherwise,
         it is converted to 32 bpp rgb.

Definition at line 499 of file boxfunc3.c.

References boxaGetCount(), and pixCopy().

◆ pixDrawBoxaRandom()

PIX* pixDrawBoxaRandom ( PIX pixs,
BOXA boxa,
l_int32  width 
)

pixDrawBoxaRandom()

Parameters
[in]pixsany depth, can be cmapped
[in]boxaof boxes, to draw
[in]widththickness of line
Returns
pixd with box outlines drawn, or NULL on error
Notes:
     (1) If pixs is 1 bpp, we draw the boxa using a colormap;
         otherwise, we convert to 32 bpp.
     (2) We use up to 254 different colors for drawing the boxes.
     (3) If boxes overlap, the later ones draw over earlier ones.

Definition at line 563 of file boxfunc3.c.

References boxaGetCount(), and pixCopy().

◆ pixMaskBoxa()

PIX* pixMaskBoxa ( PIX pixd,
PIX pixs,
BOXA boxa,
l_int32  op 
)

pixMaskBoxa()

Parameters
[in]pixd[optional] may be NULL
[in]pixsany depth; not cmapped
[in]boxaof boxes, to paint
[in]opL_SET_PIXELS, L_CLEAR_PIXELS, L_FLIP_PIXELS
Returns
pixd with masking op over the boxes, or NULL on error
Notes:
     (1) This can be used with:
             pixd = NULL  (makes a new pixd)
             pixd = pixs  (in-place)
     (2) If pixd == NULL, this first makes a copy of pixs, and then
         bit-twiddles over the boxes.  Otherwise, it operates directly
         on pixs.
     (3) This simple function is typically used with 1 bpp images.
         It uses the 1-image rasterop function, rasteropUniLow(),
         to set, clear or flip the pixels in pixd.
     (4) If you want to generate a 1 bpp mask of ON pixels from the boxes
         in a Boxa, in a pix of size (w,h):
             pix = pixCreate(w, h, 1);
             pixMaskBoxa(pix, pix, boxa, L_SET_PIXELS);

Definition at line 151 of file boxfunc3.c.

Referenced by boxaCompareRegions().

◆ pixMaskConnComp()

PIX* pixMaskConnComp ( PIX pixs,
l_int32  connectivity,
BOXA **  pboxa 
)

pixMaskConnComp()

Parameters
[in]pixs1 bpp
[in]connectivity4 or 8
[out]pboxa[optional] bounding boxes of c.c.
Returns
pixd 1 bpp mask over the c.c., or NULL on error
Notes:
     (1) This generates a mask image with ON pixels over the
         b.b. of the c.c. in pixs.  If there are no ON pixels in pixs,
         pixd will also have no ON pixels.

Definition at line 97 of file boxfunc3.c.

◆ pixPaintBoxa()

PIX* pixPaintBoxa ( PIX pixs,
BOXA boxa,
l_uint32  val 
)

pixPaintBoxa()

Parameters
[in]pixsany depth, can be cmapped
[in]boxaof boxes, to paint
[in]valrgba color to paint
Returns
pixd with painted boxes, or NULL on error
Notes:
     (1) If pixs is 1 bpp or is colormapped, it is converted to 8 bpp
         and the boxa is painted using a colormap; otherwise,
         it is converted to 32 bpp rgb.
     (2) There are several ways to display a box on an image:
           * Paint it as a solid color
           * Draw the outline
           * Blend the outline or region with the existing image
         We provide painting and drawing here; blending is in blend.c.
         When painting or drawing, the result can be either a
         cmapped image or an rgb image.  The dest will be cmapped
         if the src is either 1 bpp or has a cmap that is not full.
         To force RGB output, use pixConvertTo8(pixs, FALSE)
         before calling any of these paint and draw functions.

Definition at line 220 of file boxfunc3.c.

References boxaGetCount(), and pixCopy().

◆ pixPaintBoxaRandom()

PIX* pixPaintBoxaRandom ( PIX pixs,
BOXA boxa 
)

pixPaintBoxaRandom()

Parameters
[in]pixsany depth, can be cmapped
[in]boxaof boxes, to paint
Returns
pixd with painted boxes, or NULL on error
Notes:
     (1) If pixs is 1 bpp, we paint the boxa using a colormap;
         otherwise, we convert to 32 bpp.
     (2) We use up to 254 different colors for painting the regions.
     (3) If boxes overlap, the later ones paint over earlier ones.

Definition at line 367 of file boxfunc3.c.

References boxaGetCount(), and pixCopy().

◆ pixSearchForRectangle()

static l_int32 pixSearchForRectangle ( PIX pixs,
BOX boxs,
l_int32  minsum,
l_int32  skipdist,
l_int32  delta,
l_int32  maxbg,
l_int32  sideflag,
BOXA boxat,
NUMA nascore 
)
static

pixSearchForRectangle()

Parameters
[in]pixs1 bpp
[in]boxscurrent region to investigate
[in]minsumminimum pixels to trigger propagation
[in]skipdistdistance before computing sum for propagation
[in]deltadifference required to stop propagation
[in]maxbgmaximum number of allowed bg pixels in ref scan
[in]sideflagside to search from
[in]boxatadd result of rectangular region found here
[in]nascoreadd score for this rectangle here
Returns
0 if OK, 1 on error
Notes:
     (1) See pixSplitComponentIntoBoxa() for an explanation of the algorithm.
         This does the sweep from a single side.  For each iteration
         in pixSplitComponentIntoBoxa(), this will be called 4 times,
         for sideflag = {0, 1, 2, 3}.
     (2) If a valid rectangle is not found, add a score of 0 and
         input a minimum box.

Definition at line 1062 of file boxfunc3.c.

◆ pixSelectLargeULComp()

BOX* pixSelectLargeULComp ( PIX pixs,
l_float32  areaslop,
l_int32  yslop,
l_int32  connectivity 
)

pixSelectLargeULComp()

Parameters
[in]pixs1 bpp
[in]areaslopfraction near but less than 1.0
[in]yslopnumber of pixels in y direction
[in]connectivity4 or 8
Returns
box, or NULL on error
Notes:
     (1) This selects a box near the top (first) and left (second)
         of the image, from the set of all boxes that have
               area >= areaslop * (area of biggest box),
         where areaslop is some fraction; say ~ 0.9.
     (2) For all boxes satisfying the above condition, select
         the left-most box that is within yslop (say, 20) pixels
         of the box nearest the top.
     (3) This can be used to reliably select a specific one of
         the largest regions in an image, for applications where
         there are expected to be small variations in region size
         and location.
     (4) See boxSelectLargeULBox() for implementation details.

Definition at line 1534 of file boxfunc3.c.

References boxaDestroy(), boxaGetCount(), boxaSelectLargeULBox(), and pixConnCompBB().

◆ pixSetBlackOrWhiteBoxa()

PIX* pixSetBlackOrWhiteBoxa ( PIX pixs,
BOXA boxa,
l_int32  op 
)

pixSetBlackOrWhiteBoxa()

Parameters
[in]pixsany depth, can be cmapped
[in]boxa[optional] of boxes, to clear or set
[in]opL_SET_BLACK, L_SET_WHITE
Returns
pixd with boxes filled with white or black, or NULL on error

Definition at line 286 of file boxfunc3.c.

References boxaGetCount(), and pixCopy().

◆ pixSplitComponentIntoBoxa()

BOXA* pixSplitComponentIntoBoxa ( PIX pix,
BOX box,
l_int32  minsum,
l_int32  skipdist,
l_int32  delta,
l_int32  maxbg,
l_int32  maxcomps,
l_int32  remainder 
)

pixSplitComponentIntoBoxa()

Parameters
[in]pix1 bpp
[in]box[optional] location of pix w/rt an origin
[in]minsumminimum pixels to trigger propagation
[in]skipdistdistance before computing sum for propagation
[in]deltadifference required to stop propagation
[in]maxbgmaximum number of allowed bg pixels in ref scan
[in]maxcompsuse 0 for unlimited number of subdivided components
[in]remainderset to 1 to get b.b. of remaining stuff
Returns
boxa of rectangles covering the fg of pix, or NULL on error
Notes:
     (1) This generates a boxa of rectangles that covers
         the fg of a mask.  It does so by a greedy partitioning of
         the mask, choosing the largest rectangle found from
         each of the four directions at each step.
     (2) The input parameters give some flexibility for boundary
         noise.  The resulting set of rectangles must cover all
         the fg pixels and, in addition, may cover some bg pixels.
         Using small input parameters on a noiseless mask (i.e., one
         that has only large vertical and horizontal edges) will
         result in a proper covering of only the fg pixels of the mask.
     (3) The input is assumed to be a single connected component, that
         may have holes.  From each side, sweep inward, counting
         the pixels.  If the count becomes greater than minsum,
         and we have moved forward a further amount skipdist,
         record that count ('countref'), but don't accept if the scan
         contains more than maxbg bg pixels.  Continue the scan
         until we reach a count that differs from countref by at
         least delta, at which point the propagation stops.  The box
         swept out gets a score, which is the sum of fg pixels
         minus a penalty.  The penalty is the number of bg pixels
         in the box.  This is done from all four sides, and the
         side with the largest score is saved as a rectangle.
         The process repeats until there is either no rectangle
         left, or there is one that can't be captured from any
         direction.  For the latter case, we simply accept the
         last rectangle.
     (4) The input box is only used to specify the location of
         the UL corner of pix, with respect to an origin that
         typically represents the UL corner of an underlying image,
         of which pix is one component.  If box is null,
         the UL corner is taken to be (0, 0).
     (5) The parameter maxcomps gives the maximum number of allowed
         rectangles extracted from any single connected component.
         Use 0 if no limit is to be applied.
     (6) The flag remainder specifies whether we take a final bounding
         box for anything left after the maximum number of allowed
         rectangle is extracted.
     (7) So if maxcomps > 0, it specifies that we want no more than
         the first maxcomps rectangles that satisfy the input
         criteria.  After this, we can get a final rectangle that
         bounds everything left over by setting remainder == 1.
         If remainder == 0, we only get rectangles that satisfy
         the input criteria.
     (8) It should be noted that the removal of rectangles can
         break the original c.c. into several c.c.
     (9) Summing up:
           * If maxcomp == 0, the splitting proceeds as far as possible.
           * If maxcomp > 0, the splitting stops when maxcomps are
               found, or earlier if no more components can be selected.
           * If remainder == 1 and components remain that cannot be
               selected, they are returned as a single final rectangle;
               otherwise, they are ignored.

Definition at line 947 of file boxfunc3.c.

◆ pixSplitIntoBoxa()

BOXA* pixSplitIntoBoxa ( PIX pixs,
l_int32  minsum,
l_int32  skipdist,
l_int32  delta,
l_int32  maxbg,
l_int32  maxcomps,
l_int32  remainder 
)

pixSplitIntoBoxa()

Parameters
[in]pixs1 bpp
[in]minsumminimum pixels to trigger propagation
[in]skipdistdistance before computing sum for propagation
[in]deltadifference required to stop propagation
[in]maxbgmaximum number of allowed bg pixels in ref scan
[in]maxcompsuse 0 for unlimited number of subdivided components
[in]remainderset to 1 to get b.b. of remaining stuff
Returns
boxa of rectangles covering the fg of pixs, or NULL on error
Notes:
     (1) This generates a boxa of rectangles that covers
         the fg of a mask.  For each 8-connected component in pixs,
         it does a greedy partitioning, choosing the largest
         rectangle found from each of the four directions at each iter.
         See pixSplitComponentIntoBoxa() for details.
     (2) The input parameters give some flexibility for boundary
         noise.  The resulting set of rectangles may cover some
         bg pixels.
     (3) This should be used when there are a small number of
         mask components, each of which has sides that are close
         to horizontal and vertical.  The input parameters delta
         and maxbg determine whether or not holes in the mask are covered.
     (4) The parameter maxcomps gives the maximum number of allowed
         rectangles extracted from any single connected component.
         Use 0 if no limit is to be applied.
     (5) The flag remainder specifies whether we take a final bounding
         box for anything left after the maximum number of allowed
         rectangle is extracted.

Definition at line 838 of file boxfunc3.c.