1

I am trying to rotate an image in Matlab about an arbitrary set of points.

So far, I have used imrotate, but it looks like imrotate only rotates about the center.

Is there a nice way of doing this without first padding the image and then using imrotate?

Thank you

intl
  • 2,753
  • 9
  • 45
  • 71
  • 1
    [Rotating about an arbitrary point is the same as rotating and then translating](https://stackoverflow.com/questions/56728791/how-can-we-rotate-an-rgb-image-using-nearest-neighbor-interpolation-algorithm-ab/56730080#56730080). This question is a duplicate of [this other one](https://stackoverflow.com/questions/10026905/how-to-rotate-an-image-about-a-point-that-is-not-the-images-center-point-using) but the answer there is not very good IMO, so I won't close this question. – Cris Luengo Nov 08 '19 at 01:31
  • [This other question](https://stackoverflow.com/questions/25458442/rotate-a-2d-image-around-specified-origin-in-python) has an answer with code, but it's Python. Maybe you'll be albe to translate that? – Cris Luengo Nov 08 '19 at 01:32

1 Answers1

1

The "nice way" is using imwarp

Building the transformation matrix is a little tricky.
I figured out how to build it from a the following question: Matlab image rotation
The transformation supports rotation, translation and zoom.

Parameters:
(x0, y0) is the center point that you rotate around it.
phi is rotation angle.
sx, sy are horizontal and vertical zoom (set to value to 1).
W and H are width and height of input (and output) images.

Building 3x3 transformation matrix:

T = [sx*cos(phi), -sx*sin(phi), 0
     sy*sin(phi),  sy*cos(phi), 0
     (W+1)/2-((sx*x0*cos(phi))+(sy*y0*sin(phi))), (H+1)/2+((sx*x0*sin(phi))-(sy*y0*cos(phi))), 1];

Using imwarp:

tform = affine2d(T);
J = imwarp(I, tform, 'OutputView', imref2d([H, W]), 'Interp', 'cubic');

Here is a complete executable code sample:

I = imresize(imread('peppers.png'), 0.5); %I is the input image

[H, W, ~] = size(I);  %Height and Width of I

phi = 120*pi/180; %Rotate 120 degrees

%Zoom coefficients
sx = 1;
sy = 1;

%Center point (the point that the image is rotated around it).
x0 = (W+1)/2 + 50;
y0 = (H+1)/2 + 20;

%Draw white cross at the center of the point of the input image.
I(y0-0.5:y0+0.5, x0-19.5:x0+19.5, :) = 255;
I(y0-19.5:y0+19.5, x0-0.5:x0+0.5, :) = 255;

%Build transformation matrix.
T = [sx*cos(phi), -sx*sin(phi), 0
     sy*sin(phi),  sy*cos(phi), 0
     (W+1)/2-((sx*x0*cos(phi))+(sy*y0*sin(phi))), (H+1)/2+((sx*x0*sin(phi))-(sy*y0*cos(phi))), 1];

tform = affine2d(T);
J = imwarp(I, tform, 'OutputView', imref2d([H, W]), 'Interp', 'cubic');

%Draw black cross at the center of the output image:
J(end/2:end/2+1, end/2-15:end/2+15, :) = 0;
J(end/2-15:end/2+15, end/2:end/2+1, :) = 0;

%Shows that the center of the output image is the point that the image was rotated around it.
figure;imshow(J)

Input image:
enter image description here

Output image:
enter image description here


Note:
Important advantage over other methods (like imrotate after padding), is that the center coordinates don't have to be integer values.
You can rotate around (100.4, 80.7) for example.

Rotem
  • 30,366
  • 4
  • 32
  • 65