Leptonica  1.82.0
Image processing and image analysis suite
rotate.c File Reference
#include <math.h>
#include "allheaders.h"

Go to the source code of this file.

Functions

PIXpixRotate (PIX *pixs, l_float32 angle, l_int32 type, l_int32 incolor, l_int32 width, l_int32 height)
 
PIXpixEmbedForRotation (PIX *pixs, l_float32 angle, l_int32 incolor, l_int32 width, l_int32 height)
 
PIXpixRotateBySampling (PIX *pixs, l_int32 xcen, l_int32 ycen, l_float32 angle, l_int32 incolor)
 
PIXpixRotateBinaryNice (PIX *pixs, l_float32 angle, l_int32 incolor)
 
PIXpixRotateWithAlpha (PIX *pixs, l_float32 angle, PIX *pixg, l_float32 fract)
 

Variables

l_float32 AlphaMaskBorderVals [2]
 
static const l_float32 MinAngleToRotate = 0.001
 
static const l_float32 Max1BppShearAngle = 0.06
 
static const l_float32 LimitShearAngle = 0.35
 

Detailed Description


    General rotation about image center
             PIX     *pixRotate()
             PIX     *pixEmbedForRotation()

    General rotation by sampling
             PIX     *pixRotateBySampling()

    Nice (slow) rotation of 1 bpp image
             PIX     *pixRotateBinaryNice()

    Rotation including alpha (blend) component
             PIX     *pixRotateWithAlpha()

    Rotations are measured in radians; clockwise is positive.

    The general rotation pixRotate() does the best job for
    rotating about the image center.  For 1 bpp, it uses shear;
    for others, it uses either shear or area mapping.
    If requested, it expands the output image so that no pixels are lost
    in the rotation, and this can be done on multiple successive shears
    without expanding beyond the maximum necessary size.

Definition in file rotate.c.

Function Documentation

◆ pixEmbedForRotation()

PIX* pixEmbedForRotation ( PIX pixs,
l_float32  angle,
l_int32  incolor,
l_int32  width,
l_int32  height 
)

pixEmbedForRotation()

Parameters
[in]pixs1, 2, 4, 8, 32 bpp rgb
[in]angleradians; clockwise is positive
[in]incolorL_BRING_IN_WHITE, L_BRING_IN_BLACK
[in]widthoriginal width; use 0 to avoid embedding
[in]heightoriginal height; use 0 to avoid embedding
Returns
pixd, or NULL on error
Notes:
     (1) For very small rotations, just return a clone.
     (2) Generate larger image to embed pixs if necessary, and
         place the center of the input image in the center.
     (3) Rotation brings either white or black pixels in
         from outside the image.  For colormapped images where
         there is no white or black, a new color is added if
         possible for these pixels; otherwise, either the
         lightest or darkest color is used.  In most cases,
         the colormap will be removed prior to rotation.
     (4) The dest is to be expanded so that no image pixels
         are lost after rotation.  Input of the original width
         and height allows the expansion to stop at the maximum
         required size, which is a square with side equal to
         sqrt(w*w + h*h).
     (5) For an arbitrary angle, the expansion can be found by
         considering the UL and UR corners.  As the image is
         rotated, these move in an arc centered at the center of
         the image.  Normalize to a unit circle by dividing by half
         the image diagonal.  After a rotation of T radians, the UL
         and UR corners are at points T radians along the unit
         circle.  Compute the x and y coordinates of both these
         points and take the max of absolute values; these represent
         the half width and half height of the containing rectangle.
         The arithmetic is done using formulas for sin(a+b) and cos(a+b),
         where b = T.  For the UR corner, sin(a) = h/d and cos(a) = w/d.
         For the UL corner, replace a by (pi - a), and you have
         sin(pi - a) = h/d, cos(pi - a) = -w/d.  The equations
         given below follow directly.

Definition at line 243 of file rotate.c.

References L_BRING_IN_BLACK, and L_BRING_IN_WHITE.

◆ pixRotate()

PIX* pixRotate ( PIX pixs,
l_float32  angle,
l_int32  type,
l_int32  incolor,
l_int32  width,
l_int32  height 
)

pixRotate()

Parameters
[in]pixs1, 2, 4, 8, 32 bpp rgb
[in]angleradians; clockwise is positive
[in]typeL_ROTATE_AREA_MAP, L_ROTATE_SHEAR, L_ROTATE_SAMPLING
[in]incolorL_BRING_IN_WHITE, L_BRING_IN_BLACK
[in]widthoriginal width; use 0 to avoid embedding
[in]heightoriginal height; use 0 to avoid embedding
Returns
pixd, or NULL on error
Notes:
     (1) This is a high-level, simple interface for rotating images
         about their center.
     (2) For very small rotations, just return a clone.
     (3) Rotation brings either white or black pixels in
         from outside the image.
     (4) The rotation type is adjusted if necessary for the image
         depth and size of rotation angle.  For 1 bpp images, we
         rotate either by shear or sampling.
     (5) Colormaps are removed for rotation by area mapping.
     (6) The dest can be expanded so that no image pixels
         are lost.  To invoke expansion, input the original
         width and height.  For repeated rotation, use of the
         original width and height allows the expansion to
         stop at the maximum required size, which is a square
         with side = sqrt(w*w + h*h).

