Сначала построим матрицу вращения вида
[cos(theta) -sin(theta) 0]
R = [sin(theta) cos(theta) 0]
[0 0 1]
Применение этого преобразования координат дает вам вращение вокруг начала координат.
Если вместо этого вы хотите повернуть вокруг центра изображения, вы должны сначала сместить центр изображения
к началу координат, затем примените вращение, а затем переместите все обратно. Вы можете сделать это с помощью
Матрица перевода:
[1 0 -image_width/2]
T = [0 1 -image_height/2]
[0 0 1]
Матрица преобразования для перевода, вращения и обратного перевода становится:
H = inv(T) * R * T
Мне нужно немного подумать о том, как связать наклонную матрицу с трехмерным преобразованием. Я ожидаю, что самый простой способ - установить матрицу 4D-преобразования, а затем спроецировать ее обратно на 2D-однородные координаты. Но пока общий вид косой матрицы:
[x_scale 0 0]
S = [0 y_scale 0]
[x_skew y_skew 1]
Значения x_skew
и y_skew
обычно крошечные (1e-3 или менее).
Вот код:
from skimage import data, transform
import numpy as np
import matplotlib.pyplot as plt
img = data.camera()
theta = np.deg2rad(10)
tx = 0
ty = 0
S, C = np.sin(theta), np.cos(theta)
# Rotation matrix, angle theta, translation tx, ty
H = np.array([[C, -S, tx],
[S, C, ty],
[0, 0, 1]])
# Translation matrix to shift the image center to the origin
r, c = img.shape
T = np.array([[1, 0, -c / 2.],
[0, 1, -r / 2.],
[0, 0, 1]])
# Skew, for perspective
S = np.array([[1, 0, 0],
[0, 1.3, 0],
[0, 1e-3, 1]])
img_rot = transform.homography(img, H)
img_rot_center_skew = transform.homography(img, S.dot(np.linalg.inv(T).dot(H).dot(T)))
f, (ax0, ax1, ax2) = plt.subplots(1, 3)
ax0.imshow(img, cmap=plt.cm.gray, interpolation='nearest')
ax1.imshow(img_rot, cmap=plt.cm.gray, interpolation='nearest')
ax2.imshow(img_rot_center_skew, cmap=plt.cm.gray, interpolation='nearest')
plt.show()
И вывод: