2012-10-08 58 views
4

CUDA NPP库支持使用nppiFilter_8u_C1R命令过滤图像,但不断收到错误。启动并运行boxFilterNPP示例代码我没有任何问题。CUDA,NPP滤镜

eStatusNPP = nppiFilterBox_8u_C1R(oDeviceSrc.data(), oDeviceSrc.pitch(), 
            oDeviceDst.data(), oDeviceDst.pitch(), 
            oSizeROI, oMaskSize, oAnchor); 

但是,如果我改变它使用nppiFilter_8u_C1R代替,eStatusNPP返回错误-24(NPP_TEXTURE_BIND_ERROR)。下面的代码是我对原始boxFilterNPP示例所做的更改。

NppiSize oMaskSize = {5,5}; 
npp::ImageCPU_32s_C1 hostKernel(5,5); 

for(int x = 0 ; x < 5; x++){ 
    for(int y = 0 ; y < 5; y++){ 
     hostKernel.pixels(x,y)[0].x = 1; 
    } 
} 

npp::ImageNPP_32s_C1 pKernel(hostKernel); 

Npp32s nDivisor = 1; 

eStatusNPP = nppiFilter_8u_C1R(oDeviceSrc.data(), oDeviceSrc.pitch(), 
           oDeviceDst.data(), oDeviceDst.pitch(), 
           oSizeROI, 
           pKernel.data(), 
           oMaskSize, oAnchor, 
           nDivisor); 

这已经尝试了CUDA 4.2和5.0,与相同的结果。

的代码与预期结果运行时oMaskSize = {1,1}

+0

其CUDA你使用的是哪个版本? – sgarizvi

+0

版本4.2,V0.2.1221 – Steenstrup

回答

2

我有同样的问题,当我保存我的内核为ImageCPU/ImageNPP

一个好的解决方案是将内核作为传统1D阵列存储在设备上。我试过这个,它给了我很好的结果(并且没有那些不可预测的或垃圾图像)。

感谢Frank Jargstorff为this StackOverflow post提供了一维创意。

NppiSize oMaskSize = {5,5}; 
Npp32s hostKernel[5*5]; 

for(int x = 0 ; x < 5; x++){ 
    for(int y = 0 ; y < 5; y++){ 
     hostKernel[x*5+y] = 1; 
    } 
} 

Npp32s* pKernel; //just a regular 1D array on the GPU 
cudaMalloc((void**)&pKernel, 5 * 5 * sizeof(Npp32s)); 
cudaMemcpy(pKernel, hostKernel, 5 * 5 * sizeof(Npp32s), cudaMemcpyHostToDevice); 

使用this original image,这里的模糊的结果,我从你的代码获得与1D核心阵列: enter image description here

,我用其他参数:

Npp32s nDivisor = 25; 
NppiPoint oAnchor = {4, 4}; 
7

滤波器应用于掩模向上和向左延伸,即两个功能之间的卷积反转所述第二方向上的数学惯例以下功能。

箱式过滤器罩向下向右延伸,这可能更直观。

在任何情况下,该问题由以下事实:在改变的代码输入图像将不得不在什么实际上将SOURCE [-4,要被采样引起-4),以便计算DESTINATION [0,0 ]。由于输入图像是通过纹理采样器访问的,将源图像指针偏移(-4,-4)会导致出现纹理绑定错误。

解决方法:此问题最简单的解决方法是将锚点设置为(4,4),这将有效地将蒙版向下移动到右侧。您仍然需要知道您想要反转内核数组中的权重(即K[-4, -4] -> K[0, 0],K[0, 0] -> K[-4, -4]等)。

+0

TY的帮助。得到了错误,但越来越smo – Steenstrup

1

谢谢你的帮助。 了解了这个错误,但我看到一些奇怪的行为。图像会根据我之前运行的程序而变化,图像不会显示我正在发生的事情。

我试图模仿的例子是使用nppiFilter_8u_C1R的nppiFilterBox_8u_C1R,其中我将内核设置为1,将nDivisor设置为内核的总和。

此代码仍然是对boxFilterNPP示例代码的更改。

NppiSize oMaskSize = {5,5}; 
npp::ImageCPU_32s_C1 hostKernel(5,5); 
for(int x = 0 ; x < 5; x++){ 
    for(int y = 0 ; y < 5; y++){ 
     hostKernel.pixels(x,y)[0].x = 1; 
    } 
} 

npp::ImageNPP_32s_C1 pKernel(hostKernel); 
Npp32s nDivisor = 25; 
NppiPoint oAnchor = {4, 4}; 
eStatusNPP = nppiFilter_8u_C1R(oDeviceSrc.data(),oDeviceSrc.pitch(), 
           oDeviceDst.data(), oDeviceDst.pitch(), 
           oSizeROI, 
           pKernel.data(), 
           oMaskSize, oAnchor, 
           nDivisor); 

由于内核只有一个需要反转权重不应该是一个问题。

此代码返回的5种不同的图像显示如下。大多数是最后一个返回。

http://1ordrup.dk/kasper/image/Lena_boxFilter1.jpg 
http://1ordrup.dk/kasper/image/Lena_boxFilter2.jpg 
http://1ordrup.dk/kasper/image/Lena_boxFilter3.jpg 
http://1ordrup.dk/kasper/image/Lena_boxFilter4.jpg 
http://1ordrup.dk/kasper/image/Lena_boxFilter5.jpg 

我认为出现这种情况的原因是,内核未正确initilised或没有使用,伪随机内容用于内核这样的数据。

+0

你最终弄清楚为什么我们看到这些奇怪的输出图像?我发现'nppiFilter'适用于1D内核,但存在你描述2D内核的问题。我发布了一个关于它的其他问题:http://stackoverflow.com/questions/12902688/nvidia-npp-nppifilter-produces-garbage-when-convolving-with-2d-kernel – solvingPuzzles

+0

是的,我解决了它,ty为输入。 – Steenstrup