2010-12-29 98 views
8

Estoy tratando de automatizar la mejora de algunas imágenes que se van a transferir a un marco digital. Tengo un código en su lugar que cambia el tamaño, agrega una fecha/hora al rincón menos significativo (menos detalles) de la imagen y pega pares de imágenes verticales para evitar mostrar un solo retrato en la pantalla de baja resolución 41:20 del marco.Conversión de RGB a HSV usando PIL

Implementé un filtro de estiramiento del brillo para aquellas imágenes donde la iluminación no era tan buena, usando la función colorsys.rgb_to_hsv para calcular las bandas H, S, V, operando en la V y luego convirtiendo nuevamente a RGB guardando un JPEG en el marco digital. Obviamente, la conversión lleva mucho tiempo, incluso usando itertools trucos; Logré mejorar las cosas usando psyco.

Sin embargo, he notado un ejemplo para el PIL Image.convert donde RGB se puede convertir en XYZ color space utilizando una matriz de 4 × 4 como segundo argumento al método convert, y llegué a preguntarse:

¿Cómo puedo convertir RGB a HSV (y luego HSV a RGB) usando una matriz personalizada en la llamada al método convert? (Los errores de redondeo menores no son importantes en este caso, así que no me importa que cada banda se exprese como una serie de 0 ... 255 enteros)

Gracias de antemano.

+0

Nota: es posible que lo que hago también se puede hacer con la función 'ImageOps.autocontrast'; sin embargo, deseo poder expandir el filtro según sea necesario (por ejemplo, quizás darle un poco más de saturación a la saturación), y es por eso que quiero un método rápido para RGB↔HSV). – tzot

Respuesta

1

Aunque he visto referencias [1] que afirman que el espacio de color HSV es una transformación lineal de RGB, lo que parece implicar que podría hacerse con una matriz, no he podido encontrarlo o determinarlo solo cómo sería una matriz así. En cierto modo, esto no me sorprende realmente en base a todas las implementaciones de procedimientos no similares a la matriz que también he visto: la forma en que lo hacen no se ve como lineal.

De todos modos, mientras se mira en esto, me encontré con un artículo [algo anticuado] en línea portátil gráficos por ordenador antiguo investigador Paul Haeberli SGI titulado Matrix Operations for Image Processing que describe cómo hacer un número de diferentes transformaciones de color usando matrices 4x4 que podría ayudar tú. Todos los ejemplos proporcionados operan directamente en las imágenes de color RGB y, al igual que las transformaciones de matriz geométrica, cualquier secuencia de ellas se puede combinar en una sola matriz mediante concatenación.

Espero que esto ayude.


[1]: conversiones de espacio de color < http://www.poynton.com/PDFs/coloureq.pdf>:

2.7.3 HSL (Hue Saturación y Luminosidad)

Esto representa una gran cantidad de espacios similares colores, nombres alternativos incluyen HSI (intensidad), HSV (valor), HCI (croma/color), HVC, TSD (saturación y oscuridad del matiz) etc. La mayoría de estos espacios de color son se transforman linealmente desde RGB y son por lo tanto dependientes del dispositivo y no lineales. Su ventaja radica en la manera extremadamente intuitiva de que especifica el color. Es muy fácil seleccionar el matiz deseado y luego modificarlo ligeramente ajustando su saturación e intensidad.

+0

Gracias, lo estoy investigando. Al igual que usted, el código que he visto hasta ahora no me hace optimista sobre una respuesta positiva a mi pregunta ... – tzot

+0

Algo que se acercó (pero no un cigarro): [Convirtiendo entre RGB y ...] (http: //local.wasp .uwa.edu.au/~ pbourke/texture_colour/convert /) de Paul Bourke. Desafortunadamente, la conversión de ida y vuelta de YIQ/YUV sesga mucho la información de color; quizás esto se deba a los pocos lugares decimales de los números en las matrices. En cualquier caso, no son útiles tal como están. – tzot

+0

Las transformaciones son de hecho lineales, pero son por partes, por lo que creo que es imposible transformarlas con una sola matriz (y no estoy seguro de que sería muy útil o posible usar "matrices por partes"). – heltonbiker

0

La fórmula para transformar un valor RGB a un valor HSV se puede encontrar aquí: http://www.rapidtables.com/convert/color/rgb-to-hsv.htm. Una vez lo necesité al revés, e hice la siguiente función para ello.

def hsb2rgb(hsb): 
    ''' 
    Transforms a hsb array to the corresponding rgb tuple 
    In: hsb = array of three ints (h between 0 and 360, s and v between 0 and 100) 
    Out: rgb = array of three ints (between 0 and 255) 
    ''' 
    H = float(hsb[0]/360.0) 
    S = float(hsb[1]/100.0) 
    B = float(hsb[2]/100.0) 

    if (S == 0): 
     R = int(round(B * 255)) 
     G = int(round(B * 255)) 
     B = int(round(B * 255)) 
    else: 
     var_h = H * 6 
     if (var_h == 6): 
      var_h = 0 # H must be < 1 
     var_i = int(var_h) 
     var_1 = B * (1 - S) 
     var_2 = B * (1 - S * (var_h - var_i)) 
     var_3 = B * (1 - S * (1 - (var_h - var_i))) 

     if  (var_i == 0): 
      var_r = B  ; var_g = var_3 ; var_b = var_1 
     elif (var_i == 1): 
      var_r = var_2 ; var_g = B  ; var_b = var_1 
     elif (var_i == 2): 
      var_r = var_1 ; var_g = B  ; var_b = var_3 
     elif (var_i == 3): 
      var_r = var_1 ; var_g = var_2 ; var_b = B 
     elif (var_i == 4): 
      var_r = var_3 ; var_g = var_1 ; var_b = B 
     else: 
      var_r = B  ; var_g = var_1 ; var_b = var_2 

     R = int(round(var_r * 255)) 
     G = int(round(var_g * 255)) 
     B = int(round(var_b * 255)) 

    return [R, G, B] 
+0

Ya uso el módulo 'colorsys'. La pregunta sobre una matriz que se puede usar con la función 'convert'. – tzot

Cuestiones relacionadas