从HDD读取灰度图像的最快方法

时间:2015-01-23 02:46:08

标签: c++ image opencv cuda

我正在使用GPU上的图像处理(CUDA)。 CUDA内核的输入是两个灰度8位图像(.tif)。它们必须在GPU RAM内存中作为1D阵列(基于0的行主存储)。处理时间约为24ms,因此读取速度对我来说很重要。为了做到这一点,首先我需要将图像从HDD读取到CPU RAM内存(进入1d浮点数组),然后使用cudamemcpy将其复制到GPU RAM中。用c ++读取硬盘的最快方法是什么?

我的图像是8位灰度1200x1600(大小1.92 mb)。我写了测试程序,读取大约250张图像并测量时间:

使用matlab(imread),阅读1张图片的时间为5.8ms。这相当于~300 Mb/s,接近我硬盘的峰值带宽。

但是,只要我使用CUDA,我就需要使用C ++。我安装了OpenCV。不幸的是,我无法使用OpenCV将图像直接读入浮点数组。在将其读入uchar数组后,我将数据转换为浮点数组:

image = imread(b, 0);
image.convertTo(img_float, CV_32F);
float *d = img_float.ptr<float>(0);

在测试此实现后,我得到了更糟糕的结果:每个图像8.8ms。没有转换它是8.2 ms。通常c++比Matlab更快。是否有可能用c ++实现峰值带宽,就像我用Matlab做的那样?

P.S。在c ++中,我使用了release x64模式并进行了全面优化。阅读250个不同图像的时间是通过matlab中的clock()c++中的函数tic-toc来测量的(并且在每个图像中被划分为250以找到时间)。

由于

1 个答案:

答案 0 :(得分:2)

有几点需要注意。第一:尝试验证您的基准测试是否正确。文件系统缓存可以影响结果吗?如果是,请尝试使用更大的数据。您的基准测量是否衡量您真正想要测量的内容(即MatLab是否真的将图像转换为浮动)?图像是否正确读取而没有错误?

您问题的直接答案&#34;用c ++读取硬盘的最快方法是什么?&#34;很可能&#34; C ++(几乎)没有影响从HDD到RAM的数据传输速度&#34;。分配所需的内存量并使用操作系统的本机API来读取文件:您将获得最大值。

可能重要的是TIFF图像处理库。试着找出OpenCV用来处理TIFF的库。它是否对某些中间表示执行任何不必要的转换或只读取字节blob?如果前者是真的,尝试找到另一个库,甚至手动解析TIFF图像(如果它没有压缩,解析TIFF不是什么大问题)。转换为浮动可能不是瓶颈。 OpenCV能够使用多线程(验证所有CPU内核都被使用)和矢量化(您可以通过查看执行转换的实际代码来检查它)。此外,如果您需要重复执行这些操作,请避免在循环中分配和释放内存:不要执行转换&#34;就地&#34;,而是使用两个单独的数组(一个用于8位图像,一个对于浮点)。

P.S。是不是可以在GPU中转换图像?