给定两个角点计算图像的旋转度数?

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

我正在尝试编写一个 C# 控制台应用程序,该应用程序获取其中包含文本的图像并旋转它,使文本尽可能接近水平,从而使 OCR 更加准确。

使用 AWS Rekognition 我可以获得一个带有角点的边界框,它提供了所需旋转的指南,但是我没有数学能力来计算哪种算法最有效。

例如,AWS 将提供这些相对坐标:

"X": 0.6669167280197144, "Y": 0.6940382719039917

"X": 0.759939968585968, "Y": 0.681664764881134

"X": 0.7622751593589783, "Y": 0.7211361527442932

"X": 0.6692519187927246, "Y": 0.7335096001625061

到目前为止,我已尝试使用顶部或底部 "Y" 坐标创建比率,然后将其乘以 6 或 -6。

这是我试过的代码。

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

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

这似乎应该是相当简单的触发。

给定一个点的 xy 坐标,我们可以使用Math.Atan2方法:

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

radians 设置为 0.7853981...(或 45 度)。

我们可以使用它来找到两点之间的角度,方法是找到两点之间的差异并计算角度,如上所示:

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);

(用的很简单 Point class 我就是拼凑起来的。)

这导致 1.70303529... 弧度(97.5767... 度)。遍历点列表给我们......一些奇怪的结果:

          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

遗憾的是,这毕竟不是一个简单的问题。我们可以算出任意两点之间的角度,但看起来我们并没有在这里定义一个合适的矩形。看起来它可能是一个平行四边形。我们有两对大致平行的线,但这两对线并不成直角。内角大约为 94.2 和 85.8 度。

为了修复此图像,您可能需要先旋转它,使最长的边([p0,p1][p3,p0])处于水平状态。这将是(90 - 97.576734 = -7.576734 度或 1.5707963 - 1.7030353 = -0.1322383 弧度)的旋转,最好围绕点的中心 ({X: 0.7145959, Y: 0.7075872})。然后你可以计算出偏斜值并将平行四边形固定回矩形。