tmighty
tmighty

Reputation: 11419

Calculating image rotation by 2 points

I have the following image:

enter image description here

I would like to rotate the image in such a way that the 2 points are on the same line.

The lowest points of the eyes should be on the same "level".

How could I determine by which degree I would have to rotate the image?

I have tried the atan2 function as suggested, but that wouldn't result in the desired angle. I tested it both with my rotation function as well as with Photoshop.

I got the following results:

pt1 = {X = 421 Y = 350}
pt2 = {X = 241 Y = 325}
angle = -3.0035866299322738 (calculated with the atan2 function as proposed in one answer)

It results in this rotation: enter image description here

After the rotation with the angle -3, the green line should be perfectly straight, however that's not the case, so I don't know where's the culprit here.

Perhaps my rotation code isn't correct.

Here's my rotation code:

Public Function RotateImage(ByVal uBmp As Bitmap, ByVal uAngle As Double) As Bitmap

    ' //create a New empty bitmap to hold rotated image
    Dim nBmp As Bitmap = New Bitmap(uBmp.Width, uBmp.Height)
    nBmp.SetResolution(uBmp.HorizontalResolution, uBmp.VerticalResolution)

    '//make a graphics object from the empty bitmap
    Using g As Graphics = Graphics.FromImage(nBmp)

        ' //Put the rotation point in the center of the image
        ' rotate aroung the center of the image
        g.TranslateTransform(uBmp.Width \ 2, uBmp.Height \ 2)

        'rotate
        g.RotateTransform(uAngle)

        g.TranslateTransform(-uBmp.Width \ 2, -uBmp.Height \ 2)

        ' //draw passed in image onto graphics object
        g.DrawImage(uBmp, New PointF(0, 0))
    End Using

    Return nBmp

End Function

Here is a simple check:

Using an online tool to draw an angle, I got the following image:

enter image description here

I have determined 2 points: pt1 is located at (0,0) pt2 is located at (120,33)

The online tool drew an angle of 15°.

But the atan2 function returns angle = 0.26836621090590684.

How could I get my 15° back?

Upvotes: 0

Views: 1700

Answers (1)

Rory Daulton
Rory Daulton

Reputation: 22564

If you have the coordinates of those two points, and if the aspect ratio of those coordinates is one-to-one, and if the coordinate system is defined so that moving right increases the first (x) coordinate and moving up increases the second (y) coordinate, and if the first point (x1, y1) is the left-most of those two points, most computer languages can calculate your desired angle by

angle = atan2(y2 - y1, x2 - x1)

Rotating the picture by that angle clockwise will put the two points horizontal to each other. If the returned angle is negative, change it to positive and rotate counterclockwise.

Note that a few languages swap the x and the y coordinates, and most languages will return the angle in radians. (If you need degrees, multiply the resulting radians angle by 180 then divide by pi.) If any of my stated assumptions are false, that formula would need to be adjusted accordingly. If you have more details on any of those assumptions, let me know and I can adjust the formula for you.


(Added after an attempt was made by the questioner.)

As I just emphasized in my original answer, my formula depends on multiple assumptions being true. Now that you have shown the details on your attempt I see that two of the assumptions are false.

Most important, one assumption is "moving up increases the second (y) coordinate," which is the standard for Euclidean geometry. Many graphics environments have an increasing second (y) coordinate moving down, and you example shows that is the case for you. With this assumption, change my formula to

angle = atan2(y1 - y2, x2 - x1)

Note that I swapped y1 and y2, which in effect replaces each of those with its negative.

The second assumption is "the first point (x1, y1) is the left-most of those two points." In your example the first point is the right-most point, not the left-most. You should code your routine to swap the points if the first point has a larger x-coordinate.

With those changes, your points are

pt1 = {X = 241 Y = 325}
pt2 = {X = 421 Y = 350}

and using the formula angle = atan2(y1 - y2, x2 - x1) gives the result

-0.13800602365751946

That angle is negative, so rotate your picture counterclockwise by the angle 0.13800602365751946 radians, which is 7.907162702958458 degrees.

Try that and see if it works. I do not know your language (is it VB.NET?) so I can't comment on your code or show you code for your environment. I program in Python these days.

Upvotes: 1

Related Questions