ros tutorial

02: Fundamentos de las imágenes en OpenCV

fractal

En esta entrada vamos a intentar entender cómo es una imagen para nuestro ordenador, vamos a ver como manipular con la librería OpenCV dichas imágenes. 

¿Cómo es una imagen ?

La primera pregunta que deberíamos hacernos es la siguiente: «Cómo es una imagen??»

Una imagen es  algo muy fácil y elemental de entender para un ser humano. Cuando vemos una foto no nos exige esfuerzo entender los colores o formas de esta, incluso nuestro cerebro le añade una profundidad que no tiene la foto para que entendamos el contenido de la imagen.

 

Pero esto en el «mundo del silicio» es mas complicado. Un ordenador, por defecto, no distingue ni las formas ni los colores de las imágenes, ni mucho menos el contenido de esta.  Para poder realizar estos procesos con un ordenador y la librería OpenCV debemos considerar que una imagen en realidad no es mas que una matriz. Es por eso que para el trabajo de la visión artificial en ordenadores nos ayudamos de la librería Numpy, librería que facilita el trabajo con matrices 

Pensemos por un momento en la foto de el «crack» Fernando Alonso de nuestra entrada anterior, esta foto es una matriz cuyo numero de columnas será el ancho de la foto y cuyo numero de filas será igual a la altura de la foto. Cada «hueco» en esta matriz corresponde a un pixel. Vamos a verlo:

alonso vision artificial

Copiamos el código  para cargar una imagen desde un archivo de la entrada anterior en nuestro editor de código favorito, recuerda que lo tienes en nuestro Github, y añadimos lo siguiente: 

				
					print (image.shape)
				
			

Esto nos va a devolver por pantalla el tamaño de la imagen, es decir el tamaño de una matriz, ya que OpenCV transforma las imágenes en matrices, en este caso nos devuelve :   (554, 980, 3)

Es decir nuestra imagen es una matriz de 554 filas por 980 columnas. El último número luego lo explicamos.

 Las matrices se denotan siempre de la siguiente manera: numero de filas x numero de columnas.  Esto choca con la manera tradicional de entender el tamaño de las imágenes donde normalmente sería 980×554 es decir ancho x alto.

Y que significa el último número?? que significa ese 3?? Pues bien ya hemos explicado cómo OpenCV guarda las imágenes en forma de matriz.  Pero cuales son los valores que guarda en cada hueco de la matriz?

Vamos a ver la imagen de abajo

bgr

En esta imagen vemos una imagen a color representada como una matriz, vemos una matriz azul, una verde y otra roja. Porqué es así?? Pues por que una imagen a color se puede descomponer en tres matrices con sus colores primarios , BGR por defecto en OpenCV, la primera matriz es para indicar el valor  de la componente de color azul en esa imagen, esta matriz representa un canal, la segunda matriz, la verde, que será del mismo tamaño que la azul, indica el valor del componente de color verde que tiene la imagen en cada punto de la matriz, por último la matriz roja, que representa el canal rojo, del mismo tamaño,  indica el valor de la componente de color rojo en cada punto.

 

Por qué entonces la imagen de Fernando Alonso tenía un tres como tercer valor?? Pues porque la función shape que hemos aplicado nos devuelve el tamaño de la matriz , numero de filas x numero de columnas y la dimensión de esta matriz, es decir,  el número de colores. Por eso nos devuelve 3, porque esa imagen tiene componentes B, G y R, luego es un 3, es decir esta imagen tendría esta forma:

bgr

Si tuviéramos esta misma imagen en escala de grises o en blanco y negro (veremos más adelante como hacer estas transformaciones de color), cuando aplicamos el comando «shape» a nuestra imagen esto nos devolvería: (554, 980 ,1). Es decir nuestra imagen es una matriz de 554 x 980 (nº filas x nº de columnas) y de dimensión 1, es decir sólo tiene una dimensión de color ya que es en blanco y negro.

Vamos a introducir en nuestro código, la siguiente sentencia

				
					imagen_reducida = cv2.resize(image, (640, 480))
				
			

Creamos una imagen llamada imagen_reducida aplicando el metodo resize a la imagen que queremos

				
					cv2.imshow('Alonso en Alpine_reducida',imagen_reducida)
    print(imagen_reducida.shape)
				
			

Ahora mostramos por pantalla la imagen reducida y volvemos a aplicar el comando shape pero esta vez sobre nuestra imagen reducida, esta vez el comando nos devolverá (480, 640, 3) , ya que con el comando resize hemos forzado a nuestra imagen a tener ese tamaño, es decir la hemos forzado a ser una matriz de 480 filas por 640 columnas.

Subscríbete a nuestro blog

Creando matrices

En algunas entradas de este tutorial sobre visión artificial vamos a trabajar con matrices, por lo que conviene ver una serie de conceptos básicos para trabajar con estas. 

Lo primero que haremos será importar la  libreria numpy, para ello escribiremos

import numpy as np

Ahora creamos por ejemplo una matriz llamada ceros de 480 filas x 320 columnas, por ejemplo, y la vamos a rellenar de ceros en todas las posiciones, para ello usamos la función zeros() de numpy.  Numpy es un programa para trabajar con matrices, así que primero metemos el numero de filas y luego el de columnas, después la dimensión, en este caso 3 , ya que puede que usemos esta matriz para rellenar con colores, el dtype indica el tipo de elemento que rellana la matriz, en este caso 0, que es un uint8, es decir un integer sin signo.

ceros = np.zeros((480,320,3),dtype=np.uint8)

Ahora mostramos la imagen en pantalla e imprimimos  mediante el comando shape el tamaño de la matriz  

cv2.imshow('ceros', ceros)
print(ceros.shape)

Efectivamente vemos como nos ha creado una imagen negra que en realidad es una matriz de 480 filas por 320 columnas y tiene una dimensión de 3, nos devuelve (480, 320, 3)

Ahora si pensamos un poco en lo visto hasta ahora, porqué hemos rellenado la matriz con ceros y ha salido negra?  En el formato BGR y en otros formatos de color cada valor del pixel puede ir desde valores 0 a valores 255. Cero representa el color negro y 255 el blanco .La combinación de cada valor de cada pixel en cada  canal, da como fruto la imagen en BGR, es decir la imagen original

Ahora vamos a elegir una zona de nuestra matriz ceros y vamos a llenar una región determinada por ejemplo con color blanco, para ello escribimos:

ceros[0:50,0:100] = 255

Estamos indicando que coja la región que va desde la fila 0 hasta la 50 y de la columna 0 a la 100 y le aplique un valor 255, si mostramos esta imagen veremos algo así:

opencv_zeros

Así acabamos esta entrada, hemos aprendido unos pocos conceptos, pero es importante el interiorizarlos y comprenderlos bien, ya que son la base de la visión artificial. Hasta pronto!!

ROS_custom_message

10 ROS Custom Message

ROS Custom Message Fundamentos de ROS Accede a otros posts En tutoriales anteriores a la hora de la comunicación pub/sub, siempre hemos usado mensajes predefinidos

Read More »

This website uses cookies to ensure you get the best experience on our website. By continuing to browse on this website, you accept the use of cookies for the above purposes.