Ste*_*nko 3 opencv nvidia image-resizing
我正在调整这张测试图片的大小:
Mat im = Mat::zeros(Size(832*3,832*3),CV_8UC3);
putText(im,"HI THERE",Point2i(10,90),1,7,Scalar(255,255,255),2);
Run Code Online (Sandbox Code Playgroud)
按标准
cv::resize(im,out,Size(416,416),0,0,INTER_NEAREST);
Run Code Online (Sandbox Code Playgroud)
并通过 CUDA 版本的调整大小:
static void gpuResize(Mat in, Mat &out){
double k = in.cols/416.;
cuda::GpuMat gpuInImage;
cuda::GpuMat gpuOutImage;
gpuInImage.upload(in);
const Size2i &newSize = Size(416, in.rows / k);
//cout << "newSize " << newSize<< endl;
cuda::resize(gpuInImage, gpuOutImage, newSize,INTER_NEAREST);
gpuOutImage.download(out);
}
Run Code Online (Sandbox Code Playgroud)
测量时间表明 cv::resize 快了大约 25 倍。我究竟做错了什么?我在 GTX1080ti 显卡上,也在 Jetson NANO 上观察到同样的情况。可能有任何替代方法可以比使用 nvidia 硬件加速的 cv::resize 更快地调整图像大小?
我今天做了类似的事情,并且在 NVP 模型 2 模式(15W,6 核)下运行的 Jetson NX 上得到了相同的结果。
使用 CPU 将图像大小调整 10,000 倍比使用 GPU 将同一图像大小调整 10,000 倍要快。
这是我的 CPU 代码:
cv::Mat cpu_original_image = cv::imread("test.png"); // 1400x690 RGB image
for (size_t count = 0; count < number_of_times_to_iterate; count ++)
{
cv::Mat cpu_resized_image;
cv::resize(cpu_original_image, cpu_resized_image, desired_image_size);
}
Run Code Online (Sandbox Code Playgroud)
这是我的 GPU 代码:
cv::cuda::GpuMat gpu_original_image;
gpu_original_image.upload(cpu_original_image);
for (size_t count = 0; count < number_of_times_to_iterate; count ++)
{
cv::cuda::GpuMat gpu_resized_image;
cv::cuda::resize(gpu_original_image, gpu_resized_image, desired_image_size);
}
Run Code Online (Sandbox Code Playgroud)
我的计时代码(上面未显示)仅用于循环for()
,它不包括imread()
nor upload()
。
当循环调用 10K 次时,我的结果是:
upload()
)然后我对每个循环做了 1 处更改。我将“调整大小”的垫移到循环之外,以防止它在每次迭代时被创建和销毁。我的代码如下所示:
cv::Mat cpu_original_image = cv::imread("test.png"); // 1400x690 RGB image
cv::Mat cpu_resized_image;
for (size_t count = 0; count < number_of_times_to_iterate; count ++)
{
cv::resize(cpu_original_image, cpu_resized_image, desired_image_size);
}
Run Code Online (Sandbox Code Playgroud)
...对于 GPU:
cv::cuda::GpuMat gpu_original_image;
gpu_original_image.upload(cpu_original_image);
cv::cuda::GpuMat gpu_resized_image;
for (size_t count = 0; count < number_of_times_to_iterate; count ++)
{
cv::cuda::resize(gpu_original_image, gpu_resized_image, desired_image_size);
}
Run Code Online (Sandbox Code Playgroud)
循环for()
计时结果现在是:
这看起来好多了! 现在,GPU 调整大小比 CPU 调整大小更快...只要您使用 GPU 进行大量工作而不是一次调整大小。只要你不不断地重新分配临时 GPU 垫,因为这似乎相当昂贵。
但毕竟,回到你原来的问题:如果你所做的只是调整单个图像的大小一次,或者每次调整多个图像的大小,GPU 调整大小不会帮助你,因为将每个图像上传到 GPU mat 将花费比原来的调整大小更长!以下是我在 Jetson NX 上尝试时的结果:
因此,在 CPU 上,NX 可以在 < 4 毫秒内完成,而在 GPU 上则需要超过 400 毫秒。