【问题标题】:Speeding up linear interpolation of many pixel locations in NumPy加速 NumPy 中许多像素位置的线性插值
【发布时间】:2012-03-14 02:06:11
【问题描述】:

我试图在我的一个程序中复制主要瓶颈。

我想同时获得几个非整数像素值的linearly (or rather bilinearly) interpolated 值。 不是每个像素坐标都以相同的方式受到扰动的情况。下面是一个完整/最小的脚本以及演示问题的 cmets。如何加快result的计算速度?

import numpy as np
import time

im = np.random.rand(640,480,3) # my "image"
xx, yy = np.meshgrid(np.arange(im.shape[1]), np.arange(im.shape[0]))
print "Check these are the right indices:",np.sum(im - im[yy,xx,:])

# perturb the indices slightly
# I want to calculate the interpolated
# values of "im" at these locations
xx = xx + np.random.normal(size=im.shape[:2])
yy = yy + np.random.normal(size=im.shape[:2])

# integer value/pixel locations
x_0 = np.int_(np.modf(xx)[1])
y_0 = np.int_(np.modf(yy)[1])
x_1, y_1 = x_0 + 1, y_0 + 1

# the real-valued offsets/coefficients pixels
a = np.modf(xx)[0][:,:,np.newaxis]
b = np.modf(yy)[0][:,:,np.newaxis]

# make sure we don't go out of bounds at edge pixels
np.clip(x_0,0,im.shape[1]-1,out=x_0)
np.clip(x_1,0,im.shape[1]-1,out=x_1)
np.clip(y_0,0,im.shape[0]-1,out=y_0)
np.clip(y_1,0,im.shape[0]-1,out=y_1)

# now perform linear interpolation: THIS IS THE BOTTLENECK!
tic = time.time()
result = ((1-a) * (1-b) * im[y_0, x_0, :] +
             a  * (1-b) * im[y_1, x_0, :] +
          (1-a) *    b  * im[y_0, x_1, :] +
             a  *    b  * im[y_1, x_1, :] )
toc = time.time()

print "interpolation time:",toc-tic

【问题讨论】:

  • 你为什么要避免scipy.ndimage.map_coordinates? (例如,想要避免对 scipy.ndimage 的依赖?)如果不是,这就是你想要的功能。
  • @JoeKington 我不知道这一点 - 让我看看我是否可以使用此功能以及它是否更快。谢谢。

标签: python matlab image-processing numpy scipy


【解决方案1】:

感谢@JoeKington 的建议。这是我能想到的最好的使用scipy.ndimage.map_coordinates

# rest as before
from scipy import ndimage
tic = time.time()
new_result = np.zeros(im.shape)
coords = np.array([yy,xx,np.zeros(im.shape[:2])])
for d in range(im.shape[2]):
    new_result[:,:,d] = ndimage.map_coordinates(im,coords,order=1)
    coords[2] += 1
toc = time.time()
print "interpolation time:",toc-tic

更新:添加了 cmets 中建议的调整并尝试了其他一两件事。这是最快的版本:

tic = time.time()
new_result = np.zeros(im.shape)
coords = np.array([yy,xx])
for d in range(im.shape[2]):
    ndimage.map_coordinates(im[:,:,d],
                            coords,order=1,
                            prefilter=False,
                            output=new_result[:,:,d] )
toc = time.time()

print "interpolation time:",toc-tic

运行时间示例:

 original version: 0.463063955307
   better version: 0.204537153244
     best version: 0.121845006943

【讨论】:

  • 对不起,我之前没有发布示例。我的时间不多了。很高兴你明白了!您可以通过调用map_coordinates 来完成此操作,但根据图像的大小,遍历每个波段可能是更好的选择。存储一个临时的 3D 坐标数组会消耗大量内存。如果您一次只将一个频段传递给map_coordinates,您可以加快速度。它还允许您跳过 coords 中的 zeros 数组。
  • 另外,在双线性插值的情况下,如果您指定prefilter=False,您可以节省一点内存并稍微加快速度。对于小图像,您不会注意到差异,但对于较大的图像,它可以避免在内存中制作额外的副本。
猜你喜欢
  • 2016-01-09
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
相关资源
最近更新 更多