Python HSV到RGB颜色转换

Python HSV到RGB颜色转换,python,colors,pygame,rgb,hsv,Python,Colors,Pygame,Rgb,Hsv,有没有办法使用python中的pygame模块将HSV颜色参数转换为RGB类型的颜色参数?我尝试了下面的代码,但它返回了荒谬的值 import colorsys test_color = colorsys.hsv_to_rgb(359, 100, 100) print(test_color) 这段代码返回下面的废话 (100, -9900.0, -9900.0) 这显然不是RGB。我做错了什么?该函数要求s饱和度和v值为十进制,而不是百分比。除以100 >>> import

有没有办法使用python中的pygame模块将HSV颜色参数转换为RGB类型的颜色参数?我尝试了下面的代码,但它返回了荒谬的值

import colorsys
test_color = colorsys.hsv_to_rgb(359, 100, 100)
print(test_color)
这段代码返回下面的废话

(100, -9900.0, -9900.0)

这显然不是RGB。我做错了什么?

该函数要求s饱和度和v值为十进制,而不是百分比。除以100

>>> import colorsys

# Using percent, incorrect
>>> test_color = colorsys.hsv_to_rgb(359,100,100)
>>> test_color
(100, -9900.0, -9900.0)

# Using decimal, correct
>>> test_color = colorsys.hsv_to_rgb(1,1,1)
>>> test_color
(1, 0.0, 0.0)
如果您想要非规范化的RGB元组,这里有一个函数包装colorsys函数

def hsv2rgb(h,s,v):
    return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h,s,v))
示例功能

>>> hsv2rgb(0.5,0.5,0.5)
(64, 128, 128)

如果您喜欢性能,最好避免导入并使用您自己的优化代码

下面是colorsys的精确代码,经过稍微修改后,字节码速度稍微加快:

    def hsv_to_rgb(h, s, v):
        if s == 0.0: return (v, v, v)
        i = int(h*6.) # XXX assume int() truncates!
        f = (h*6.)-i; p,q,t = v*(1.-s), v*(1.-s*f), v*(1.-s*(1.-f)); i%=6
        if i == 0: return (v, t, p)
        if i == 1: return (q, v, p)
        if i == 2: return (p, v, t)
        if i == 3: return (p, q, v)
        if i == 4: return (t, p, v)
        if i == 5: return (v, p, q)
输出:

>>> hsv_to_rgb(359,1,1)
[1, 0.0, 0.0]
使用像上面这样的if链实际上比使用elif更快

使用包装器,就像Cyber的回答一样,需要口译员执行一些额外的步骤。 另外,Cyber示例中的for循环在这样使用时是一个真正的性能杀手

如果您想稍微提高性能,只需执行以下操作: 我不会说这是最好的表现,但肯定更好

    def hsv_to_rgb(h, s, v):
        if s == 0.0: v*=255; return (v, v, v)
        i = int(h*6.) # XXX assume int() truncates!
        f = (h*6.)-i; p,q,t = int(255*(v*(1.-s))), int(255*(v*(1.-s*f))), int(255*(v*(1.-s*(1.-f)))); v*=255; i%=6
        if i == 0: return (v, t, p)
        if i == 1: return (q, v, p)
        if i == 2: return (p, v, t)
        if i == 3: return (p, q, v)
        if i == 4: return (t, p, v)
        if i == 5: return (v, p, q)
^这保证了int输出的范围为255,但输入仍然相同

>>> hsv_to_rgb(359./360.,1,1)
(255, 0, 0)
小贴士:尽可能远离第三方,如果可能,尝试直接方法。
执行:编译的C扩展(如PIL或NumPy)或ctypes包装(如PyOpenGL)使用DLL

我已经准备了一个矢量化版本,速度快了10倍

def hsv_to_rgb(h, s, v):
    shape = h.shape
    i = int_(h*6.)
    f = h*6.-i

    q = f
    t = 1.-f
    i = ravel(i)
    f = ravel(f)
    i%=6

    t = ravel(t)
    q = ravel(q)

    clist = (1-s*vstack([zeros_like(f),ones_like(f),q,t]))*v

    #0:v 1:p 2:q 3:t
    order = array([[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]])
    rgb = clist[order[i], arange(prod(shape))[:,None]]

    return rgb.reshape(shape+(3,))

