Leptonica  1.54
Файл src/boxfunc1.c
#include "allheaders.h"

Функции

l_int32 boxContains (BOX *box1, BOX *box2, l_int32 *presult)
l_int32 boxIntersects (BOX *box1, BOX *box2, l_int32 *presult)
BOXAboxaContainedInBox (BOXA *boxas, BOX *box)
BOXAboxaIntersectsBox (BOXA *boxas, BOX *box)
BOXAboxaClipToBox (BOXA *boxas, BOX *box)
BOXAboxaCombineOverlaps (BOXA *boxas)
BOXboxOverlapRegion (BOX *box1, BOX *box2)
BOXboxBoundingRegion (BOX *box1, BOX *box2)
l_int32 boxOverlapFraction (BOX *box1, BOX *box2, l_float32 *pfract)
l_int32 boxOverlapArea (BOX *box1, BOX *box2, l_int32 *parea)
BOXAboxaHandleOverlaps (BOXA *boxas, l_int32 op, l_int32 range, l_float32 min_overlap, l_float32 max_ratio, NUMA **pnamap)
l_int32 boxSeparationDistance (BOX *box1, BOX *box2, l_int32 *ph_sep, l_int32 *pv_sep)
l_int32 boxContainsPt (BOX *box, l_float32 x, l_float32 y, l_int32 *pcontains)
BOXboxaGetNearestToPt (BOXA *boxa, l_int32 x, l_int32 y)
l_int32 boxGetCenter (BOX *box, l_float32 *pcx, l_float32 *pcy)
l_int32 boxIntersectByLine (BOX *box, l_int32 x, l_int32 y, l_float32 slope, l_int32 *px1, l_int32 *py1, l_int32 *px2, l_int32 *py2, l_int32 *pn)
BOXboxClipToRectangle (BOX *box, l_int32 wi, l_int32 hi)
l_int32 boxClipToRectangleParams (BOX *box, l_int32 w, l_int32 h, l_int32 *pxstart, l_int32 *pystart, l_int32 *pxend, l_int32 *pyend, l_int32 *pbw, l_int32 *pbh)
BOXboxRelocateOneSide (BOX *boxd, BOX *boxs, l_int32 loc, l_int32 sideflag)
BOXboxAdjustSides (BOX *boxd, BOX *boxs, l_int32 delleft, l_int32 delright, l_int32 deltop, l_int32 delbot)
BOXAboxaSetSide (BOXA *boxad, BOXA *boxas, l_int32 side, l_int32 val, l_int32 thresh)
BOXAboxaAdjustWidthToTarget (BOXA *boxad, BOXA *boxas, l_int32 sides, l_int32 target, l_int32 thresh)
BOXAboxaAdjustHeightToTarget (BOXA *boxad, BOXA *boxas, l_int32 sides, l_int32 target, l_int32 thresh)
l_int32 boxEqual (BOX *box1, BOX *box2, l_int32 *psame)
l_int32 boxaEqual (BOXA *boxa1, BOXA *boxa2, l_int32 maxdist, NUMA **pnaindex, l_int32 *psame)
l_int32 boxSimilar (BOX *box1, BOX *box2, l_int32 leftdiff, l_int32 rightdiff, l_int32 topdiff, l_int32 botdiff, l_int32 *psimilar)
l_int32 boxaSimilar (BOXA *boxa1, BOXA *boxa2, l_int32 leftdiff, l_int32 rightdiff, l_int32 topdiff, l_int32 botdiff, l_int32 debug, l_int32 *psimilar, NUMA **pnasim)
l_int32 boxaJoin (BOXA *boxad, BOXA *boxas, l_int32 istart, l_int32 iend)
l_int32 boxaaJoin (BOXAA *baad, BOXAA *baas, l_int32 istart, l_int32 iend)
l_int32 boxaSplitEvenOdd (BOXA *boxa, l_int32 fillflag, BOXA **pboxae, BOXA **pboxao)
BOXAboxaMergeEvenOdd (BOXA *boxae, BOXA *boxao, l_int32 fillflag)

Функции

BOXA* boxaAdjustHeightToTarget ( BOXA boxad,
BOXA boxas,
l_int32  sides,
l_int32  target,
l_int32  thresh 
)

boxaAdjustHeightToTarget()

