投影空间坐标和线的齐次变换
一、基本原理公式
1、齐次点在线上,当且仅当: x T l = l T x = 0 x^{T}l=l^{T}x=0 xTl=lTx=0
2、齐次点和线在应用了变换矩阵H后,新的点 x n e w x_{new} xnew 依然在新的线 l n e w l_{new} lnew 上:
l n e w = H − T l o l d l_{new} = H^{-T}l_{old} lnew=H−Tlold
x n e w = H x o l d x_{new} = Hx_{old} xnew=Hxold
x n e w T l n e w = l n e w T x n e w = 0 x_{new}^{T}l_{new}=l_{new}^{T}x_{new}=0 xnewTlnew=lnewTxnew=0
二、代码实现
1、证明共线点 x 1 , x 2 , x 3 x_{1},x_{2}, x_{3} x1,x2,x3 在线 l l l 上
三个共线点:
x
3
=
[
1
3
1
]
,
x
2
=
[
2
56
11
1
]
,
x
3
=
[
3
79
11
1
]
x_{3} = \begin{bmatrix} 1 \\ 3 \\1 \end{bmatrix}, x_{2} = \begin{bmatrix} 2 \\ \frac{56}{11} \\1 \end{bmatrix}, x_{3} = \begin{bmatrix} 3 \\ \frac{79}{11} \\1 \end{bmatrix}
x3=⎣⎡131⎦⎤,x2=⎣⎡211561⎦⎤,x3=⎣⎡311791⎦⎤
在线上 2.3 x − 1.1 y + 1 = 0 2.3x-1.1y+1=0 2.3x−1.1y+1=0
x = sympy.Symbol('x')
y = sympy.Symbol('y')
I = sympy.Matrix([[2.3], [-1.1], [1]])
x = sympy.Matrix([[x], [y], [1]])
I.T*x
得线 [ 2.3 x − 1.1 y + 1 ] [2.3x−1.1y+1] [2.3x−1.1y+1]
I = np.array(I)
p = np.array([[1], [3], [1]])
q = np.array([[2], [56/11], [1]])
r = np.array([[3], [79/11], [1]])
由此得:
x
1
:
2.3
×
1
−
1.1
×
3
+
1
=
0
x_{1}: 2.3 \times 1 - 1.1 \times 3+1=0
x1:2.3×1−1.1×3+1=0
x 2 : 2.3 × 2 − 1.1 × 56 11 + 1 = 0 x_{2}: 2.3 \times 2 - 1.1 \times \frac{56}{11}+1=0 x2:2.3×2−1.1×1156+1=0
x 3 : 2.3 × 3 − 1.1 × 79 11 + 1 = 0 x_{3}: 2.3 \times 3 - 1.1 \times \frac{79}{11}+1=0 x3:2.3×3−1.1×1179+1=0
ax = plt.figure().add_subplot(projection='3d')
linex = np.linspace(-5, 5, 100)
liney = (2.3*linex+1)/1.1
ax.plot(linex, liney, zs=0, zdir='z', label='line=[2.3,-1.1,1]')
xpoints = np.array([1, 2, 3])
ypoints = np.array([3, 56/11, 79/11])
#zpoints = np.array([1, 1, 1])
ax.scatter(xpoints, ypoints, zs=0, zdir='z', c=['r', 'g', 'b'], label='points')
ax.legend()
ax.set_xlim(-5, 5)
ax.set_ylim(-5, 5)
ax.set_zlim(-3, 3)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
2、证明 x n e w x_{new} xnew 在线 l n e w l_{new} lnew 上
假设变换矩阵H为:
H = [ 0.02 0.35 0.02 0.05 0.16 0.22 0.41 0.48 0.19 ] H = \begin{bmatrix} 0.02 & 0.35 & 0.02 \\ 0.05 & 0.16 & 0.22 \\ 0.41 & 0.48 & 0.19 \end{bmatrix} H=⎣⎡0.020.050.410.350.160.480.020.220.19⎦⎤
计算
l
n
e
w
=
H
−
T
l
o
l
d
l_{new} = H^{-T}l_{old}
lnew=H−Tlold
和
x n e w = H x o l d x_{new} = Hx_{old} xnew=Hxold
lold = np.array([[2.3], [-1.1], [1]])
xold = np.array([[1, 2, 3], [3, 56/11, 79/11], [1, 1, 1]])
H = np.array([[0.02, 0.35, 0.02], [0.05, 0.16, 0.22], [0.41, 0.48, 0.19]])
lnew = np.matmul(np.linalg.inv(H).T, lold)
lnew = lnew / lnew[2]
xnew = np.matmul(H, xold)
xnew = xnew / xnew[2]
print('New line: \n', lnew, '\n\n New Points: \n', xnew)
得:
ax = plt.figure().add_subplot(projection='3d')
linex = np.linspace(0, 1, 100)
liney = (-lnew[0]*linex-lnew[2])/lnew[1]
ax.plot(linex, liney, zs=0, zdir='z', label='New line')
xpoints = np.array([xnew[0][0], xnew[0][1], xnew[0][2]])
ypoints = np.array([xnew[1][0], xnew[1][1], xnew[1][2]])
ax.scatter(xpoints, ypoints, zs=0, zdir='z', c=['r', 'g', 'y'], label='points')
ax.legend()
ax.set_xlim(0.5, 0.6)
ax.set_ylim(0.25, 0.35)
ax.set_zlim(0, 1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()