NPP Warp Perspective

I am performing a 4-point perspective transform using OpenCV functions, but would like to use NPP to perform the same thing. This is similar to trying to create a “birdseye” view projection from 4 points in the image. After trying what I thought were the right functions, nothing seems to work.

Input to my function:

  1. an 8U 3C image
  2. 4 points within the image that define a quadrangle, which is likely not a square or rectangle.
  3. output rectangle size

Desired output:
An image, the size of “output rectangle” that is built from the projected pixels within the defined quadrangle.

This is easily done in OpenCV with a combination of cv::getPerspectiveTransform to get the transformation matrix, followed by cv::warpPerspective to create the output image.

When first looking at the NPP docs, I thought that there would be a similar process: find the transform matrix and then apply the transform. I couldn’t find an example for performing the perspective transform, so here’s basically what I did:

void NPP_Util::warpImage(int width, int height, uint8_t* h_data, double roiCorners[4][2],
                          int targetWidth, int targetHeight, uint8_t* targetData)
{
    uint8_t *d_data, *d_dest;
    size_t imageSize = width * height * 3; // this is the input image size
    size_t targetSize = targetWidth * targetHeight * 3; // this is the output image size

    // move input image to gpu
    cudaMalloc(&d_data, imageSize);
    cudaMemcpy(d_data,h_data, imageSize,cudaMemcpyHostToDevice);

    // allocate for output image
    cudaMalloc(&d_dest, targetSize);


    // define size of output image ????
    NppiRect roiRect;
    roiRect.x = 0;  
    roiRect.y = 0;  
    roiRect.width = width;
    roiRect.height = height;

    
    // calc perspective transformation matrix
    double T[3][3];
    NppStatus status = nppiGetPerspectiveTransform(roiRect, d_roiCorners, T);

    // declare a host image object for an 8-bit, 3 channel color image
    npp::ImageCPU_8u_C3 oHostSrc;

    NppiSize oSrcSize;
    oSrcSize.width = width;
    oSrcSize.height = height;
    NppiRect oSrcROI;
    oSrcROI.x = 0; oSrcROI.y = 0; oSrcROI.width = width; oSrcROI.height = height;
    NppiRect oDstROI;
    oDstROI.x = 0; oDstROI.y = 0; oDstROI.width = targetWidth; oDstROI.height = targetHeight;

    // perform perspective transformation onto output image ... should this be backwards transform??
    nppiWarpPerspective_8u_C3R (h_data, oSrcSize, width*3, oSrcROI, 
                d_dest, targetWidth*3, oDstROI, T, NPPI_INTER_LINEAR);

    // copy output image to cpu buffer
    cudaMemcpy(targetData, d_data, targetSize, cudaMemcpyDeviceToHost);

    // clean up
    cudaFree(d_data);
    cudaFree(d_dest);
}

The output image is unrecognizable. I suspect that I’m not setting the function input parameters correctly, or I should be performing a “backwards” transform, or I’m trying to use functions that are not meant to do this.

Any suggestions would be greatly appreciated.

Thanks,
Bryan