Ejemplo n.º 1
0
/*!
 *  pixRotateShearIP()
 *
 *      Input:  pixs (any depth; not colormapped)
 *              xcen, ycen (center of rotation)
 *              angle (radians)
 *              incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      (1) This does an in-place rotation of the image
 *          about the image center, using the 3-shear method.
 *      (2) A positive angle gives a clockwise rotation.
 *      (3) 3-shear rotation by a specified angle is equivalent
 *          to the sequential transformations
 *            y' = y + tan(angle/2) * (x - xcen)      for first y-shear
 *            x' = x + sin(angle) * (y - ycen)        for x-shear
 *            y' = y + tan(angle/2) * (x - xcen)      for second y-shear
 *      (4) Computation of tan(angle) is performed in the shear operations.
 *      (5) This brings in 'incolor' pixels from outside the image.
 *      (6) The pix cannot be colormapped, because the in-place operation
 *          only blits in 0 or 1 bits, not an arbitrary colormap index.
 */
l_int32
pixRotateShearIP(PIX       *pixs,
                 l_int32    xcen,
                 l_int32    ycen,
                 l_float32  angle,
                 l_int32    incolor)
{
l_float32  hangle;

    PROCNAME("pixRotateShearIP");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
        return ERROR_INT("invalid value for incolor", procName, 1);
    if (pixGetColormap(pixs) != NULL)
        return ERROR_INT("pixs is colormapped", procName, 1);

    if (angle == 0.0)
        return 0;

    hangle = atan(sin(angle));
    pixHShearIP(pixs, ycen, angle / 2., incolor);
    pixVShearIP(pixs, xcen, hangle, incolor);
    pixHShearIP(pixs, ycen, angle / 2., incolor);

    return 0;
}
Ejemplo n.º 2
0
/*!
 * \brief   pixRotateShearIP()
 *
 * \param[in]    pixs any depth; not colormapped
 * \param[in]    xcen, ycen center of rotation
 * \param[in]    angle radians
 * \param[in]    incolor L_BRING_IN_WHITE, L_BRING_IN_BLACK
 * \return  0 if OK; 1 on error
 *
 * <pre>
 * Notes:
 *      (1) This does an in-place rotation of the image about the
 *          specified point, using the 3-shear method.  It should only
 *          be used for angles smaller than LIMIT_SHEAR_ANGLE.
 *          For larger angles, a warning is issued.
 *      (2) A positive angle gives a clockwise rotation.
 *      (3) 3-shear rotation by a specified angle is equivalent
 *          to the sequential transformations
 *            y' = y + tan(angle/2) * (x - xcen)      for first y-shear
 *            x' = x + sin(angle) * (y - ycen)        for x-shear
 *            y' = y + tan(angle/2) * (x - xcen)      for second y-shear
 *      (4) Computation of tan(angle) is performed in the shear operations.
 *      (5) This brings in 'incolor' pixels from outside the image.
 *      (6) The pix cannot be colormapped, because the in-place operation
 *          only blits in 0 or 1 bits, not an arbitrary colormap index.
 * </pre>
 */
l_int32
pixRotateShearIP(PIX       *pixs,
                 l_int32    xcen,
                 l_int32    ycen,
                 l_float32  angle,
                 l_int32    incolor)
{
l_float32  hangle;

    PROCNAME("pixRotateShearIP");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
        return ERROR_INT("invalid value for incolor", procName, 1);
    if (pixGetColormap(pixs) != NULL)
        return ERROR_INT("pixs is colormapped", procName, 1);

    if (angle == 0.0)
        return 0;
    if (L_ABS(angle) > LIMIT_SHEAR_ANGLE) {
        L_WARNING("%6.2f radians; large angle for in-place 3-shear rotation\n",
                  procName, L_ABS(angle));
    }

    hangle = atan(sin(angle));
    pixHShearIP(pixs, ycen, angle / 2., incolor);
    pixVShearIP(pixs, xcen, hangle, incolor);
    pixHShearIP(pixs, ycen, angle / 2., incolor);
    return 0;
}
Ejemplo n.º 3
0
int main(int    argc,
         char **argv)
{
char        *filein, *fileout;
l_int32      i, w, h, liney, linex, same;
l_float32    angle, deg2rad;
PIX         *pixt1, *pixt2, *pixs, *pixd;
static char  mainName[] = "sheartest";

    if (argc != 4)
        return ERROR_INT(" Syntax:  sheartest filein angle fileout",
                         mainName, 1);

        /* Compare in-place H shear with H shear to a new pix */
    pixt1 = pixRead("marge.jpg");
    pixGetDimensions(pixt1, &w, &h, NULL);
    pixt2 = pixHShear(NULL, pixt1, (l_int32)(0.3 * h), 0.17, L_BRING_IN_WHITE);
    pixHShearIP(pixt1, (l_int32)(0.3 * h), 0.17, L_BRING_IN_WHITE);
    pixEqual(pixt1, pixt2, &same);
    if (same)
        fprintf(stderr, "Correct for H shear\n");
    else
        fprintf(stderr, "Error for H shear\n");
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);

        /* Compare in-place V shear with V shear to a new pix */
    pixt1 = pixRead("marge.jpg");
    pixGetDimensions(pixt1, &w, &h, NULL);
    pixt2 = pixVShear(NULL, pixt1, (l_int32)(0.3 * w), 0.17, L_BRING_IN_WHITE);
    pixVShearIP(pixt1, (l_int32)(0.3 * w), 0.17, L_BRING_IN_WHITE);
    pixEqual(pixt1, pixt2, &same);
    if (same)
        fprintf(stderr, "Correct for V shear\n");
    else
        fprintf(stderr, "Error for V shear\n");
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);

    filein = argv[1];
    angle = atof(argv[2]);
    fileout = argv[3];
    deg2rad = 3.1415926535 / 180.;

    if ((pixs = pixRead(filein)) == NULL)
        return ERROR_INT("pix not made", mainName, 1);

    pixGetDimensions(pixs, &w, &h, NULL);

