如何在缩放和旋转后重新计算点的cooredinates?

S.E*_*.EB 0 python image-processing draw computer-vision cv2

我在图像中有6个点的坐标

(170.01954650878906, 216.98866271972656)
(201.3812255859375, 109.42137145996094)
(115.70114135742188, 210.4272918701172)
(45.42426300048828, 97.89037322998047)
(167.0367889404297, 208.9329833984375)
(70.13690185546875, 140.90538024902344)
Run Code Online (Sandbox Code Playgroud)

我有一点作为中心[89.2458, 121.0896].我试图用4个旋转度(从0,90,-90,180)和6个比例因子(0.5,0.75,1,1.10,1.25,1.35,1.5)重新计算python中点的位置.
我的问题是如何旋转和缩放相对于中心点的上述点并获得这6个点的新坐标?

非常感谢您的帮助.

小智 7

数学

数学方法是代表这个数据从中心到图像点的载体,这些载体转化到原点,应用转型和重新定位他们周围的中心点.让我们来看看它的工作原理.

表示为矢量

我们可以在网格中显示这些向量,这将产生以下图像

将给定点表示为围绕中心点的向量

此图像提供了查看这些点的好方法,因此我们可以看到我们的行为以可视方式发生.中心点在所有箭头的开头标有一个点,每个箭头的末尾是问题中提供的一个点的位置.

矢量可以看作是点坐标值的列表

my_vector = [point[0], point[1]]
Run Code Online (Sandbox Code Playgroud)

可以是python中矢量的表示,它只保存一个点的坐标,因此问题中的格式可以按原样使用!请注意,我将在整个答案中使用0x坐标和1y坐标的位置.

我只添加了这种表示作为视觉辅助,我们可以将任意两个点视为矢量,不需要计算,这只是查看这些点的不同方式.

翻译到原点

第一次计算发生在这里.我们需要将所有这些向量转换为原点.例如,我们可以通过从所有其他点减去中心点的位置来轻松完成此操作(可以在一个简单的循环中完成):

point_origin_x = point[0] - center_point[0] # Xvalue point - Xvalue center
point_origin_y = point[1] - center_point[1] # Yvalue point - Yvalue center
Run Code Online (Sandbox Code Playgroud)

现在可以围绕原点旋转结果点并相对于原点进行缩放.新点(作为向量)看起来像这样:

与上面相同的向量,但在原点周围翻译

在这张图片中,我故意保持比例不变,因此很明显这些是完全相同的矢量(箭头),在大小和方向上,只是转移到(0,0)左右.

为什么起源

那么为什么要将这些点转换为原点呢?好吧,旋转和缩放动作很容易(在数学上)围绕原点进行,而不是在其他点周围容易.

此外,从现在开始,我将只在这些图像中包含第1,第2和第4点以节省一些空间.

缩放原点

缩放操作在原点周围非常容易.只需将点的坐标乘以缩放系数:

scaled_point_x = point[0] * scaling_factor
scaled_point_y = point[1] * scaling_factor
Run Code Online (Sandbox Code Playgroud)

以可视方式,看起来像这样(全部缩放1.5):

缩放矢量和原始矢量

其中蓝色箭头是原始矢量,红色箭头是缩放矢量.

旋转

现在轮换.这有点困难,因为旋转通常用与该向量的矩阵乘法来描述.

要乘以的矩阵如下

旋转矩阵

(来自维基百科:旋转矩阵)

因此,如果V是向量而不是我们需要执行V_r = R(t) * V以获得旋转向量V_r.这个旋转总是逆时针旋转!为了顺时针旋转,我们只需要使用R(-t).

因为在问题中只需要90°的倍数,矩阵变得几乎无足轻重.对于逆时针旋转90°,矩阵为:

旋转矩阵逆时针旋转90°

这基本上是代码:

rotated_point_x = -point[1]    # new x is negative of old y
rotated_point_y = point[0]     # new y is old x
Run Code Online (Sandbox Code Playgroud)

同样,这可以通过视觉方式很好地显示:

逆时针旋转90°

在哪里我匹配了矢量的颜色.

顺时针旋转90°

rotated_counter_point_x = point[1]    # x is old y
rotated_counter_point_y = -point[0]   # y is negative of old x
Run Code Online (Sandbox Code Playgroud)

180°的旋转将采用负坐标,或者您可以按-1的比例缩放,这基本上是相同的.

作为这些操作的最后一点,我可以补充说,您可以按顺序缩放和/或旋转,以获得所需的结果.

转换回中心点

在缩放动作和/或旋转之后,剩下的唯一事情是将向量重新转换到中心点.

retranslated_point_x = new_point[0] + center_point_x
retranslated_point_y = new_point[1] + center_point_y
Run Code Online (Sandbox Code Playgroud)

一切都完成了.

回顾一下

所以回顾这篇长篇文章:

  1. 从图像点的坐标中减去中心点的坐标
  2. 通过简单地乘以坐标来缩放因子
  3. 使用矩阵乘法的思想来考虑旋转(你可以在Google或维基百科上轻松找到这些东西).
  4. 将中心点的坐标添加到图像点的新坐标

我现在意识到我可以给出这个回顾,但是现在这篇文章中至少有一些视觉辅助和一些轻微的数学背景,这也很好.我真的相信从数学的角度来看这些问题,数学描述可以帮助很多.