Está en la página 1de 12

Imagenes en Matlab

Cristian S. Rocha, Andrea Manna, . . .


Taller 1

1.

Prefacio

Antes de empezar a trabajar con el Octavehay que asegurarse que la version


en la que se trabaja no tiene ning
un bug perdido.
Sabemos que en la versi
on 3.2.4 del octave no se puede mostrar imagenes.
La raz
on se puede leer en el wiki:
http://wiki.octave.org/wiki.pl?OctaveForWindows
y se resuelve ejecutando el siguiente comando de la linea de comandos:
pkg rebuild -noauto oct2mat
que deshabilita el m
odulo oct2mat cada vez que se inicia el Octave. Aparentemente este m
odulo es el que provoca el problema. Una vez deshabilitado se
reinicia el Octavey el comando imshow vuelve a funcionar.

2.
2.1.

Primera Parte
Introducci
on

Para trabajar computacionalmente con una imagen hay que interpretarla


como una funci
on matem
atica. Algunas caractersticas de una imagen guardada de una computadora es que tiene una cantidad finitas de puntos, es una
interpretaci
on de una imagen original que debera formarse por una cantidad
infinita (o mucha mas grande) de puntos. Cada punto de la imagen esta indexado a traves de valores naturales x, y que referencian a las coordenadas x e y
del plano. A su vez cada punto puede contener mas de un canal asociado a una
frecuencia o energa que son capaces de reflejar.
Im
agenes
Definition 1 (Im
agen). Una Imagen normalizada es una funcion
I : N2+1 [0, 1]
Cada tupla de naturales x, y : N2 se la conoce como pixel. Y cada valor I(x, y, c)
es la intensidad asociada al pixel (x, y) del canal c.
1

Existen varias formas de representar la luz reflejada por los puntos, pero la
m
as com
un es descomponiendola en colores primarios rojo, verde y azul. La
descomposici
on se asocia a canales (c) cuyos valores se encuentran en general
entre 0 y 1, indicando el 0 la falta total de ese canal y 1 la intensidad maxima
de ese canal. Por ejemplo en la representacion RGB tener todos los canales en 1
representan el color blanco, y tener todos los canales en 0 representan el negro.
Esto puede variar seg
un la descomposicion elegida.
Los canales m
as conocidos son Rojo, Verde y Azul (RGB), aunque existen
otras combinaciones (ACM), (CMYK), (HSV), (YUV), . . .
Una imagen con un u
nico canal se lo conoce como imagen de escala de grises.
La idea de Imagenes normalizadas surge porque existen muchas formas de
almacenar esas im
agenes en la computadora. Es com
un encontrar que los valores
sean entre 0 y 255 ya que se almacenan en la computadora con 8 bits o un byte.
Y en general 256 valores son suficientes. Otro es el caso que la imagen provenga
de satelites, o se quiera representar imagenes con mayor cantidad de colores.
Pero ese es un tema del cual no vamos a hablar.
Canales

Imagen RGB sin descomponer

Canal Rojo

2.2.

Canal Verde

Canal Azul

Procesamiento b
asico de im
agenes

La forma m
as tradicional para trabajar con Imagenes es interpretando que
son matrices de 2 + 1 dimensiones.
En Octavelas operaciones de lectura y escritura de imagenes son imread y
imwrite. Para imread el nombre del archivo es suficiente para devolver una matriz de la cantidad de pixels y canales que almacena el archivo. Para almacenar
una matriz como una imagen hay que indicar en que formato se debe almacenar. Para ver la imagen se usa el comando imshow cuyo parametro de entrada
es la matriz a mostrar como una imagen. Utilicen estos comandos y averig
uen
2

