调整PIL像素值的更快方法 [英] Faster method for adjusting PIL pixel values

查看:210
本文介绍了调整PIL像素值的更快方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为色度键(绿屏)编写脚本,并使用Python和PIL(枕头)合成一些视频.我可以设置720p图像的关键点,但是绿色溢出部分还剩下一些.可以理解,但是我正在编写例程来消除溢出……但是我在花多长时间而苦苦挣扎.我可以使用numpy技巧来获得更好的速度,但是我并不那么熟悉.有任何想法吗?

I'm writing a script to chroma key (green screen) and composite some videos using Python and PIL (pillow). I can key the 720p images, but there's some left over green spill. Understandable but I'm writing a routine to remove that spill...however I'm struggling with how long it's taking. I can probably get better speeds using numpy tricks, but I'm not that familiar with it. Any ideas?

这是我的漏油处理程序.它需要一个PIL图像和一个灵敏度数字,但到目前为止,我一直将其设置为1 ...效果很好.我要花4秒钟多一点的时间来拍摄720p帧,以消除这种溢出.为了进行比较,色度键例程每帧运行大约2秒.

Here's my despill routine. It takes a PIL image and a sensitivity number but I've been leaving that at 1 so far...it's been working well. I'm coming in at just over 4 seconds for a 720p frame to remove this spill. For comparison, the chroma key routine runs in about 2 seconds per frame.

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数组,而不是putpixel,然后将其转换为PIL图像,但是平均仅需5秒钟以上...因此,这会以某种方式更快.我知道putpixel不是最轻松的选择,但我很茫然...

Instead of putpixel, I tried to write the output pixel values to a numpy array then convert the array to a PIL image, but that was averaging just over 5 seconds...so this was faster somehow. I know putpixel isn't the snappiest option but I'm at a loss...

推荐答案

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

putpixel is slow, and loops like that are even slower, since they are run by the Python interpreter, which is slow as hell. The usual solution is to convert immediately the image to a numpy array and solve the problem with vectorized operations on it, which run in heavily optimized C code. In your case I would do something like:

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

(可能不正确,我相信可以对其进行更好的优化,这只是一个草图)

(it may not be correct and I'm sure it can be optimized way better, this is just a sketch)

这篇关于调整PIL像素值的更快方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