I am starting with a starting colour, a target colour and a starting position in an image. I want to change every contiguous pixel if it is close to the starting colour.
Imagine a stop sign. It has 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, and 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.
from colormath.color_objects import RGBColor 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')