【问题标题】:OpenCV CUDA Morphology is much slower than on CPUOpenCV CUDA Morphology 比 CPU 慢得多
【发布时间】:2021-10-31 20:12:54
【问题描述】:

我正在使用 C++ 和 OpenCV 在 while 循环中处理视频中尺寸为 2208x1242 的图像。
为了加快速度,我想在我的 Nvidia Jetson Nano 的 GPU 上执行操作。
对于使用 cv::cuda::cvtColor 而不是 cv::cvtColor 从 BGR 到 HSV 的颜色转换,我实现了 5 倍的加速。

不幸的是,GPU 上的形态运算要慢得多:

int num_frame = 10;
int frame = 0;

cv::Mat img;
cv::cuda::GpuMat img_gpu;

cv::Mat open_kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(11, 11));
cv::Mat close_kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(21, 21));

while (frame < num_frame){

  // load image to img
  // ...

  img_gpu.upload(img);

  cv::Ptr<cv::cuda::Filter> morph_filter_open = cv::cuda::createMorphologyFilter(cv::MORPH_OPEN, img_gpu.type(), open_kernel);
  cv::Ptr<cv::cuda::Filter> morph_filter_close = cv::cuda::createMorphologyFilter(cv::MORPH_CLOSE, img_gpu.type(), close_kernel);

  morph_filter_open->apply(img_gpu, img_gpu);
  morph_filter_close->apply(img_gpu, img_gpu);

  frame++;
}

仅测量 apply() 调用,GPU 版本在 Jetson Nano 的 CPU 上比 cv::morphologyEx 慢约 20 倍(0.07s vs. 1.5s 对于单帧)。

nvprof 表明,大部分时间都花在了cudaDeviceSynchronize 上(这是为了整个程序比上面的代码示例做更多的事情,但长时间运行的操作可能与形态有关):

  API calls:   71.05%  17.2756s       665  25.978ms  25.730us  1.44814s  cudaDeviceSynchronize
                8.36%  2.03194s      1826  1.1128ms  34.844us  847.66ms  cudaLaunchKernel
                5.16%  1.25490s         1  1.25490s  1.25490s  1.25490s  cuCtxDestroy
                4.80%  1.16684s       544  2.1449ms  17.865us  10.378ms  cudaMallocPitch
                1.89%  460.14ms       616  746.98us  20.469us  346.82ms  cudaFree
                1.65%  401.38ms        76  5.2813ms  44.533us  19.211ms  cudaMemcpy2D
                1.45%  352.97ms        51  6.9209ms  18.803us  242.14ms  cudaMalloc
                1.42%  345.25ms         1  345.25ms  345.25ms  345.25ms  cudaFuncGetAttributes
                1.23%  299.95ms         1  299.95ms  299.95ms  299.95ms  cuCtxCreate
                1.03%  251.43ms        20  12.572ms  162.61us  103.74ms  cudaMallocManaged
                0.92%  224.67ms        13  17.283ms  32.553us  65.173ms  cudaMemcpy
                0.56%  135.48ms         1  135.48ms  135.48ms  135.48ms  cudaDeviceReset
...

希望有人能帮我找出问题所在!

【问题讨论】:

  • 我打算发布同样的问题,因为我在评估结果中得到了类似的结果。我希望您能获得有关导致此问题的任何最新信息!
  • 不幸的是,我没有。我使用其他类似的函数(cv::cuda::createGaussianFilter)测试了完全相同的代码,我发现它比 cv::GaussianBlur 快很多,所以我怀疑问题出在 cv:: 的实现中cuda::createMorphologyFilter 本身。

标签: c++ opencv


【解决方案1】:

我遇到了同样的问题,我设法将基于 CUDA 的形态学的性能提高了一些。我没有在循环中创建形态过滤器对象,而是取出对象创建并将其放在图像捕获循环之外。

所以代码应该是这样的:

int num_frame = 10;
int frame = 0;

cv::Mat img;
cv::cuda::GpuMat img_gpu;

cv::Mat open_kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(11, 11));
cv::Mat close_kernel = cv::getStructuringElement(cv::MORPH_RECT, 

cv::Size(21, 21));

// Morphology filter object creation outside the loop.
cv::Ptr<cv::cuda::Filter> morph_filter_open = cv::cuda::createMorphologyFilter(cv::MORPH_OPEN, img_gpu.type(), open_kernel);
cv::Ptr<cv::cuda::Filter> morph_filter_close = cv::cuda::createMorphologyFilter(cv::MORPH_CLOSE, img_gpu.type(), close_kernel);

while (frame < num_frame){

  // load image to img
  // ...

  img_gpu.upload(img);

  morph_filter_open->apply(img_gpu, img_gpu);
  morph_filter_close->apply(img_gpu, img_gpu);

  frame++;
}

除此之外,我找不到任何方法来提高 CUDA 形态过滤器的性能。

【讨论】:

    猜你喜欢
    • 2011-11-23
    • 2022-01-19
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 2018-09-15
    • 1970-01-01
    相关资源
    最近更新 更多