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.]])
解释:
- aa和bb是2帧的匹配点
- self.K是我的相机矩阵
- 从基本矩阵中提取旋转和平移矩阵
- 根据匹配的关键点计算的基本矩阵。它每一帧都会改变。
- 投影矩阵 2 每帧变化。
更改第一个投影矩阵后的输出(我从 matplotlib 切换到 pangolin 作为 3D 可视化工具):
使用我在评论中提到的 P1 和 P2 后的输出:
我的错误在哪里?如果需要任何进一步的信息,请告诉我。我会更新我的问题。
不幸的是,我无法直接double-check,但我的直觉是,您面临的问题本质上是由于您选择了第一个投影矩阵
我做了一些研究,发现 this great paper 既有理论又有实践。尽管与您的方法略有不同,但有一点值得一提
如果仔细检查,第一个投影矩阵正是相机矩阵,最后一列为零。事实上,第一个相机的旋转矩阵减少为单位矩阵,相应的平移向量是一个空向量,所以使用 this general formula:
P = KT
其中P
是投影矩阵,K
是相机矩阵,T
是由旋转矩阵R
得到的矩阵,两侧是平移向量t
根据:
T = [R|t]
那么你会得到:
回到你的情况,首先我建议改变你刚才所说的第一个投影矩阵
此外,我知道您计划在每一帧都使用不同的东西,但是如果在建议的更改之后,东西仍然不匹配,那么在您看来我会开始只使用 2 张图像 [我认为您已经隐含地创建了 aa
和 bb
] 之间的对应关系,首先使用您的算法计算矩阵,然后检查根据上述文章获得的矩阵
通过这种方式,您可以understand/debug哪些矩阵给您带来了麻烦
祝你有美好的一天,
安东尼奥
非常感谢@Antonino 所做的一切努力。我的网络摄像头非常糟糕。在更改我的代码的每一部分并进行多次试验后,我决定更换我的网络摄像头并购买了好的网络摄像头。它起作用了:D 这是结果:
我正在尝试使用 cv2.triangulatePoints 获取 3D 点,但它总是 returns 几乎相同的 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.]])
解释:
- aa和bb是2帧的匹配点
- self.K是我的相机矩阵
- 从基本矩阵中提取旋转和平移矩阵
- 根据匹配的关键点计算的基本矩阵。它每一帧都会改变。
- 投影矩阵 2 每帧变化。
更改第一个投影矩阵后的输出(我从 matplotlib 切换到 pangolin 作为 3D 可视化工具):
使用我在评论中提到的 P1 和 P2 后的输出:
我的错误在哪里?如果需要任何进一步的信息,请告诉我。我会更新我的问题。
不幸的是,我无法直接double-check,但我的直觉是,您面临的问题本质上是由于您选择了第一个投影矩阵
我做了一些研究,发现 this great paper 既有理论又有实践。尽管与您的方法略有不同,但有一点值得一提
如果仔细检查,第一个投影矩阵正是相机矩阵,最后一列为零。事实上,第一个相机的旋转矩阵减少为单位矩阵,相应的平移向量是一个空向量,所以使用 this general formula:
P = KT
其中P
是投影矩阵,K
是相机矩阵,T
是由旋转矩阵R
得到的矩阵,两侧是平移向量t
根据:
T = [R|t]
那么你会得到:
回到你的情况,首先我建议改变你刚才所说的第一个投影矩阵
此外,我知道您计划在每一帧都使用不同的东西,但是如果在建议的更改之后,东西仍然不匹配,那么在您看来我会开始只使用 2 张图像 [我认为您已经隐含地创建了 aa
和 bb
] 之间的对应关系,首先使用您的算法计算矩阵,然后检查根据上述文章获得的矩阵
通过这种方式,您可以understand/debug哪些矩阵给您带来了麻烦
祝你有美好的一天,
安东尼奥
非常感谢@Antonino 所做的一切努力。我的网络摄像头非常糟糕。在更改我的代码的每一部分并进行多次试验后,我决定更换我的网络摄像头并购买了好的网络摄像头。它起作用了:D 这是结果: