RGB en OpenCV – Python

Por Administrador

 

CONTENIDO:

  1. RGB en OpenCV
  2. Construyendo una imagen con numpy
  3. Imagen de BGR a RGB

Te doy la bienvenida a un nuevo post, recuerda ver el video y complementarlo con la información que se encuentra a continuación.

RGB en OpenCV

Una imagen es un conjunto de pixeles distribuidos en forma de cuadrícula. Cada pixel a su vez está conformado por otros componentes, que combinados forman los colores que podemos ver en una imagen. Hoy hablaremos de aquellos componentes que estructuran un color, principalmente RGB, y como se utiliza en OpenCV.

RGB (Red Green Blue / Rojo Verde Azul), es uno de los espacios de color más utilizado en cuanto a imágenes se trata y el que usa por defecto OpenCV al momento de leer una imagen o dibujar figuras geométricas, por ello es de vital importancia conocer como se maneja este espacio de color en esta librería, es más el tener esta información a la mano te quitará algunos dolores de cabeza si estás empezando a realizar aplicaciones de visión por computador.

Atención: El orden en el que OpenCV usa estos componentes es en BGR, no RGB. Sí, a pesar de no parecer muy importante, en realidad te puede ayudar a entender desde ya como asignar distintos colores en este formato. La siguiente es una lista de colores y como están compuestos:

Figura 1: Algunos colores en BGR.

Hay que tomar en cuenta que RGB, posee 3 componentes y cada uno toma valores de entre 0 y 255. Analizando la figura 1 por ejemplo, para representar el color negro, cada uno de los canales tiene valor de 0, mientras que para representar el color blanco todos poseen 255.

Si se quiere representar los colores básicos en rgb, es decir, rojo verde y azul, basta con elevar a 255 el canal al que corresponde y el resto 0, como se puede ver en la figura 1. Por otro lado para obtener otros colores se necesita distintos valores en los canales, como podemos ver en la segunda columna de la imagen, donde se ha representado por ejemplo el color aqua, fucsia, amarillo, marrón y naranja.

Teniendo en claro como se estructuran los colores en rgb y cómo los usa OpenCV podemos continuar construyendo una imagen con la librería Numpy.

CONSTRUYENDO UNA IMAGEN CON NUMPY

Numpy es una librería matemática que trabaja conjuntamente con OpenCV para realizar múltiples procesos, pues trata a la imagen como una matriz de diversos canales. Por esta razón nos ayudaremos de esta librería para construir una imagen de distintos colores, a continuación la programación:

import cv2
import numpy as np

bgr = np.zeros((300, 300, 3), dtype=np.uint8)
cv2.imshow('BGR', bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

Analicemos las líneas de este programa:

Línea 1 y 2: Importar las librerías necesarias OpenCV y numpy con el alias np.

Línea 4: Aquí es donde se está construyendo la imagen, con np.zeros, es decir estamos creando una matriz de ceros, de 300 filas, 300 columnas de 3 canales, correspondientes a BGR. Se especifica el tipo de dato con np.uint8, esto quiere decir que se tomará valores de entre 0 y 255.

Línea 5 a 7: Se realiza la visualización de la imagen, lo que mostraría:

Figura 2: Visualización de una imagen creada con numpy

Se puede modificar el color de la imagen creada añadiendo una línea en donde especifique las filas, columnas en donde se debe representar el nuevo color.

import cv2
import numpy as np

bgr = np.zeros((300, 300, 3), dtype=np.uint8)
bgr[:,:,:] = (255, 0, 100)
cv2.imshow('BGR', bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

Línea 5: Se toma todos los elementos de la matriz creada y se asignan nuevos valores para representar un nuevo color, en BGR.

Se visualizaría de la siguiente manera:

Figura 3: Visualización de la imagen modificando los valores en BGR

¡A practicar, modificando una imagen creada con numpy!

Si quieres practicar un poco más con la representación de distintos colores sobre una imagen creada con numpy te dejo el siguiente programa que puedes analizar:

import cv2
import numpy as np

bgr = np.zeros((500,800,3),dtype=np.uint8)
font = cv2.FONT_HERSHEY_SIMPLEX
#AZUL-------------------------------------------------------------
bgr[:100, :200] = (255,0,0)
bgr[:100, 200:400] = (255)
bgr[:100, 400:600] = (0)
bgr[:100, 600:800] = (0)

cv2.putText(bgr,'Azul (255,0,0) -->',(5,55), font, 0.5,(255,255,255),1,cv2.LINE_AA)
cv2.putText(bgr,'B= 255',(220,55), font, 1,(255,0,0),2,cv2.LINE_AA)
cv2.putText(bgr,'G= 0',(440,55), font, 1,(255,0,0),2,cv2.LINE_AA)
cv2.putText(bgr,'R= 0',(640,55), font, 1,(255,0,0),2,cv2.LINE_AA)

#VERDE------------------------------------------------------------
bgr[100:200, :200] = (0,255,0)
bgr[100:200, 200:400] = (0)
bgr[100:200, 400:600] = (255)
bgr[100:200, 600:800] = (0)

cv2.putText(bgr,'Verde (0,255,0) -->',(5,145), font, 0.5,(255,255,255),1,cv2.LINE_AA)
cv2.putText(bgr,'B= 0',(240,155), font, 1,(0,255,0),2,cv2.LINE_AA)
cv2.putText(bgr,'G= 255',(420,155), font, 1,(0,255,0),2,cv2.LINE_AA)
cv2.putText(bgr,'R= 0',(640,155), font, 1,(0,255,0),2,cv2.LINE_AA)

#ROJO------------------------------------------------------------
bgr[200:300, :200] = (0,0,255)
bgr[200:300, 200:400] = (0)
bgr[200:300, 400:600] = (0)
bgr[200:300, 600:800] = (255)

cv2.putText(bgr,'Rojo (0,0,255) -->',(5,245), font, 0.5,(255,255,255),1,cv2.LINE_AA)
cv2.putText(bgr,'B= 0',(240,255), font, 1,(0,0,255),2,cv2.LINE_AA)
cv2.putText(bgr,'G= 0',(440,255), font, 1,(0,0,255),2,cv2.LINE_AA)
cv2.putText(bgr,'R= 255',(620,255), font, 1,(0,0,255),2,cv2.LINE_AA)

#Naranja
bgr[300:400, :200] = (20,117,240)
bgr[300:400, 200:400] = (20)
bgr[300:400, 400:600] = (117)
bgr[300:400, 600:800] = (240)

cv2.putText(bgr,'Naranja(20,117,240)->',(5,345), font, 0.5,(255,255,255),1,cv2.LINE_AA)
cv2.putText(bgr,'B= 20',(230,355), font, 1,(20,117,240),2,cv2.LINE_AA)
cv2.putText(bgr,'G= 117',(420,355), font, 1,(20,117,240),2,cv2.LINE_AA)
cv2.putText(bgr,'R= 240',(620,355), font, 1,(20,117,240),2,cv2.LINE_AA)

bgr[400:500, :200] = (109,45,215)
bgr[400:500, 200:400] = (109)
bgr[400:500, 400:600] = (45)
bgr[400:500, 600:800] = (215)

cv2.putText(bgr,'Rosa (109,45,215)-->',(5,445), font, 0.5,(255,255,255),1,cv2.LINE_AA)
cv2.putText(bgr,'B= 109',(220,455), font, 1,(109,45,215),2,cv2.LINE_AA)
cv2.putText(bgr,'G= 45',(430,455), font, 1,(109,45,215),2,cv2.LINE_AA)
cv2.putText(bgr,'R= 215',(620,455), font, 1,(109,45,215),2,cv2.LINE_AA)

cv2.imshow('B= Blue, G= Green, R= Red',bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

Nota: Si se iguala cierta cantidad de pixeles a un solo valor, como gran parte del código (líneas 8 a 10, 19 a 21, 30 a 32, 41 a 43, 51 a 53), se asigna dicho valor a los 3 canales de B, G y R.

Teniendo como resultado la siguiente imagen:

Figura 4: Practicando con asignación de colores a una imagen creada con numpy

La primera columna de la figura 4, muestra distintos colores, mientras que a su derecha se muestran los valores de cada componente en BGR, para obtener dichos colores. Por ejemplo, para poder obtener el color azul, se necesita que B esté en 255, mientras que G y R en 0.

IMAGEN DE BGR A RGB

Pueden haber casos en los que necesites cambiar el orden de los canales de bgr a rgb. Para este ejemplo se usará la siguiente imagen:

Figura 5: Imagen a usar para pasar de BGR a RGB

Para transformar de bgr a rgb necesitamos de la función cv2.cvtColor, a la cual debemos entregar la imagen a la que queremos procesar, seguido de cv2.COLOR_BGR2RGB.

import cv2
import numpy as np

bgr = cv2.imread('prueba.png')
C1 = bgr[:,:,0]
C2 = bgr[:,:,1]
C3 = bgr[:,:,2]
cv2.imshow('BGR',np.hstack([C1,C2,C3]))

rgb = cv2.cvtColor(bgr,cv2.COLOR_BGR2RGB)
C1 = rgb[:,:,0]
C2 = rgb[:,:,1]
C3 = rgb[:,:,2]
cv2.imshow('RGB',np.hstack([C1,C2,C3]))
cv2.waitKey(0)
cv2.destroyAllWindows()

Línea 4: Se lee la imagen, como no se ha especificado una forma de lectura, por defecto está leyendo la imagen en bgr.

Línea 5 a 7: Se separa cada uno de los canales correspondientes a b: bgr[:,:,0], g: bgr[:,:,1] y r: bgr[:,:,2]. Para posteriormente visualizar el cambio de orden.

Línea 8: Se visualiza cada uno de los canales uno al lado del otro usando la función np.hstack.

Línea 10: Se transforma de bgr a rgb.

Línea 11 a 14: Se realiza un proceso similar al de las líneas 5 a 8, para la imagen en rgb.

Ahora vamos a visualizar las dos imágenes obtenidas:

Figura 6: Canal B, Canal G, Canal R, de la imagen leída.

Figura 7: Canal R, Canal G, Canal B obtenidos luego de aplicar la función cv2.cvtColor.

Tomando como base la figura 5, si la descomponemos en sus 3 canales se obtienen resultados como se visualiza en la figura 6, allí podemos ver el orden de los canales BGR. Mientras que si aplicáramos la función cv2.cvtColor, y luego especificamos cv2.COLOR_BGR2RGB, se está cambiando el orden de estos canales y se obtendría una imagen en RGB.

En ambas figuras (6 y 7), podemos ver cada componente en escala de grises, esto es debido a que por separado se visualiza de esa manera, mientras que cuando se integran los 3 componentes se visualiza una imagen a color. Aquí lo que se quería lograr, es visualizar como se cambian de orden los canales al aplicar cv2.cvtColor.

RESUMEN DEL CONTENIDO DE ESTE POST