给定两个角点计算图像的旋转度数?
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;
这似乎应该是相当简单的触发。
给定一个点的 x
和 y
坐标,我们可以使用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}
)。然后你可以计算出偏斜值并将平行四边形固定回矩形。
我正在尝试编写一个 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;
这似乎应该是相当简单的触发。
给定一个点的 x
和 y
坐标,我们可以使用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}
)。然后你可以计算出偏斜值并将平行四边形固定回矩形。