Definition at line 101 of file rotate.c.

References L_BRING_IN_BLACK, L_BRING_IN_WHITE, L_ROTATE_AREA_MAP, L_ROTATE_SAMPLING, and L_ROTATE_SHEAR.

◆ pixRotateBinaryNice()

PIX* pixRotateBinaryNice ( PIX pixs,
l_float32  angle,
l_int32  incolor 
)

pixRotateBinaryNice()

Parameters
[in]pixs1 bpp
[in]angleradians; clockwise is positive; about the center
[in]incolorL_BRING_IN_WHITE, L_BRING_IN_BLACK
Returns
pixd, or NULL on error
Notes:
     (1) For very small rotations, just return a clone.
     (2) This does a computationally expensive rotation of 1 bpp images.
         The fastest rotators (using shears or subsampling) leave
         visible horizontal and vertical shear lines across which
         the image shear changes by one pixel.  To ameliorate the
         visual effect one can introduce random dithering.  One
         way to do this in a not-too-random fashion is given here.
         We convert to 8 bpp, do a very small blur, rotate using
         linear interpolation (same as area mapping), do a
         small amount of sharpening to compensate for the initial
         blur, and threshold back to binary.  The shear lines
         are magically removed.
     (3) This operation is about 5x slower than rotation by sampling.

Definition at line 457 of file rotate.c.

◆ pixRotateBySampling()

PIX* pixRotateBySampling ( PIX pixs,
l_int32  xcen,
l_int32  ycen,
l_float32  angle,
l_int32  incolor 
)

pixRotateBySampling()

Parameters
[in]pixs1, 2, 4, 8, 16, 32 bpp rgb; can be cmapped
[in]xcenx value of center of rotation
[in]yceny value of center of rotation
[in]angleradians; clockwise is positive
[in]incolorL_BRING_IN_WHITE, L_BRING_IN_BLACK
Returns
pixd, or NULL on error
Notes:
     (1) For very small rotations, just return a clone.
     (2) Rotation brings either white or black pixels in
         from outside the image.
     (3) Colormaps are retained.

Definition at line 324 of file rotate.c.

References L_BRING_IN_BLACK, L_BRING_IN_WHITE, and pixGetDimensions().

◆ pixRotateWithAlpha()

PIX* pixRotateWithAlpha ( PIX pixs,
l_float32  angle,
PIX pixg,
l_float32  fract 
)

pixRotateWithAlpha()

Parameters
[in]pixs32 bpp rgb or cmapped
[in]angleradians; clockwise is positive
[in]pixg[optional] 8 bpp, can be null
[in]fractbetween 0.0 and 1.0, with 0.0 fully transparent and 1.0 fully opaque
Returns
pixd 32 bpp rgba, or NULL on error
Notes:
     (1) The alpha channel is transformed separately from pixs,
         and aligns with it, being fully transparent outside the
         boundary of the transformed pixs.  For pixels that are fully
         transparent, a blending function like pixBlendWithGrayMask()
         will give zero weight to corresponding pixels in pixs.
     (2) Rotation is about the center of the image; for very small
         rotations, just return a clone.  The dest is automatically
         expanded so that no image pixels are lost.
     (3) Rotation is by area mapping.  It doesn't matter what
         color is brought in because the alpha channel will
         be transparent (black) there.
     (4) If pixg is NULL, it is generated as an alpha layer that is
         partially opaque, using fract.  Otherwise, it is cropped
         to pixs if required and fract is ignored.  The alpha
         channel in pixs is never used.
     (4) Colormaps are removed to 32 bpp.
     (5) The default setting for the border values in the alpha channel
         is 0 (transparent) for the outermost ring of pixels and
         (0.5 * fract * 255) for the second ring.  When blended over
         a second image, this
         (a) shrinks the visible image to make a clean overlap edge
             with an image below, and
         (b) softens the edges by weakening the aliasing there.
         Use l_setAlphaMaskBorder() to change these values.
     (6) A subtle use of gamma correction is to remove gamma correction
         before rotation and restore it afterwards.  This is done
         by sandwiching this function between a gamma/inverse-gamma
         photometric transform:
             pixt = pixGammaTRCWithAlpha(NULL, pixs, 1.0 / gamma, 0, 255);
             pixd = pixRotateWithAlpha(pixt, angle, NULL, fract);
             pixGammaTRCWithAlpha(pixd, pixd, gamma, 0, 255);
             pixDestroy(&pixt);
         This has the side-effect of producing artifacts in the very
         dark regions.

Definition at line 535 of file rotate.c.

References pixGetDimensions().