[英]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.