CUDA帮助实现具有320 * 240图像处理的内核功能

时间:2012-12-13 16:45:46

标签: multithreading visual-c++ mfc cuda kernel

我对cuda很新,我试图通过这段代码在cuda中读取一个帧但是我得到一个推翻错误并获得黑色输出.. 这是我的代码..

BYTE *imageBuf = 0;
BYTE *maBuf = 0;
BYTE *fgBuf = 0;
BYTE *tempBuf = 0;

cudaMalloc((void **)&maBuf , m_imgWidth*m_imgHeight);
cudaMalloc((void **)&fgBuf , m_imgWidth*m_imgHeight);
cudaMalloc((void **)&imageBuf , m_imgWidth*m_imgHeight);
cudaMalloc((void **)&tempBuf , m_imgWidth*m_imgHeight);
cudaMalloc((void **)&m_pixel_ptr , m_imgWidth*m_imgHeight);

cudaMemcpy(m_pixel_ptr , m_pixelParam , m_imgWidth*m_imgHeight , cudaMemcpyHostToDevice);
cudaMemcpy(imageBuf , inImgBuf , m_imgWidth*m_imgHeight , cudaMemcpyHostToDevice);
cudaMemcpy(fgBuf , foregroundBUf , m_imgWidth*m_imgHeight , cudaMemcpyHostToDevice);
cudaMemcpy(maBuf , maskBuf , m_imgWidth*m_imgHeight , cudaMemcpyHostToDevice);
cudaMemcpy(tempBuf , foregroundBUf , m_imgWidth*m_imgHeight , cudaMemcpyHostToDevice);

kernel<<<16,20>>>(imageBuf, maBuf, fgBuf , 320 , 240 , m_pixel_ptr , tempBuf , 0);


cudaMemcpy (maskBuf, maBuf , m_imgWidth*m_imgHeight , cudaMemcpyDeviceToHost);
cudaMemcpy (foregroundBUf, fgBuf , m_imgWidth*m_imgHeight , cudaMemcpyDeviceToHost);
cudaMemcpy (inImgBuf, imageBuf , m_imgWidth*m_imgHeight , cudaMemcpyDeviceToHost);
cudaMemcpy (m_pixelParam , m_pixel_ptr , m_imgWidth*m_imgHeight , cudaMemcpyDeviceToHost);

cudaFree(m_pixel_ptr);
cudaFree(imageBuf);
cudaFree(maBuf);
cudaFree(tempBuf);
cudaFree(fgBuf);

这就是我调用我的内核函数的方法,这是我的内核函数

    __global__ void kernel(BYTE *inImgBuf, BYTE *maskBuf,  BYTE *foregroundBUf , int width , int height , PixelPara *m_pixelParam , BYTE *tmpBuffer , int j)
{


int m_IniWeight = 0.005;
int m_IniStd = 400.0;
int m_Threshold = 0.7;
int fgTh;

int thresholdRank;


for(int i = 0; i < width; i++)
{
        int tid = ((threadIdx.x + blockIdx.x * blockDim.x)*width + i);
        if (m_pixelParam[tid].m_validModels == 0) 
        {
            m_pixelParam[j*width+i].m_weight[0] = m_IniWeight;
            m_pixelParam[j*width+i].m_stdVar[0] = m_IniStd;
            m_pixelParam[j*width+i].m_priRank[0] = 0;
            m_pixelParam[j*width+i].m_mean[0] = (double)inImgBuf[j*width+i];
            m_pixelParam[j*width+i].m_validModels++;


        }
        else
        {
            thresholdRank = 0;
            fgTh = 0.0;             
            while (true)
            {
                fgTh += m_pixelParam[j*width+i].m_weight[m_pixelParam[j*width+i].m_priRank[thresholdRank]];                 

                if ((fgTh > m_Threshold) || (thresholdRank >= m_pixelParam[j*width+i].m_validModels - 1)) 
                    break;      

                thresholdRank++;
            }

                gmmImplementation (inImgBuf, maskBuf, foregroundBUf ,width , height , m_pixelParam , (j*width+i) ,tmpBuffer ,thresholdRank );




            foregroundBUf = tmpBuffer;


        }

}






}

任何人都可以帮助我在这里如何处理cuda中的320 * 240帧我试图在cuda上实现GMM但是我没有...任何帮助或指导......谢谢。

1 个答案:

答案 0 :(得分:1)

问题似乎是您正在分配大小为m_imgWidth*m_imgHeight的m_pixel_ptr,而它看起来应该是m_imgWidth*m_imgHeight * sizeof(PixelPara)。这可以解释为什么你得到缓冲区溢出。您可能尝试读取和写入数组末尾的方式。当然,您的cudaMemcpy调用m_pixel_ptr也需要长度为m_imgWidth*m_imgHeight * sizeof(PixelParam),以便将整个缓冲区复制到设备和从设备复制。

另外,imageBuf应该包含双精度数还是单个字节数?现在,您的代码只为inImgBuf中的每个像素读取一个字节,然后在将其存储到m_pixelParam[j*width+i].m_mean[0]之前将其强制转换为双精度。如果它应该是读取双精度数,则需要分配和复制大小为m_imgWidth*m_imgHeight * sizeof(double)的imageBuf,并且需要在内核参数列表中将inImgBuf声明为double *而不是作为BYTE *