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

C# 计算给定两个角点的图像旋转度?,c#,algebra,C#,Algebra,我正在尝试编写一个C#console应用程序,该应用程序可以获取包含文本的图像,并旋转图像,使文本尽可能接近水平,从而使OCR更加准确 使用AWS Rekognion,我可以得到一个带有角点的边界框,它为所需的旋转提供了指导,但是我没有数学能力计算出哪种算法最有效 例如,AWS将提供以下相对坐标: "X": 0.6669167280197144, "Y": 0.6940382719039917 "X": 0.759939968585968, "Y": 0.681664764881134 "X

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

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

例如,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);


这看起来应该是相当简单的trig

给定一个点的
x
y
坐标,我们可以使用
Math.Atan2
方法从“向上”向量(
{x:0,y:1}
)顺时针获得该点的角度(弧度):

double x = 1;
double y = 1;
double radians = Math.Atan2(x, y);
弧度
设置为
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);
(使用一个非常简单的
类,我刚刚拼凑在一起。)

这将导致
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}
)。然后你可以计算出倾斜值并将平行四边形固定回一个矩形。

这看起来应该是一个相当简单的三角形

给定一个点的
x
y
坐标,我们可以使用
Math.Atan2
方法从“向上”向量(
{x:0,y:1}
)顺时针获得该点的角度(弧度):

double x = 1;
double y = 1;
double radians = Math.Atan2(x, y);
弧度
设置为
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);
(使用一个非常简单的
类,我刚刚拼凑在一起。)

这将导致
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}
)。然后你可以计算出倾斜值,然后将平行四边形固定回一个矩形。

你在哪里得出乘数-6、6或10?可以通过拾取任何边并使用基本三角来计算必要的旋转角度。在纸上画出一个旋转矩形,画出正确的旋转角度,并考虑正弦和COS的平均值。计算直线的近似宽度和高度。一个简单的公式,
w=length(p1+p3-p2-p4)/2
h=length(p1+p2-p3-p4)/2
,我可能错过了顺序,其想法是计算连接四边形相对中点的线段长度。构造仿射变换矩阵,将输入的四边形映射到该尺寸的轴对齐矩形中。使用该矩阵变换图像。与仅仅旋转不同,这还应该补偿倾斜或透视扭曲,这两种情况在人们使用智能手机而不是扫描仪时都会发生。谢谢@EricJ。把它写在纸上很有帮助。TAN(Opp/Adj)给出了边界框顶部的角度,但是由于图像是围绕图像的中点旋转的,而不是在计算角度的位置,因此该值不正确。谢谢@Soonts。你的解决方案听起来正是我需要的,但我不太明白你的答案。你能为像我这样的数学高手提供更多的细节吗?你在哪里提出你的乘数-6,6,或10?可以通过拾取任何边并使用基本三角来计算必要的旋转角度。在纸上画出一个旋转矩形,画出正确的旋转角度,并考虑正弦和COS的平均值。计算直线的近似宽度和高度。一个简单的公式,
w=length(p1+p3-p2-p4)/2
h=length(p1+p2-p3-p4)/2
,我可能错过了顺序,其想法是计算连接四边形相对中点的线段长度。构造仿射变换矩阵,将输入的四边形映射到该尺寸的轴对齐矩形中。使用该矩阵变换图像。与仅仅旋转不同,这还应该补偿倾斜或透视失真,这两种情况都是在人们使用智能手机而不是扫描仪时发生的