c++ - 从硬盘读取灰度图像的最快方法

标签 c++ image opencv cuda

我正在使用 GPU (CUDA) 上的图像处理。 CUDA 内核的输入是两个灰度 8 位图像 (.tif)。它们必须在 GPU RAM 内存中作为一维数组(从 0 开始,行优先存储)。处理时间约为 24 毫秒,因此阅读速度对我来说很重要。为此,首先我需要将图像从 HDD 读取到 CPU RAM 内存(进入一维 float 组),然后使用 cudamemcpy 将其复制到 GPU RAM 中。使用 C++ 从 HDD 读取最快的方法是什么?

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

使用 matlab (imread) 读取 1 张图像的时间是 5.8ms。这对应于 ~300 Mb/s,接近我硬盘的峰值带宽。

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

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

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

附言在 c++ 中,我使用了完全优化的 release x64 模式。读取 250 张不同图像的时间是通过 c++ 中的函数 clock() 和 matlab 中的 tic-toc 测量的(并被分成 250 多个以找到每一张图片的时间)。

谢谢

最佳答案

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

对“使用 C++ 从 HDD 读取最快的方法是什么?”这个问题的直截了当的回答可能是“C++(几乎)对从 HDD 到 RAM 的数据传输速度没有影响”。分配所需的内存量并使用操作系统的 native API 读取文件:您将获得最大内存量。

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

附言不是可以在 GPU 中转换图像吗?

关于c++ - 从硬盘读取灰度图像的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28102232/

相关文章:

C++将数据从数据文件输入到结构变量中

java - 正确缩放图像的位置Java

python - 如何在没有 twilio 的情况下使用 python 和 opencv 流式传输视频?

python - 如何使用 OpenCV-Python 检测照片上的黑色形状轮廓

python - 使用 numpy、openCV 和 python 自定义灰度图像

c++ - 为什么vector::push_back有两个重载?

c++ - 将函数和参数传递给线程

c++ - 模板参数变量/动态实例化

javascript - onclick 发生 onload?

HTML Bootstrap 将图像放入行内的列中