矢量化一个numpy例程

时间:2014-06-01 08:02:39

标签: python numpy

我已经完成了以下程序,我写了两条任意曲线并扭曲它们之间的空间,使它适合两条直线。对于循环,它按列处理,因为np.linspace不对矢量AFAIK进行操作。有没有办法摆脱这个循环并立即击中整个事情?

def warp(img, iris_curve, pupil_curve):
  height, width = img.shape[:2]
  iris_height = np.uint8(np.max(np.int8(iris_curve) - pupil_curve))
  out = np.zeros((iris_height, width))

  for r in range(0,width):
    map_theta = np.linspace(pupil_curve[r], iris_curve[r], iris_height)
    map_theta = np.uint8(np.rint(map_theta))
    out[:, r] = img[map_theta, r]

  return np.uint8(out)

谢谢!

2 个答案:

答案 0 :(得分:1)

如果您查看np.linspace的{​​{3}},可以将其用作向量化代码的指南。然后你的循环将被替换为:

steps = (iris_curve - pupil_curve) / iris_height
map_theta = np.arange(iris_height)[:, None] * steps + pupil_curve
map_theta = np.rint(map_theta).astype(np.uint8)
out = img[map_theta, np.arange(width)]

您可能需要转置输出,如果没有示例,很难调试此类代码。

答案 1 :(得分:0)

我首先想到的是这个代码是for循环不太可能是妨碍性能的最重要因素。在这段代码中有大量的数据复制(调用linspace创建一个新的数组,然后将其复制回更大的输出数组。转换为不同的类型也涉及复制数据)。例如,您是否可以将输出作为

启动
np.empty((h,w),dtype=np.uint8)

此外,你真的需要明确计算所有这些值吗?除非你引用所有这些,否则你最好只使用scipy的2D线性插值器。

如果你真的想按原样生成输出,我认为你必须在Cython或类似的东西中编写一些自定义的东西。