Input: boxad (use null to get a new one) boxas sides (L_ADJUST_TOP, L_ADJUST_BOT, L_ADJUST_TOP_AND_BOT) target (target height if differs by more than thresh) thresh (min abs difference in height to cause adjustment) Return: boxad, or null on error

Notes: (1) Conditionally adjusts the height of each box, by moving the indicated edges (top and/or bot) if the height differs by or more from . (2) Use boxad == NULL for a new boxa, and boxad == boxas for in-place. Use one of these: boxad = boxaAdjustHeightToTarget(NULL, boxas, ...); // new boxaAdjustHeightToTarget(boxas, boxas, ...); // in-place

BOXA* boxaAdjustWidthToTarget ( BOXA boxad,
BOXA boxas,
l_int32  sides,
l_int32  target,
l_int32  thresh 
)

boxaAdjustWidthToTarget()

Input: boxad (use null to get a new one; same as boxas for in-place) boxas sides (L_ADJUST_LEFT, L_ADJUST_RIGHT, L_ADJUST_LEFTL_AND_RIGHT) target (target width if differs by more than thresh) thresh (min abs difference in width to cause adjustment) Return: boxad, or null on error

Notes: (1) Conditionally adjusts the width of each box, by moving the indicated edges (left and/or right) if the width differs by or more from . (2) Use boxad == NULL for a new boxa, and boxad == boxas for in-place. Use one of these: boxad = boxaAdjustWidthToTarget(NULL, boxas, ...); // new boxaAdjustWidthToTarget(boxas, boxas, ...); // in-place

l_int32 boxaaJoin ( BOXAA baad,
BOXAA baas,
l_int32  istart,
l_int32  iend 
)

boxaaJoin()

Input: baad (dest boxaa; add to this one) baas (source boxaa; add from this one) istart (starting index in baas) iend (ending index in baas; use -1 to cat all) Return: 0 if OK, 1 on error

Notes: (1) This appends a clone of each indicated boxa in baas to baad (2) istart < 0 is taken to mean 'read from the start' (istart = 0) (3) iend < 0 means 'read to the end' (4) if baas == NULL, this is a no-op.

BOXA* boxaClipToBox ( BOXA boxas,
BOX box 
)

boxaClipToBox()

Input: boxas box (for clipping) Return boxad (boxa with boxes in boxas clipped to box), or null on error

Notes: (1) All boxes in boxa not intersecting with box are removed, and the remaining boxes are clipped to box.

BOXA* boxaCombineOverlaps ( BOXA boxas)

boxaCombineOverlaps()

Input: boxas Return: boxad (where each set of boxes in boxas that overlap are combined into a single bounding box in boxad), or null on error.

Notes: (1) If there are no overlapping boxes, it simply returns a copy of . (2) The alternative method of painting each rectanle and finding the 4-connected components gives the wrong result, because two non-overlapping rectangles, when rendered, can still be 4-connected, and hence they will be joined. (3) A bad case is to have n boxes, none of which overlap. Then you have one iteration with O(n^2) compares. This is still faster than painting each rectangle and finding the connected components, even for thousands of rectangles.

BOXA* boxaContainedInBox ( BOXA boxas,
BOX box 
)

boxaContainedInBox()

Input: boxas box (for containment) Return: boxad (boxa with all boxes in boxas that are entirely contained in box), or null on error

Notes: (1) All boxes in boxa that are entirely outside box are removed.

BOX* boxAdjustSides ( BOX boxd,
BOX boxs,
l_int32  delleft,
l_int32  delright,
l_int32  deltop,
l_int32  delbot 
)

boxAdjustSides()

Input: boxd (<optional>; this can be null, equal to boxs, or different from boxs) boxs (starting box; to have sides adjusted) delleft, delright, deltop, delbot (changes in location of each side) Return: boxd, or null on error or if the computed boxd has width or height <= 0.

Notes: (1) Set boxd == NULL to get new box; boxd == boxs for in-place; or otherwise to resize existing boxd. (2) For usage, suggest one of these: boxd = boxAdjustSides(NULL, boxs, ...); // new boxAdjustSides(boxs, boxs, ...); // in-place boxAdjustSides(boxd, boxs, ...); // other (1) New box dimensions are cropped at left and top to x >= 0 and y >= 0. (2) For example, to expand in-place by 20 pixels on each side, use boxAdjustSides(box, box, -20, 20, -20, 20);

