使用Python将RGB值转换为对应的HSV值
我想用Python把RGB值转换成HSV值。我找了一些代码示例,但得到的结果中S和V的值都超过了100。(例如:http://code.activestate.com/recipes/576554-covert-color-space-from-hsv-to-rgb-and-rgb-to-hsv/)有没有人能提供更好的代码,能把RGB转换成HSV,反之亦然?
谢谢!
8 个回答
9
根据numpy中的数组索引和切片,这就是我处理前向转换的方法:
import numpy as np
def rgb2hsv(rgb):
""" convert RGB to HSV color space
:param rgb: np.ndarray
:return: np.ndarray
"""
rgb = rgb.astype('float')
maxv = np.amax(rgb, axis=2)
maxc = np.argmax(rgb, axis=2)
minv = np.amin(rgb, axis=2)
minc = np.argmin(rgb, axis=2)
hsv = np.zeros(rgb.shape, dtype='float')
hsv[maxc == minc, 0] = np.zeros(hsv[maxc == minc, 0].shape)
hsv[maxc == 0, 0] = (((rgb[..., 1] - rgb[..., 2]) * 60.0 / (maxv - minv + np.spacing(1))) % 360.0)[maxc == 0]
hsv[maxc == 1, 0] = (((rgb[..., 2] - rgb[..., 0]) * 60.0 / (maxv - minv + np.spacing(1))) + 120.0)[maxc == 1]
hsv[maxc == 2, 0] = (((rgb[..., 0] - rgb[..., 1]) * 60.0 / (maxv - minv + np.spacing(1))) + 240.0)[maxc == 2]
hsv[maxv == 0, 1] = np.zeros(hsv[maxv == 0, 1].shape)
hsv[maxv != 0, 1] = (1 - minv / (maxv + np.spacing(1)))[maxv != 0]
hsv[..., 2] = maxv
return hsv
还有反向颜色空间转换的方法:
def hsv2rgb(hsv):
""" convert HSV to RGB color space
:param hsv: np.ndarray
:return: np.ndarray
"""
hi = np.floor(hsv[..., 0] / 60.0) % 6
hi = hi.astype('uint8')
v = hsv[..., 2].astype('float')
f = (hsv[..., 0] / 60.0) - np.floor(hsv[..., 0] / 60.0)
p = v * (1.0 - hsv[..., 1])
q = v * (1.0 - (f * hsv[..., 1]))
t = v * (1.0 - ((1.0 - f) * hsv[..., 1]))
rgb = np.zeros(hsv.shape)
rgb[hi == 0, :] = np.dstack((v, t, p))[hi == 0, :]
rgb[hi == 1, :] = np.dstack((q, v, p))[hi == 1, :]
rgb[hi == 2, :] = np.dstack((p, v, t))[hi == 2, :]
rgb[hi == 3, :] = np.dstack((p, q, v))[hi == 3, :]
rgb[hi == 4, :] = np.dstack((t, p, v))[hi == 4, :]
rgb[hi == 5, :] = np.dstack((v, p, q))[hi == 5, :]
return rgb
我写这些代码的原因是,我对逐个像素转换不太放心,因为这样会增加计算负担,而且我也不想依赖其他库,比如OpenCV。
如果你有建议,可以告诉我,看看怎么能让这个解决方案更优雅和通用。
10
如果你在使用PIL,并且你的Pillow版本是比较新的话,建议你使用下面的代码:
def rgb2hsv(image):
return image.convert('HSV')
40
你试过使用 colorsys 这个库吗?
colorsys 模块可以在不同的颜色表示方式之间进行转换。它可以把颜色值在 RGB(红绿蓝)这种电脑显示器常用的颜色空间和另外三种颜色坐标系统之间互相转换:YIQ、HLS(色相、亮度、饱和度)和 HSV(色相、饱和度、明度)。
下面是一个例子(来自上面的链接):
>>> import colorsys
>>> colorsys.rgb_to_hsv(.3, .4, .2)
(0.25, 0.5, 0.4)
>>> colorsys.hsv_to_rgb(0.25, 0.5, 0.4)
(0.3, 0.4, 0.2)