首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CUDA、NPP过滤器

CUDA、NPP过滤器
EN

Stack Overflow用户
提问于 2012-10-08 17:04:59
回答 3查看 3.2K关注 0票数 4

CUDA NPP库支持使用nppiFilter_8u_C1R命令过滤图像,但不断收到错误。我可以毫无问题地启动并运行boxFilterNPP示例代码。

代码语言:javascript
复制
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示例所做的更改。

代码语言:javascript
复制
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}时,代码以预期的结果运行

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-16 13:24:34

当我将内核存储为ImageCPU/ImageNPP时,我也遇到了同样的问题。

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

感谢的Frank Jargstorff提出了1D的想法。

代码语言:javascript
复制
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内核数组的代码中得到的模糊结果:

我使用的其他参数:

代码语言:javascript
复制
Npp32s nDivisor = 25;
NppiPoint oAnchor = {4, 4};
票数 3
EN

Stack Overflow用户

发布于 2012-10-09 08:48:08

根据两个函数之间的卷积与第二个函数的方向相反的数学约定,Filter应用向上向左扩展的遮罩。

长方体滤镜蒙版向下和向右延伸,这可能更直观。

在任何情况下,问题都是由这样一个事实引起的,即更改后的代码中的输入图像必须在有效的源[-4,-4]处采样,以便计算DESTINATION0,0。由于输入图像是通过纹理采样器访问的,绑定源图像指针偏移量(-4,-4)会导致您看到的纹理绑定错误。

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

票数 7
EN

Stack Overflow用户

发布于 2012-10-09 20:12:39

谢谢你的帮助。克服了这个错误,但我看到了一些奇怪的行为。图像会根据我之前运行的程序而变化,并且图像不会显示我要做的事情。

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

这段代码仍然是对boxFilterNPP示例代码的修改。

代码语言:javascript
复制
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种不同类型的图像。大多数情况下,最后一个是返回的。

代码语言:javascript
复制
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

我认为发生这种情况的原因是内核没有正确初始化或没有使用,因此带有伪随机内容的数据被用于内核。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12778463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档