6

I am creating a rotation matrix in python as follows:

import numpy as np def make_rot(angle): cost = np.cos(np.deg2rad(angle)) sint = np.sin(np.deg2rad(angle)) rot = np.array([[cost, -sint, 0], [sint, cost, 0], [0, 0, 1]]) return rot 

This is as defined in the wikipedia page here: http://en.wikipedia.org/wiki/Rotation_matrix

I run it with the angle parameter as 45 degrees and I get something like:

[[ 0.70710678 -0.70710678 0. ] [ 0.70710678 0.70710678 0. ] [ 0. 0. 1. ]] 

Now, I use the OpenCV getRotationMatrix2D API as follows:

import cv2 M = cv2.getRotationMatrix2D((0, 0), 45, 1) 

The matrix I get is the inverse of the matrix (the transpose as it is a rotation matrix). The result is as follows:

[[ 0.70710678 0.70710678 0. ] [-0.70710678 0.70710678 0. ]] 

As you can see it is the inverse. I have not found anything in the OpenCV documentation which says anything about this behaviour.

Now, I can use this matrix in OpenCV and skimage to transform an image as follows:

# openCV M = cv2.getRotationMatrix2D((0, 0), 45, 1) dst = cv2.warpAffine(image2, M, (coumns, rows)) # skimage from skimage import transform as tf tform = tf.AffineTransform(matrix=make_rot(45)) dst = tf.warp(image_2, tform) 

The surprising thing is that the result from using my matrix and OpenCV matrix is the same.

My question is why is OpenCV working with the inverse of the transformation? I am wondering if this is something they are not mentioning in the documentation or if I am using this wrong somehow.

7
  • Should depend on whether it rotates clockwise or counter-clockwise... openCV doc says it uses [cos sin; -sin cos] for ccw rotation but Im not sure whether that is right. Just try whether it is cw or ccw by warping or multiplying points; ) Commented Jan 25, 2015 at 21:25
  • 4
    Mind this part of wikipedia: "The examples in this article apply to active rotations of vectors counter-clockwise in a right-handed coordinate system by pre-multiplication. If any one of these is changed (e.g. rotating axes instead of vectors, i.e. a passive transformation), then the inverse of the example matrix should be used, which coincides precisely with its transpose." So maybe image origin (top left or bottom left e.g.) differ in sci-kit and openCV? Commented Jan 25, 2015 at 21:28
  • This must be it. I will investigate. Commented Jan 25, 2015 at 21:50
  • 1
    So it turns out that skimage warp function expects the inverse transform (from the output image to the input image). I am not sure why that is. This is not a problem for affine transformations as they are bijective. However, having the transformation used from input coordinates->output coordinates is better imo. Commented Jan 26, 2015 at 0:13
  • To prevent leaving holes in the output image, the inverse transformation should be a better choice. Commented Jan 26, 2015 at 5:18

1 Answer 1

8

I think the problem is that in a traditional right-handed coordinate system the rotation matrix looks exactly like the one you are using.

Whereas in images (and OpenCV works with images) the origin is in the top-left corner, the x-axis goes to the right (as usual), but y-axis goes down rather than up, which means that the coordinate system is left-handed and the rotation matrix is different.

Let's build the rotation matrix in this coordinate system. If we denote:

A - linear transformation (rotation in our case)

then we get

A(i) = (cos(angle), -sin(angle))

where i - is the base vector corresponding to x-axis

A(j) = (sin(angle), cos(angle))

where j- is the base vector for y-axis.

Consequently, rotation matrix looks exactly like in OpenCV:

A(i) is its first column,

A(j) is the second one.

Sign up to request clarification or add additional context in comments.

3 Comments

Is this behavior documented somewhere?
Sorry for the late response. I have no idea whether this is documented anywhere or not. To me, it is just common sense and understanding of what a classical rotation matrix is. It really worked for me: I needed the rotation matrix to cut out a slightly rotated square from an image and then to recalculate the coordinates of the cell inside this square.
@Him the behaviour in question is simply "x is to the right, and y is down, (not up)", which differs from mathematical convention in that it mirors everything, affecting rotation. Rather than adjusting the rotation matrix, I prefer to follow a convention where 'positive rotation' means 'from x towards y' (as in standard convention) and then the roate matrix looks like the standard one, but the rotations sign changes: CW is positive for the left-handed axes. Unfortunately getRotationMatrix2D does not follow this and uses CCW = postiive.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.