Я хотел бы повернуть изображение без квадрата с помощью Matlab:
- без использования функции
imrotate
, поскольку она является частью панели инструментов обработки изображений,
- с параметром
loose
, что означает, что размер вывода отличается от размера входного изображения,
- и с не слишком медленной функцией по сравнению с
imrotate
.
Я уже нашел функцию , чтобы сделать это (просто замените imshow
и bestblk
вашими собственными функциями, чтобы не использовать панель инструментов), но на самом деле это медленно для больших изображений. Мой подход состоит в том, чтобы избегать создания петель и максимально полагаться на interp2
.
Подпись функции будет:
imOutput = my_imrotate(imInput, theta_degres, interpolation, bbox)
где:
interpolation
будет bilinear
, bicubic
или nearest
,
bbox
будет crop
или loose
.
Crop
У меня уже есть хороший результат с параметром crop
, но мне не удается найти смещение для параметра loose
.
Вот код для параметра crop
, где Z
- это вход, а Zi
- это выход:
Z = double(imInput);
sz = size(Z);
[X,Y] = meshgrid(1:sz(2), 1:sz(1));
%# Center
c = sz(end:-1:1)/2;
%# Angle
t = theta_degres*pi/180;
%# Rotation
ct = cos(t);
st = sin(t);
Xi = c(1) + ct*(X-c(1))-st*(Y-c(2));
Yi = c(2) + st*(X-c(1))+ct*(Y-c(2));
%# Rotation
Zi = interp2(X, Y, Z, Xi, Yi);
Сыпучие
Моя идея состоит в том, чтобы вычислить размер кадра, который будет содержать исходное изображение и повернутое изображение, а затем:
- дополняет исходное изображение таким образом, чтобы иметь изображение, размер которого равен размеру рамки,
- используйте
interp2
для дополненного изображения,
- обрезать получившееся изображение так, чтобы получилось повернутое изображение без остатков отступов.
Чтобы получить размер повернутого изображения с помощью параметра loose
, я вычисляю rotation_matrix
и вызываю rotate_points
по координатам углов p
входного изображения:
rotation_matrix = [ct, -st; st, ct];
rotate_points = @(p) bsxfun(@plus, c', rotation_matrix * bsxfun(@minus, p, c)')';
Любая помощь будет принята с благодарностью.
Редактировать: Используя решение, представленное в ответе ниже, и следующий код, кажется, работает правильно:
%# See the answer below
[sz1,sz2] = size(Z);
sz1New = sz1*cos(t)+sz2*sin(t);
sz2New = sz2*cos(t)+sz1*sin(t);
[Xi,Yi] = meshgrid(-(sz2New-1)/2:(sz2New-1)/2,-(sz1New-1)/2:(sz1New-1)/2);
%# now all that's left is rotating Xi,Yi - I have already subtracted the center
%# My little piece of additional code
Xii = (1+sz2)/2 + ct*Xi - st*Yi;
Yii = (1+sz1)/2 + st*Xi + ct*Yi;
Zi = interp2(X, Y, Z, Xii, Yii);