调整 PIL 像素值的更快方法
Faster method for adjusting PIL pixel values
我正在为色度键(绿屏)编写脚本,并使用 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 不是最快捷的选择,但我不知所措...
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)
(它可能不正确,我相信它可以更好地优化,这只是一个草图)
我正在为色度键(绿屏)编写脚本,并使用 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 不是最快捷的选择,但我不知所措...
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)
(它可能不正确,我相信它可以更好地优化,这只是一个草图)