【问题标题】:Sfm, reconstruction from stereo imageSfm,从立体图像重建
【发布时间】:2019-02-10 20:09:03
【问题描述】:

我需要你的帮助。 我必须从立体图像重建 3D 空间中的标记。就我而言,我想使用未校准的方法重建标记。

我现在拍了 2 张照片并手动在标记上签名。

import cv2
import numpy as np
from matplotlib import pyplot as plt
from scipy import linalg


img1 =  cv2.imread('3.jpg',0)


img2 = cv2.imread('4.jpg',0)


pts1 = np.array([(1599.6711229946527, 1904.8048128342245), (1562.131016042781, 1734.4304812834225), (1495.7139037433158, 1295.5), 
     (2373.5748663101604, 1604.4839572192514), (2362.0240641711234, 2031.8636363636363), (2359.136363636364, 2199.3502673796793), 
     (2656.5695187165775, 1653.5748663101604), (2676.7834224598937, 1506.302139037433), (2740.312834224599, 1026.9438502673797), 
     (1957.745989304813, 807.4786096256685)],dtype='float64')

pts2 = np.array([(1579.457219251337, 1899.0294117647059), (1539.0294117647059, 1737.3181818181818),
     (1472.612299465241, 1307.0508021390374), (2315.8208556149734, 1633.3609625668448),
     (2298.4946524064176, 2054.9652406417113), (2301.3823529411766, 2190.687165775401), 
     (2630.5802139037432, 1670.9010695187167), (2642.131016042781, 1538.066844919786),
     (2711.4358288770054, 1076.0347593582887), (1949.0828877005351, 842.1310160427806)],dtype='float64')

随后我找到了基本矩阵

F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_7POINT)

并从 cv2.computeCorrespondEpilines 打印结果

link

它似乎运作良好!

我有相机矩阵,之前用棋盘校准过,按照opencv网站上的教程进行

mtx=np.array([[3.19134206e+03, 0.00000000e+00, 2.01707613e+03],
       [0.00000000e+00, 3.18501724e+03, 1.54542273e+03],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])

按照 Hartley 和 Zisserman 书中的内容提取基本矩阵

E = K.t() * F * K

E = mtx.T * F * mtx

我分解了这个矩阵来找到旋转和平移矩阵

R1, R2, T = cv2.decomposeEssentialMat(E)
kr= np.dot(mtx,R1)
kt= np.dot(mtx,T)
projction2=np.hstack((kr,kt))
projction1 = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])

获取投影矩阵。 P1 是第一个矩阵,在上面的书中总是描述为P1 = [I | 0] 第二个矩阵是P2 = K [ R | t ]

现在我使用以下代码返回到点的三角剖分

points4D = cv2.triangulatePoints(projction1, projction2, pts1.T, pts2.T)

我将齐次坐标转换为笛卡尔坐标,结果是这样的:

coordinate_eucl= cv2.convertPointsFromHomogeneous(points4D.T)

coordinate_eucl=coordinate_eucl.reshape(-1,3)
x,y,z=coordinate_eucl.T

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c='r', marker='o')
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()

link

我错了什么?

谢谢

【问题讨论】:

    标签: python opencv 3d camera-calibration triangulation


    【解决方案1】:

    最好单独检查每个步骤。 (您可能想先看第 4 步)
    1-首先,您说您之前校准过相机。你有多少重投影误差?您是否进行了任何检查以验证校准是否成功。我还假设您的两个相机基本相同。
    2-如果您找到的基本矩阵是正确的(顺便确保您的点列表对两个列表具有相同的顺序),它应该满足极线约束p' F p = 0 其中p' 是右视图中的点,p 是左视图中的点(均匀像素坐标)。虽然它们不会完全为 0,但应该接近 0。这个方程必须适用于所有点对应。如果没有,请尝试使用 CM_FM_RANSAC 或跳至第 3 步。
    3-检查您是否可以使用opencv function直接计算基本矩阵。此外,对于基本矩阵,类似的方程必须成立。
    4- OpenCV decomposeEssentialMat 函数返回两个可能的旋转矩阵,并且有两个可能的平移(因此总共有 4 个可能的 R T 组合)。尝试测试所有这些。如果您可以使用 4 种组合之一获得正确的解决方案,我将编辑我的答案以包括如何获得正确的组合。
    如果您的基本/基本矩阵计算正确且问题仍然存在,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 2013-10-22
      • 2012-11-09
      • 1970-01-01
      • 2020-07-08
      • 2015-02-27
      • 2014-09-06
      相关资源
      最近更新 更多