l_int32 boxaEqual ( BOXA boxa1,
BOXA boxa2,
l_int32  maxdist,
NUMA **  pnaindex,
l_int32 psame 
)

boxaEqual()

Input: boxa1 boxa2 maxdist &naindex (<optional return>=""> index array of correspondences &same (<return> 1 if equal; 0 otherwise) Return 0 if OK, 1 on error

Notes: (1) The two boxa are the "same" if they contain the same boxes and each box is within of its counterpart in their positions within the boxa. This allows for small rearrangements. Use 0 for maxdist if the boxa must be identical. (2) This applies only to geometry and ordering; refcounts are not considered. (3) allows some latitude in the ordering of the boxes. For the boxa to be the "same", corresponding boxes must be within of each other. Note that for large , we should use a hash function for efficiency. (4) naindex[i] gives the position of the box in boxa2 that corresponds to box i in boxa1. It is only returned if the boxa are equal.

BOX* boxaGetNearestToPt ( BOXA boxa,
l_int32  x,
l_int32  y 
)

boxaGetNearestToPt()

Input: boxa x, y (point) Return box (box with centroid closest to the given point [x,y]), or NULL if no boxes in boxa)

Notes: (1) Uses euclidean distance between centroid and point.

BOXA* boxaHandleOverlaps ( BOXA boxas,
l_int32  op,
l_int32  range,
l_float32  min_overlap,
l_float32  max_ratio,
NUMA **  pnamap 
)

boxaHandleOverlaps()

Input: boxas op (L_COMBINE, L_REMOVE_SMALL) range (> 0, forward distance over which overlaps are checked) min_overlap (minimum fraction of smaller box required for overlap to count; 0.0 to ignore) max_ratio (maximum fraction of small/large areas for overlap to count; 1.0 to ignore) &namap (<optional return>=""> combining map) Return: boxad, or null on error.

Notes: (1) For all n(n-1)/2 box pairings, if two boxes overlap, either: (a) op == L_COMBINE: get the bounding region for the two, replace the larger with the bounding region, and remove the smaller of the two, or (b) op == L_REMOVE_SMALL: just remove the smaller. (2) If boxas is 2D sorted, range can be small, but if it is not spatially sorted, range should be large to allow all pairwise comparisons to be made. (3) The parameter allows ignoring small overlaps. If == 1.0, only boxes fully contained in larger boxes can be considered for removal; if == 0.0, this constraint is ignored. (4) The parameter allows ignoring overlaps between boxes that are not too different in size. If == 0.0, no boxes can be removed; if == 1.0, this constraint is ignored.

BOXA* boxaIntersectsBox ( BOXA boxas,
BOX box 
)

boxaIntersectsBox()

Input: boxas box (for intersecting) Return boxad (boxa with all boxes in boxas that intersect box), or null on error

Notes: (1) All boxes in boxa that intersect with box (i.e., are completely or partially contained in box) are retained.

l_int32 boxaJoin ( BOXA boxad,
BOXA boxas,
l_int32  istart,
l_int32  iend 
)

boxaJoin()

Input: boxad (dest boxa; add to this one) boxas (source boxa; add from this one) istart (starting index in boxas) iend (ending index in boxas; use -1 to cat all) Return: 0 if OK, 1 on error

Notes: (1) This appends a clone of each indicated box in boxas to boxad (2) istart < 0 is taken to mean 'read from the start' (istart = 0) (3) iend < 0 means 'read to the end' (4) if boxas == NULL or has no boxes, this is a no-op.

BOXA* boxaMergeEvenOdd ( BOXA boxae,
BOXA boxao,
l_int32  fillflag 
)

boxaMergeEvenOdd()

Input: boxae (boxes to go in even positions in merged boxa) boxao (boxes to go in odd positions in merged boxa) fillflag (1 if there are invalid boxes in placeholders) Return: boxad (merged), or null on error

Notes: (1) This is essentially the inverse of boxaSplitEvenOdd(). Typically, boxae and boxao were generated by boxaSplitEvenOdd(), and the value of needs to be the same in both calls. (2) If == 1, both boxae and boxao are of the same size; otherwise boxae may have one more box than boxao.

