HSV to RGB Color Conversion

后端 未结 9 1671
离开以前
离开以前 2020-12-14 01:16

Is there a way to convert HSV color arguments to RGB type color arguments using pygame modules in python? I tried the following code, but it returns ridiculous values.

相关标签:
9条回答
  • 2020-12-14 01:30

    The Hue argument should also vary from 0-1.

    import colorsys
    test_color = colorsys.hsv_to_rgb(359/360.0, 1, 1)
    
    0 讨论(0)
  • 2020-12-14 01:31

    That function expects decimal for s (saturation) and v (value), not percent. Divide by 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)
    

    If you would like the non-normalized RGB tuple, here is a function to wrap the colorsys function.

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

    Example functionality

    >>> hsv2rgb(0.5,0.5,0.5)
    (64, 128, 128)
    
    0 讨论(0)
  • 2020-12-14 01:35

    If you are working with Numpy arrays then matplotlib.colors.hsv_to_rgb is quite direct:

    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)
    

    Note that the input and output images have values in the range [0, 1].

    0 讨论(0)
  • 2020-12-14 01:38

    In opencv, use any of their color conversions. Note that BGR and RGB are flipped in cv2 land.

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

    Usage:

    hsvColor = (0,255,255) #bright red
    bgrColor = convertColor(hsvColor, cv2.COLOR_HSV2BGR)
    
    0 讨论(0)
  • 2020-12-14 01:39

    OpenCV also offers this possibility. Note that R and B channels are inverted, i.e. BGR. So uses the function that best fits your needs:

    import cv2
    
    rgbimg = cv2.cvtColor(hsvimg, cv2.COLOR_HSV2RGB)
    bgrimg = cv2.cvtColor(hsvimg, cv2.COLOR_HSV2BGR)
    
    0 讨论(0)
  • 2020-12-14 01:39

    Since the question is tagged pygame, I want to mention that PyGame allows conversion between color schemes. The pygame.Color object can be used to convert between the RGB and HSL/HSV color schemes.

    The hsva property:

    Gets or sets the HSVA representation of the Color. The HSVA components are in the ranges H = [0, 360], S = [0, 100], V = [0, 100], A = [0, 100].

    hsva = pygame.Color((red, green, blue, alpha)).hsva
    
    color = pygame.Color(0)
    color.hsva = (hue, saturation, value, alpha)
    rgba = (color.r, color.g, color.b, color.a)
    

    The hsla property:

    Gets or sets the HSLA representation of the Color. The HSLA components are in the ranges H = [0, 360], S = [0, 100], V = [0, 100], A = [0, 100].

    hsla = pygame.Color((red, green, blue, alpha)).hsla
    
    color = pygame.Color(0)
    color.hsla = (hue, saturation, lightness, alpha)
    rgba = (color.r, color.g, color.b, color.a)
    

    Minimal example:

    import pygame
    
    pygame.init()
    
    window = pygame.display.set_mode((450, 300))
    clock = pygame.time.Clock()
    
    run = True
    while run:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
    
        window.fill((255, 255, 255))
        w, h = window.get_size()
        for i in range(6):
            color = pygame.Color(0)
            color.hsla = (i * 60, 100, 50, 100)
            pygame.draw.circle(window, color, 
                (w//6 + w//3 * (i%3), h//4 + h//2 * (i//3)), 
                round(min(window.get_width() * 0.16, window.get_height() * 0.2)))
    
        pygame.display.flip()
    
    pygame.quit()
    exit()
    
    0 讨论(0)
提交回复
热议问题