martes, 9 de agosto de 2016

Rotar matrices en MATLAB


La rotación de matrices consiste en redefinir la posición de sus elementos mediante una modificación que no afecta el valor de sus elementos. Para comenzar, suponga que se tiene un vector v definido como sigue:

v = [v1, v2, v3, ⋯, vn − 1, vn]

Y sea vea v' el vector cuyas componentes son las mismas que v pero dispuestas en un orden inverso, es decir:

v′=[vn, vn − 1, ⋯, v3, v2, v1]

En MATLAB invertir el orden de los elementos de un vector resulta una tarea muy sencilla, esto puede lograrse indexando los elementos de la forma que a continuación se muestra:

>> v=[-2 5 8 7 3 0] % Vector original
v =
    -2     5     8     7     3     0
>> vp=v(end:-1:1) % Vector con elementos invertidos
vp =
     0     3     7     8     5    -2

La anterior es una forma muy simple de realizar dicha tarea, pero si usted prefiere el uso de funciones existe para tal fin la función fliplr cuya tarea es exactamente esa, extendiéndose su uso también a matrices, véase el ejemplo utilizando el mismo vector definido anteriormente:

>> vp=fliplr(v)
vp =
     0     3     7     8     5    -2

La función fliplr rota una matriz en un eje vertical, de tal modo que las columnas situadas a la izquierda queden en la parte derecha. Véase el ejemplo a continuación:

>> A=randi(10,3)
A =
     4     5     3
     2     2     4
     5     6     6
>> Ar=fliplr(A)
Ar =
     3     5     4
     4     2     2
     6     6     5

Está claro que fliplr ejecuta una rotación basada en las columnas, pero MATLAB dispone también de la función flipud que ejerce una rotación en un eje horizontal o basada en las filas, enseguida se muestra un ejemplo:

>> A=randi(10,4)
A =
     5     6     8     2
     9     4     5     3
     8     2     1     5
    10     7     3     6
>> Ar=flipud(A)
Ar =
    10     7     3     6
     8     2     1     5
     9     4     5     3
     5     6     8     2

Además de las anteriores MATLAB proporciona la función rot90 que permite girar la matriz en un ángulo múltiplo de 90° en el sentido contrario a las manecillas del reloj, de manera informal es como si la matriz rodase en dirección izquierda. Los argumentos de entrada de la función son primeramente la matriz a rotar y como segundo argumento un escalar entero que indica el múltiplo de 90° con el cual habrá de ejecutarse la rotación, si no se introduce un segundo argumento se asume que este será unitario. Véanse los ejemplos a continuación:

>> A=randi(20,3)
A =
    14     8    10
     1    19     9
    13     1    10
>> A90=rot90(A)  % Matriz rotada 90°
A90 =
    10     9    10
     8    19     1
    14     1    13
>> A180=rot90(A,2)  % Matriz  rotada en 180°
A180 =
    10     1    13
     9    19     1
    10     8    14
>> A270=rot90(A,3)   % Matriz rotada 270°

A270 =

    13     1    14
     1    19     8
    10     9    10

Resolver ecuaciones e inecuaciones algebraicas


Una ecuación es una igualdad matemática entre dos expresiones algebraicas en las que aparecen valores conocidos y una variable desconocida (incógnita), relacionados mediante operaciones matemáticas básicas, ejemplos de ecuaciones se muestran a continuación:

$$ 3x^2 + 2x - 2 = 0 $$

$$ x+\frac{3}{7}=2 $$

$$ \cos(x)+sin(\frac{\pi}{2})=0 $$

Las ecuaciones algebraicas sirven para modelar situaciones poco complejas pero que requieren el uso de la herramienta matemática para obtener una solución satisfactoria. Existen diversos métodos para resolver ecuaciones, los cuales se aplican dependiendo del tipo de ecuación, incluso hay fórmulas establecidas para algunos tipos de ecuaciones que minimizan el esfuerzo de cálculo.

MATLAB dispone de la función solve perteneciente al Symbolic Math Toolbox, la cual permite resolver ecuaciones, inecuaciones y sistemas de ecuaciones; la sintaxis general de la función solve es:

solve(ec, var);

Donde ec es una ecuación algebraica definida usando variables simbólicas y var es la incógnita respecto a la cual se resuelve la ecuación dada.

A manera de ejemplo se resolverá la siguiente ecuación lineal

$$ x+3=2 $$


>> x=sym('x');
>> solve(x+3==2,x)
ans =
-1

Es importante hacer mención que para especificar una igualdad se utilizan dos signos, dado que un sólo signo hace referencia a una asignación.

Si no se especifica el segundo miembro de la igualdad, MATLAB asumirá que la expresión estará igualada a cero, es decir, para resolver la ecuación:

$$ x^2 - 2x - 1 = 0 $$

Puede hacerlo de las diversas formas que enseguida se muestran:

