问题描述
因此该设置给出了如下所示的坐标系,其中 z
轴指向屏幕外(朝向您),相机焦距为 270
像素,图像分辨率为 {{ 1}},那么我们在 3D 空间的某个地方有一个物体,两个无人机 640x480
和 d1
在两个不同的视点进行两次观察,其中 d2
位于 d1
物体对应的图像坐标为(6,3,2)
,(320,280)
的坐标为d2
和(9.5,4.5,3)
,(160,408)
的标题为{{1} } 与 d1
轴的度数和 -20
的度数是 y
轴的 d2
度,目标是确定 +30
对象所在的位置,无人机悬停在 y
平面
Click Here for Image Illustration
给定信息,通过让(x,y,z)
作为参考系,我们可以得到相机内在函数xy
,变换是用d1
轴旋转K = [[270,320],[0,270,240],1]]
度为旋转轴和平移 +50
,因此我的代码
z
这给你一个齐次坐标 t = [3.5,1.5,1]
,其中 import numpy as np
import cv2
def pixel2cam(pt,K):
u = (pt[0] - K[0][2]) / K[0][0]
v = (pt[1] - K[1][2]) / K[1][1]
return np.array([u,v],dtype=np.float32)
def triangulate(points_1,points_2,K,R,t):
cam_pts_1 = pixel2cam(points_1,K).reshape(2,1)
cam_pts_2 = pixel2cam(points_2,1)
T1 = np.array([[1,0],1,0]],dtype=np.float32)
T2 = np.hstack((R,t))
X = cv2.triangulatePoints(T1,T2,cam_pts_1,cam_pts_2)
X /= X[3]
return X
K = np.array([[270,1]],dtype=np.float32)
# rotate +50 degrees along z axis
R = np.array([[0.643,-0.766,[0.766,0.643,dtype=np.float32)
t = np.array([[3.5],[1.5],[1]],dtype=np.float)
pt_1 = (320,280)
pt_2 = (160,408)
X = triangulate(pt_1,pt_2,t)
是负数,所以我的问题是
- 我在此处正确地表述了
X = [[-2.4155867],[ -5.1455526],[-12.032189],[1.]])
和z
吗? - 如果是,那么错误可能是由于此处使用的相机坐标系与
R
中的不同吗?
感谢任何帮助!
解决方法
我在您的代码中看到多个问题。我将尝试在下面的不同部分中一一检查它们。
OpenCV 点三角剖分
首先,OpenCV cv2.triangulatePoints()
将投影矩阵从世界坐标转换为像素坐标,以及图像上世界点的像素坐标。请参阅 cv2.triangulatePoints()
documentation。您还可以在 this page 的“详细描述”部分阅读 OpenCV 投影背后的数学原理。
这是您的 triangulate()
函数的更正版本:
def triangulate(points_1,points_2,K,R,t):
T1 = np.array([[1,0],[0,1,0]],dtype=np.float32)
T2 = np.hstack((R,t))
proj1 = np.matmul(K,T1)
proj2 = np.matmul(K,T2)
X = cv2.triangulatePoints(proj1,proj2,points_1,points_2)
X /= X[3]
return X
旋转矩阵
在 OpenCV 坐标系中,相机的 z 轴是光轴(参见 this answer 中的图表)。绕 z 轴旋转与您在问题中链接的图像不匹配,绕 y 轴旋转 -50 度似乎更正确。
您可以使用 cv2.Rodrigues()
重新计算旋转矩阵。请注意,此函数以弧度表示角度,请参阅 documentation。
rotation_vector = np.array([0,-50 / 180 * np.pi,0])
R,_ = cv2.Rodrigues(rotation_vector)
单位
你说你的焦点是以像素为单位的。查看数据,我非常怀疑焦距和平移值是否一致,至少如果它们以像素表示的话。我看到两种可能性:
- 数据是正确的,但您在写问题时误解了焦距的单位。在这种情况下,忘记了本节的其余部分;
- 您问题中所述的单位是正确的,并且您正在尝试使用不一致的数据对点进行三角测量。
要解决此问题,请确保焦距和平移均以像素或相同的距离单位表示。您可以通过相机的像素间距进行从像素到距离单位的转换,并通过乘以像素间距来进行从距离单位到像素的转换。像素间距应写在您使用的相机型号的数据表中。
结果
应用上述三个修正后,我得到了一个 X
向量,它的 z 坐标为正。不过,我获得的值并没有多大意义,因为我不确定数据的正确值和单位。