la resoluci
on (Cantidad de pixels en los ejes X e Y) que tiene la imagen usando
el comando size
Empezando a trabajar con im
agenes en Octave y Matlab
> A = imread(lena std.tif);
> imwrite(A, lena std.tif, tif);
> imshow(A);
Proponer que generen las imagenes en escala de grises a partir de los canales
Rojos, Verdes y Azul de la imagen. Se pueden obtener pidiendo la submatriz
A(:, :, 1), A(:, :, 2), A(:, :, 3) respectivamente. Aqu puede verse como la imagen
tiene una resoluci
on de 512x512 pixels y tres canales correspondientes a los
canales del RGB. Mostramos el canal rojo en escalas de grises con el comando
imshow. El comando imshow siempre toman al canal rojo, verde y azul como
esas submatrices. Tambien puede usarse la funcion imfinfo para conocer la informaci
on de la imagen.
Empezando a trabajar con im
agenes en Octave y Matlab
> A = imread(lena std.tif);
> size(A)
ans =
512

512

> imshow(A(:,:,1))
> imfinfo(lena std.tif)
...
Para confirmar que la imagen no esta normalizada obtener el maximo y
mnimo valor de la matriz usando las funciones max y min. Notar que hay que
repetir las funciones porque se aplican sucesivamente en cada dimension de la
matriz. En este caso las im
agenes no estan normalizadas.
Empezando a trabajar con im
agenes en Octave y Matlab
> A = imread(lena std.tif);
> max(max(max(A)))
ans = 255
3

> min(min(min(A)))
ans = 3
Para normalizar la imagen se puede realizar la siguiente operacion. La funci
on double convierte la matriz de n
umeros enteros a n
umeros reales y 255
normaliza los valores.
Empezando a trabajar con im
agenes en Octave y Matlab
> A = imread(lena std.tif);
> N = double(A) / 255;
> imshow(N)

2.3.

Ejercicios

A partir de aqu se proponen los siguientes ejercicios.


Ejercicio
Represente la imagen de Lena apagando los diferentes canales. Esto pude
hacerse asignando 0 a cada canal.
Deje encendido solo el canal Rojo.
Deje encendido solo el canal Verde.
Deje encendido solo el canal Azul.
Deje encendido solo los canales Rojo y Verde.
Deje encendido solo los canales Verde y Azul.
Deje encendido solo los canales Rojo y Azul.
Para ello recomiendo copiar la imagen a una matriz temporal e ir apagando
los canales de a poco. A continuacion solo apagamos el canal Rojo.
Soluci
on
> A = imread(lena std.tif);
> T = A
> T(:,:,2) = 0

> T(:,:,3) = 0
> imshow(T)
El siguiente ejercicio ayuda a reconstruir una imagen a partir de canales
calculados en forma independiente. Se introduce la funcion ndgrid que permite
generar matrices a partir del ndice.
Ejercicio
Se pide reconstruir una imagen a partir de canales generados a partir de las
siguientes funciones.
r(x, y) = sin(x) + sin(y)
g(x, y) = sin(x + ,25) + sin(y + ,25)
b(x, y) = sin(x + ,5) + sin(y + ,5)
Soluci
on
> X = ndgrid(0:0.1:2*pi,0:0.1:2*pi);
> Y = X;
> R = 0.5+sin(X)+sin(Y);
> G = 0.5+sin(X+0.25*pi)+sin(Y+0.25*pi);
> B = 0.5+sin(X+0.5*pi)+sin(Y+0.5*pi);
> I = zeros(size(R,1), size(R,2), 3);
> I(:,:,1)=R;
> I(:,:,2)=G;
> I(:,:,2)=B;
> imshow(I)
El siguiente ejercicio introduce el uso de la funcion hist para conocer la
distribuci
on de la intensidad de los diferentes canales. Esto nos permite realizar
otras operaciones a futuro.

Ejercicio
Represente el histograma por cada canal.
Rojo.
Verde.
Azul.
Supongo que saben realizar estas operaciones. Las vieron en una clase anterior.
Ahora la idea es jugar con partes de imagenes.
Ejercicio
Se pide intercambiar el cuarto superior izquierdo de la imagen con el cuarto
inferior derecho.

