【问题标题】:Optimizing a nested for-loop using CUDA使用 CUDA 优化嵌套的 for 循环
【发布时间】:2012-09-23 00:28:52
【问题描述】:

所以我有一个正在处理的项目,它使用 OpenCV 来检测移动物体的运动。我正在尝试加快检测速度并有一个嵌套的 for 循环,我想使用 CUDA 来加速它。我在 Visual Basic 中设置了 CUDA 集成。这是我的 .cpp 文件中的嵌套 for 循环。

      for (int i=0; i<NumberOfFeatures; i++)
  {
    // Compute integral image.
    cvIntegral(mFeatureImgs[i], mFirstOrderIIs[i]);

    for (int j=0; j<NumberOfFeatures; j++)
    {
      // Compute product feature image.
      cvMul(mFeatureImgs[i], mFeatureImgs[j], mWorker);

      // Compute integral image.
      cvIntegral(mWorker, mSecondOrderIIs[i][j]);
    }
  }

我对 CUDA 比较陌生,所以我的问题是,有人可以向我展示一个示例,说明如何使用 CUDA 使这个嵌套的 for 循环运行得更快吗?

【问题讨论】:

标签: cuda gpu


【解决方案1】:

正如 sgar91 所指出的,OpenCV 包含一个 GPU 模块,如下所述:

http://opencv.willowgarage.com/wiki/OpenCV_GPU

该 wiki 还建议如何在 Yahoo 的 OpenCV 帮助论坛上提出与 GPU 相关的问题。

有一个gpu加速的图像积分功能。如果您环顾四周,您可能还会发现 cvMul 的等价物。

您不能在非 GPU 代码和 GPU 版本中使用完全相同的数据类型。看看我之前发布的 wiki 页面上给出的“简短示例”示例。您将看到您需要执行以下操作才能将现有数据传输到可由 GPU 操作的数据结构:

    cv::gpu::GpuMat dst, src;  // this is defining variables that can be accessed by the GPU
    src.upload(src_host);      // this is loading the src (GPU variable) with the image data

    cv::gpu::threshold(src, dst, 128.0, 255.0, CV_THRESH_BINARY);  //this is causing the GPU to act

你需要做一些类似的事情,例如:

    cv::gpu::GpuMat dst, src;
    src.upload(src_data);

    cv::gpu::integral(src, dst);

【讨论】:

  • 感谢 Robert 的回复,我在来 StackOverflow 之前就问过那里。还是没有反应,已经2天了。关于如何让这个 OpenCV GPU 模块运行积分的任何建议?当我将 cvIntegral 切换到 cv::gpu::integral 时,它会给我一个参数错误,因为我没有名为 gpu::mat 的东西?
【解决方案2】:

cv_integral 基本上是沿两个维度对像素值求和 - 这只能通过矩阵运算来完成。因此,如果您愿意,也可以尝试使用 arrayfire。 我为您创建了一个如何使用矩阵进行图像处理的小示例:

// computes integral image
af::array cv_integral(af::array img) {

  // create an integral image of size + 1
  int w = img.dims(0), h = img.dims(1);
  af::array integral = af::zeros(w + 1, h + 1, af::f32);

  integral(af::seq(1,w), af::seq(1,h)) = img;

  // compute inclusive prefix sums along both dimensions
   integral = af::accum(integral, 0);
   integral = af::accum(integral, 1);

   std::cout << integral << "\n";

   return integral;
}

void af_test()
{
 int w = 6, h = 5; // image size
 float img_host[] = {5,2,3,4,1,7,
                    1,5,4,2,3,4,
                    2,2,1,3,4,45,
                    3,5,6,4,5,2,
                    4,1,3,2,6,9};

  //! create a GPU image (matrix) from the host data
  //! NOTE: column-major order!!
  af::array img(w, h, img_host, af::afHost);

   //! create an image from random data
   af::array img2 = af::randu(w, h) * 10;
   // compute integral images
   af::array integral = cv_integral(img);
   // elementwise product of the images
   af::array res = integral * img2;
   //! compute integral image
   res = cv_integral(res);
   af::eval(res);
   std::cout << res << "\n";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-27
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    相关资源
    最近更新 更多