我们的计算机一次获取数百个图像,我们需要尽快旋转和调整它们的大小。旋转角度为90度、180度或270度。
目前,我们正在使用命令行工具GraphicsMagick来旋转图像。旋转图像(5760*3840~22MP)大约需要4到7秒。
下面的python代码不幸地给了我们相同的结果
import cv
img = cv.LoadImage("image.jpg")
timg = cv.CreateImage((img.height,img.width), img.depth, img.channels) # transposed image
# rotate counter-clockwise
cv.Transpose(img,timg)
cv.Flip(timg,timg,flipMode=0)
cv.SaveImage("rotated_counter_clockwise.jpg", timg)
有没有一种更快的方法可以使用显卡的功能旋转图像?想到了OpenCL和OpenGL,但我们想知道性能的提高是否值得注意。
我们使用的硬件相当有限,因为设备应该尽可能小。
- Intel Atom D525(1.8 Ghz)
- Mobility Radeon HD 5430系列
- 4 GB RAM
- SSD垂直3
该软件是debian 6与官方(开源)radeon驱动程序。
您可以执行无损旋转,只需修改EXIF部分。这样可以更快地旋转图片。
看看jpegtran实用程序,它可以执行无损jpeg修改。https://linux.die.net/man/1/jpegtran
irfanview有一个jpeg无重新压缩插件,IIRC可以在无需重新压缩的情况下旋转和调整图像大小(以简单的方式),它还可以运行一个图像目录-这应该会更快
GPU可能不会有帮助,你几乎可以肯定的是,opencv中的I/O受到限制,它并没有真正适用于高速文件访问
我不是jpeg和压缩主题的专家,但由于您的问题的I/O非常有限(假设您可以在没有大量去编码相关计算的情况下进行旋转),您可能无法在现有GPU上对其进行很大的加速。(Un)幸运的是,您的参考是一个相当慢的Atom CPU。
我认为Radeon有单独的主存储器。这意味着数据需要通过PCI-E进行通信,这与CPU执行相比是额外的延迟,并且在不隐藏的情况下,您可以确定这是瓶颈。这就是为什么在GPU上使用OpenCV的代码速度较慢的最可能原因(除了你要做两个内存绑定操作,即转置和翻转,而不是一个)。
关键是通过使用多个缓冲区,通过计算尽可能多地隐藏PCI-E传输时间。只有当有问题的卡具有双DMA引擎(如高端Radeons或NVIDIA Quadro/Tsla卡)时,才能通过利用PCI-E的全双工功能在GPU和计算之间进行重叠传输——我对此深表怀疑。
如果你的GPU计算时间(GPU进行旋转所需的时间)低于传输所用的时间,你将无法完全重叠。HD 4530有一个非常慢的内存接口,峰值只有12.8 Gb/s,并且旋转内核应该非常受内存限制。然而,我只能猜测,但我想说的是,如果你达到峰值PCI-E传输速率约1.5 Gb/s(4x PCI-E AFAIK),计算内核将比传输快几倍,你将能够重叠得很少。您可以简单地分别对各部分进行计时,而不需要复杂的异步代码,并且您可以估计获得最佳重叠的速度。
你可能想考虑的一件事是获得不将PCI-E作为瓶颈的硬件,例如:
- 基于AMD APU的系统。在这些平台上,您将能够页面锁定内存,并直接从GPU使用它
- 与主机共享主存储器的集成GPU
- 快速低功耗CPU,如移动Intel Ivy Bridge,例如i5-3427U,其消耗几乎与Atom D525一样少,但具有AVX支持,并且应该快几倍