Search code examples
image-processingcudanpp

NPP CUDA without freeImage


Is the NPP library for CUDA build to use freeImage only or can I use other struct or just unsigned char *image as inputs in NPPs function.

The reason that I a make this Question is that all the samples for NPP have large wrappers for freeImage.

I have looked thoroughly through the NVIDIA Performance Primitives ( NPP ) but there a image is only mentioned, not particular which image format are used.

If you have an example of how to use NPP without freeImage or just without loading the image from disk, then I would by wary happy.


Solution

  • NPP is neither dependent on FreeImage, nor does it follow any image processing library specific conventions. It just follows a general convention used in image processing domains. It expects images to be stored in row-major order. Images are usually stored as strided linear memory. Therefore NPP functions take the pointer to raw image data stored on the device, the size of the image, and the step of the image as arguments.

    In the NPP samples, FreeImage is just used as an image I/O library and for ease of image handling on the host side.

    I develop image processing functions utilizing NPP. To test the functions, I use OpenCV to read image from the disk, copy the data from IplImage to a raw device pointer and pass the pointer to NPP function.

    Here is an example to use NPP with OpenCV as host.

    #include <iostream>
    #include <cuda_runtime.h>
    #include <npp.h>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    
    int main()
    {    
        const int width = 640, height = 480;
    
        //Create an 8 bit single channel image
        IplImage* img = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,1);
        //Set All Image Pixels To 0
        cvZero(img);
    
        cvShowImage("Input",img);
        cvWaitKey();
    
    
        const int step = img->widthStep;
        const int bytes = img->widthStep * img->height;
    
        unsigned char *dSrc, *dDst;
        cudaMalloc<unsigned char>(&dSrc,bytes);
        cudaMalloc<unsigned char>(&dDst,bytes);
    
        //Copy Data From IplImage to Device Pointer
        cudaMemcpy(dSrc,img->imageData,bytes,cudaMemcpyHostToDevice);
    
        NppiSize size;
        size.width = width;
        size.height = height;
    
        const Npp8u value = 150;
    
        //Call NPP function to add a constant value to each pixel of the image
        nppiAddC_8u_C1RSfs(dSrc,step,value,dDst,step,size,1);
    
        //Copy back the result from device to IplImage
        cudaMemcpy(img->imageData,dDst,bytes,cudaMemcpyDeviceToHost);
    
        cudaFree(dSrc);
        cudaFree(dDst);
    
        cvShowImage("Output",img);
        cvWaitKey();
    
        cvReleaseImage(&img);
    
        return 0;
    }