Resultado
> L = imread(lena std.tif);
> Qsi = L(1:256,1:256,:);
> Qid = L(257:512,257:512,:);
> L(257:512,257:512,:)=Qsi;
> L(1:256,1:256,:)=Qid;
> imshow(L)

3.
3.1.

Segunda Parte
Operaciones de matrices y resultados en im
agenes

Antes de cualquier cosa debemos poder crear imagenes vacas para poder
almacenar resultados en ellas. Ahora hay que hablar de como crear matrices que
sean compatibles con las imagenes, porque sino no se va a poder almacenarlas
ni verlas.
Creaci
on de im
agenes vacias
Las im
agenes se crean como cualquier matriz, pero hay que indicar que el
tipo de dato a usar es de tipo byte.
> zeros( [10,10,3], uint8)
Algunas operaciones sobre matrices tienen efectos interesantes en las imagenes.
Ahora enumeraremos algunas de estas operaciones.
Operaciones
Siendo M la matriz de la imagen, I la matriz identidad y E es la matriz
identidad espejada.
Espejado diagonal D = M t .
Espejado horizontal H = M E
Espejado vertical V = E M
El problema principal de trabajar con estas operaciones es conseguir la matriz identidad del tama
no adecuada y asegurarse que la imagen es cuadrada. Recuerden que la multiplicaci
on de matrices require equivalencia entre el tama
no
de las matrices. Se pueden multiplicar una imagen M de n m por una matriz
I de m p, y el resultado sera una matriz de n p. Es por eso que recomiendo
usar matrices cuadradas. Para eso es necesario generar una matriz mas grande
donde almacenar la imagen si es que esta no es cuadrada.
A continuaci
on muestro como encuadrar la imagen. Cargo primero una imagen que no es cuadrada y la copio a una imagen pre-creada cuadrada del tama
no
adecuado.
Encuadrar una Imagen
> S = imread(san diego.tif);
> c = size(S,3);
> n = max(size(S)(1:2));
> D = zeros([n,n,3],uint8);
7

> D(1:size(S,1),1:size(S,2),:) = S;
En el caso que no se quiera utilizar operaciones con matrices porque tardan
mucho tiempo en resolverse o porque una matriz no puede resolver el problema, se puede calcular con una doble iteracion sobre el las filas y las columnas
respectivamente.
Aqu por ejemplo mostramos como calcular cual es el valor promedio que
hay en los pixels de la imagen en el canal 1.
Modificar una imagen
> I = imread(san diego.tif);
> s =0;
> for i in 1:size(I,1)
> for j in 1:size(I,2)
> s = s + double(I(i,j,1));
> end
> end
> s/(size(I,1)*size(I,2))

3.2.

Ejercicios

Ahora vamos a resolver algunos ejercicios de traslacion y rotacion.


Primero vamos a encuadrar la imagen y centrar.
Ejercicio
Encuadrar y centrar la imagen san diego.tif en una nueva matriz.
Soluci
on
> I = imread(san diego.tif);
> n = max(size(I)(1:2));
> D = zeros([n, n, size(I,3)], uint8);
> top = (n - size(I,1)) / 2 + 1;

> left = (n - size(I,2)) / 2 + 1;


> D(top:top+size(I,1)-1, left:left+size(I,2)-1, :) = I;
> imshow(D);
Ahora vamos a rotar las imagenes. Una funcion importante para rotar es
fliplr que realiza un espejo vertical. Aunque esta funcion puede resolver todo el
problema, lo interesante es usarla para conseguir la matriz identidad espejada
y luego aplicarla para rotar en horizontal y vertical.
Otro tema al que hay que prestar atencion es que no se pueden multiplicar
matrices de tipo uint8. Lo que si se puede hacer es convertirlas en matrices de
tipo double, multiplicar y luego volver a uint8.
Ejercicio
Se pide realizar un espejado vertical y horizontal de lena.
Soluci
on
> I = imread(lena std.tif);
> E = eye(size(I)(1:2));
> E = fliplr(E);
> D = uint8(double(I(:,:,1))*double(E));
> showim(D);
> D = uint8(double(E)*double(I(:,:,1)));
> showim(D);
Ahora vamos a rotar la imagen 90 grados.
Ejercicio
Rotar 90 grados la imagen de lena.
Para la soluci
on podemos realizar un espejado diagonal para luego realizar
una espejado horizontal. O al reves. . .
Soluci
on
> I = imread(lena std.tif);
> E = eye(size(I)(1:2));

