Python中最快的图像迭代

时间:2013-11-05 09:50:37

标签: python optimization python-2.7 python-imaging-library

我正在使用Python 2.7.4创建一个简单的绿屏应用程序,但结果却很慢。我目前正在使用PIL 1.1.7加载和迭代图像,并看到巨大的加速从旧的getpixel()更改为更新的load()和像素访问对象索引。但是,对于大约720p分辨率的图像,以下循环仍然需要大约2.5秒才能运行:

def colorclose(Cb_p, Cr_p, Cb_key, Cr_key, tola, tolb):
    temp = math.sqrt((Cb_key-Cb_p)**2+(Cr_key-Cr_p)**2)
    if temp < tola:
        return 0.0
    else: 
        if temp < tolb:
            return (temp-tola)/(tolb-tola)
        else:
            return 1.0

...

for x in range(width):
    for y in range(height):
        Y, cb, cr = fg_cbcr_list[x, y]
        mask = colorclose(cb, cr, cb_key, cr_key, tola, tolb)
        mask = 1 - mask
        bgr, bgg, bgb = bg_list[x,y]
        fgr, fgg, fgb = fg_list[x,y]
        pixels[x,y] = (
            (int)(fgr - mask*key_color[0] + mask*bgr),
            (int)(fgg - mask*key_color[1] + mask*bgg),
            (int)(fgb - mask*key_color[2] + mask*bgb))

我在这里做了什么非常低效的事情,这让它运行得如此之慢?我已经看到类似的,更简单的例子,例如,循环被布尔矩阵替换,但是对于这种情况,我看不到替换循环的方法。

像素[x,y]分配似乎需要花费大量时间,但不太了解Python我不确定更有效的方法。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

最好通过行像素对像素进行迭代,因为这是内存中使用的布局。

所以而不是:

for x in range(width):
    for y in range(height):

使用

for y in range(height):
    for x in range(width):

编辑:例如,为什么这很重要,您可以阅读关于iterating over an array

的numpy文档
  

要注意这个迭代的一个重要事项是选择顺序以匹配数组的内存布局,而不是使用标准C或Fortran排序。这样做是为了提高访问效率,反映了默认情况下只需要访问每个元素而不关心特定排序的想法。我们可以通过迭代前一个数组的转置来看到这一点,而不是以C顺序获取该转置的副本。