Cambio del espacio de color.
La función que usa OpenCV para efectuar cambios en el espacio de color es cvtColor(). Podemos encontrar información exhaustiva aquí.
Sintaxis:
imagen = cv2.cvtColor(src,código)
Parámetros:
imagen --> imagen de salida con las mismas características de profundidad de color que la imagen de entrada.
scr --> Imagen de entrada.
código --> color código de conversión de espacio (ver ColorConversionCodes).
Selección de color.
El acrónimo HSV que define el espacio de color HSV proviene de las siglas en inglés de HUE (matiz o tono), SATURATION (saturación) y VALUE (valor). El modelo HSV fue creado en 1978 y se trata de una transformación no lineal del espacio de color RGB.
Fig. 1
MATIZ
El ángulo de rotación del matiz nos da el color, por ejemplo:
0° = RGB(255, 0, 0) Rojo
120° = RGB(0, 255, 0) Verde
240° = RGB(0, 0, 255) Azul
Valores diferentes de color los obtenemos con el resto de valores.
60º = RGB(255,255,0) Amarillo
SATURACIÓN
Se representa como la distancia al eje de brillo negro-blanco. Los valores posibles van del 0 al 100%. Cuanto menor sea la saturación de un color, mayor tonalidad grisácea habrá y más decolorado estará. Esto lo podemos ver en la figura 1, cuanto más cerca estemos del eje más ligero será el color.
VALOR
Representa la altura en el eje blanco-negro. Los valores posibles van del 0 al 100%. 0 siempre es negro. Dependiendo de la saturación, 100 podría ser blanco o un color más o menos saturado.
¿Como filtramos el color?
Si tenemos una imagen en está en el espacio de color BGR o RGB podemos pasarla al espacio de color HSV y con los límites de matiz que determina un color, entre 0 hasta 255, establecer los límites inferior y superior del mismo y filtrar ese color mediante una máscara. El procedimiento para determinar los límites lo haríamos usando un array de numpy, de la forma:
lower_hue_blue = np.array([30,0,0])
Dentro del corchete [65,0,0] tenemos los valores inferiores con los que queremos trabajar, 30 para el matiz y 0 para los valores inferiores de saturación y valor.
upper_hue_blue = np.array([110, 255,255])
Dentro del corchete [110,255,255] tenemos los valores superiores con los que queremos trabajar, 110 para el matiz y 255 para saturación y valor.
Una vez definidos los límites, tendremos que crear una máscara que filtre el color que se encuentra entre los límites establecidos. Para ello utilizamos la función cv2.inRange().
Sintaxis:
cv2.inRange(src,lowerb,upperb)
Parámetros:
scr --> La imagen en donde se va a visualizar.
lowerb --> Las coordenadas del punto inicial en x e y.
upperb --> Las coordenadas del punto final en x e y.
¿Dónde están los límites de color en un espacio de color HSV?
Este tema genera distintas controversias. Para ilustrar nuestras actividades he encontrado en internet una imagen que nos permitirá establecer un criterio.
En el eje horizontal (el de la X) de la imagen tenemos entre 0 y 180 los valores posibles de H (HUE) matiz o tono, de tal manera que podemos establecer de forma aproximada que el rosa puede estar entre los valores 145 y 165, el color verde entre 45 y 65 y el color azul oscuro entre 110 y 125, todos estos valores son aproximaciones, que son suficientes para nuestro propósito.
a) Descarga la imagen del enlace (shapes.png). Presenta apiladas horizontalmente las conversiones de la imagen shapes.png a:
b) Una imagen denominada HSV con un espacio de color HSV.
C) Una imagen denominada RGB con un espacio de color RGB.
2. Haciendo uso de la imagen shapes.png con el espacio de color HSV:
a) Filtra el color azul (toma como límites (90, 0, 0) y (110, 255,255)) y presenta el resultado en pantalla.
b) Filtra el color rojo (toma como límites (0, 100, 100) y (20,255,255)) y presenta el resultado en pantalla.
c) Filtra el color verde (toma como límites (45, 0, 0) y (65,255,255)) y presenta el resultado en pantalla.
d) Filtra el color rojo (toma como límites (20, 0, 0) y (35,255,255)) y presenta el resultado en pantalla.
e) Representa apiladas con np.stack las cuatro máscaras en el orden siguiente: Rojo, azul, verde, amarillo.
La solución del apartado e la podemos ver en la siguiente imagen.