Search code examples
imagecuda

CUDA Image Rotation


I am having trouble implementing image rotation in CUDA. I have a very simple Rotate function working as follows:

__device__ float readPixVal( float* ImgSrc,int ImgWidth,int x,int y)
{
    return (float)ImgSrc[y*ImgWidth+x];
}
__device__ void putPixVal( float* ImgSrc,int ImgWidth,int x,int y, float floatVal)
{
    ImgSrc[y*ImgWidth+x] = floatVal;
}

__global__ void Rotate(float* Source, float* Destination, int sizeX, int sizeY, float deg)
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;// Kernel definition
    int j = blockIdx.y * blockDim.y + threadIdx.y;

    if(i < sizeX && j < sizeY)
    {
        putPixVal(Destination, sizeX, ((float)i)*cos(deg) - ((float)j)*sin(deg), ((float)i)*sin(deg) + ((float)j)*cos(deg)), readPixVal(Source, sizeX, i, j));
    }
}

The problem is, I do not know how to do any interpolation. With the above, many pixels are skipped due to integer roundoff. Anyone know how to fix this, or are there any free/opensource implementations of image rotate? I could not find any for CUDA.


Solution

  • This seems to do the trick

    __global__ void Rotate(float* Source, float* Destination, int sizeX, int sizeY, float deg)
    {
        int i = blockIdx.x * blockDim.x + threadIdx.x;// Kernel definition
        int j = blockIdx.y * blockDim.y + threadIdx.y;
        int xc = sizeX - sizeX/2;
        int yc = sizeY - sizeY/2;
        int newx = ((float)i-xc)*cos(deg) - ((float)j-yc)*sin(deg) + xc;
        int newy = ((float)i-xc)*sin(deg) + ((float)j-yc)*cos(deg) + yc;
        if (newx >= 0 && newx < sizeX && newy >= 0 && newy < sizeY)
        {
            putPixVal(Destination, sizeX, i , j, readPixVal(Source, sizeX, newx, newy));
        }
    }