I am creating a simple green screen app with Python 2.7.4 but am getting quite slow results. I am currently using PIL 1.1.7 to load and iterate the images and saw huge speed-ups changing from the old getpixel() to the newer load() and pixel access object indexing. However the following loop still takes around 2.5 seconds to run for an image of around 720p resolution:
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))
Am I doing anything hugely inefficient here which makes it run so slow? I have seen similar, simpler examples where the loop is replaced by a boolean matrix for instance, but for this case I can't see a way to replace the loop.
The pixels[x,y] assignment seems to take the most amount of time but not knowing Python very well I am unsure of a more efficient way to do this.
Any help would be appreciated.