cv2 triangulatePoints 总是 returns 相同的 Z 值

cv2 triangulatePoints always returns same Z value

我正在尝试使用 cv2.triangulatePoints 获取 3D 点,但它总是 returns 几乎相同的 Z 值。我的输出是这样的: 正如它所看到的,所有点都在几乎相同的 Z 值中。没有深度。

这是我的三角剖分:

    def triangulate(self, proj_mat1, pts0, pts1):
        proj_mat0 = np.zeros((3,4))
        proj_mat0[:, :3] = np.eye(3)
        pts0, pts1 = self.normalize(pts0), self.normalize(pts1) 
        pts4d = cv2.triangulatePoints(proj_mat0, proj_mat1, pts0.T, pts1.T).T
        pts4d /= pts4d[:, 3:]
        out = np.delete(pts4d, 3, 1)
        print(out)
        return out

这是我的投影矩阵计算:

    def getP(self, rmat, tvec):
       P = np.concatenate([rmat, tvec.reshape(3, 1)], axis = 1)
       return P

这是我得到 rmat、tvec 和调用三角测量的部分:

    E, mask = cv2.findEssentialMat(np.array(aa), np.array(bb), self.K)
    _, R, t, mask = cv2.recoverPose(E, np.array(aa), np.array(bb), self.K)
    proj_mat1 = self.getP(R, t)
    out = self.triangulate(proj_mat1, np.array(aa, dtype = np.float32), np.array(bb, dtype = np.float32))

我的相机矩阵:

array([[787.8113353 ,   0.        , 318.49905794],
       [  0.        , 786.9638204 , 245.98673477],
       [  0.        ,   0.        ,   1.        ]])

我的投影矩阵1:

array([[1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.]])

解释:

更改第一个投影矩阵后的输出(我从 matplotlib 切换到 pangolin 作为 3D 可视化工具):

使用我在评论中提到的 P1 和 P2 后的输出:

我的错误在哪里?如果需要任何进一步的信息,请告诉我。我会更新我的问题。

不幸的是,我无法直接double-check,但我的直觉是,您面临的问题本质上是由于您选择了第一个投影矩阵

我做了一些研究,发现 this great paper 既有理论又有实践。尽管与您的方法略有不同,但有一点值得一提

如果仔细检查,第一个投影矩阵正是相机矩阵,最后一列为零。事实上,第一个相机的旋转矩阵减少为单位矩阵,相应的平移向量是一个空向量,所以使用 this general formula:

P = KT

其中P是投影矩阵,K是相机矩阵,T是由旋转矩阵R得到的矩阵,两侧是平移向量t 根据:

T = [R|t]

那么你会得到:

回到你的情况,首先我建议改变你刚才所说的第一个投影矩阵

此外,我知道您计划在每一帧都使用不同的东西,但是如果在建议的更改之后,东西仍然不匹配,那么在您看来我会开始只使用 2 张图像 [我认为您已经隐含地创建了 aabb] 之间的对应关系,首先使用您的算法计算矩阵,然后检查根据上述文章获得的矩阵

通过这种方式,您可以understand/debug哪些矩阵给您带来了麻烦

祝你有美好的一天,
安东尼奥

非常感谢@Antonino 所做的一切努力。我的网络摄像头非常糟糕。在更改我的代码的每一部分并进行多次试验后,我决定更换我的网络摄像头并购买了好的网络摄像头。它起作用了:D 这是结果: