gpt4 book ai didi

python - RGB 到 HSV Python,不断改变色调

转载 作者:太空狗 更新时间:2023-10-30 03:01:02 25 4
gpt4 key购买 nike

我正在尝试做的事情:连续更改图像的 Hue 值,从 0 到 360,为每个 Hue 保存一张图像。

我是如何尝试的:我首先使用在 this link 上找到的代码,然后修改它以更改色调并保存图像。

问题是什么:上面链接中的代码显然没有将图像保存为真正的 HSV,因为当它合并图像时它使用 图像模式 RGB。但我找不到使它成为 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)

我尝试的最后一个解决方案: 是按照上面的方法进行转换,然后使用与 hueChange(...) 类似的代码将其转换回 RGB。然而,效果只是输出图像上有一个 *(单色)* 颜色叠加层。

有什么想法吗?谢谢你的时间(:

最佳答案

使用 colorsys.hsv_to_rgb 将 (H,S,V) 元组转换回 RGB:

import os
import colorsys
import Image

def hueChange(img, hue):
# It's better to raise an exception than silently return None if img is not
# an Image.
img.load()
r, g, b = img.split()
r_data = []
g_data = []
b_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.)
rgb = colorsys.hsv_to_rgb(hue/360., s, v)
rd, gr, bl = [int(x*255.) for x in rgb]
r_data.append(rd)
g_data.append(gr)
b_data.append(bl)

r.putdata(r_data)
g.putdata(g_data)
b.putdata(b_data)
return Image.merge('RGB',(r,g,b))

filename = 'image.png'
basename, ext = os.path.splitext(filename)
img = Image.open(filename).convert('RGB')
for hue in range(1, 360, 30):
img2 = hueChange(img, hue)
out_name = '{}_hue{:03d}.jpg'.format(basename, hue)
img2.save(out_name)

对于大图像,逐像素更改值可能非常慢。为了获得更好的性能,请使用 NumPy。 (NumPy 函数取自 here ):

import os
import Image
import numpy as np

def rgb_to_hsv(rgb):
# Translated from source of colorsys.rgb_to_hsv
# r,g,b should be a numpy arrays with values between 0 and 255
# rgb_to_hsv returns an array of floats between 0.0 and 1.0.
rgb = rgb.astype('float')
hsv = np.zeros_like(rgb)
# in case an RGBA array was passed, just copy the A channel
hsv[..., 3:] = rgb[..., 3:]
r, g, b = rgb[..., 0], rgb[..., 1], rgb[..., 2]
maxc = np.max(rgb[..., :3], axis=-1)
minc = np.min(rgb[..., :3], axis=-1)
hsv[..., 2] = maxc
mask = maxc != minc
hsv[mask, 1] = (maxc - minc)[mask] / maxc[mask]
rc = np.zeros_like(r)
gc = np.zeros_like(g)
bc = np.zeros_like(b)
rc[mask] = (maxc - r)[mask] / (maxc - minc)[mask]
gc[mask] = (maxc - g)[mask] / (maxc - minc)[mask]
bc[mask] = (maxc - b)[mask] / (maxc - minc)[mask]
hsv[..., 0] = np.select(
[r == maxc, g == maxc], [bc - gc, 2.0 + rc - bc], default=4.0 + gc - rc)
hsv[..., 0] = (hsv[..., 0] / 6.0) % 1.0
return hsv

def hsv_to_rgb(hsv):
# Translated from source of colorsys.hsv_to_rgb
# h,s should be a numpy arrays with values between 0.0 and 1.0
# v should be a numpy array with values between 0.0 and 255.0
# hsv_to_rgb returns an array of uints between 0 and 255.
rgb = np.empty_like(hsv)
rgb[..., 3:] = hsv[..., 3:]
h, s, v = hsv[..., 0], hsv[..., 1], hsv[..., 2]
i = (h * 6.0).astype('uint8')
f = (h * 6.0) - i
p = v * (1.0 - s)
q = v * (1.0 - s * f)
t = v * (1.0 - s * (1.0 - f))
i = i % 6
conditions = [s == 0.0, i == 1, i == 2, i == 3, i == 4, i == 5]
rgb[..., 0] = np.select(conditions, [v, q, p, p, t, v], default=v)
rgb[..., 1] = np.select(conditions, [v, v, v, q, p, p], default=t)
rgb[..., 2] = np.select(conditions, [v, p, t, v, v, q], default=p)
return rgb.astype('uint8')

def hueChange(img, hue):
arr = np.array(img)
hsv = rgb_to_hsv(arr)
hsv[..., 0] = hue
rgb = hsv_to_rgb(hsv)
return Image.fromarray(rgb, 'RGB')

filename = 'image.png'
basename, ext = os.path.splitext(filename)
img = Image.open(filename).convert('RGB')
for hue in np.linspace(0, 360, 8):
img2 = hueChange(img, hue/360.)
out_name = '{}_hue{:03d}.jpg'.format(basename, int(hue))
img2.save(out_name)

根据 this page ,当 Photoshop 的“着色”框未选中时,每个像素的色调将偏移相同的量。选中“着色”框时,每个像素的色调设置相同。

因此,要将色调移动固定量,请使用:

def hueShift(img, amount):
arr = np.array(img)
hsv = rgb_to_hsv(arr)
hsv[..., 0] = (hsv[..., 0]+amount) % 1.0
rgb = hsv_to_rgb(hsv)
return Image.fromarray(rgb, 'RGB')

filename = 'without_colorize.jpg'
basename, ext = os.path.splitext(filename)
img = Image.open(filename).convert('RGB')
for amount in (50, 133):
img2 = hueShift(img, amount/360.)
out_name = '{}_hue{:+03d}.jpg'.format(basename, int(amount))
img2.save(out_name)

without_colorize.jpg:

enter image description here

色调+50:

enter image description here

色调+133:

enter image description here

注意:在某个区域变换色调时头发和脸的颜色变成了不同的颜色,带有明显的、不自然的边界。看起来我的代码没有忠实地再现 Photoshop 正在做的事情......

关于python - RGB 到 HSV Python,不断改变色调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27041559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com