> E = fliplr(E);
> D = uint8(double(I(:,:,1))*double(E));
> D = uint8(double(D));
> showim(D);
Este es un ejercicio difcil de resolver, pero es un ejercicio bien completo.
Ejercicio
Se busca una funci
on que permita re-escalar una imagen.
Ayuda: Usar las funciones meshgrid y linspace para rehubicar los pixels
La funci
on meshgrid genera las coordenadas de una grilla de N dimensiones
asociada a una matriz.
Aqu se presenta un ejemplo de lo que meshgrid devuelve
Meshgrid
> [XX,YY] = meshgrid(0:0.2:1,0:0.2:1)
XX =
0.00000

0.20000

0.40000

0.60000

0.80000

1.00000

0.00000

0.20000

0.40000

0.60000

0.80000

1.00000

0.00000

0.20000

0.40000

0.60000

0.80000

1.00000

0.00000

0.20000

0.40000

0.60000

0.80000

1.00000

0.00000

0.20000

0.40000

0.60000

0.80000

1.00000

0.00000

0.20000

0.40000

0.60000

0.80000

1.00000

0.00000

0.00000

0.00000

0.00000

0.00000

0.00000

0.20000

0.20000

0.20000

0.20000

0.20000

0.20000

0.40000

0.40000

0.40000

0.40000

0.40000

0.40000

0.60000

0.60000

0.60000

0.60000

0.60000

0.60000

0.80000

0.80000

0.80000

0.80000

0.80000

0.80000

YY =

10

1.00000

1.00000

1.00000

1.00000

1.00000

1.00000

Por ejemplo, tenemos una matriz M de 5x5 que representa valores en un


espacio bidimensional de 0 a 1. Entonces si queremos conocer en que posicion
debe ir el valor de M (1, 2) , entonces podemos fijarnos en las matrices resultantes
de meshgrid, que en este caso esta asociado a la coordenada XX(1), Y Y (1).
Meshgrid
> A = eyes(5);
> [XX,YY] = meshgrid(0:1/(size(A,1)-1):1,
0:1/(size(A,2)-1):1);
> XX[1], YY[2], A(1,2)
ans = 0
ans =

0.20000

ans = 0
En combinaci
on con linspace se puede realizar varias tareas de interpolacion
lineal.
la funci
on linspace(a,b,n) permite generar n valores intermedios entre dos
valores a y b en forma lineal. Muy parecido a lo que realizamos previamente con
la generaci
on de un vector por rango, excepto que linspace es mas elegante.
Linspace
> linspace(0, 1, 5)
ans =
0.00000

0.25000

0.50000

0.75000

1.00000

> 0:1/(5-1):1
ans =
0.00000

0.25000

0.50000

0.75000

1.00000

Ahora esta interpolaci


on puede usarse para conocer que pixel debe asociarse
a la matriz resultante. La funcion meshgrid me permite conocer como se reordenan los nuevos pixels. La funcion round pasa los valores reales a valores enteros
11

que representan donde est


an los pixels originales correspondiente a ese punto de
la matriz.
Entonces la soluci
on a este problema es el siguiente:
Soluci
on

function [ ret ] = imagezoom (I, factor)


[ width, height, c ] = size(I);
new width = width * factor;
new height = height * factor;
ret = zeros([new width, new height, c], uint8);
[XX, YY] = meshgrid(linspace(1,width,new width),
linspace(1,height,new height));
XX = round(XX);
YY = round(YY);
for i = 1:new width
for j = 1:new height
ret(i,j,:) = I(XX(j,i),YY(j,i),:);
end
end
endfunction

12

También podría gustarte