Matlab - ENMARCAR MATRIZ CON MARCO DADO EFECTO PADDING

 
Vista:
sin imagen de perfil
Val: 15
Ha aumentado su posición en 4 puestos en Matlab (en relación al último mes)
Gráfica de Matlab

ENMARCAR MATRIZ CON MARCO DADO EFECTO PADDING

Publicado por Carlos (10 intervenciones) el 02/03/2018 17:08:47
Hola, estoy haciendo una funcion en matlab que dada una matriz imagen y un marco lo que tiene que hacer es enmarcar la matriz.
Para enmarcar la matriz se hace lo siguiente :

1. Crea una matriz B1 de tamaño 30x20 con valores ordenados por
columnas que vayan desde el 1 al 600.

2. Crea una matriz B2 de tamaño 30x22 de manera que las dos primeras
columnas coincidan con la primera columna de B1 y las dos últimas
columnas coincidan con la última columna de B1.

3. Crea una matriz B3 de tamaño 32x22 de manera que las dos primeras
filas coincidan con la primera fila de la matriz B2 y las dos últimas filas
coincidan con la última fila de la matriz B2


Bien hasta aqui es fácil y lo tengo hecho el problema viene cuando me piden esto :
Ejercicios (recuerda ejecutar diary off después de finalizar el
último ejercicio).
6.- Función de enmarcado: El objetivo de este ejercicio es crear una función de
enmarcado que nos sea útil cuando vayamos a aplicar convoluciones sobre
imágenes.
La función a crear deberá admitir como parámetros de entrada una matrizimagen
y el tamaño del marco.
Como salida se obtendrá una matriz-imagen con un marco con el tamaño
indicado y cuyo método de creación será aquel descrito en el ejercicio 2.
Si la imagen de entrada era de tamaño MxN y el tamaño del marco pasado por
parámetro es 3, la imagen de salida debería ser de tamaño (M+6)x(N+6).
Si para la creación de esta función necesitas el uso de un bucle FOR, consulta su
sintaxis a través de la ayuda de MatLab.


Bien mi funcion es la siguiente :

1
2
3
4
5
6
7
8
9
10
11
12
function [matriz_salida]=enmarcar(imagen,marco)
A=sort(imagen);
[m,n]=size(A);
B2=zeros(m,n+2*marco);
B2(1)=A(1);
B2(end)=A(end);
B2(:,end)=A(:,end);
B2=[A(:,1) A A(:,n)];
B21=B2';
B3=[B21(:,1) B21 B21(:,n)];

matriz_salida = B3';

Mi problema esta en que no me sale el tamaño de la matriz como me pide en el enunciado solamente me sale por ejemplo para una matriz de 30, 20 me sale un tamaño de 32,22 eso seria para un marco de tamaño 1 pero si es de 3 deberia ser 36,26 y a mi no me sale eso.
¿Alguien me puede ayudar y decirme el error? No encuentro el error
Saludos y gracias
Estos son los datos creo una matriz aleatoria de numeros entre 1 y 600 de 30,20 y la ordeno.
B1=sort(rand(30,20)*599+1);
Y con esa matriz se la paso a la funcion y la tiene que enmarcar.
Cuando paso por parametros la matriz B1 y un marco de tamaño 3 me devuelve una matriz de tamaño 32x22 cuando debe ser 36x26
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Lindsey
Val: 426
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

ENMARCAR MATRIZ CON MARCO DADO EFECTO PADDING

Publicado por Lindsey (112 intervenciones) el 02/03/2018 18:52:00
Hola, la verdad es que ya tienes un problema desde la línea 5, ya que con:

1
2
B2(1)=A(1);
B2(end)=A(end);

No estás guardando la primera columna de A en la primera columna de B2, sino que solo estás guardando el primer elemento de A en el primer elemento de B2, para guardar toda la columna necesitarías especificar que vas a guardar todas las filas de la primera columna de A en todas las filas de la primera columna de B2. Todas las filas se escriben con dos puntos (:). Lo mismo pasa para la última columna. Lo harías así:

1
2
B2(:,1)=A(:,1);
B2(:,end)=A(:,end);

Dentro del paréntesis se escribe siempre primero fila, y luego columna: A(fila,columna), B2(fila,columna), etc.

Tu otro problema, es que al hacer este reemplazo no lo estás haciendo variable. Sí es cierto que si tienes un marco de 1, la primera columna de B2 tiene que ser la primera columna de A, pero si el marco es de 2? Las dos primeras columnas de B2 las tienes que reemplazar con información de A, por lo que B2(:,1)=A(:,1) no te serviría porque ahí siempre va a ser la primera columna.

Y bueno, para hacer lo que quieres vamos paso por paso:

Inicio de la función y parte del código que ya tienes bien



1
2
3
4
5
6
7
function [matriz_salida]=enmarcar(imagen,marco)
 
% Orden los valores de las columnas
A=sort(imagen);
[m,n]=size(A);
% Crear matriz B2 de tamaño m x n+2*marco
B2=zeros(m,n+2*marco);

Hasta aquí tienes tu matriz A, que vendría siendo la misma B1 con sus columnas ordenadas, y la matriz B2 llena de ceros.

Reemplazo de las columnas del marco de B2 con la información de A



En las siguientes líneas se llenan las columnas del marco de la izquierda de B2:

1
2
3
4
% Hacer coincidir las columnas del marco de la izquierda con la primera columna de B1
for col=1:marco
    B2(:,col) = A(:,1);
end

Como puedes observar aquí ya se implementa un for. Esto permite que el reemplazo de las columnas sea variable, y no estático como lo tenías. la estructura de un for la puedes ver en la ayuda de matlab como te lo sugiere el ejercicio. Veamos el vector 1:marco, que corresponde a los pasos de for.

