Поворот изображения в Matlab относительно произвольных точек - PullRequest
1 голос
/ 08 ноября 2019

Я пытаюсь повернуть изображение в Matlab относительно произвольного набора точек.

До сих пор я использовал imrotate, но похоже, что imrotate вращается только вокруг центра.

Есть ли хороший способ сделать это без того, чтобы сначала дополнить изображение, а затем использовать imrotate?

Спасибо

1 Ответ

1 голос
/ 09 ноября 2019

«Хороший путь» использует imwarp

Построить матрицу преобразования немного сложно.
Я понял, как построить ее из следующего вопроса: Matlab вращение изображения
Преобразование поддерживает вращение, перевод и масштабирование.

Параметры:
(x0, y0) - это центральная точка, вокруг которой вы вращаетесь.
phi - угол поворота.
sx, syгоризонтальное и вертикальное масштабирование (установлено значение 1).
W и H - ширина и высота входного (и выходного) изображения.

Построение матрицы преобразования 3x3:

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];

Использование imwarp:

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

Вот полный пример исполняемого кода:

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)

Входное изображение:
enter image description here

Выходное изображение:
enter image description here


Примечание:
Важным преимуществом перед другими методами (например, imrotate после заполнения) является то, что координаты центра не обязательно должны быть целочисленными значениями.
Например, вы можете вращаться вокруг (100.4, 80.7).

...