Search code examples
matlabimage-processingrotationimage-rotation

Image Rotation in Three Dimensions (Matlab)


I am trying to rotate a 2D image in Matlab xyz 3-D space. I want to rotate the image I by an angle θ=i about the x-axis. I am doing this by means of multiplication with the rotation matrix (as defined here):

This is my code:

x = linspace(-1,1,size(I,1));
[x0,y0,z0] = meshgrid(x,x,1);
R = [1 0 0; 0 cosd(-i) -sind(-i); 0 sind(-i) cosd(-i)];
xy = [x0(:),y0(:), z0(:)]*R';
X = reshape(xy(:,1),size(x0));
Y = reshape(xy(:,2),size(y0));
Z = reshape(xy(:,3),size(z0));
rotatedI = interp3(x0,y0,z0,I,X,Y,Z, 'nearest');
rotatedI(isnan(rotatedI)) = 0;

The error that I am getting is in the interpolation line:

Error using griddedInterpolant
Interpolation requires at least two sample points in each
dimension.

So what exactly is the problem here and how can I fix it?

I am confused because this code works fine when specialized to two dimensions. Any explanation is much appreciated.


Solution

  • the problem is that your input z grid z0 contains a single value (1), while your desired z grid Z contains multiple values. therefore there is no way to interpolate this single value into multiple ones.

    you can assign the input z grid with multiple values so that it will be possible to interpolate.

    I = im2double(imread('cameraman.tif'));
    I = cat(3,I,I,I);
    i = 10;
    x = linspace(-1,1,size(I,1));
    [x0,y0,z0] = meshgrid(x,x,-1:1); % 3 z values
    R = [1 0 0; 0 cosd(-i) -sind(-i); 0 sind(-i) cosd(-i)];
    xy = [x0(:),y0(:), z0(:)]*R;
    X = reshape(xy(:,1),size(x0));
    Y = reshape(xy(:,2),size(y0));
    Z = reshape(xy(:,3),size(z0));
    rotatedI = interp3(x0,y0,z0,I,X,Y,Z, 'nearest');
    rotatedI(isnan(rotatedI)) = 0;
    imshow(rotatedI);
    

    enter image description here

    in addition, you can use rotx, roty, and rotz to generate rotation matrices easily.

    UPDATE

    if you want to rotate the image 2D plane in the 3D space you don't need to use interpolation and can do something like:

    I = im2double(imread('cameraman.tif'));
    i = 10;
    x = linspace(-1,1,size(I,1));
    [x0,y0,z0] = meshgrid(x,x,-1:1); % 3 z values
    [x0,y0,z0] = meshgrid(x,x,1); % 3 z values
    R = [1 0 0; 0 cosd(-i) -sind(-i); 0 sind(-i) cosd(-i)];
    xy = [x0(:),y0(:), z0(:)]*R;
    X = reshape(xy(:,1),size(x0));
    Y = reshape(xy(:,2),size(y0));
    Z = reshape(xy(:,3),size(z0));
    warp(X,Y,Z,I);
    grid on
    

    enter image description here