O.T.
O.T.

Reputation: 147

How to create a 2D image by rotating 1D vector of numbers around its center element?

I have 1D vector of numbers which represents a center cut of a circular symmetric object. The vector itself is symmetric around its center element. I want to create in MATLAB a 2D image of the original object by rotating the 1D vector around its center element.

I tried the following code (with a dummy original vector of numbers) , but the center cut I get from the generated 2D image does not match the original 1D vector, as can be seen if you run the code. I'll appreciate any help !!!

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')

enter image description here

enter image description here

Upvotes: 2

Views: 2520

Answers (1)

Dan
Dan

Reputation: 45752

I didn't follow your code but how about this:

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

So instead of interpolating on the angle, I interpolate on the radius. So r represents a vector of the distance from the centre of each of the elements of V, in 1D. ri then represents the distance from the centre in 2D and these are the values we want to interpolate to. I then only use half of r and V because they are symmetrical.

You might want to set all the NaNs to 0 afterwards because you can't interpolate the corners because their radius is larger than the radius of your furthest point in V.

Using your plotting code I get

enter image description here

and

enter image description here

The blue and magenta curves overlap exactly.


Explanation

Imagine that your vector, V, was only a 1-by-5 vector. Then this diagram shows what r and ri would be:

enter image description here

I didn't mark it on the diagram but r' would be the middle column. Now from the code we have

ri = bsxfun(@(x,y)(sqrt(x.^2+y.^2)),r,r');

and according to the diagram r = [2,1,0,1,2] so now for each pixel we have the euclidean distance from the centre so pixel (1,1) is going to be sqrt(r(1).^2+r(1).^2) which is sqrt(2.^2+2.^2) which is sqrt(8) as shown in the diagram.

Also you will notice that I have "greyed" out the corners pixels. These pixels are further from the centre than any point we have data for because the maximum radius (distance from the centre) of our data is 2 but sqrt(8) > sqrt(5) > 2 so you can't interpolate those data, you would have to extrapolate to get values for them. interp1 returns NaN for these points.

Why does the interpolation work? Think of the position of each pixel as referring to the centre of the pixel. Now in this diagram, the red circle is what happens when you rotate the outer elements (i.e. r==2) and the green is rotating the elements 1 further in (i.e. r==1). You'll see that the pixel that gets the distance of sqrt(2) (blue arrow) lies between these two radii when we rotate them and so we have to interpolate that distance between those two pixels.

enter image description here

Upvotes: 5

Related Questions