Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用opencv-traingulatePoints单位从两幅图像确定3d位置_Opencv_Triangulation_Stereo 3d - Fatal编程技术网

使用opencv-traingulatePoints单位从两幅图像确定3d位置

使用opencv-traingulatePoints单位从两幅图像确定3d位置,opencv,triangulation,stereo-3d,Opencv,Triangulation,Stereo 3d,给定两个任意(即不平行)图像的一组对应点(如SURF发现的),我尝试使用以下方法提取点的3D位置 def triangulate(pts1,pts2): cameraMatrix = np.array([[1, 0,0],[0,1,0],[0,0,1]]) F,m1 = cv2.findFundamentalMat(pts1, pts2) # apparently not necessary # using the essential matrix ca

给定两个任意(即不平行)图像的一组对应点(如SURF发现的),我尝试使用以下方法提取点的3D位置

def triangulate(pts1,pts2):
    cameraMatrix = np.array([[1, 0,0],[0,1,0],[0,0,1]])        
    F,m1 = cv2.findFundamentalMat(pts1, pts2) # apparently not necessary

    # using the essential matrix can get you the rotation/translation bet. cameras, although there are two possible rotations: 
    E,m2 = cv2.findEssentialMat(pts1, pts2, cameraMatrix, cv2.RANSAC, 0.999, 1.0)
    Re1, Re2, t_E = cv2.decomposeEssentialMat(E)

    # recoverPose gets you an unambiguous R and t. One of the R's above does agree with the R determined here. RecoverPose can already triangulate, I check by hand below to compare results. 
    K_l = cameraMatrix
    K_r = cameraMatrix
    retval, R, t, mask2, triangulatedPoints = cv2.recoverPose(E,pts_l_norm, pts_r_norm, cameraMatrix,distanceThresh=0.5)

    # given R,t you can  explicitly find 3d locations using projection 
    M_r = np.concatenate((R,t),axis=1)
    M_l = np.concatenate((np.eye(3,3),np.zeros((3,1))),axis=1)
    proj_r = np.dot(cameraMatrix,M_r)
    proj_l = np.dot(cameraMatrix,M_l)
    points_4d_hom = cv2.triangulatePoints(proj_l, proj_r, np.expand_dims(pts1, axis=1), np.expand_dims(pts2, axis=1))
    points_4d = points_4d_hom / np.tile(point_s4d_hom[-1, :], (4, 1))
    points_3d = points_4d[:3, :].T
    return points_3d

我假设我的内在相机矩阵在上面近似为I。由两种方法(findEssentialMat->DecompositeEssentialMat vs recoverPose)确定的R、t一致,由两种方法(recoverPose vs triangulatePoints)确定的三角化点也一致。我的问题与我看到的值有关,点_3d的值通常在x、y的0-50范围内,z的0-0.03范围内。据我所知,这些值应该以像素为单位;我对照相机矩阵的选择是否影响了比例?

您应该使用校准过的照相机。您可以在OpenCV中查找相机校准教程,它提供了代码并解释了如何校准相机

校准将为您提供相机矩阵和失真系数,您必须使用它们来获取将用于三角点的未失真冲浪关键点(也称为特征)

通常,计算的摄影机平移是单位向量,因此3D点将使用该位移作为缩放单位。假设你的两张照片是用相距1米的相机拍摄的,3D点的单位是米。3D比例从不以像素为单位

最后评论:

1-用这种方法对点进行三角剖分不太准确。精度是通过多视图或slam方法实现的,它们都不简单。而且总是使用校准过的摄像机

2-如果您不校准您的相机,您可以近似您的相机矩阵(恶化的结果,但总比没有好),假设: CX和CY位于图像的中间。
-fx=fy=半水平分辨率(例如1920/2像素),假设您的相机具有90度光圈。否则,您必须绘制等腰三角形并进行一些几何操作。

是的,您选择的相机矩阵直接影响比例。OpenCV中的相机矩阵应包含fx和fy的值,这是指以像素单位表示的相机焦距(主距离)。
如果将这两个值都设置为1,则会得到3D点的“较小值”(以像素为单位)。通常,(明显取决于摄像机)fx、fy的值约为1000。
您可以找到一个很好的示例,仅使用分辨率和近似视野(FOV)来估计网络摄像头的焦距。

是的,它直接影响比例。相机矩阵应包含fx和fy,这是以像素单位表示的焦距:。您将两个值设置为1,从而得到3D点数的“较小值”。考虑将评论移到答案;既然这是正确的答案,我会像suchOk一样检查它,我已经这样做了:)