我正在尝试获取一个单应性矩阵来描述从一个图像到另一个图像的转换。我尝试通过使用特征分解并取最小特征向量来做到这一点。显然,我必须将其重塑为 3x3 矩阵,但 numpy linalg 函数返回形状为 (9,9) 的特征值。 (尝试从 4 个点计算)
A 是一个 8x9 矩阵。 pts1 和 pts2 分别是源图像和目标图像中的 4 个点的数组。
代码从对称矩阵开始进行单应性计算(大小8x9)
A_t = A.transpose()
sym_mat = np.dot(A_t,A)
eig_val,eig_vec = np.linalg.eig(sym_mat)
#sort according to value
idx = np.argsort(eig_val)
eig_val = eig_val[idx]
eig_vec = eig_vec[:,idx]
# Return the eigenvector corresponding to the smallest eigenvalue, reshaped
# as a 3x3 matrix.
H = np.reshape(smallest,(3,3))
`
请参阅 this 作为具体示例,了解如何从一组 4 个
A
和相应的 src
点计算单应性矩阵 dst
(9x9)。继续相同的示例,但删除矩阵的最后一行 A
,因此维度现在变为 8x9,
A = A[:-1,:]
print(A.shape)
# (8, 9)
sym_mat = np.dot(A.T,A)
eig_val, eig_vec = np.linalg.eig(sym_mat)
# sort eigenvalues and choose the index corresponding to the smallest eigenvalue
idx = np.argsort(eig_val)[0] # here is where the above code had mistake
eig_val = eig_val[idx]
eig_vec = eig_vec[:,idx]
# Return the eigenvector corresponding to the smallest eigenvalue, reshaped as a 3x3 matrix.
H = np.reshape(eig_vec,(3,3))
H = H / H[2,2] # normalize, assuming the last entry of the matrix to be 1
print(H)
# [[ 1.68470998e+00 -9.45348887e-02 1.45839239e+01]
# [ 5.00688641e-02 -9.70746853e-01 2.42751631e+02]
# [ 2.64367645e-03 2.77831031e-04 1.00000000e+00]]
验证估计的单应矩阵是否与使用
opencv-python
计算的单应矩阵匹配:
import cv2
h, _ = cv2.findHomography(src, dst)
print(h)
# [[ 1.68471000e+00 -9.45348782e-02 1.45839218e+01]
# [ 5.00688662e-02 -9.70746856e-01 2.42751631e+02]
# [ 2.64367648e-03 2.77831077e-04 1.00000000e+00]]
np.allclose(H, h)
# True