nppiFilter_8u_C1R : Error -24 NPP_TEXTURE_BIND_ERROR

Hi everybody,

I try to use the npp function nppiFilter_8u_C1R. To test it, I use the example “boxFilterNPP” and I replace the function “nppiFilterBox_8u_C1R” by “nppiFilter_8u_C1R” with a specific kernel. When I run the example, I have the return error -24 (NPP_TEXTURE_BIND_ERROR).

Can you help me please ?

Regards,

David

Here my code (in blue the original code from boxFilterNPP and in red my code):

    std::string sFilename;

    char *filePath = findFilePath("Lena.pgm", argv[0]);

    if (filePath) {

        sFilename = filePath;

    } else {

        printf("Error %s was unable to find Lena.pgm\n");

        shrQAFinishExit(argc, (const char **)argv, QA_FAILED);

    }

// Parse the command line arguments for proper configuration

    parseCommandLineArguments(argc, argv);

printfNPPinfo(argc, argv);

if (g_bQATest == false && (g_nDevice == -1) && argc > 1) {

        sFilename = argv[1];

    }

// if we specify the filename at the command line, then we only test sFilename[0].

    int file_errors = 0;

    std::ifstream infile(sFilename.data(), std::ifstream::in);

    if (infile.good()) {

        std::cout << "boxFilterNPP opened: <" << sFilename.data() << "> successfully!" << std::endl;

        file_errors = 0;

        infile.close();

    } else {

        std::cout << "boxFilterNPP unable to open: <" << sFilename.data() << ">" << std::endl;

        file_errors++;

        infile.close();

    }

    if (file_errors > 0) {

        shrQAFinish(argc, (const char **)argv, QA_FAILED);

        exit(EXIT_FAILURE);

    }

std::string sResultFilename = sFilename;

std::string::size_type dot = sResultFilename.rfind(’.’);

    if (dot != std::string::npos) sResultFilename = sResultFilename.substr(0, dot);

    sResultFilename += "_boxFilter.pgm";

if (argc >= 3 && !g_bQATest)

        sResultFilename = argv[2];

// declare a host image object for an 8-bit grayscale image

    npp::ImageCPU_8u_C1 oHostSrc;

            // load gray-scale image from disk

    npp::loadImage(sFilename, oHostSrc);

            // declare a device image and copy construct from the host image,

            // i.e. upload host to device

    npp::ImageNPP_8u_C1 oDeviceSrc(oHostSrc);

// create struct with box-filter mask size

    NppiSize oMaskSize = {3, 3};

            // create struct with ROI size given the current mask

    NppiSize oSizeROI = {oDeviceSrc.width() - oMaskSize.width + 1, oDeviceSrc.height() - oMaskSize.height + 1};

            // allocate device image of appropriatedly reduced size

    npp::ImageNPP_8u_C1 oDeviceDst(oSizeROI.width, oSizeROI.height);

            // set anchor point inside the mask to (0, 0)

    NppiPoint oAnchor = {0, 0};

            // run box filter

    NppStatus eStatusNPP;

//eStatusNPP = nppiFilterBox_8u_C1R(oDeviceSrc.data(), oDeviceSrc.pitch(),

    //                                  oDeviceDst.data(), oDeviceDst.pitch(), 

    //                                  oSizeROI, oMaskSize, oAnchor);

Npp32s pKernelCPU[9] = { 1, 1, 1, 1, 1, 1,1, 1, 1 };

    Npp32s* pKernelGPU;

    cudaMalloc<Npp32s>((Npp32s**)&pKernelGPU, 3*3*sizeof(Npp32s));

    cudaMemcpy( pKernelGPU, pKernelCPU,9 * sizeof(Npp32s),cudaMemcpyDeviceToHost );

eStatusNPP=nppiFilter_8u_C1R(oDeviceSrc.data(), oDeviceSrc.pitch(),oDeviceDst.data(), oDeviceDst.pitch(),oSizeROI, pKernelGPU, oMaskSize, oAnchor, 9);

if ( NPP_NO_ERROR != eStatusNPP )

    {

        std::cerr << " xxxxx error "<<eStatusNPP<<" xxxxx"<<std::endl;

    }

NPP_ASSERT(NPP_NO_ERROR == eStatusNPP);

            // declare a host image for the result

    npp::ImageCPU_8u_C1 oHostDst(oDeviceDst.size());

            // and copy the device result data into it

    oDeviceDst.copyTo(oHostDst.data(), oHostDst.pitch());

saveImage(sResultFilename, oHostDst);

    std::cout << "Saved image: " << sResultFilename << std::endl;

    shrQAFinish(argc, (const char **)argv, QA_PASSED);

exit(EXIT_SUCCESS);

Hi David,

because nppiFilter implements a generalized convolution with weight indices increase in the opposite direction of the pixel indices, the actual mask also extends the opposite direction as in the box filter. The output pixel O(0,0) requires source pixels from I(-(W-1),-(H-1)) to I(0, 0).

The nppiBoxFilter simply sums the elements under the mask which extends from the anchor in the same direction as the image indexing. In order to compute the output pixel at (0,0) the kernel pulls I(0,0) to I(W-1, H-1).

So in your specific case, you could either move the mask anchor to (2,2) or move the pSrc pointer by two pixels in each direction towards the center of the image.

–Frank