3

在 python 中,我scipy.ndimage.zoom用来对图像执行双三次插值,但发现上采样速度太慢。我想用其他一些支持 GPU 的 python 库来替换它,但不幸的是我找不到一个可用于 python 的库。

NVIDIA 提供了一个很好的例子,它在 C/C++ 中完全实现了双三次插值。它们是我们可以直接使用和替换的众所周知的等效CUDA Pythonscipy.ndimage.zoom示例/库吗?

我在网上做了一些搜索,但无法在 python 中使用 GPU 找到双三次插值。因此,我相信没有多少答案会导致固执的答案和垃圾邮件。

4

1 回答 1

3

它不是 GPU(而是试图利用线程和 CPU 的向量单元),但pyvips比 scipy 快很多,你可以测试一下。

我做了一个基准:

import sys
import time

import scipy.ndimage
import pyvips

scale = 10
n_loops = 10

start = time.time()
test_image = scipy.ndimage.imread(sys.argv[1])
for i in range(0, n_loops):
    result = scipy.ndimage.interpolation.zoom(test_image, scale)
end = time.time()

print 'scipy took', end - start

start = time.time()
test_image = pyvips.Image.new_from_file(sys.argv[1])
for i in range(0, n_loops):
    result = test_image.resize(scale).write_to_memory()
end = time.time()

print 'pyvips took', end - start

# transform with both libraries to compare results

ndi = scipy.ndimage.imread(sys.argv[1])
result = scipy.ndimage.interpolation.zoom(ndi, scale)
scipy.misc.imsave('ndi.tif', result)

im = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
result = im.resize(scale)
result.write_to_file('pyvips.tif')

两者都默认为双三次。pyvips 是一个惰性库,所以write_to_memory()最后需要额外的来生成内存数组。

在这个运行 Ubuntu 17.10 的四核/八线程桌面上,所有库的打包版本和 512x512 单声道版本的“lena”测试图像,我看到:

$ python zoom.py ~/pics/lena.png 
scipy took 15.6309859753
pyvips took 1.36838102341

GPU upsizer 显然会再次更快,但也许 pyvips 会足够快?

如果您比较两个输出图像,您会看到 scipy 图像向上移动了一小部分。您可以使用非常小的输入图像更清楚地看到正在发生的事情,例如,这个 3x3 像素的图像:

3x3 像素测试图像

当通过 scipy 和 pyvips 放大 20 倍时变为:

使用 scipy 和 pyvips 放大 20 倍

这让我很困惑。此外,他们显然使用了不同的内核,这也很奇怪。

于 2018-02-05T12:35:49.313 回答