Esta solución se basa en el código de Pablo. Arreglé DivByZero Bug e implementé RGB a HSL. También hay HSL a RGB:
import numpy
def rgb_to_hsl_hsv(a, isHSV=True):
"""
Converts RGB image data to HSV or HSL.
:param a: 3D array. Retval of numpy.asarray(Image.open(...), int)
:param isHSV: True = HSV, False = HSL
:return: H,S,L or H,S,V array
"""
R, G, B = a.T
m = numpy.min(a, 2).T
M = numpy.max(a, 2).T
C = M - m #chroma
Cmsk = C != 0
# Hue
H = numpy.zeros(R.shape, int)
mask = (M == R) & Cmsk
H[mask] = numpy.mod(60 * (G[mask] - B[mask])/C[mask], 360)
mask = (M == G) & Cmsk
H[mask] = (60 * (B[mask] - R[mask])/C[mask] + 120)
mask = (M == B) & Cmsk
H[mask] = (60 * (R[mask] - G[mask])/C[mask] + 240)
H *= 255
H /= 360 # if you prefer, leave as 0-360, but don't convert to uint8
# Saturation
S = numpy.zeros(R.shape, int)
if isHSV:
# This code is for HSV:
# Value
V = M
# Saturation
S[Cmsk] = ((255 * C[Cmsk])/V[Cmsk])
# H, S, and V are now defined as integers 0-255
return H.swapaxes(0, 1), S.swapaxes(0, 1), V.swapaxes(0, 1)
else:
# This code is for HSL:
# Value
L = 0.5 * (M + m)
# Saturation
S[Cmsk] = ((C[Cmsk])/(1 - numpy.absolute(2 * L[Cmsk]/255.0 - 1)))
# H, S, and L are now defined as integers 0-255
return H.swapaxes(0, 1), S.swapaxes(0, 1), L.swapaxes(0, 1)
def rgb_to_hsv(a):
return rgb_to_hsl_hsv(a, True)
def rgb_to_hsl(a):
return rgb_to_hsl_hsv(a, False)
def hsl_to_rgb(H, S, L):
"""
Converts HSL color array to RGB array
H = [0..360]
S = [0..1]
l = [0..1]
http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL
Returns R,G,B in [0..255]
"""
C = (1 - numpy.absolute(2 * L - 1)) * S
Hp = H/60.0
X = C * (1 - numpy.absolute(numpy.mod(Hp, 2) - 1))
# initilize with zero
R = numpy.zeros(H.shape, float)
G = numpy.zeros(H.shape, float)
B = numpy.zeros(H.shape, float)
# handle each case:
mask = (Hp >= 0) == (Hp < 1)
R[mask] = C[mask]
G[mask] = X[mask]
mask = (Hp >= 1) == (Hp < 2)
R[mask] = X[mask]
G[mask] = C[mask]
mask = (Hp >= 2) == (Hp < 3)
G[mask] = C[mask]
B[mask] = X[mask]
mask = (Hp >= 3) == (Hp < 4)
G[mask] = X[mask]
B[mask] = C[mask]
mask = (Hp >= 4) == (Hp < 5)
R[mask] = X[mask]
B[mask] = C[mask]
mask = (Hp >= 5) == (Hp < 6)
R[mask] = C[mask]
B[mask] = X[mask]
m = L - 0.5*C
R += m
G += m
B += m
R *=255.0
G *=255.0
B *=255.0
return R.astype(int),G.astype(int),B.astype(int)
def combineRGB(r,g,b):
"""
Combines separated R G B arrays into one array = image.
scipy.misc.imsave("rgb.png", combineRGB(R,G,B))
"""
rgb = numpy.zeros((r.shape[0],r.shape[1],3), 'uint8')
rgb[..., 0] = r
rgb[..., 1] = g
rgb[..., 2] = b
return rgb
¿Es necesario convertir la imagen a HSV? Puede considerar realizar la transformación en el rango de requisitos para encontrar una ventana de requisitos de RGB adecuada (la transformación no es lineal, por lo que se pregunta si una aproximación es correcta) – Paul
¿Utiliza NumPy? Por lo general, evito la mayoría de las funciones de PIL para las operaciones de matriz numpy cuando las cosas no son ajustes de imagen "estándar". – Paul
podría usar numpy, aunque no estoy familiarizado con él. y sí, la transformación debe ser hsv, pero si no fuera así, ¿cómo lo haría con rgb? – Claudiu