11 de enero de 2011

Comparación entre Matlab y OpenCV en Python

Hoy me encontré con un taller de instrucciones básicas para el procesamiento digital de imágenes en Matlab y me surgió una curiosidad: ¿Sera que puedo realizar tan fácilmente como en Matlab procesamiento digital de imágenes en python?.
Personalmente creo que una de las ventajas de usar matlab para el procesamiento digital de imagenes es su sencillez de sintaxis, esto es si la comparamos con C.
El propósito de esta entrada es ver las similitudes y diferencias entre la sintaxis de Matlab y su ToolBox de procesamiento digital de imagenes y Python con la libreria de OpenCV.

El enlace al curso es el siguiente:
http://www.wiphala.net/courses/imagen/KAS_IMG/2009-I/homework/hw00_image_processing_with_matlab.doc


Vamos a comenzar:


a) Lectura de imagen
Matlab:
I = imread('your_image.tif');

Python:
I = cv.LoadImage("your_image.tif")

Estas dos instrucciones son bastante similares. Debo anotar un par de cosas: En python se puede usar comillas dobles o comillas sencillas por lo que la ruta de la imagen también se hubiera podido escribir como la de matlab. Por otro lado, no es necesario colocar el punto y coma al finalizar una linea; En matlab tampoco es necesario pero si no ponemos el punto y coma nos mostrara la matriz equivalente de la imagen.

b) Grabación

Matlab:
imwrite(I,filename)


Python:
cv.SaveImage(filename,I)


En esta instrucción existe una diferencia solamente en el orden en que se le pasan los argumentos. En matlab se pasa primero la imagen a grabar y después el nombre del archivo con su correspondiente extensión mientras que en python se pasa el nombre del archivo y después la imagen a grabar. Para esta instrucción de matlab no es necesario ponerle punto y coma ya que no se va a mostrar nada, solo a guardar una imagen en disco.


c) Presentación

Matlab:
imshow(I)


Python 
cv.ShowImage('ventana',I)


Aqui ya podemos ver una diferencia mayor. En python es necesario escribir el nombre de la ventana en la que se ve a mostrar la imagen mientras que en matlab se le da un nombre por defecto a la ventana sino se especifica. Aqui existe una diferencia entre C y python y es que en python no es necesario crear la ventana en la que se va a mostrar la imagen, solo con decirle como se va a llamar la ventana python la creara por si solo.


d) Presentar varias imagenes en diferentes ventanas 

Matlab:
figure, imshow(I1)
figure, imshow(I2)

Python:
cv.ShowImage('ventana1',I1)
cv.ShowImage('ventana2',I2)

Esta no es necesario explicarla es bastante evidente.

e) Presentar varias imagenes en una misma ventana  

Matlab:
subplot(2,2,1), imshow(I1);
subplot(2,2,2), imhist(I2);
subplot(2,2,3), imshow(I3);
subplot(2,2,4), imhist(I4);

Python:
Para esta instruccion matlab se lleva el premio ya que en opencv no existe una función que permita colocar varias imagenes en una sola ventana. Sin embargo no es imposible hacerlo pero es significativamente mas complicado. En la entrada numero 8 Ejercicio 4.1.b ( http://rafapoveda89.blogspot.com/2011/01/8-ejercicios-capitulo-4.html ) muestro como poner varias imagenes en una sola ventana. El procedimiento es crear una imagen vacia que tenga por tamaño el de todas las imagenes que se van a poner en ella. Osea, si vamos a poner 4 imagenes de 100x100 la imagen que crearemos sera de 200x200 si ponemos las imagenes de tal forma que queden dos arriba y dos abajo. Para mas detalles mirar en la entrada 8.


f) Obtener tamaño


Matlab:
[Rows, Cols, RGB] = size( imagen )

  
Python:
alto, ancho = cv.GetSize('Imagen')

g) Tipo de dato
 
Matlab:
C = class (I)

Python:
C = Type (I)

h) Extraer colores de una imagen RGB
Matlab:
R = I(:,:,1)
G = I(:,:,2)
B = I(:,:,3)

Python:
R=cv.CreateImage(cv.GetSize(I),cv.IPL_DEPTH_8U,1)
G=cv.CreateImage(cv.GetSize(I),cv.IPL_DEPTH_8U,1)
B=cv.CreateImage(cv.GetSize(I),cv.IPL_DEPTH_8U,1)
cv.Split(I,R,G,B) 


En matlab nos crea directamente las imagenes en las cuales vamos a dividir la imagen original. En python debemos crearlas especificando el tamaño, la profundidad ( en este caso, imagenes de 8 bits sin signo) y los canales osea 1.

y despues dividir la imagen I con la función split.


i) Conversion de tipos

Matlab:
E = uint8(I)

E = uint16(I)


Python:
I = cv.LoadImage("imagen.jpg")
I2 = cv.CreateImage(cv.GetSize(I), cv.IPL_DEPTH_32F, 3)
cv.ConvertScale(I,I2)

La función convertScale, basicamente convierte una imagen de un tipo en otro. La verdad la sintaxis es bastante clara. Donde se pone la profundidad de I2 se puede cambiar:
 
IPL_DEPTH_8U     - Entero de 8 Bits sin signo
IPL_DEPTH_8S     - Entero de 8 Bits con signo
IPL_DEPTH_16S   - Entero de 16 Bits con signo
IPL_DEPTH_32S   - Entero de 32 Bits con signo
IPL_DEPTH_32F   - 32-bit Floating-point single-precision (32f)
IPL_DEPTH_64F   - 64-bit Floating-point double-precision (64f)
(no supe como traducir esos dos ultimos, nunca los he usado).



2 comentarios:

  1. ¡Hola, gracias por la entrada!

    Muy buena comparación, pero cuando entro a http://rafapoveda89.blogspot.com/2011/01/8-ejercicios-capitulo-4.html me dice que no existe.

    ResponderEliminar
  2. Gracias por tu comentario. Lo que pasa es que ese link corresponde al dominio anterior del blog. El Nuevo link seria http://sherlockcode.blogspot.com/2011/01/8-ejercicios-capitulo-4.html

    Saludos

    ResponderEliminar