>> solve(x^2-2*x-1==0,x)
ans =
 2^(1/2) + 1
 1 - 2^(1/2)
>> solve(x^2-2*x-1,x)
ans =
 2^(1/2) + 1
 1 - 2^(1/2)
>> solve(x^2-2*x-1)
ans =
 2^(1/2) + 1
 1 - 2^(1/2)

Para resolver desigualdades o inecuaciones la sintaxis es prácticamente la misma, claro, sólo hay que utilizar los operadores relacionales mayor que o menor que en lugar del signo de igualdad. Por ejemplo, resolviendo la siguiente desigualdad

$$  x+2>10 $$

>> solve(x+2>10,x)
ans =
Dom::Interval(8, Inf)

MATLAB devuelve el intervalo solución para la inecuación, en este caso $ (8,\infty) $. Para el caso de un intervalo cerrado MATLAB devuelve entre corchetes el valor del límite correspondiente, por ejemplo:

>> solve(x+2>=10,x)
ans =
Dom::Interval([8], Inf)

Un sistema de ecuaciones se compone de dos o más ecuaciones y un número equivalente de valores desconocidos, es posible resolver sistemas de ecuaciones utilizando también la función solve con la sintaxis siguiente:

solve(ec1,ec2,ec3,…)

Un ejemplo, resolver el siguiente sistema de ecuaciones:

x + y = 4

x − y = 3

>> syms x y
>> sol=solve(x+y==4,x-y==3)
sol = 
    x: [1x1 sym]
    y: [1x1 sym]

Para visualizar los resultados puede acceder a los campos de cada variable como se muestra enseguida:

>> sol.x 
ans =
7/2
>> sol.y
ans =
1/2

jueves, 4 de agosto de 2016

Convertir una imagen a escala de grises


La manera rápida


Si cuenta con el Image Processing Toolbox MATLAB dispone de una función llamada rgb2gray que permite convertir una imagen RGB a una en escala de grises, ej:

X = imread('lenna.png');
XG = rgb2gray(X);
imshow(XG);

Imagen original

Imagen en escala de grises

Como puede notar es muy simple, sólo necesita pasar como argumento la matriz que contiene la información de la imagen RGB.

La otra, un poco de algoritmos...


Si no dispone del toolbox de procesamiento de imagen, entonces puede implementar su propio algoritmo para realizar dicha tarea.

El algoritmo más simple es el del promedio (average method), que consiste en calcular el promedio de los canales RGB y asignarlos al pixel correspondiente en la imagen de grises. Por ejemplo dada una matriz de MxNx3 correspondiente a una imagen, el pixel de la matriz de grises en la posición (i, j) se calcula como sigue:

$$ XG_{i,j} = \frac{X_{i,j,1} + X_{i,j,2} + X_{i,j,3}}{3} $$

Donde XG es la matriz de grises, de dimensiones MxN. Y Xi, j, 1Xi, j, 2 y Xi, j, 3 las componentes correspondientes a los canales R, G y B, respectivamente.

Implementando esto en MATLAB:

X = imread('lenna.png');
XG = uint8(mean(X,3));
imshow(XG);

¿Bastante simple verdad?, lo que hacemos es hacer el promedio en la dimensión 3, es decir, para cada pixel. La conversión a entero de 8-bits (uint8) es necesaria para que se muestre correctamente cuando utilizamos imshow, dado que la función mean devuelve una matriz de tipo double.

Otro método para convertir a escala de grises es el de la luminosidad (luminosity method) que consiste en asignar una proporción específica (ponderada) a cada uno de los canales, dependiendo la aportación de estos. De hecho MATLAB utiliza este tipo de transformación en la función rgb2gray. Con este método, la expresión para calcular el valor de un pixel de grises viene dado por:

XGi, j = 0.2889 Xi, j, 1 + 0.5870 Xi, j, 2 + 0.1140 Xi, j, 3

LLevando esto a un código MATLAB:

X = imread('img/lenna.png');
k = [0.2989 0.5870 0.1140];
XG = X(:,:,1)*k(1) + X(:,:,2)*k(2) + X(:,:,3)*k(3);
imshow(XG)

martes, 10 de mayo de 2016

Detección de bordes en imágenes con MATLAB


La detección de bordes en MATLAB es una de las operaciones de procesamiento de imágenes más común y básica, cuyo objetivo es determinar las regiones en una imagen que presentan cambios significativos de intensidad en los pixeles que la conforman.

Recuerde que una imagen en escala de grises puede expresarse como una función bivariable f(x, y), donde x e y son las coordenadas de ubicación (fila, columna). Así una forma sencilla de detectar los bordes en una imagen es utilizar el gradiente, mismo que determina la tasa de variación en ambas direcciones de una función bivariable, dado por:

$$ \nabla f = \begin{bmatrix} \frac{\partial f}{\partial x} \\ \frac{\partial f}{\partial y} \end{bmatrix} $$

