为了验证两视图SFM方法估计相机姿态[R|t]的结果,我使用了我用于校准的棋盘模式,特别是OpenCV中的"calibrateCamera"函数返回每个模式的旋转和平移向量。因此,可以很容易地计算前两种模式之间的相对姿态。
然而,我没有得到正确的相机姿势,我一直在努力解决这个问题,但没有成功。
我真的很感谢你为解决我的问题所做的贡献。
我的代码描述:
- 不侵权的图像
- 在两个图像中查找棋盘角
- 匹配点(通过并排绘制两个图像和线条进行验证)
- 估计基本矩阵(已验证:x'T*F*x=0)
- 基本矩阵(E)=KT*F*K(已验证:X’T*E*X=0)
- E的SVD=U*S*VT
-
R=U*W*VT或U*WT*VT,使得WT=[0,-1,0;1,0,0;0,0,1]
FundMat, mask = cv2.findFundamentalMat(imgpoints1, imgpoints2, cv2.FM_LMEDS) # is the fundamental matrix is really a fundamental Matrix. xFx'=0 ?? # verfication of fundamental matrix for i in range(len(imgpoints1)): X = np.array([imgpoints1[i][0],imgpoints1[i][1],1]) X_prime = np.array([imgpoints2[i][0],imgpoints2[i][1],1]) err = np.dot(np.dot(X_prime.T,FundMat),X) if mask[i] == True: print(err) # E = [t]R = (K_-T)_-1 * F * K = K_T*F*K term1 = np.dot(np.transpose(mtx), FundMat) # newcameramtx , mtx E = np.dot(term1, mtx) # newcameramtx , mtx # verfication of Essential matrix for i in range(len(imgpoints1)): X_norm = np.dot(np.linalg.inv(mtx), np.array([imgpoints1[i][0],imgpoints1[i][1],1]).T) X_prime_norm = np.dot(np.linalg.inv(mtx), np.array([imgpoints2[i][0],imgpoints2[i][1],1]).T) err_Ess = np.dot(np.dot(X_prime_norm.T,E),X_norm) if mask[i] == True: print(err_Ess) # SVD of E U,S,V_T = np.linalg.svd(E) # computation of Rotation and Translation without enforcement W = np.array([[0,-1,0],[1,0,0],[0,0,1]]) Rot1 = np.dot(np.dot(U, W), V_T) Rot2 = np.dot(np.dot(U, W.T), V_T)
您的问题是使用棋盘中的点:您无法从共面点估计基本矩阵。解决此问题的一种方法是使用通用方法(如SIFT或SURF)匹配场景点。另一种方法是使用5点算法直接估计本质矩阵,因为本质矩阵可以从共面点计算。
此外,请记住,您只能根据Essential矩阵按比例计算相机姿势。换句话说,你的翻译最终将成为一个单位向量。计算比例因子以获得翻译的实际长度的一种方法是使用棋盘。