是否可以使用solvePnP找到4个角点的实际位置?

时间:2017-11-21 16:15:18

标签: python opencv math 3d computer-vision

我可以使用solvepnp找到凸轮框架和世界框架的(0,0,0)的旋转和平移。

mtx = np.array([
[463.889   ,       0       ,    320],
[0         ,       463.889,     240],
[0         ,       0   ,         1 ],
])
dist = np.array([0.0,0,0,0,0])


objp = np.zeros((4,3), np.float32)
objp[:,:2] = np.mgrid[0:2,0:2].T.reshape(-1,2)

#objp = array([[ 0.,  0.,  0.], 
#   [ 1.,  0.,  0.],
#   [ 0.,  1.,  0.],
#   [ 1.,  1.,  0.]], dtype=float32)
# let assume the square len is 1cm.

corners2 = np.float32([ [[498,136]] , [[558,138]],  [[505,184]], [[569,186]]])
retval, rvecs, tvecs = cv2.solvePnP(objp, corners2, mtx, dist)

imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)

tvecs是否对应于相机框架中的(0,0,0)位置?

我怎样才能找到其他3分的翻译? ([1.,0.,0。],[0,1。,0。],[1.,1.,0。])

换句话说,我可以得到角落2中所有点的实际位置吗?

2 个答案:

答案 0 :(得分:2)

  

tvecs是否对应于相机框架中的(0,0,0)位置?

在OpenCV文档中,您可以找到答案。

  
      
  • rvec - 输出旋转矢量(参见Rodrigues()),它与tvec一起,将模型坐标系中的点带到   摄像机坐标系。
  •   
  • tvec - 输出翻译矢量。
  •   

这里它告诉你它将模型坐标系中的点带到摄像机中,这意味着无论你的坐标系是什么,它都会找到将其移动到可以投影的位置所需的平移和旋转到图像平面并产生2D图像。

对于你的问题,这取决于......如果你假设你的点来自一个看着它们的相机并用相机生成它们(0,0,0)然后是。如果原点位于您的点的中间,并且通过相机表示生成图像的位置,您获得2D点,那么此tvecs就是这个相机的原点。

  

我怎样才能找到其他3分的翻译? ([1.,0.,0。],[0,1。,0。],[1.,1.,0。])

非常简单,第一,您需要从rvecs和tvecs中创建转换矩阵。 rvecs在Rodrigues中,您可以使用该函数获取旋转矩阵(3x3),然后将平移作为列向量放在它旁边,在它下面的一行0和1位于las位置,如下所示:

                 R11 R12 R13 T1

转化= R21 R22 R23 T2

                 R31 R32 R33 T3

                 0   0   0   1

现在你将这些点放在齐次坐标中(基本上是一个额外行中的1个。然后你将它相乘。

P = 1
    0
    0
    1

Transformation * P

你可以用你想要的所有点来做到这一点:)在这种情况下,它会给你一个代表你的3D点的4x1向量和最后一部分(在这种情况下)它将是1并且可以被删除以返回到一个3D点。在其他情况下,最后一个组件划分其他组件(使其成为1),并且它也被删除。

作为最后一个注意事项,您还可以获得相机的姿势,并可以连续跟踪它。

我希望这会对你有所帮助。

答案 1 :(得分:0)

所以它是这样的吗?非常感谢。

rotMat,_ = cv2.Rodrigues(rvecs)
T0 = np.zeros((4, 4))
T0[:3,:3] = rotMat
T0[:4,3] = [0, 0, 0, 1]
T0[:3,3] =  np.transpose(tvecs)

p0 = np.array([0, 0, 0, 1])
z0 = np.dot(T0, p0);

p1 = np.array([0, 1, 0, 1])
z1 = np.dot(T0, p1);

p2 = np.array([1, 0, 0, 1])
z2 = np.dot(T0, p2);

p3 = np.array([1, 1, 0, 1])
z3 = np.dot(T0, p3);