BOXA* boxaSetSide ( BOXA boxad,
BOXA boxas,
l_int32  side,
l_int32  val,
l_int32  thresh 
)

boxaSetSide()

Input: boxad (use null to get a new one; same as boxas for in-place) boxas side (L_SET_LEFT, L_SET_RIGHT, L_SET_TOP, L_SET_BOT) val (location to set for given side, for each box) thresh (min abs difference to cause resetting to ) Return: boxad, or null on error

Notes: (1) Sets the given side of each box. Use boxad == NULL for a new boxa, and boxad == boxas for in-place. (2) Use one of these: boxad = boxaSetSide(NULL, boxas, ...); // new boxaSetSide(boxas, boxas, ...); // in-place

l_int32 boxaSimilar ( BOXA boxa1,
BOXA boxa2,
l_int32  leftdiff,
l_int32  rightdiff,
l_int32  topdiff,
l_int32  botdiff,
l_int32  debug,
l_int32 psimilar,
NUMA **  pnasim 
)

boxaSimilar()

Input: boxa1 boxa2 leftdiff, rightdiff, topdiff, botdiff debug (output details of non-similar boxes) &similar (<return> 1 if similar; 0 otherwise) &nasim (<optional return>=""> na containing 1 if similar; else 0) Return 0 if OK, 1 on error

Notes: (1) See boxSimilar() for parameter usage. (2) Corresponding boxes are taken in order in the two boxa. (3) is an indicator array with a (0/1) for each box pair. (4) With or debug == 1, boxes continue to be tested after failure.

l_int32 boxaSplitEvenOdd ( BOXA boxa,
l_int32  fillflag,
BOXA **  pboxae,
BOXA **  pboxao 
)

boxaSplitEvenOdd()

Input: boxa fillflag (1 to put invalid boxes in place; 0 to omit) &boxae, &boxao (<return> save even and odd boxes in their separate boxa, setting the other type to invalid boxes.) Return: 0 if OK, 1 on error

Notes: (1) If == 1, boxae has copies of the even boxes in their original location, and nvalid boxes are placed in the odd array locations. And v.v. (2) If == 0, boxae has only copies of the even boxes.

BOX* boxBoundingRegion ( BOX box1,
BOX box2 
)

boxBoundingRegion()

Input: box1, box2 (two boxes) Return: box (of bounding region containing the input boxes), or null on error

Notes: (1) This is the geometric union of the two rectangles.

BOX* boxClipToRectangle ( BOX box,
l_int32  wi,
l_int32  hi 
)

boxClipToRectangle()

Input: box wi, hi (rectangle representing image) Return: part of box within given rectangle, or NULL on error or if box is entirely outside the rectangle

Notes: (1) This can be used to clip a rectangle to an image. The clipping rectangle is assumed to have a UL corner at (0, 0), and a LR corner at (wi - 1, hi - 1).

l_int32 boxClipToRectangleParams ( BOX box,
l_int32  w,
l_int32  h,
l_int32 pxstart,
l_int32 pystart,
l_int32 pxend,
l_int32 pyend,
l_int32 pbw,
l_int32 pbh 
)

boxClipToRectangleParams()

Input: box (<optional> requested box; can be null) w, h (clipping box size; typ. the size of an image) &xstart (<return>) &ystart (<return>) &xend (<return> one pixel beyond clipping box) &yend (<return> one pixel beyond clipping box) &bw (<optional return>=""> clipped width) &bh (<optional return>=""> clipped height) Return: 0 if OK; 1 on error

