2013-08-20 54 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; 
} 

大部分代碼是從示例boxFilterNPP.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是600 * 450和間距600x4 = 2400
  • memcpydataoHostSrc是確定,因爲它們具有相同的寬度和間距。
  • oDeviceSrc拿起從oHostSrcc(600x450)大小
  • oDeviceDstoDeviceSrc略小,因爲它只能拿起ROI的大小,所以它有點像596x446。
  • 您的代碼創建的oHostDstoDeviceDst的尺寸相同,因此大約是596x446。
  • .copyTo操作將oDeviceDst(傾斜)596x446圖像複製到(未交叉)oHostDst,也是596x446。
  • 最終memcpy打破了圖像,因爲它正在將圖像複製到600x450 data區域。

的解決方案是創建oHostDst在600x450並讓.copyTo操作手柄在線的尺寸和間距的差異。

原始代碼沒有這個問題,因爲沒有該代碼中任何地方的未修改副本(例如,沒有使用原始memcpy)。只要您在每個複製步驟中明確處理源和目標音高和寬度,無論您是將最終圖像創建爲600x450還是596x446,都無關緊要。但是,您的最終memcpy操作沒有明確處理音調和寬度,而是隱含地假設來源和目標都是相同大小,並非如此。

+0

謝謝你的幫助!問題解決了!在我改變了這一行之後(就像在你的回答中),輸出圖像變得像原來的一樣。我改變了:'npp :: ImageCPU_8u_C4 oHostDst(oDeviceSrc.size());'to:'npp :: ImageCPU_8u_C4 oHostDst(width,height);'我的過濾器正常工作! – greg