色调参数也应在0-1之间变化

import colorsys
test_color = colorsys.hsv_to_rgb(359/360.0, 1, 1)

如果您使用的是Numpy阵列,则非常直接:

import numpy as np
from matplotlib.colors import hsv_to_rgb
# This will create a nice image of varying hue and value
hsv = np.zeros((512, 512, 3))
hsv[..., 0] = np.linspace(0, 1, 512)
hsv[..., 1] = 1.
hsv[..., 2] = np.linspace(0, 1, 512)[:, np.newaxis]
rgb = hsv_to_rgb(hsv)

请注意,输入和输出图像的值在[0,1]范围内。

我发现以下代码可用于表示为numpy ndarray的图像:

from skimage.io import imread
import matplotlib.colors as mcolors
img = imread( 'my_image.png' )
img_hsv = mcolors.rgb_to_hsv( img )
img_hsv = img_hsv / (1.0, 1.0, 255.0)

最后一个除法对于转换为介于0.0和1.0之间的浮动表示很有用,因为出于某种原因,最后一个组件最初介于0和255之间。

OpenCV也提供了这种可能性。请注意,R和B通道是反向的,即BGR。因此,请使用最适合您需要的功能:

import cv2

rgbimg = cv2.cvtColor(hsvimg, cv2.COLOR_HSV2RGB)
bgrimg = cv2.cvtColor(hsvimg, cv2.COLOR_HSV2BGR)

由于问题已标记,我想提及允许颜色方案之间的转换。该对象可用于在RGB和颜色方案之间转换

财产:

获取或设置颜色的HSVA表示形式。HSVA分量的范围为H=[0360],S=[01100],V=[01100],A=[01100]

hsva=pygame。红色、绿色、蓝色、alpha.hsva color=pygame.Color0 color.hsva=色调、饱和度、值、alpha rgba=color.r,color.g,color.b,color.a 财产:

获取或设置颜色的HSLA表示形式。HSLA组件的范围为H=[0360]、S=[01100]、V=[01100]、A=[01100]

hsla=pygame。红色、绿色、蓝色、alpha.hsla color=pygame.Color0 color.hsla=色调、饱和度、亮度、alpha rgba=color.r,color.g,color.b,color.a 最简单的例子:

导入pygame pygame.init window=pygame.display.set_mode450300 clock=pygame.time.clock 运行=真 运行时: 时钟滴答滴答 对于pygame.event.get中的事件: 如果event.type==pygame.QUIT: 运行=错误 window.fill255、255、255 w、 h=窗口。获取大小 对于范围6中的i: color=pygame.Color0 color.hsla=i*60100,50100 pygame.draw.circlewindow,颜色, w//6+w//3*i%3,h//4+h//2*i//3, roundminwindow.get_width*0.16,window.get_height*0.2 pygame.display.flip pygame.退出 出口
在opencv中,使用它们的任何颜色转换。请注意,BGR和RGB在cv2焊盘中翻转

def convertColor(hsv, conversion):
    return tuple(int(i) for i in cv2.cvtColor(np.uint8([[hsv]]), conversion).flatten())
用法:

hsvColor = (0,255,255) #bright red
bgrColor = convertColor(hsvColor, cv2.COLOR_HSV2BGR)

谢谢是否有任何内置函数来反规范化RGB函数?我不知道开箱即用的函数,但您可以编写一个。请参阅我对该函数的最新编辑。色调参数也应在0-1Yep之间变化,以响应Anand C U和Paul Beloff所说的,您需要将色调除以360,例如125/360,以获得绿色。否则你会经常发红,所以。。。为什么我被降级??为什么没有评论告诉我我做错了什么,这样我才能更好地自己??因为你的解决方案采用0到1的色调值,但在你的示例中,你使用0到360的值。如果我们谈论性能,我会远离列表,而是返回元组。+Matteo Italia:长大一点后,我实际上同意你的看法,如果我在电话中的任何人想编辑此答案以返回元组,请随意。NameError:未定义名称“ravel”,否则我将向上投票。ravel是一个numpy函数。在代码之前从numpy import*添加。非常好的注释,我想知道为什么我总是变红!。谢谢,这节省了我很多时间!