What I'm trying to do: continuously change the Hue value of an image, from 0 to 360, saving one image for each Hue.
How I'm trying: I started by using code I found on this link, then modifying it to change the Hue and save the images.
What is the problem: The code from the link above apparently doesn't save the image as true HSV, because when it merges the image it uses the image mode RGB. But I can't find a way to make it HSV.
def hueChange(img, hue):
if isinstance(img, Image.Image):
img.load()
r, g, b = img.split()
h_data = []
s_data = []
v_data = []
for rd, gr, bl in zip(r.getdata(), g.getdata(), b.getdata()):
h, s, v = colorsys.rgb_to_hsv(rd / 255., bl / 255., gr / 255.)
h_data.append(int(hue))
s_data.append(int(s * 255.))
v_data.append(int(v * 255.))
r.putdata(h_data)
g.putdata(s_data)
b.putdata(v_data)
return toRGB(Image.merge('RGB',(r,g,b)))
else:
return None
# Don't care about the range indices, they are just for testing
for hue in range(1, 255, 30):
in_name = '/Users/cgois/Dropbox/Python/fred/fred' + str(hue) + '.jpg'
img = Image.open(in_name)
img = hueChange(img, hue)
out_name = '/Users/cgois/Dropbox/Python/fred/hue/fred_hue' + str(hue) + '.png'
img.save(out_name)
The last solution I tried: was to do the conversion as above, and then convert it back to RGB using a similar code to hueChange(...). However, the effect was just that the output images had a *(single)*color overlay on top of them.
Any ideas? Thank you for your time (:
Use
colorsys.hsv_to_rgb
to convert the (H,S,V) tuple back to RGB:Changing the values pixel by pixel can be very slow for large images. For better performance, use NumPy. (The NumPy functions were taken from here):
According to this page, when the Photoshop "Colorize" box is unchecked, the hue of each pixel is shifted by the same amount. When the "Colorize" box is checked, the hue of each pixel is set to the same amount.
So, to shift the hue by a fixed amount, use:
without_colorize.jpg:
hue+50:
hue+133:
Note: When shifting the hue certain region s of the hair and face became a different color with a distinct, unnatural border. It looks like my code does not faithfully reproduces what Photoshop is doing...