Aunque claro, para nuestros propósitos lo que usaremos es la magnitud del gradiente:

$$ |\nabla f| = \sqrt{ \left(\frac{\partial f}{\partial x}\right)^2 + \left(\frac{\partial f}{\partial y}\right)^2} $$

Así, para determinar los bordes en una imagen, o lo que sería lo mismo: localizar las regiones en donde la magnitud del gradiente es mayor, podemos utilizar la función gradient, vea el siguiente ejemplo:

X = imread('Lenna.png');
XG = rgb2gray(X);
[dx,dy] = gradient(double(XG));
M = uint8(sqrt(dx.^2+dy.^2));
imshow(M);



MATLAB cuenta con una función especial para detectar bordes en una imagen: edge, la cual utiliza operadores matriciales especiales que transforman una imagen en escala de grises en una imagen binarizada con bordes resaltados.

X = imread('Lenna.png');
XG = rgb2gray(X);
XB = edge(XG,'sobel');
imshow(XB);


lunes, 4 de enero de 2016

Ordenar matrices en MATLAB


El ordenamiento de datos es una tarea muy común dentro del mundo de la informática y en la programación científica. Se ordenan datos para realizar análisis cualitativos, para la visualización gráfica o cualquier otro procedimiento que requiera datos organizados. Los datos se pueden organizar por criterios diversos, pero en esta sección veremos simplemente como ordenarlos de acuerdo a su valor numérico, en orden ascendente o descendente.

Generalmente los algoritmos de ordenamiento forman parte de los cursos básicos de programación y algorítmica, dada su importancia mencionada con anterioridad. Se estudian por lo general métodos tradicionales como: el método de ordenamiento por selección, ordenamiento por inserción y ordenamiento por combinación.

Ahora, enseguida sólo veremos cómo implementar el método de ordenamiento por selección, puesto que resulta muy didáctico y fácil de programar, y como no estamos en disposición de reinventar la rueda,  entonces, para el ordenamiento de las matrices y/o vectores utilizaremos la función sort incluida en el núcleo de MATLAB, y el resto de métodos de ordenamiento tradicionales se propondrán como ejercicios al final de este capítulo.

Así pues, puede revisar el siguiente código:

X=input('Inserte un vector: ');
for i=1:length(X)
   [menor,k]=min(X(i:end));
   X((i-1)+k)=X(i);
   X(i)=menor;
end
disp(X); % Vector ordenado

El programa anterior tiene como punto de entrada un vector introducido por el usuario de forma interactiva y que puede contener valores numéricos cualesquiera. Una vez se ha introducido el vector, se utiliza un bucle for cuyo recorrido está determinado por la longitud del vector, y en cada iteración se busca el elemento de menor valor ubicado en el sub-arreglo $X(i,i+1,...,n-1,n)$ donde i es el i-ésimo elemento dado por el número de iteración actual, y n el último elemento del arreglo, la función min de MATLAB devuelve dos resultados: el valor y la posición del mínimo encontrado, con ello se procede a intercambiar el valor mínimo encontrado con aquel ubicado en la i-ésima posición del arreglo. Y así, cuando se hayan ejecutado tantas iteraciones como elementos tenga el vector, se habrán ordenado en forma ascendente dichos valores. Si por el contrario necesita ordenar un vector en forma descendente, simplemente habrá de sustituir la función min por max, es decir, buscar un valor máximo en lugar del mínimo en cada iteración, o bien, reutilizar el mismo algoritmo y audazmente rotar el vector resultante mediante la función fliplr.

Como se mencionó, en MATLAB todo lo anterior puede reemplazarse utilizando la función sort.
cuya sintaxis más general es:

>> sort(X, dim, mod);

Donde X es la matriz o vector a ordenar, dim es un escalar que puede ser 1 (columnas) o 2 (filas) y que representa la dimensión de referencia sobre la cual se ordenará, y mod es el modo de ordenamiento, que puede ser 'ascend' (menor a mayor) o 'descend' (mayor a menor), por defecto las matrices o vectores se ordenan en forma ascendente. 

Véanse los ejemplos siguientes:

>> X=[10 2 8 17 20 1 4 8 9];
>> sort(X)
ans =
    1     2     4     8     8     9    10    17    20
>> M=randi(10,5)
M =
    3    10     3     2     8
    8     7     2    10     6
    9     4     9     5     5
    1    10     8     3    10
    4     8     4     5     6
>> sort(M,1) % Ordenada por columnas
ans =
    1     4     2     2     5
    3     7     3     3     6
    4     8     4     5     6
    8    10     8     5     8
    9    10     9    10    10
>> sort(M,2) % Ordenada por filas
ans =
    2     3     3     8    10
    2     6     7     8    10
    4     5     5     9     9
    1     3     8    10    10
    4     4     5     6     8