Si marco = 1, entonces 1:marco = [1]
Si marco = 2, entonces 1:marco = [1 2]
Si marco = 3, entonces 1:marco = [1 2 3]
Y así sucesivamente.

Como puedes ver el vector 1:marco se crea en función del tamaño del marco y corresponde a las columnas del marco de la izquierda en la que vas a meter la información de A. Ahora lo que no vi claro, es que por ejemplo, si el marco es de 2, las primeras dos columnas de B2 deben coincidir con la primera columna de A, o con las dos primeras columnas de A? De todos modos, en el for está hecho como que siempre las columnas nuevas en B2 se llenan con la primera columna de A, pero se puede cambiar.

Ahora, para las columnas del lado derecho de B2:

1
2
3
4
% Hacer coincidir las columnas del marco de la derecha con la última columna de B1
for col=(marco + n + 1):size(B2,2)
    B2(:,col) = A(:,end);
end

Aquí de nuevo se hace un for. Y los pasos del for son (marco + n + 1):size(B2,2). ¿Qué quiere decir esto? Así como en tu ejemplo, si A es de tamaño 30 x 20, entonces n = 20, y size(B2,2) es el número de columnas de B2.

Si marco = 1, entonces (marco + n + 1):size(B2,2) = [22] (el número de columnas de B2 es 22)
Si marco = 2, entonces (marco + n + 1):size(B2,2) = [23 24] (el número de columnas de B2 es 24)
Si marco = 3, entonces (marco + n + 1):size(B2,2) = [24 25 26] (el número de columnas de B2 es 26]
Y así sucesivamente.

Entonces puedes ver que en el resultado de (marco + n + 1):size(B2,2) se van a obtener las columnas en las cuales vas a ubicar la información de la última columna de A, y en el for se hace este reemplazo.

Hasta este punto las filas intermedias de B2 siguen siendo 0, pues solo has hecho los reemplazos de las columnas pertenecientes al marco, para meter el resto de la información usarías:

1
2
% Meter el resto de la matriz B1 en B2
B2(:,marco+1:marco+n) = A;

El resultado de marco+1:marco+n y su variación la puedes calcular como lo he hecho anteriormente.

De aquí en adelante solo queda repetir el procedimiento para crear B3, pero esta vez trabajando con las filas

Creación de B3



Acá está el código para esta parte, solo sigue el procedimiento que es bastante similar al anterior pero haciendo el reemplazo en las filas:

1
2
3
4
5
6
7
8
9
10
11
12
% Crear matriz B3 de tamaño m+2*marco x n+2*marco
B3 = zeros(m+2*marco,n+2*marco);
% Hacer coincidir las filas del marco de arriba con la primera fila de B2
for fil=1:marco
    B3(fil,:) = B2(1,:);
end
% Hacer coincidir las filas del marco de abajo con la última fila de B2
for fil=(marco + m + 1):size(B3,1)
    B3(fil,:) = B2(end,:);
end
% Meter el resto de la matriz B2 en B3
B3(marco+1:marco+m,:) = B2;

Y pues al final ya solo te queda crear la variable matriz_salida para que sea la salida de la función.

El código entero sería este:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function [matriz_salida]=enmarcar(imagen,marco)
 
% Orden los valores de las columnas
A=sort(imagen);
[m,n]=size(A);
% Crear matriz B2 de tamaño m x n+2*marco
B2=zeros(m,n+2*marco);
% Hacer coincidir las columnas del marco de la izquierda con la primera columna de B1
for col=1:marco
    B2(:,col) = A(:,1);
end
% Hacer coincidir las columnas del marco de la derecha con la última columna de B1
for col=(marco + n + 1):size(B2,2)
    B2(:,col) = A(:,end);
end
% Meter el resto de la matriz B1 en B2
B2(:,marco+1:marco+n) = A;
% Crear matriz B3 de tamaño m+2*marco x n+2*marco
B3 = zeros(m+2*marco,n+2*marco);
% Hacer coincidir las filas del marco de arriba con la primera fila de B2
for fil=1:marco
    B3(fil,:) = B2(1,:);
end
% Hacer coincidir las filas del marco de abajo con la última fila de B2
for fil=(marco + m + 1):size(B3,1)
    B3(fil,:) = B2(end,:);
end
% Meter el resto de la matriz B2 en B3
B3(marco+1:marco+m,:) = B2;
 
matriz_salida=B3;
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 15
Ha aumentado su posición en 4 puestos en Matlab (en relación al último mes)
Gráfica de Matlab

ENMARCAR MATRIZ CON MARCO DADO EFECTO PADDING

Publicado por Carlos (10 intervenciones) el 02/03/2018 20:24:59
Muchiiisiimas gracias de verdad mira llevo toda la tarde tratando de hacerlo y nada no he sido capaz ya daba el ejercicio por imposible pero de verdad muchiiisiimas gracias muy bien explicado y lo he entendido perfectamente :)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Daniel
Val: 397
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

ENMARCAR MATRIZ CON MARCO DADO EFECTO PADDING

Publicado por Daniel (264 intervenciones) el 02/03/2018 20:33:54
Me parece un poco larga la solución

la funcion podria ser:

1
2
3
4
5
6
7
function B3=marco(B1,n)
for j=1:n
    B2=[B1(:,1) B1 B1(:,end)];
    B3=[B2(1,:);B2;B2(end,:)];
    B1=B3;
end
end

y el script de ejecucion, por ejempo:

1
2
3
4
5
6
clc
clear all
B1=reshape((rand(600,1)),30,20);
n=3;
res=marco(B1,n);
imagesc(res)

Saludos

Daniel
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar