Search code examples
pythonopencvimage-rotationaffinetransformtransformation-matrix

Calculating center of rotation from Affine2D transformation matrix


I have two 2D images, where the second one undergoes translation and rotation, resulting the coordinates (xn, yn) in the first picture to move to (xn', yn').

I have no problem obtaining the rotation angle, translation and scaling factor from the translation matrix described below. The rotation center however is not at the center of the image, and it is quite far from the images position. I might do a bad job on trying to draw the problem, but it looks like the picture attached:

The attached picture

I am trying to find the center of rotation from the transformation matrix obtained from cv2.estimateAffinePartial2D, which is↓

s*cos(theta), -s*sin(theta), Tx
s*sin(theta),  s*cos(theta), Ty

where s is scaling factor, theta is the rotation angle, Tx and Ty is translation on x axis and y axis respectively.

I tried calculating it by solving the equation below↓

Tx = (1-a)*Cx - b*Cy
Ty = b*Cx + (1-a)*Cy

where Cx and Cy is the center of the rotation and...

a = s*cos(theta)
b = s*sin(theta)

but I am not sure if this is correct.

Am I doing this wrong?

Equation to calculate the center of the rotation from the transformation matrix I give above.

EDIT: the (xn,yn) and (xn', yn') is known sets of coordinates, that are random points inside the small blue rectangle, not necessarily the center. I am sorry for the lack of explanation. They are like [[x1,y1],[x2,y2]...[xn.yn]], and similar points that have been translated and rotated to [[x1',y1'],[x2',y2']...[xn',yn']].


Solution

  • Affine Transformation is

    x' = (s * R) * x + T

    Also, if rotation center is C = (Cx,Cy), this transformation will be written as

    x' = (s * R) * ( x - C ) + C

    So, you can solve C from First_Equation = Second_Equation.
    This becomes to

    Tx = (1-a)*Cx - b*Cy
    Ty = - b*Cx + (1-a)*Cy
    

    (with your definition of a and b)

    Different point is sign of -b * Cx part only.

    You can solve (Cx,Cy) from this simultaneous equations directly. However, it seems that you should take care about that 1-a and b can be zero (for some theta values).


    (Edit)
    I written above may be wrong:

    After that, I re-checked as:

    The Frist_Equation = Second_Equation is

    (s * R) * x + T = (s * R) * x + (s * R) * ( - C ) + C

    deleting the term { ( s * R ) * x } from both side, it becomes

    T = ( s * R ) * ( - C ) + C

    With definition of a and b, this is

    [Tx] = [ a -b ][ -Cx ] + [ Cx ]
    [Ty]   [ b  a ][ -Cy ]   [ Cy ]
    

    So, finally, it becomes below, and I found my mistake.

    Tx = (1-a)*Cx + b*Cy  // <-- Here, sign of b*Cy is different from I written above
    Ty = - b*Cx + (1-a)*Cy