java
sql
css
c
ajax
mysql
database
xcode
android
ruby-on-rails
regex
objective-c
flash
html5
json
oracle
tsql
apache
php5
dom
First, build the rotation matrix, of the form
[cos(theta) -sin(theta) 0] R = [sin(theta) cos(theta) 0] [0 0 1]
Applying this coordinate transform gives you a rotation around the origin.
If, instead, you want to rotate around the image center, you have to first shift the image center to the origin, then apply the rotation, and then shift everything back. You can do so using a translation matrix:
[1 0 -image_width/2] T = [0 1 -image_height/2] [0 0 1]
The transformation matrix for translation, rotation, and inverse translation then becomes:
H = inv(T) * R * T
I'll have to think a bit about how to relate the skew matrix to the 3D transformation. I expect the easiest route is to set up a 4D transformation matrix, and then to project that back to 2D homogeneous coordinates. But for now, the general form of the skew matrix:
[x_scale 0 0] S = [0 y_scale 0] [x_skew y_skew 1]
The x_skew and y_skew values are typically tiny (1e-3 or less).
x_skew
y_skew
Here's the code:
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()
And the output:
I do not get the way you build your rotation matrix. It seems rather complicated to me. Usually, it would be built by constructing a zero matrix, putting 1 on unneeded axes, and the common sin, cos, -cos, sin into the two used dimensions. Then multiplying all these together.
1
sin
cos
-cos
Where did you get that np.eye(3) + np.sin(angle) * skew(axis) + (1 - np.cos(angle)) * skew(axis).dot(skew(axis)) construct from?
np.eye(3) + np.sin(angle) * skew(axis) + (1 - np.cos(angle)) * skew(axis).dot(skew(axis))
Try building the projection matrix from basic building blocks. Constructing a rotation matrix is fairly easy, and "rotationmatrix dot skewmatrix" should work.
You might need to pay attention to the rotation center though. Your image probably is placed at a virtual position of 1 on the z axis, so by rotating on x or y, it moves around a bit. So you'd need to use a translation so z becomes 0, then rotate, then translate back. (Translation matrixes in affine coordinates are pretty simple, too. See wikipedia: https://en.wikipedia.org/wiki/Transformation_matrix )