簡體   English   中英

OpenCV CUDA 形態比 CPU 慢得多

[英]OpenCV CUDA Morphology is much slower than on CPU

我正在使用 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.07 秒對 1.5 秒)。

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
...

我希望有人能幫助我找出問題所在!

我遇到了同樣的問題,我設法將基於 CUDA 的形態學的性能提高了一些。 我沒有在循環中創建形態過濾器對象,而是取出 object 創建並將其放在圖像捕獲循環之外。

所以代碼應該是這樣的:

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 形態濾波器的性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM