如何使用CUDA和OpenCV访问cv :: gpu :: GpuMat矩阵上的元素?

时间:2012-04-10 18:16:43

标签: opencv matrix cuda gpu gpu-programming

我正在研究一个在CUDA平台上实现人脸检测算法的项目。

目前我要访问GpuMat个实例上的元素。

我尝试了以下传统方法:

  1. 尝试从cv:Mat进行归纳,GpuMat没有<T>.at方法。
  2. 我尝试过使用CV_MAT_ELEM,收到错误。
  3. 以下是我在 FaceDetection.cu 文件中的代码:

            int DetectFacesGPU(cv::gpu::GpuMat * sumMat ,cv::gpu::GpuMat * qSumMat , float factor)
                {
                    //
                    int i = CV_MAT_ELEM(*sumMat,int ,0,0); 
                    // 
    

    我收到错误

    Error   29  error : expression must have class type C:\Users\Shahar\Dropbox\OpenCV2.3\OpenCV2.3\FaceDetectionLatest\FaceDetectionCuda\FaceDetectionLatest\FaceDetection.cu  139
    

2 个答案:

答案 0 :(得分:3)

您必须将其下载到cv::Mat,然后使用标准方式访问它。

我认为下载它很简单:

cv::Mat mat;
sumMat->download(mat); // or something like that. 

答案 1 :(得分:0)

CV_MAT_ELEM的定义,CV_MAT_ELEM(*sumMat, int, 0, 0);扩展为:

*(int*)CV_MAT_ELEM_PTR_FAST(*sumMat, 0, 0, 4));

然后扩展到:

*(int*)(assert ( 0 < (*sumMat).rows && 0 < (*sumMat).cols ),
               (*sumMat).data.ptr + (size_t)(*sumMat).step*0 + 4*0);

假设您的DetectFacesGPU函数被定义为设备代码,上述语句有问题,因为您无法在设备代码中取消引用sumMat。通过这样做,您将从设备代码访问主机内存。你必须要小心,因为 GpuMat类本身是在主机内存中分配的。它只是在设备存储器中分配的实际矩阵数据

因此,GpuMat类本身通常不会传递给内核。要访问内核中GpuMat的单个像素,必须将引用实际矩阵数据(位于设备内存中)的指针传递给内核,并对该指针执行指针算法。