简体   繁体   中英

Calculate degree of rotation of an image given two corner points?

I'm trying to write a C# console application that takes an image with text in it and rotate it so the text is as close to horizontal as possible so that OCR is more accurate.

Using AWS Rekognition I can get a bounding box with corner points which provide a guide as to the rotation needed however I don't have the maths ability to work out what sort of algorithm would work best.

As an example, AWS will provide these relative coordinates:

"X": 0.6669167280197144, "Y": 0.6940382719039917

"X": 0.759939968585968, "Y": 0.681664764881134

"X": 0.7622751593589783, "Y": 0.7211361527442932

"X": 0.6692519187927246, "Y": 0.7335096001625061

So far, I've tried using either the top or bottom "Y" coordinates to create a ratio and then multiplying that by either 6 or -6.

This is the code I've tried.

var rotationAngle = (int)Math.Round(coordRatio * 6 * rotationDirection);

OR

var rotationAngle = Math.Sin(Math.Cos(coordRatio * Math.PI)) * 10 * rotationDirection;

This seems like it should be reasonably simple trig.

Given the x and y coordinates of a point we can get the angle of that point in radians clockwise from the 'up' vector ( {x:0, y:1} ) using the Math.Atan2 method:

double x = 1;
double y = 1;
double radians = Math.Atan2(x, y);

radians is set to 0.7853981... (or 45 degrees).

We can use this to find the angle between two points by finding the different between the points and calculate the angle as above:

Point p1 = new Point(0.6669167280197144d, 0.6940382719039917d);
Point p2 = new Point(0.759939968585968d, 0.681664764881134);
Point difference = p2 - p1;
double radians = Math.Atan2(difference.X, difference.Y);

(Using a very simple Point class I just threw together.)

This results in 1.70303529... radians ( 97.5767... degrees). Walking the list of points gives us... some strange results:

          Radians     Degrees
-------------------------------
p1 - p0   1.7030353   97.576734
p2 - p1   0.0590928   3.3857640
p3 - p2  -1.4385580  -82.423302
p0 - p3  -3.0824998  -176.61423

Sadly it doesn't look like this is a simple problem after all. We can figure out the angles between any two points, but it doesn't look like we've got a proper rectangle defined here. It looks like it might be a parallelogram. We have two pairs of roughly parallel lines, but those pairs are not at right angles. Internal angles are approximately 94.2 and 85.8 degrees.

In order to fix this image you'll probably want to start by rotating it so that the longest sides ( [p0,p1] and [p3,p0] ) are horizontal. This would be a rotation of ( 90 - 97.576734 = -7.576734 degrees, or 1.5707963 - 1.7030353 = -0.1322383 radians), preferably around the center of the points ( {X: 0.7145959, Y: 0.7075872} ). Then you can work out the skew value and fix the parallelogram back into a rectangle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM