CONTENIDO:
- RGB en OpenCV
- Construyendo una imagen con numpy
- 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:
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:
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:
¡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:
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:
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:
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
.
Hola ¿Con qué instrucción se asignan los colores de fondo en dónde aparecen las letras B=255, G=0 y R=0? y en general todas las letras
Hola Abel, ¿puedes explicarme un poquito más tu pregunta?
¿Me puedes aclarar una duda?
Hola Rosa, dime. 🙂
Hola, una pregunta si te digo convertir una imagen cualquiera a espacio de color RGB y a HSI con opencv como seria ?, en el RGB cual usarias ? y para HSI sabes cual es ?
cv::COLOR_BayerBG2BGR,
cv::COLOR_BayerGB2BGR,
cv::COLOR_BayerRG2BGR,
cv::COLOR_BayerGR2BGR,
cv::COLOR_BayerBG2RGB,
cv::COLOR_BayerGB2RGB,
cv::COLOR_BayerRG2RGB,
cv::COLOR_BayerGR2RGB
Por separado ambas conversiones, por el momento me interesa la imagen resultante
Hola Juan Miguel, en realidad no estoy segura, pero estos links te podrían ayudar: https://stackoverflow.com/questions/43661868/hsi-color-format-in-python-with-opencv-library https://answers.opencv.org/question/62446/conversion-from-rgb-to-hsi/
Para RGB estoy usando esto, pero en android studio
BitmapDrawable drawable =(BitmapDrawable)imgviewtomarfoto.getDrawable();
Bitmap bitmap= drawable.getBitmap();
Mat tmp = new Mat (bitmap.getWidth(), bitmap.getHeight(), CvType.CV_8UC1);
Utils.bitmapToMat(bitmap, tmp);
Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_BGR2RGB ,3 );
Utils.matToBitmap(tmp, bitmap)
Amiga en android studio existe COLOR_BGR2HSV y COLOR_BGR2HSV_FULL; cual es su diferencia y/o cual es mejor usar para el tratamiento de imagenes, la imagen seria para ser comparada con otra que pasara por el mismo tratamiento.
hola, todo bien, hasta que llegué a laparte de convertir BGR a RGB
Traceback (most recent call last):
File «C:/Users/PV-VENTANILLA/AppData/Local/Programs/Python/Python39/bgr_rgb_01.py», line 4, in
C1 = bgr[:,:,0]
TypeError: ‘NoneType’ object is not subscriptable
¿A qué se podría deber?
Saludos
Error mio,
habia guardado el archivo .py en un directorio donde no estaba la imagen.
Otro error de usuario a tenerse en cuenta 🙂
Saludos
Me alegra mucho que hayas podido resolver el error! 😀
Me pasaba el mismo error, pero fue porque ejecutaba el programa en el cmd….estando en una carpeta que no era.
tengo el mismo error
File «d:\programa\python1.1\FUNDAMENTOS DE PROGRAMACION\python1\OPENCV\transformarImagen.py», line 5, in
C1=bgr[:,:,0]
ya comprobé que la imagen estuviera en la misma carpeta
les agradezco su colaboración
hola, es necesario aprender primero otras librerias antes de manejar OpenCV?
Hola muy buenos días, me encanto el tutorial, tengo una pregunta como hago para obtener una imagen a color de tres imágenes de una escena, que representan las intensidades de color rojo, verde y azul?
Como detectar un huevo roto