#if 0
        /* Select an operation from this list ...
         * ------------------------------------------
    pixd = pixHShear(NULL, pixs, liney, deg2rad * angle, L_BRING_IN_WHITE);
    pixd = pixVShear(NULL, pixs, linex, deg2rad * angle, L_BRING_IN_WHITE);
    pixd = pixHShearCorner(NULL, pixs, deg2rad * angle, L_BRING_IN_WHITE);
    pixd = pixVShearCorner(NULL, pixs, deg2rad * angle, L_BRING_IN_WHITE);
    pixd = pixHShearCenter(NULL, pixs, deg2rad * angle, L_BRING_IN_WHITE);
    pixd = pixVShearCenter(NULL, pixs, deg2rad * angle, L_BRING_IN_WHITE);
    pixHShearIP(pixs, liney, deg2rad * angle, L_BRING_IN_WHITE); pixd = pixs;
    pixVShearIP(pixs, linex, deg2rad * angle, L_BRING_IN_WHITE); pixd = pixs;
    pixRasteropHip(pixs, 0, h/3, -50, L_BRING_IN_WHITE); pixd = pixs;
    pixRasteropVip(pixs, 0, w/3, -50, L_BRING_IN_WHITE); pixd = pixs;
         * ------------------------------------------
         *  ... and use it in the following:         */
    pixd = pixHShear(NULL, pixs, liney, deg2rad * angle, L_BRING_IN_WHITE);
    pixWrite(fileout, pixd, IFF_PNG);
    pixDisplay(pixd, 50, 50);
    pixDestroy(&pixd);
#endif

#if 0
        /* Do a horizontal shear about a line */
    for (i = 0; i < NTIMES; i++) {
        liney = i * h / (NTIMES - 1);
        if (liney >= h)
            liney = h - 1;
        pixd = pixHShear(NULL, pixs, liney, deg2rad * angle, L_BRING_IN_WHITE);
        pixDisplay(pixd, 50 + 10 * i, 50 + 10 * i);
        pixDestroy(&pixd);
    }
#endif

#if 0
        /* Do a vertical shear about a line */
    for (i = 0; i < NTIMES; i++) {
        linex = i * w / (NTIMES - 1);
        if (linex >= w)
            linex = w - 1;
        pixd = pixVShear(NULL, pixs, linex, deg2rad * angle, L_BRING_IN_WHITE);
        pixDisplay(pixd, 50 + 10 * i, 50 + 10 * i);
        pixDestroy(&pixd);
    }
#endif

#if 0
        /* Do a horizontal in-place shear about a line */
    pixSetPadBits(pixs, 0);
    for (i = 0; i < NTIMES; i++) {
        pixd = pixCopy(NULL, pixs);
        liney = i * h / (NTIMES - 1);
        if (liney >= h)
            liney = h - 1;
        pixHShearIP(pixd, liney, deg2rad * angle, L_BRING_IN_WHITE);
        pixDisplay(pixd, 50 + 10 * i, 50 + 10 * i);
        pixDestroy(&pixd);
    }
#endif

#if 0
        /* Do a vertical in-place shear about a line */
    for (i = 0; i < NTIMES; i++) {
        pixd = pixCopy(NULL, pixs);
        linex = i * w / (NTIMES - 1);
        if (linex >= w)
            linex = w - 1;
        pixVShearIP(pixd, linex, deg2rad * angle, L_BRING_IN_WHITE);
        pixDisplay(pixd, 50 + 10 * i, 50 + 10 * i);
        pixDestroy(&pixd);
    }
