2013-06-27 8 views
6

Capisco che una conversione da RGB a HSV debba assumere valori RGB da 0 a 255 e convertire in valori HSV [0-360, 0-1, 0-1]. Per esempio, vedi questo converter in java:colori matplotlib rgb_to_hsv non funziona correttamente. Forse ha bisogno di segnalarlo?

Quando eseguo matplotlib.colors.rbg_to_hsv su un'immagine, sembra invece di inviare valori [0-1, 0-1, 0-360]. Tuttavia, ho usato questa funzione su un image like this e sembra che funzioni nell'ordine corretto [H, S, V], solo che V è troppo grande.

Esempio:

In [1]: import matplotlib.pyplot as plt 

In [2]: import matplotlib.colors as colors 

In [3]: image = plt.imread("/path/to/rgb/jpg/image") 

In [4]: print image 
[[[126 91 111] 
    [123 85 106] 
    [123 85 106] 
    ..., 

In [5]: print colors.rgb_to_hsv(image) 
[[[ 0 0 126] 
    [ 0 0 123] 
    [ 0 0 123] 
    ..., 

Quelli non sono 0s, sono un numero compreso tra 0 e 1.

Qui è la definizione da matplotlib.colors.rgb_to_hsv

def rgb_to_hsv(arr): 
    """ 
    convert rgb values in a numpy array to hsv values 
    input and output arrays should have shape (M,N,3) 
    """ 
    out = np.zeros(arr.shape, dtype=np.float) 
    arr_max = arr.max(-1) 
    ipos = arr_max > 0 
    delta = arr.ptp(-1) 
    s = np.zeros_like(delta) 
    s[ipos] = delta[ipos]/arr_max[ipos] 
    ipos = delta > 0 
    # red is max 
    idx = (arr[:, :, 0] == arr_max) & ipos 
    out[idx, 0] = (arr[idx, 1] - arr[idx, 2])/delta[idx] 
    # green is max 
    idx = (arr[:, :, 1] == arr_max) & ipos 
    out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0])/delta[idx] 
    # blue is max 
    idx = (arr[:, :, 2] == arr_max) & ipos 
    out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1])/delta[idx] 
    out[:, :, 0] = (out[:, :, 0]/6.0) % 1.0 
    out[:, :, 1] = s 
    out[:, :, 2] = arr_max 
    return out 

I userei una delle altre conversioni rgb_to_hsv come colorsys, ma questo è l'unico pitone vettorializzato che ho trovato. Possiamo capirlo? Dobbiamo segnalarlo su github?

Matplotlib 1.2.0, NumPy 1.6.1, Python 2.7, Mac OS X 10.8

risposta

6

Funziona in modo bello se, invece di unsigned int valori RGB da 0 a 255, si alimentano galleggiare valori RGB da 0 a 1. Sarebbe bello se la documentazione lo specificasse, o se la funzione cercasse di cogliere quello che sembra essere un errore umano molto probabile. Ma è possibile ottenere ciò che si vuole semplicemente chiamando:

print colors.rgb_to_hsv(image/255) 
+0

Grazie Jaime che potrebbe averlo risolto. Sai perché H si presenta come un valore compreso tra 0-1 anziché 0-360? – chimpsarehungry

+1

Normalizzare ogni componente di uno spazio colore su '0-1' è una convenzione ragionevole che si può legittimamente adottare. Poiché matplotlib lo sta facendo con lo spazio cromatico RGB, è coerente per farlo con lo spazio cromatico HSV. –

+0

Si noti che l'immagine deve essere di dtype 'float' in modo che la divisione di 255 funzioni. – facuq

0

Prendersi cura, il commento Fonte stati di ingresso/uscita dovrebbe essere di dimensione M, N, 3, e la funzione non riesce per RGBA (M, N, 4 immagini, ad es file png importati.