Nvidia Performance Primitives (NPP)은 사용자가 제공 한 이미지를 사용자 제공 커널과 컨벌루션하기위한 nppiFilter
기능을 제공합니다. 1D 컨벌루션 커널의 경우 nppiFilter
이 올바르게 작동합니다. 그러나 nppiFilter
은 2D 커널 용 가비지 이미지를 생성하고 있습니다. Nvidia NPP nppiFilter는 2d 커널과 컨볼 루션 할 때 쓰레기를 생성합니다.
여기 좋은 출력을 생성하는 1D 컨볼 루션 커널, 내 실험입니다. 커널 [-1 0 1]
와 상기 코드
#include <npp.h> // provided in CUDA SDK
#include <ImagesCPU.h> // these image libraries are also in CUDA SDK
#include <ImagesNPP.h>
#include <ImageIO.h>
void test_nppiFilter()
{
npp::ImageCPU_8u_C1 oHostSrc;
npp::loadImage("Lena.pgm", oHostSrc);
npp::ImageNPP_8u_C1 oDeviceSrc(oHostSrc); // malloc and memcpy to GPU
NppiSize kernelSize = {3, 1}; // dimensions of convolution kernel (filter)
NppiSize oSizeROI = {oHostSrc.width() - kernelSize.width + 1, oHostSrc.height() - kernelSize.height + 1};
npp::ImageNPP_8u_C1 oDeviceDst(oSizeROI.width, oSizeROI.height); // allocate device image of appropriately reduced size
npp::ImageCPU_8u_C1 oHostDst(oDeviceDst.size());
NppiPoint oAnchor = {2, 1}; // found that oAnchor = {2,1} or {3,1} works for kernel [-1 0 1]
NppStatus eStatusNPP;
Npp32s hostKernel[3] = {-1, 0, 1}; // convolving with this should do edge detection
Npp32s* deviceKernel;
size_t deviceKernelPitch;
cudaMallocPitch((void**)&deviceKernel, &deviceKernelPitch, kernelSize.width*sizeof(Npp32s), kernelSize.height*sizeof(Npp32s));
cudaMemcpy2D(deviceKernel, deviceKernelPitch, hostKernel,
sizeof(Npp32s)*kernelSize.width, // sPitch
sizeof(Npp32s)*kernelSize.width, // width
kernelSize.height, // height
cudaMemcpyHostToDevice);
Npp32s divisor = 1; // no scaling
eStatusNPP = nppiFilter_8u_C1R(oDeviceSrc.data(), oDeviceSrc.pitch(),
oDeviceDst.data(), oDeviceDst.pitch(),
oSizeROI, deviceKernel, kernelSize, oAnchor, divisor);
cout << "NppiFilter error status " << eStatusNPP << endl; // prints 0 (no errors)
oDeviceDst.copyTo(oHostDst.data(), oHostDst.pitch()); // memcpy to host
saveImage("Lena_filter_1d.pgm", oHostDst);
}
출력 - 그 적당한 그라데이션 화상처럼 보이는 : I가 2D 컨볼 루션 커널을 사용하면
그러나 nppiFilter
가비지 화상 출력 . 여기에 2D 커널 [-1 0 1; -1 0 1; -1 0 1]
실행하기 내가 위의 코드에서 변경된 사항은 다음과 같습니다
NppiSize kernelSize = {3, 3};
Npp32s hostKernel[9] = {-1, 0, 1, -1, 0, 1, -1, 0, 1};
NppiPoint oAnchor = {2, 2}; // note: using anchor {1,1} or {0,0} causes error -24 (NPP_TEXTURE_BIND_ERROR)
saveImage("Lena_filter_2d.pgm", oHostDst);
는 2D 커널 [-1 0 1; -1 0 1; -1 0 1]
를 사용하여 출력 이미지입니다.
내가 뭘 잘못하고 있니? http://1ordrup.dk/kasper/image/Lena_boxFilter5.jpg
몇 최종 노트 : 2 차원 커널
- 특정 앵커를 들어, 사용자 Steenstrup의 이미지와 같이
는 비슷한 문제를 설명 값 (예 : NppiPoint oAnchor = {0, 0}
또는 {1, 1}
)을 입력하면 오류 -24
이 표시됩니다. NPP User Guide에 따라 NPP_TEXTURE_BIND_ERROR
으로 변환됩니다. 이 문제는 this StackOverflow post에서 간략하게 언급되었습니다.
아, 훌륭합니다. 저는 1D''cudaMalloc''과 1D''cudaMemcpy''를 지금 시험 중입니다. 또한, 'ScaleFactor = 0'처럼 스케일링을주지 않을 것 같은가요? – solvingPuzzles
1D malloc과 memcpy를 사용하면 문제가 해결되었습니다 !! 감사! 다음은 2 차원 3x3 커널로 처리 된 이미지입니다 : http://i.stack.imgur.com/wziix.png – solvingPuzzles
NPP가 '2^(- ScaleFactor)'로 비례한다면'ScaleFactor = 0'은 그러나 ScaleFactor = 0으로 설정하면 나에게 빈 이미지가 생깁니다. – solvingPuzzles