2014-06-10 3 views
2

외부 모듈에 의존하지 않는 HSV 색상을 RGB로 변환하는 좋은 파이썬 알고리즘을 알고 있습니까? 일부 애니메이션 생성 코드를 작업하고 HSV 색상 공간을 지원하려고하지만 Rdbberry Pi에서 실행 중이며 부동 소수점을 피하려고합니다.파이썬에서 부동 소수점 연산없이 HSV를 RGB로 변환

+0

그렇다면 외부 모듈은 다음과 같은 의미입니까? https://docs.python.org/2/library/colorsys.html (표준 라이브러리)는 옵션이 아닙니까? – Dair

+0

글쎄 ... 나는 플로트를 사용하지 않는 경우와 같은 모듈을 내장하고 있어도 괜찮습니다. 그것은 모든 것을 위해 0.0에서 1.0을 사용하지만 0에서 255가 필요합니다. –

+0

언어 선택을 논쟁 할 수는 없습니다 ... 옵션은 없습니다. 그것은 가능해야합니다. –

답변

3

이 사이트 here은 정수 나누기를 사용하여 수행하는 방법을 포함하여 단계를 안내합니다. 여기 저기 설명 HSV 함수에 RGB의 파이썬 포트가

colorsys 기능

import colorsys 
RGB = (127, 127, 127) 

Converted_2_HSV = RGB_2_HSV(RGB) 
Verify_RGB_2_HSV = colorsys.rgb_to_hsv(RGB[0], RGB[1], RGB[2]) 

print Converted_2_HSV 
>>> (0, 0, 127) 

print Verify_RGB_2_HSV # multiplied by 255 to bring it into the same scale 
>>> (0.0, 0.0, 127.5) 

및 확인할 수와 비교할 때 정확한 결과를 제공

def RGB_2_HSV(RGB): 
    ''' Converts an integer RGB tuple (value range from 0 to 255) to an HSV tuple ''' 

    # Unpack the tuple for readability 
    R, G, B = RGB 

    # Compute the H value by finding the maximum of the RGB values 
    RGB_Max = max(RGB) 
    RGB_Min = min(RGB) 

    # Compute the value 
    V = RGB_Max; 
    if V == 0: 
     H = S = 0 
     return (H,S,V) 


    # Compute the saturation value 
    S = 255 * (RGB_Max - RGB_Min) // V 

    if S == 0: 
     H = 0 
     return (H, S, V) 

    # Compute the Hue 
    if RGB_Max == R: 
     H = 0 + 43*(G - B)//(RGB_Max - RGB_Min) 
    elif RGB_Max == G: 
     H = 85 + 43*(B - R)//(RGB_Max - RGB_Min) 
    else: # RGB_MAX == B 
     H = 171 + 43*(R - G)//(RGB_Max - RGB_Min) 

    return (H, S, V) 

출력 사실기로 아직 있는지 정수

type(Converted_2_HSV[0]) 
>>> <type 'int'> 

이제 역기전력을 위해. 원래 소스는 here이며, 여기에 파이썬 포트가 있습니다.

def HSV_2_RGB(HSV): 
    ''' Converts an integer HSV tuple (value range from 0 to 255) to an RGB tuple ''' 

    # Unpack the HSV tuple for readability 
    H, S, V = HSV 

    # Check if the color is Grayscale 
    if S == 0: 
     R = V 
     G = V 
     B = V 
     return (R, G, B) 

    # Make hue 0-5 
    region = H // 43; 

    # Find remainder part, make it from 0-255 
    remainder = (H - (region * 43)) * 6; 

    # Calculate temp vars, doing integer multiplication 
    P = (V * (255 - S)) >> 8; 
    Q = (V * (255 - ((S * remainder) >> 8))) >> 8; 
    T = (V * (255 - ((S * (255 - remainder)) >> 8))) >> 8; 


    # Assign temp vars based on color cone region 
    if region == 0: 
     R = V 
     G = T 
     B = P 

    elif region == 1: 
     R = Q; 
     G = V; 
     B = P; 

    elif region == 2: 
     R = P; 
     G = V; 
     B = T; 

    elif region == 3: 
     R = P; 
     G = Q; 
     B = V; 

    elif region == 4: 
     R = T; 
     G = P; 
     B = V; 

    else: 
     R = V; 
     G = P; 
     B = Q; 


    return (R, G, B) 

그리고 우리는 그러나 이러한 확인을 할 수있는 응용 프로그램에 따라, 정수 연산은 약간의 오차가 소개 않습니다

interger_HSV = (127, 127, 127) 
Converted_2_RGB = HSV_2_RGB(interger_HSV) 
Verify_HSV_2_RGB = colorsys.hsv_to_rgb(0.5, 0.5, 0.5) 

print Converted_2_RGB 
>>> (63, 127, 124) 

print type(Converted_2_RGB[0]) 
>>> <type 'int'> 

print Verify_HSV_2_RGB # multiplied these by 255 so they are on the same scale 
>>> (63.75, 127.5, 127.5) 

전에 같은 방법으로 결과를 확인할 수 있습니다.

+1

'S = 255 * ((RGB_Max - RGB_Min)/V)'는 파이썬 2에서 대부분의 시간이 잘못되거나 (파이썬 3에서) float 나눗셈을 사용합니다. 파이썬 2에서'/'는 정수 나누기를 수행하지만 255와 0의 채도는 정확하지만 그 사이에는 아무 것도 얻지 못합니다. 가장 바깥 쪽 괄호를 없애고 시도해보십시오. 또한 전달 호환성을 위해 정수 나누기를 원하는 곳에는 항상 '// 연산자'를 사용해야합니다. – Blckknght

+0

그 점을 알려 주셔서 감사합니다. 제안 사항을 포함하도록 답변을 업데이트하고 테스트 사례를 경계면에 맞지 않게 변경했습니다. –

관련 문제