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

Posted

技术标签:

【中文标题】CUDA 帮助实现具有 320*240 图像处理的内核函数【英文标题】:CUDA help in implementing kernel function with 320*240 image to process 【发布时间】:2012-12-13 16:45:45 【问题描述】:

我对 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 但失败了..任何帮助或指导..谢谢。

【问题讨论】:

每个 API 调用添加错误检查,以确保在进一步调试内核代码之前一切正常。另外,什么是“推翻”错误? 【参考方案1】:

问题似乎是您正在分配大小为m_imgWidth*m_imgHeight 的m_pixel_ptr,而它看起来应该是m_imgWidth*m_imgHeight * sizeof(PixelPara)。这可以解释为什么你会遇到缓冲区溢出。您可能正在尝试读取和写入超出数组末尾的方式。当然,您对 m_pixel_ptr 的 cudaMemcpy 调用也需要长度为 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 *

【讨论】:

您好,谢谢您的帮助.. imageBuf 是一个字节数组,我一次读取一个...并按照您的建议存储 pixelParam。还有什么我应该做的。 ? 嗨,你能帮我解决这个问题吗,我正在运行这段代码,但它没有给我正确的输出,比如 m_pixelParam[tid].m_validModels 对于每一帧都不应该是 0 跨度> 我不太确定您的代码到底要做什么,但我似乎怀疑 j 被初始化为零,然后再也不会设置。因此,每个线程都在 m_pixelParam 的索引 [0 - width] 中设置字段。由于 j 始终为 0,因此 [jwidth + i] 始终等于 [i]。此外,每列有一个线程(其中 320 个),但看起来您可能试图让每个线程处理一行而不是一列。也许您需要在内核调用中使用 > 而不是 > 并将 [jwidth + i] 的实例替换为 [tid]。 另外,我不确定这些行是如何编译的:int m_IniWeight = 0.005; int m_IniStd = 400.0; int m_Threshold = 0.7; 整数(整数)是整数(例如 -1、0、1、2 等)为了存储数字具有小数部分(例如 0.005 或 0.7),您需要使用 float 类型的变量,而不是 int。如果您将带有小数部分的数字强制转换为整数变量(通过强制转换),小数部分将被截断,因此 0.005 和 0.7 都将被截断为 0。

以上是关于CUDA 帮助实现具有 320*240 图像处理的内核函数的主要内容,如果未能解决你的问题,请参考以下文章

android 版本为 2.2.1 和 2.3.5 且屏幕尺寸为 240 * 320 和屏幕尺寸为 480 * 800 的 Android 设备如何使用媒体查询?

德州仪器芯片TMS320F240PQA解密难度

ESP32+AMG8833+RGB屏240*320(ST7789)红外热成像

使用UIBezierPath在Swift中绘制椭圆

stm32能处理机器视觉吗

ffmpeg图片缩放