Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

WarpAffine, GetRotateShift, GetRotateTransform

C-Coder
Beginner
597 Views

Is there an official way of calculating the center that one should pass to the GetRotateShift function? Yes, center could be anything we want, but if we want the official center of the image. Do we use the half pixels, round up, round down, something entirely different from dividing src image height and width by 2.0? The general idea of what I'm looking to do is something like:

 

ippGetRotateShift(xCenter, yCenter, angle, &xShift, &yShift);

ippiGetRotateTransform(angle, xShift, yShift, coeffs);

...

ippiWarpAffineLinear_<mod>(...)

 

Just using a small source buffer for testing, I can look at in RAM and see what it looks like. Then look at the destination buffer in RAM after doing a 90 degree rotate and it isn't shifted correctly. If I skip calling ippGetRotateShift, and hard code the shift values as 0 for X and src width - 1 for y, then it will be properly shifted after doing the 90 degree rotate. This obviously isn't a correct solution as we want to be able to use any angle.

 

Thanks,

 

C-Coder

0 Kudos
1 Reply
C-Coder
Beginner
597 Views

We're looking to replace the behavior we had with ippiRotateCenter. When using it, we did something like:

 

    switch (iDegrees)
    {
    case 0:
    case 180:
        if (unInputHeight % 2 == 0)
        {
            dXCenter = (unInputHeight / 2.0) - 0.5;
        }
        else
        {
            dXCenter = unInputHeight / 2.0;
        }

        if (unInputWidth % 2 == 0)
        {
            dYCenter = (unInputWidth / 2.0) - 0.5;
        }
        else
        {
            dYCenter = unInputWidth / 2.0;
        }
        break;
    case 90:
        if (unInputHeight % 2 == 0)
        {
            dXCenter = (unInputHeight / 2.0) - 0.5;
            dYCenter = (unInputHeight / 2.0) - 0.5;
        }
        else
        {
            dXCenter = unInputHeight / 2.0;
            dYCenter = unInputHeight / 2.0;
        }
        break;
    case 270:
        if (unInputWidth % 2 == 0)
        {
            dXCenter = (unInputWidth / 2.0) - 0.5;
            dYCenter = (unInputWidth / 2.0) - 0.5;
        }
        else
        {
            dXCenter = unInputWidth / 2.0;
            dYCenter = unInputWidth / 2.0;
        }
        break;
    }

 

For other degrees (such as 12.1, etc) we would use the closest of the above to find the center, then just adjust the angle that we passed to RotateCenter. This generally worked well for us. Finding the center for the new methods, this does not work. I've now found that if the angle is 0, 90, 180, or 270, I can do something like:

 

    // Calculate the initial coefficients (with no shift)
    if ((IppRet = ippiGetRotateTransform(dAngle, dXShift, dYShift, dCoeffs)) != ippStsNoErr)
    {
        ...
    }

    // Calculate the shifts that we need
    if ((IppRet = ippiGetAffineBound(SrcRoi, dBounds, dCoeffs)) != ippStsNoErr)
    {
        ...
    }

    // Apply the shifts
    dXShift -= dBounds[0][0];
    dYShift -= dBounds[0][1];
 

    // ReCalculate the coefficients
    if ((IppRet = ippiGetRotateTransform(dAngle, dXShift, dYShift, dCoeffs)) != ippStsNoErr)
    {
        ...
    }
 

And that works. Then the aforementioned method of finding the center more or less works for anything that isn't one of (0, 90, 180, 270). I have to think though, that there is a proper method of doing this for all angles with the new methods.

 

Thanks,

 

C-Coder

0 Kudos
Reply