Python:使用GPU进行双三次插值

时间:2018-02-05 09:57:27

标签: python cuda scipy interpolation bicubic

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

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

我在线进行了一些搜索但无法在python中使用GPU找到双三次插值。因此,我认为没有多少答案可以引起自以为是的答案和垃圾邮件。

1 个答案:

答案 0 :(得分:2)

它不是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的四核/八线程桌面上,包含所有库的打包版本和'lena'测试图像的512x512单声道版本,我看到了:

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

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

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

3x3 pixel test image

当scipy缩放20倍时,pyvips变为:

20x upsize with scipy and pyvips

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