我用NPP写了一个BoxFilter的例子,但输出图像看起来很坏。这是我的代码:
#include <stdio.h>
#include <string.h>
#include <ImagesCPU.h>
#include <ImagesNPP.h>
#include <Exceptions.h>
#include <npp.h>
#include "utils.h"
void boxfilter1_transform( Npp8u *data, int width, int height ){
size_t size = width * height * 4;
// declare a host image object for an 8-bit RGBA image
npp::ImageCPU_8u_C4 oHostSrc(width, height);
Npp8u *nDstData = oHostSrc.data();
memcpy(nDstData, data, size * sizeof(Npp8u));
// declare a device image and copy construct from the host image,
// i.e. upload host to device
npp::ImageNPP_8u_C4 oDeviceSrc(oHostSrc);
// create struct with box-filter mask size
NppiSize oMaskSize = {3, 3};
// Allocate memory for pKernel
Npp32s hostKernel[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
Npp32s *pKernel;
checkCudaErrors( cudaMalloc((void**)&pKernel, oMaskSize.width * oMaskSize.height * sizeof(Npp32s)) );
checkCudaErrors( cudaMemcpy(pKernel, hostKernel, oMaskSize.width * oMaskSize.height * sizeof(Npp32s),
cudaMemcpyHostToDevice) );
Npp32s nDivisor = 9;
// 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_C4 oDeviceDst(oSizeROI.width, oSizeROI.height);
// set anchor point inside the mask
NppiPoint oAnchor = {2, 2};
// run box filter
NppStatus eStatusNPP;
eStatusNPP = nppiFilter_8u_C4R(oDeviceSrc.data(), oDeviceSrc.pitch(),
oDeviceDst.data(), oDeviceDst.pitch(),
oSizeROI, pKernel, oMaskSize, oAnchor, nDivisor);
//printf("NppiFilter error status %dn", eStatusNPP);
NPP_DEBUG_ASSERT(NPP_NO_ERROR == eStatusNPP);
// declare a host image for the result
npp::ImageCPU_8u_C4 oHostDst(oDeviceDst.size());
// and copy the device result data into it
oDeviceDst.copyTo(oHostDst.data(), oHostDst.pitch());
memcpy(data, oHostDst.data(), size * sizeof(Npp8u));
return;
}
大部分代码是从示例boxFilterNPP.cpp中复制的。输出图像:http://img153.imageshack.us/img153/7716/o8z.png
为什么会这样?
您有一个跨越式的问题。更改此行:
npp::ImageCPU_8u_C4 oHostDst(oDeviceDst.size());
对此:
npp::ImageCPU_8u_C4 oHostDst(oDeviceSrc.size());
发生了什么?
假设您的输入图像为600x450。
oHostSrc
为600 x 450,间距为600x4=2400- 从CCD_ 3到CCD_ 4的CCD_
oDeviceSrc
从oHostSrcc
拾取尺寸(600x450)oDeviceDst
比oDeviceSrc
稍小,因为它只拾取ROI的大小,所以它有点像596x446- 您的代码正在创建与
oDeviceDst
大小相同的oHostDst
,因此大约为596x446 .copyTo
操作将oDeviceDst(倾斜)596x446映像复制到(未倾斜)oHostDst
,也就是596x446- 最终的
memcpy
会破坏图像,因为它正在将596x446个oHostDst
图像复制到600x450个data
区域
解决方案是以600x450创建oHostDst
,并让.copyTo
操作处理线条大小和间距的差异。
原始代码没有这个问题,因为该代码中的任何位置都没有未缝合的副本(例如,没有使用原始memcpy
)。只要在每个复制步骤都明确处理源和目标的间距和宽度,那么将最终图像创建为600x450还是596x446都无关紧要。但您的最后一个memcpy
操作并没有显式地处理间距和宽度,而是隐式地假设源和目的地大小相同,但事实并非如此。