matlab - graficar - ¿Cómo crear una imagen 2D girando 1D vector de números alrededor de su elemento central?
graficar figuras geometricas en matlab (1)
Tengo un vector de números 1D que representa un corte central de un objeto circular simétrico. El vector en sí es simétrico alrededor de su elemento central. Quiero crear en MATLAB una imagen 2D del objeto original girando el vector 1D alrededor de su elemento central.
Probé el siguiente código (con un vector de números original ficticio), pero el corte central que recibo de la imagen 2D generada no coincide con el vector 1D original, como puede verse si ejecuta el código. ¡Agradeceré cualquier ayuda!
close all; clc
my1D_vector=[ zeros(1,20) ones(1,15) zeros(1,20)]; % original vector
len=length(my1D_vector);
img=zeros(len, len);
thetaVec=0:0.1:179.9; % angles through which to rotate the original vector
numRotations=length(thetaVec);
% the coordinates of the original vector and the generated 2D image:
x=(1:len)-(floor(len/2)+1);
y=x;
[X,Y]=meshgrid(x,y);
for ind_rotations=1:numRotations
theta=pi/180*thetaVec(ind_rotations);
t_theta=X.*cos(theta)+Y.*sin(theta);
cutContrib=interp1(x , my1D_vector , t_theta(:),''linear'');
img=img+reshape(cutContrib,len,len);
end
img=img/numRotations;
figure(''name'',''original vector'');plot(x,my1D_vector,''b.-'')
figure(''name'',''generated 2D image''); imagesc(x,y,img); colormap(gray) ;
figure(''name'',''comparison between the original vector and a center cut from the generated 2D image'');
plot(x,my1D_vector,''b.-'')
hold on
plot(x,img(find(x==0),:),''m.-'')
legend(''original 1D vector'',''a center cut from the generated 2D image'')
No seguí tu código, pero ¿qué tal esto?
V = [ zeros(1,20) ones(1,15) zeros(1,20)]; % Any symmetrical vector
n = floor(numel(V)/2);
r = [n:-1:0, 1:n]; % A vector of distance (measured in pixels) from the center of vector V to each element of V
% Now find the distance of each element of a square 2D matrix from it''s centre. @(x,y)(sqrt(x.^2+y.^2)) is just the Euclidean distance function.
ri = bsxfun(@(x,y)(sqrt(x.^2+y.^2)),r,r'');
% Now use those distance matrices to interpole V
img = interp1(r(1:n+1),V(1:n+1),ri);
% The corners will contain NaN because they are further than any point we had data for so we get rid of the NaNs
img(isnan(img)) = 0; % or instead of zero, whatever you want your background colour to be
Entonces, en lugar de interpolar en el ángulo, interpolar en el radio. Entonces r
representa un vector de la distancia desde el centro de cada uno de los elementos de V
, en 1D. ri
representa entonces la distancia desde el centro en 2D y estos son los valores a los que queremos interpolar. Entonces solo uso la mitad de r
V
porque son simétricos.
Es posible que desee establecer todos los NaN
a 0
después porque no puede interpolar las esquinas porque su radio es mayor que el radio de su punto más alejado en V
Usando su código de trazado consigo
y
Las curvas azul y magenta se superponen exactamente.
Explicación
Imagine que su vector, V
, era solo un vector de 1
por 5
. Entonces este diagrama muestra qué r
y ri
serían:
No lo marqué en el diagrama, pero r''
sería la columna central. Ahora desde el código que tenemos
ri = bsxfun(@(x,y)(sqrt(x.^2+y.^2)),r,r'');
y de acuerdo con el diagrama r = [2,1,0,1,2]
así que ahora para cada píxel tenemos la distancia euclidiana desde el centro para que el píxel (1,1) sea sqrt(r(1).^2+r(1).^2)
que es sqrt(2.^2+2.^2)
que es sqrt(8)
como se muestra en el diagrama.
También notará que he "grisado" los píxeles de las esquinas. Estos píxeles están más alejados del centro que cualquier punto del que tengamos datos porque el radio máximo (distancia desde el centro) de nuestros datos es 2
pero sqrt(8) > sqrt(5) > 2
por lo que no puede interpolar esos datos, tendrías que extrapolar para obtener valores para ellos. interp1
devuelve NaN
para estos puntos.
¿Por qué funciona la interpolación? Piensa en la posición de cada píxel como referencia al centro del píxel. Ahora en este diagrama, el círculo rojo es lo que sucede cuando gira los elementos exteriores (es decir, r==2
) y el verde está rotando los elementos 1 más adentro (es decir, r==1
). Verá que el píxel que obtiene la distancia de sqrt(2)
(flecha azul) se encuentra entre estos dos radios cuando los rotamos, por lo que debemos interpolar la distancia entre esos dos píxeles.