2013-08-20 2 views
0

NPP를 사용하여 BoxFilter의 예제를 작성했지만 출력 이미지가 손상된 것 같습니다. 이것은 내 코드입니다 :nppiFilter가 출력 이미지를 끊습니다.

#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 %d\n", 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; 
} 

대부분의 코드는 예제 상자 FilterNPP.cpp에서 복사했습니다. 그리고 출력 이미지 : http://img153.imageshack.us/img153/7716/o8z.png

왜 그럴 수 있습니까?

답변

2

스트라이밍에 문제가 있습니다. 이에

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

: 무슨 일

npp::ImageCPU_8u_C4 oHostDst(oDeviceSrc.size()); 

이 줄을 변경?

입력 이미지가 600x450이라고 가정 해 봅시다.

  • oHostSrc는 450 X 600이고, 피치가 동일한 피치 폭을 가지고 있기 때문에 괜찮 oHostSrcdata에서 =
  • memcpy 2400을 600x4된다.
  • oDeviceSrcoHostSrcc (600x450)의 크기에만 투자 수익 (ROI)의 크기를 집어 때문에
  • oDeviceDstoDeviceSrc보다 약간 작은 이다 집어 들고, 그래서 596x446 같은 것입니다.
  • 코드는 oDeviceDst과 같은 크기이므로 oHostDst을 생성하므로 약 596x446입니다.
  • .copyTo 작업은 oDeviceDst (피치) 596x446 이미지를 oHostDst (596x446)으로 복사합니다.
  • 최종 memcpy은 이미지를 596x446 oHostDst 이미지를 600x450 data 영역으로 복사하기 때문에 이미지가 손상됩니다.

용액 600x450에서 oHostDst을 만들고 .copyTo 동작 라인 크기 및 피치의 차이를 처리하도록한다.

아니요 코드가없는 코드 복사본 (예 : memcpy은 사용하지 않음) 때문에 원본 코드에이 문제가 없습니다. 모든 복사 단계에서 원본 및 대상 피치와 너비를 명시 적으로 처리하는 한 최종 이미지를 600x450 또는 596x446으로 만들지는 중요하지 않습니다. 그러나 귀하의 최종 memcpy 작업은 피치와 폭을 명시 적으로 처리하지 않았으며 암시 적으로 소스와 대상이 같은 크기 였다고 가정했습니다.

+0

도움을 주셔서 감사합니다. 문제가 해결되었습니다! 당신의 대답처럼 선을 변경 한 후에는 출력 이미지가 원래처럼되었습니다. 내가 변경 한 것보다 :'npp :: ImageCPU_8u_C4 oHostDst (oDeviceSrc.size());'to :'npp :: ImageCPU_8u_C4 oHostDst (width, height);'내 필터가 제대로 작동합니다! – greg

관련 문제