计算给定原始点和变换点的轴的旋转和平移

问题描述

根据转换完成前和转换完成后的点列表,我们如何推导出原点旋转和轴移动的角度。

示例:

改造前 - [(-3173.24,1503.76),(-3173.24,1599.98),(-2921.24,1941.7),(-2777.24,(-2969.24,1905.7),(-3017.24,(-3065.24,(-3161.24,2013.6),(-3179.24,2049.6),(-2759.24,1803.81),(-3113.24,1839.81),(-2789.24,1623.98),1527.76),(-2760.86,1737.92)]

改造后 - [(52.12,146.39),(52.12,242.61),(592.12,584.33),(448.12,(256.12,548.33),(640.12,(688.12,(160.12,(64.12,656.22),(46.12,692.22),(466.12,(208.12,446.44),(112.12,482.44),(436.12,266.61),170.39),(464.5,380.54)]

我们如何生成这些点之间的相关性,以便给定一个较旧的点(x,y),我们可以找到派生点(x',y')

产地详情未知。我们使用的是具有 x 和 y 轴的笛卡尔坐标系。

解决方法

您正在寻找一个 2x2 的旋转矩阵 M 和一个 2x1 的平移向量 T,例如:

(x',y') = M.(x,y) + B 

对于您的所有积分。

假设 M 是以下矩阵:

( a b )
( c d )

T 以下向量:

(Tx,Ty)

转换前 P = (Px,Py) 和转换后 P' = (P'x,P'y) 的每个点都为您提供 2 个方程:

P'x = a.Px + b.Py + Tx
P'y = c.Px + d.Py + Ty
  • 其中 a,b,c,d,Tx,Ty 是未知元素。

  • 收集所有点给出的所有方程,您可以使用优化算法(如 Levenberg Marquart 或 Gradient Descent)找到那些未知元素...

  • 请注意,您有 6 个未知数,因此您至少需要 3 个点,这将为您提供 6 个方程来解决此问题。 (如果你喜欢笔和纸,你可以手动解决这个问题:P)

一旦你解决了方程组,你就可以得到旋转角 theta,因为矩阵 M 是由以下定义的旋转矩阵:

( cos(theta) -sin(theta) )
( sin(theta)  cos(theta) )

注意1:请注意,在一般情况下,“Rotation THEN Translation”并不等同于“Translation THEN Rotation”,因为如果您之前旋转,您将不会在相同的方向;-)

  • 我上面提到的方程对应于“旋转然后平移”。

注意 2:我的回答假设变换实际上只是旋转和平移,但如果您不是 100% 确定是这种情况,则变换可以是仿射变换 (P' = MP + T 与 M 不一定是旋转矩阵)甚至非线性变换(在这种情况下,它不能用矩阵表示,我会使用 2D 模型,如 2D 多边形或类似的东西:>

f(x,y) = a.x² + b.y² + c.xy + dx + ey + f 并尝试使用数值方法找到不那么直的 a,e,f)前进。

,

新编辑。

import numpy as np
import matplotlib.pyplot as plt

x = np.array([(-3173.24,1503.76),(-3173.24,1599.98),(-2921.24,1941.7),(-2777.24,(-2969.24,1905.7),(-3017.24,(-3065.24,(-3161.24,2013.6),(-3179.24,2049.6),(-2759.24,1803.81),(-3113.24,1839.81),(-2789.24,1623.98),1527.76),(-2760.86,1737.92)])
y = np.array([(52.12,146.39),(52.12,242.61),(592.12,584.33),(448.12,(256.12,548.33),(640.12,(688.12,(160.12,(64.12,656.22),(46.12,692.22),(466.12,(208.12,446.44),(112.12,482.44),(436.12,266.61),170.39),(464.5,380.54)])

def centroid(s):
    # Centroid of a set s
    c = np.sum(s,axis=0) / len(s)
    return c[np.newaxis,:]

def rotation_translation(x,y):
    # Centroids of each set
    xG = centroid(x)
    yG = centroid(y)
    # Shape of each set
    Mx = (x-xG).T.dot(x-xG)
    My = (y-yG).T.dot(y-yG)
    # Eigendecomposition
    ex,Ux = np.linalg.eig(Mx)
    ey,Uy = np.linalg.eig(My)
    # rotation matrix
    U = Uy.dot(Ux.T)
    # translation vector
    t = yG - xG.dot(U.T)
    return U,t,xG,yG

def matrix_vector(x,y):
    # Centroids of each set
    xG = centroid(x)
    yG = centroid(y)
    # Shape of each set
    Mx = (x-xG).T.dot(x-xG)
    My = (y-yG).T.dot(y-yG)
    # Eigendecomposition: eigeinvalues,rotation matrices
    ex,Uy = np.linalg.eig(My)
    ex = np.sqrt(ex)
    ey = np.sqrt(ey)
    ex = ex[:,np.newaxis]
    ey = ey[:,np.newaxis]
    # linear matrix,rotation-scaling-rotation
    U = (ey/ex) * Ux.T
    U = Uy.dot(U)
    # trasnlation vector
    t = yG - xG.dot(U.T)
    return U,yG

def Transform(v,mtrx_vctr):
    return v.dot(mtrx_vctr[0].T) + mtrx_vctr[1] 


U,yG = rotation_translation(x,y)
z_rot = Transform(x,(U,t))

U,yG = matrix_vector(x,y)
z_aff = Transform(x,t))


plt.plot(x[:,0],x[:,1],'go')
plt.plot(y[:,y[:,'bo')
plt.plot(z_rot[:,z_rot[:,'ro')
plt.plot(z_aff[:,z_aff[:,'yo')
plt.show()

初始答案。

这两个三角形不全等,即没有平移和旋转可以将 x 转换为 y。存在仿射变换。

import numpy as np
import matplotlib.pyplot as plt

def Affine_map(before,after):
    
    b0 = before - before[0,:][np.newaxis,:]
    b0 = b0[1:3,:]
    
    a0 = after - after[0,:]
    a0 = a0[1:3,:]
    
    A = np.linalg.inv(b0).dot(a0) 
    t = after[0,:] - before[0,:].dot(A)
    return A,t
    

x = np.array([[-4648,2144],[-4311,2155],[-3589,357]])
y = np.array([[591,157],[1073,168],[1596,-223]])

A,t = Affine_map(x,y)

# map is applied as y = x.dot(A) + t

print('')
print('Matrix of affine triansformation:')
print(A)
print('')
print('Vector of translation:')
print(t)
print('')
print('Check that y = Ax + t ')
print( y - x.dot(A) - t)
print('')

plt.plot(x[:,'ro')
plt.plot(y[:,'bo')
plt.show()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...