【问题标题】:Faster method for adjusting PIL pixel values调整 PIL 像素值的更快方法
【发布时间】:2015-10-16 23:38:09
【问题描述】:

我正在为色度键(绿屏)编写脚本,并使用 Python 和 PIL(枕头)合成一些视频。我可以对 720p 图像进行抠像,但会留下一些绿色溢出。可以理解,但我正在编写一个例程来消除溢出......但是我正在努力解决它需要多长时间。我可能可以使用 numpy 技巧获得更好的速度,但我对它并不熟悉。有任何想法吗?

这是我的排漏程序。它需要一张 PIL 图像和一个敏感度数,但到目前为止我一直将其设置为 1……它运行良好。我将在 4 秒多一点的时间内进入 720p 帧以消除这种溢出。作为比较,色度键例程每帧运行大约 2 秒。

def despill(img, sensitivity=1):
    """
    Blue limits green.
    """
    start = time.time()
    print '\t[*] Starting despill'
    width, height = img.size
    num_channels = len(img.getbands())
    out = Image.new("RGBA", img.size, color=0)
    for j in range(height):
        for i in range(width):
            #r,g,b,a = data[j,i]
            r,g,b,a = img.getpixel((i,j))
            if g > (b*sensitivity):
                out_g = (b*sensitivity)
            else:
                out_g = g
            # end if

            out.putpixel((i,j), (r,out_g,b,a))
        # end for
    # end for
    out.show()
    print '\t[+] done.'
    print '\t[!] Took: %0.1f seconds' % (time.time()-start)
    exit()
    return out
# end despill

我尝试将输出像素值写入一个 numpy 数组,然后将该数组转换为 PIL 图像,而不是 putpixel,但平均只用了 5 秒多一点……所以这在某种程度上更快。我知道 putpixel 不是最好的选择,但我不知所措......

【问题讨论】:

    标签: python numpy pillow chromakey


    【解决方案1】:

    putpixel 很慢,像这样的循环甚至更慢,因为它们是由 Python 解释器运行的,这非常慢。通常的解决方案是立即将图像转换为 numpy 数组,并通过对其进行矢量化操作来解决问题,这些操作在经过高度优化的 C 代码中运行。在你的情况下,我会做类似的事情:

    arr = np.array(img)
    g = arr[:,:,1]
    bs = arr[:,:,2]*sensitivity
    cond = g>bs
    arr[:,:,1] = cond*bs + (~cond)*g
    out = Image.fromarray(arr)
    

    (可能不正确,我相信它可以更好地优化,这只是一个草图)

    【讨论】:

    • 太棒了!那快得离谱了。谢谢!
    • 是的,用 C 语言正确编写可能会快几倍。顺便说一句,我现在修复的公式中有一个错字,如果你已经复制了它,你应该更新你的代码。
    猜你喜欢
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    相关资源
    最近更新 更多