Python OpenCV-用于立体视觉的倾斜摄像机和三角测量地标

Python OpenCV-用于立体视觉的倾斜摄像机和三角测量地标,python,opencv,triangulation,stereo-3d,Python,Opencv,Triangulation,Stereo 3d,我使用的是立体系统,所以我试图通过三角测量得到一些点的世界坐标 我的相机呈现一个角度,Z轴方向(深度方向)与我的曲面不垂直。这就是为什么当我观察平面时,我得到的不是恒定的深度,而是“线性”变化,对吗?我想要基线方向的深度。。。如何重新规划 我的一段代码,带有投影数组和三角函数: #C1 and C2 are the cameras matrix (left and rig) #R_0 and T_0 are the transformation between cameras #Coord1

我使用的是立体系统,所以我试图通过三角测量得到一些点的世界坐标

我的相机呈现一个角度,Z轴方向(深度方向)与我的曲面不垂直。这就是为什么当我观察平面时,我得到的不是恒定的深度,而是“线性”变化,对吗?我想要基线方向的深度。。。如何重新规划

我的一段代码,带有投影数组和三角函数:

#C1 and C2 are the cameras matrix (left and rig)
#R_0 and T_0 are the transformation between cameras
#Coord1 and Coord2 are the correspondant coordinates of left and right respectively
P1 = np.dot(C1,np.hstack((np.identity(3),np.zeros((3,1))))) 

P2 =np.dot(C2,np.hstack(((R_0),T_0)))

for i in range(Coord1.shape[0])
    z = cv2.triangulatePoints(P1, P2, Coord1[i,],Coord2[i,])
--------以后编辑-----------

谢谢scribbleink,所以我尝试应用你的建议。但是我想我犯了一个错误,因为它不像你在下面看到的那样好用。点云似乎向图像边缘扭曲和弯曲

U, S, Vt = linalg.svd(F)
V = Vt.T

#Right epipol
U[:,2]/U[2,2]

# The expected X-direction with C1 camera matri and C1[0,0] the focal length
vecteurX = np.array([(U[:,2]/U[2,2])[0],(U[:,2]/U[2,2])[1],C1[0,0]])
vecteurX_unit = vecteurX/np.sqrt(vecteurX[0]**2 + vecteurX[1]**2 + vecteurX[2]**2)


# The expected Y axis :
height = 2048
vecteurY = np.array([0, height -1, 0])
vecteurY_unit = vecteurY/np.sqrt(vecteurY[0]**2 + vecteurY[1]**2 + vecteurY[2]**2)


# The expected Z direction :
vecteurZ = np.cross(vecteurX,vecteurY)
vecteurZ_unit = vecteurZ/np.sqrt(vecteurZ[0]**2 + vecteurZ[1]**2 + vecteurZ[2]**2)

#Normal of the Z optical (the current Z direction)
Zopitcal = np.array([0,0,1])

cos_theta = np.arccos(np.dot(vecteurZ_unit, Zopitcal)/np.sqrt(vecteurZ_unit[0]**2 + vecteurZ_unit[1]**2 + vecteurZ_unit[2]**2)*np.sqrt(Zopitcal[0]**2 + Zopitcal[1]**2 + Zopitcal[2]**2))

sin_theta = (np.cross(vecteurZ_unit, Zopitcal))[1]

#Definition of the Rodrigues vector and use of cv2.Rodrigues to get rotation matrix
v1 = Zopitcal  
v2 = vecteurZ_unit 

v_rodrigues = v1*cos_theta + (np.cross(v2,v1))*sin_theta + v2*(np.cross(v2,v1))*(1. - cos_theta)
R = cv2.Rodrigues(v_rodrigues)[0]


预期的z方向对于重建方法是任意的。通常,您有一个旋转矩阵,可以从所需方向旋转左侧摄影机。你可以很容易地建立这个矩阵,R。然后,你所需要做的就是用重建点乘以R的转置。要添加到的响应,这里有一个候选解决方案,假设预期的X方向与连接两个摄像机投影中心的线重合

  • 计算焦距f_1和f_2(通过针孔模型校准)
  • 求解摄影机2的外极在摄影机1帧中的位置。为此,您可以使用立体相机对的基本矩阵(F)或基本矩阵(E)。具体来说,左、右对极位于F的空空间中,因此可以使用。有关可靠的理论参考,请参见Hartley和Zisserman,第二版,第246页的表9.1“基本矩阵属性摘要”()
  • 摄影机1的投影中心,即(0,0,0)和右对极的位置,即(e_x,e_y,f_1)共同定义一条与摄影机中心连接线对齐的光线。这可以用作预期的X方向。把这个向量称为v_x
  • 假设预期的Y轴在图像平面中朝下,即从(0,0,f_1)到(0,height-1,f_1),其中f是焦距。把这个向量称为v_y
  • 预期的Z方向现在是向量v_x和v_y的叉积
  • 使用预期的Z方向以及相机1的光轴(Z轴),然后可以使用中列出的方法从两个3D向量计算旋转矩阵
  • 实用说明: 根据我的实际经验,如果不付出相当大的努力,期望平面对象与立体基线精确对齐是不可能的。需要进行一定量的平面拟合和额外旋转

    一次性努力: 这取决于您是否需要执行此操作一次,例如,对于一次性校准,在这种情况下,只需实时执行此估计过程,然后旋转立体相机对,直到深度贴图差异最小化。然后锁定你的相机位置,祈祷以后不会有人撞到它

    重复性:
    如果你需要保持你的估计深度图到真正的任意z轴,对于每一个新的帧捕获,那么你应该考虑在平面估计方法中的投资时间,并且使它更健壮。< /P>你能用投影矩阵来转换你的点吗?我添加补语;我不知道是否可能使用3D旋转矩阵不会导致点弯曲。请在应用R之前绘制点,并确保它们不是非平面的。由于数据看起来不是平面的,因此很难进行测试。我建议先修复平面度。问题可能出现在您建议的校准参数中,也可能出现在您用于从视差转换到三维世界坐标的零件中(例如,请参阅)。我没有足够的信息告诉你。我使用了R_0,它是每次摄像机校准时得到的旋转矩阵1和2的乘积,以便进行三角测量,但我不知道如何建立这个矩阵R。。。我试图通过拟合平面图来识别刚体运动,但效果不好…谢谢你的帮助,这很有趣!我试试看:)