#endif

    pixDestroy(&pixs);
    return 0;
}
Ejemplo n.º 4
0
static PIX *
shearTest(PIX     *pixs,
          l_int32  reduction)
{
l_int32   w, h, d;
PIX      *pixt1, *pixt2, *pixd;
PIXA     *pixa;

    PROCNAME("shearTest");

    pixa = pixaCreate(0);
    pixGetDimensions(pixs, &w, &h, &d);

    pixt1 = pixHShear(NULL, pixs, 0, ANGLE1, L_BRING_IN_WHITE);
    pixSaveTiled(pixt1, pixa, reduction, 1, 20, 32);
    pixt2 = pixHShear(NULL, pixs, h / 2, ANGLE1, L_BRING_IN_WHITE);
    pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixt1 = pixHShear(NULL, pixs, 0, ANGLE1, L_BRING_IN_BLACK);
    pixSaveTiled(pixt1, pixa, reduction, 0, 20, 0);
    pixt2 = pixHShear(NULL, pixs, h / 2, ANGLE1, L_BRING_IN_BLACK);
    pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);

    if (!pixGetColormap(pixs)) {
        pixt1 = pixCopy(NULL, pixs);
        pixHShearIP(pixt1, 0, ANGLE1, L_BRING_IN_WHITE);
        pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
        pixt2 = pixCopy(NULL, pixs);
        pixHShearIP(pixt2, h / 2, ANGLE1, L_BRING_IN_WHITE);
        pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
        pixt1 = pixCopy(NULL, pixs);
        pixHShearIP(pixt1, 0, ANGLE1, L_BRING_IN_BLACK);
        pixSaveTiled(pixt1, pixa, reduction, 0, 20, 0);
        pixt2 = pixCopy(NULL, pixs);
        pixHShearIP(pixt2, h / 2, ANGLE1, L_BRING_IN_BLACK);
        pixSaveTiled(pixt2, pixa, reduction, 0, 20, 32);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
    }

    if (d == 8 || d == 32 || pixGetColormap(pixs)) {
        pixt1 = pixHShearLI(pixs, 0, ANGLE1, L_BRING_IN_WHITE);
        pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
        pixt2 = pixHShearLI(pixs, w / 2, ANGLE1, L_BRING_IN_WHITE);
        pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
        pixt1 = pixHShearLI(pixs, 0, ANGLE1, L_BRING_IN_BLACK);
        pixSaveTiled(pixt1, pixa, reduction, 0, 20, 0);
        pixt2 = pixHShearLI(pixs, w / 2, ANGLE1, L_BRING_IN_BLACK);
        pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
    }

    pixt1 = pixVShear(NULL, pixs, 0, ANGLE1, L_BRING_IN_WHITE);
    pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
    pixt2 = pixVShear(NULL, pixs, w / 2, ANGLE1, L_BRING_IN_WHITE);
    pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixt1 = pixVShear(NULL, pixs, 0, ANGLE1, L_BRING_IN_BLACK);
    pixSaveTiled(pixt1, pixa, reduction, 0, 20, 0);
    pixt2 = pixVShear(NULL, pixs, w / 2, ANGLE1, L_BRING_IN_BLACK);
    pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);

    if (!pixGetColormap(pixs)) {
        pixt1 = pixCopy(NULL, pixs);
        pixVShearIP(pixt1, 0, ANGLE1, L_BRING_IN_WHITE);
        pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
        pixt2 = pixCopy(NULL, pixs);
        pixVShearIP(pixt2, w / 2, ANGLE1, L_BRING_IN_WHITE);
        pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
        pixt1 = pixCopy(NULL, pixs);
        pixVShearIP(pixt1, 0, ANGLE1, L_BRING_IN_BLACK);
        pixSaveTiled(pixt1, pixa, reduction, 0, 20, 0);
        pixt2 = pixCopy(NULL, pixs);
        pixVShearIP(pixt2, w / 2, ANGLE1, L_BRING_IN_BLACK);
        pixSaveTiled(pixt2, pixa, reduction, 0, 20, 32);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
    }

    if (d == 8 || d == 32 || pixGetColormap(pixs)) {
        pixt1 = pixVShearLI(pixs, 0, ANGLE1, L_BRING_IN_WHITE);
        pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
        pixt2 = pixVShearLI(pixs, w / 2, ANGLE1, L_BRING_IN_WHITE);
        pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
        pixt1 = pixVShearLI(pixs, 0, ANGLE1, L_BRING_IN_BLACK);
        pixSaveTiled(pixt1, pixa, reduction, 0, 20, 0);
        pixt2 = pixVShearLI(pixs, w / 2, ANGLE1, L_BRING_IN_BLACK);
        pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
    }

    pixd = pixaDisplay(pixa, 0, 0);
    pixaDestroy(&pixa);
    return pixd;
}