Python和OpenCV - 关于findFundamentalMat行为的问题

时间:2016-11-15 22:28:46

标签: python opencv 3d-reconstruction

很抱歉,如果标题含糊不清。用简短易懂的方式表达我的问题是很难的。

所以,我正处于3D重建项目的中间。管道与标准管道或多或少相同

  1. Undistort image
  2. 使用关键点检测器检测点
  3. 跟踪帧间的点(光流)
  4. 计算基本矩阵
  5. 等等。唯一不同的部分是在步骤2,我使用线段检测器并跨帧跟踪它。

    因此,如果我使用关键点检测器,给出两帧图像,我将得到两组关键点(每组对应于每一帧)。但至于我的情况,我有四组关键点(每一组对应于每一帧,因为一条线有一个起点和一个终点)。

    为了计算基本矩阵,我需要连接每一帧的两组点。

    一种方法是直接连接它:np.vstack([start_point, end_point])

    另一种方式是:np.hstack([start_point, end_point]).reshape(-1, 2)。手段,它是“交替”连接,即

    [[start_point[0],
      end_point[0],
      start_point[1],
      end_point[1],
                 ...]]
    

    两者最终会形成相同的形状。但公平地说,它们产生了截然不同的结果。根据我的观察,vstack产生了更像'3D'的结果,而hstack产生了更像'平面状'的重建结果。

    问题是这是为什么?谁应该更好?

    以下是提供此问题视图的示例代码:

    import numpy as np
    import cv2
    
    np.random.seed(0)
    
    def prepare_points(pts_frame1, pts_frame2):
        # Prepare the four sets of points
        (p1_f1, p2_f1) = pts_frame1
        (p1_f2, p2_f2) = pts_frame2
    
        v_stacked_f1f2 = (np.vstack([p1_f1, p2_f1]), np.vstack([p1_f2, p2_f2]))
        h_stacked_f1f2 = (np.hstack([p1_f1, p2_f1]).reshape(-1, 2), 
                          np.hstack([p1_f2, p2_f2]).reshape(-1, 2))
    
        return (v_stacked_f1f2, h_stacked_f1f2)
    
    pts_frame1 = np.random.random_sample((60, 2)).astype("float32")
    pts_frame2 = np.random.random_sample((60, 2)).astype("float32")
    
    # Emulate the two sets of points for each frame where
    # the first set is the start point, while
    # the second set is the end point of a line
    pts_frame1 = (pts_frame1[::2], pts_frame1[1::2])
    pts_frame2 = (pts_frame2[::2], pts_frame2[1::2])
    
    (v_stacked_f1f2, h_stacked_f1f2) = prepare_points(pts_frame1, pts_frame2)
    
    F_vstacked = cv2.findFundamentalMat(v_stacked_f1f2[0], v_stacked_f1f2[1],
                                        cv2.FM_RANSAC, 3, 0.99)[0]
    F_hstacked = cv2.findFundamentalMat(h_stacked_f1f2[0], h_stacked_f1f2[1],
                                        cv2.FM_RANSAC, 3, 0.99)[0]
    
    print("F_vstacked:\n", F_vstacked, "\n")
    print("F_hstacked:\n", F_hstacked, "\n")
    
    # F_vstacked:
    # [[ 3.31788127 -2.24336615 -0.77866782]
    # [ 0.83418839 -1.4066019  -0.92088302]
    # [-2.75413748  2.27311637  1.        ]] 
    
    # F_hstacked:
    # [[  7.70558741  25.29966782 -16.20835082]
    # [-12.95357284  -0.54474384  14.95490469]
    # [  1.79050172 -10.40077071   1.        ]] 
    

1 个答案:

答案 0 :(得分:0)

findFundamentalMat函数处理这样的点格式:2 * N,其中N是点数。所以我认为" F_hstacked"是正确的。 还有一件事我不清楚,为什么你只想使用线的终点来估计运动?这是准确的功能点吗?因为你无法确切地知道每个线的终点(像素)。