我有一个3D世界,我试图使用cv2.projectPoints映射到2D视图,但它没有按照我的预期行事。我对opencv,numpy和matrix ops的掌握很弱,所以我必须在某个地方做出错误的假设。这段代码:
src = np.ones((6, 3))
src[:,1] = 2
src[:,2] = range(6) # source points
rvec = np.array([0,0,0], np.float) # rotation vector
tvec = np.array([0,0,0], np.float) # translation vector
fx = fy = 1.0
cx = cy = 0.0
cameraMatrix = np.array([[fx,0,cx],[0,fy,cy],[0,0,1]])
result = cv2.projectPoints(src, rvec, tvec, cameraMatrix, None)
for n in range(len(src)):
print src[n], '==>', result[0][n]
生成此输出:
[ 1. 2. 0.] ==> [[ 1. 2.]]
[ 1. 2. 1.] ==> [[ 1. 2.]]
[ 1. 2. 2.] ==> [[ 0.5 1. ]]
[ 1. 2. 3.] ==> [[ 0.33333333 0.66666667]]
[ 1. 2. 4.] ==> [[ 0.25 0.5 ]]
[ 1. 2. 5.] ==> [[ 0.2 0.4]]
x值和y值除以z值?!我认为,因为我不使用rvec和tvec进行转换,输出应该匹配src的[x,y]值。
答案 0 :(得分:1)
对于无操作,旋转矩阵应为标识
1 0 0
0 1 0
0 0 1
编辑: 写自己是一个非常简单的功能。
foreach input 3dpoint xyz
3dpoint tmp = cameraintrinsic(3x3) * rotationvect(1x3) * xyz(3x1) + cameraintrinsic(3x3)*translation(3,1)
2dpoint screen = tmp.x/tmp.z, tmp.y / tmp.z
/ tmp.z是因为结果以齐次coords =基本上带有缩放因子的2d coords返回。
答案 1 :(得分:0)
您的代码是正确的,但正如您所怀疑的那样,您的解释是错误的。函数OpenCV :: projectPoints()不仅执行旋转和平移,还执行逆z距离缩放。
请注意,几何假设是摄像机位于z = 0并沿z轴指向。考虑到距离摄像机一定距离Z,视场(即图像的宽度)是Fx,Fy。例如,您可以以米为单位测量Z和F,但可以是任何距离单位。您还知道图像中的像素数是沿X方向的ncols和沿Y方向的nrows。接下来考虑要在z不为零的情况下投影的空间(x,y,z)中的3D点。图像坐标如下:
u= x * ncols/Fx * Z/z
v= y * nrows/Fy * Z/z
从中您可以看到fx= ncols/Fx*Z and fx=nrows/Fy*Z