I am starting with a starting colour, a target colour and a starting position in a image. I want to change every contiguous pixel if it is close to the starting colour. Imagine a stop sign. It is white letters on a red background. But the red is faded to a bunch of different reds. It should work that all of the red around the letters is one shape to be filled any colour, each letter is another shape to be coloured, and the holes of the O and P should also be shapes to be coloured. If I picked a midrange red from the stop sign and my starting point is on the outside of the letters I would want all the outside red to be changed to the target colour.
So I used colormath to do a delta_e on each pixel to see if it is less than the max acceptable delta. It works!! However it is painfully slow. I was thinking instead of doing a delta_e on each pixel I could do a histogram of all the colours and then have some sort of look up table. However I am brand spankin new to Python and I was hoping to get some help with how I would do that.
Please help optimize it for speed.
Thanks
import Image
def floodFill(x,y, d,e,f, g,h,i, image):
toFill = set()
alreadyfilled = set()
toFill.add((x,y))
image = Image.open(image)
xsize, ysize = image.size
print(xsize,ysize)
print(image.getpixel((x,y)))
while (toFill):
(x,y) = toFill.pop()
alreadyfilled.add((x,y))
#print (x,y)
(a,b,c) = image.getpixel((x,y))
if not (FindDeltaColor(a,b,c,d,e,f) < 50):
continue
image.putpixel((x,y), (g,h,i))
if x != 0:
if (x-1,y) not in alreadyfilled:
toFill.add((x-1,y))
if y != 0:
if (x,y-1) not in alreadyfilled:
toFill.add((x,y-1))
if x != (xsize-1):
if (x+1,y) not in alreadyfilled:
toFill.add((x+1,y))
if y != (ysize-1):
if (x,y+1) not in alreadyfilled:
toFill.add((x,y+1))
return image
def FindDeltaColor(r1,g1,b1,r2,g2,b2):
rgb1 = RGBColor(r1,g1,b1, rgb_type='sRGB')
rgb2 = RGBColor(r2,g2,b2, rgb_type='sRGB')
lab1 = rgb1.convert_to('lab', target_illuminant='D50')
lab2 = rgb2.convert_to('lab', target_illuminant='D50')
return lab1.delta_e(lab2, mode='cie1994')
newimg = floodFill(1,1,255,255,255,245,224,60,original.jpg' )
newimg.save(r'midway.jpg')
img = floodFill(205,350,0,0,0,45,178,191,r'midway.jpg')
img.save(r'floodfill.jpg')