更快的调整PIL像素值的方法

Mik*_*and 1 python numpy chromakey pillow

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

这是我的鄙视程序.它需要一个PIL图像和一个敏感数字,但到目前为止我已经离开了它...它一直运作良好.我正以超过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
Run Code Online (Sandbox Code Playgroud)

我尝试将输出像素值写入numpy数组,然后将数组转换为PIL图像,而不是putpixel,但是平均时间超过5秒......所以这种方式更快.我知道putpixel不是最快的选择,但我不知所措......

Mat*_*lia 5

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)
Run Code Online (Sandbox Code Playgroud)

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