Notes: (1) The return value should be checked. If it is 1, the returned parameter values are bogus. (2) This simplifies the selection of pixel locations within a given rectangle: for (i = ystart; i < yend; i++ { ... for (j = xstart; j < xend; j++ { ....

l_int32 boxContains ( BOX box1,
BOX box2,
l_int32 presult 
)

boxContains()

Input: box1, box2 &result (<return> 1 if box2 is entirely contained within box1, and 0 otherwise) Return: 0 if OK, 1 on error

l_int32 boxContainsPt ( BOX box,
l_float32  x,
l_float32  y,
l_int32 pcontains 
)

boxContainsPt()

Input: box x, y (a point) &contains (<return> 1 if box contains point; 0 otherwise) Return: 0 if OK, 1 on error.

l_int32 boxEqual ( BOX box1,
BOX box2,
l_int32 psame 
)

boxEqual()

Input: box1 box2 &same (<return> 1 if equal; 0 otherwise) Return 0 if OK, 1 on error

l_int32 boxGetCenter ( BOX box,
l_float32 pcx,
l_float32 pcy 
)

boxGetCenter()

Input: box &cx, &cy (<return> location of center of box) Return 0 if OK, 1 on error

l_int32 boxIntersectByLine ( BOX box,
l_int32  x,
l_int32  y,
l_float32  slope,
l_int32 px1,
l_int32 py1,
l_int32 px2,
l_int32 py2,
l_int32 pn 
)

boxIntersectByLine()

Input: box x, y (point that line goes through) slope (of line) (&x1, &y1) (<return> 1st point of intersection with box) (&x2, &y2) (<return> 2nd point of intersection with box) &n (<return> number of points of intersection) Return: 0 if OK, 1 on error

Notes: (1) If the intersection is at only one point (a corner), the coordinates are returned in (x1, y1). (2) Represent a vertical line by one with a large but finite slope.

l_int32 boxIntersects ( BOX box1,
BOX box2,
l_int32 presult 
)

boxIntersects()

Input: box1, box2 &result (<return> 1 if any part of box2 is contained in box1, and 0 otherwise) Return: 0 if OK, 1 on error

l_int32 boxOverlapArea ( BOX box1,
BOX box2,
l_int32 parea 
)

boxOverlapArea()

Input: box1, box2 (two boxes) &area (<return> the number of pixels in the overlap) Return: 0 if OK, 1 on error.

l_int32 boxOverlapFraction ( BOX box1,
BOX box2,
l_float32 pfract 
)

boxOverlapFraction()

Input: box1, box2 (two boxes) &fract (<return> the fraction of box2 overlapped by box1) Return: 0 if OK, 1 on error.

Notes: (1) The result depends on the order of the input boxes, because the overlap is taken as a fraction of box2.

BOX* boxOverlapRegion ( BOX box1,
BOX box2 
)

boxOverlapRegion()

Input: box1, box2 (two boxes) Return: box (of overlap region between input boxes), or null if no overlap or on error

Notes: (1) This is the geometric intersection of the two rectangles.

BOX* boxRelocateOneSide ( BOX boxd,
BOX boxs,
l_int32  loc,
l_int32  sideflag 
)

boxRelocateOneSide()

Input: boxd (<optional>; this can be null, equal to boxs, or different from boxs); boxs (starting box; to have one side relocated) loc (new location of the side that is changing) sideflag (L_FROM_LEFT, etc., indicating the side that moves) Return: boxd, or null on error or if the computed boxd has width or height <= 0.

Notes: (1) Set boxd == NULL to get new box; boxd == boxs for in-place; or otherwise to resize existing boxd. (2) For usage, suggest one of these: boxd = boxRelocateOneSide(NULL, boxs, ...); // new boxRelocateOneSide(boxs, boxs, ...); // in-place boxRelocateOneSide(boxd, boxs, ...); // other

l_int32 boxSeparationDistance ( BOX box1,
BOX box2,
l_int32 ph_sep,
l_int32 pv_sep 
)

boxSeparationDistance()

Input: box1, box2 (two boxes, in any order) &h_sep (<optional return>=""> horizontal separation) &v_sep (<optional return>=""> vertical separation) Return: 0 if OK, 1 on error

Notes: (1) This measures horizontal and vertical separation of the two boxes. If the boxes are touching but have no pixels in common, the separation is 0. If the boxes overlap by a distance d, the returned separation is -d.

l_int32 boxSimilar ( BOX box1,
BOX box2,
l_int32  leftdiff,
l_int32  rightdiff,
l_int32  topdiff,
l_int32  botdiff,
l_int32 psimilar 
)

boxSimilar()

Input: box1 box2 leftdiff, rightdiff, topdiff, botdiff &similar (<return> 1 if similar; 0 otherwise) Return 0 if OK, 1 on error

Notes: (1) The values of leftdiff (etc) are the maximum allowed deviations between the locations of the left (etc) sides. If any side pairs differ by more than this amount, the boxes are not similar.