【问题标题】:Fundamental Matrix for Point Correspondence点对应的基本矩阵
【发布时间】:2021-06-29 11:23:37
【问题描述】:

我正在估计基本矩阵,使用

cv2.findFundamentalMat()

OpenCV 的方法。我给出了从 flann matcher 获得的关键点。

# Initiate ORB detector
orb = cv2.ORB_create()
# find the keypoints with ORB
keyPointsLeft = orb.detect(imgLeft,None)
keyPointsRight= orb.detect(imgRight, None)

# compute the descriptors with ORB
keyPointsLeft, descriptorsLeft = orb.compute(imgLeft, keyPointsLeft)
keyPointsRight, descriptorsRight = orb.compute(imgRight, keyPointsRight)
desLeft = np.float32(descriptorsLeft)
desRight = np.float32(descriptorsRight)
matches = flann.knnMatch(desLeft,desRight,k=2)
# Need to draw only good matches, so create a mask
matchesMask = [[0,0] for i in range(len(matches))]

# Apply ratio test
goodMatches = []
ptsLeft = []
ptsRight = []
for i,(m,n) in enumerate(matches):
    if m.distance < 0.7*n.distance:
        x1,y1 = keyPointsLeft[m.queryIdx].pt
        x2,y2 = keyPointsRight[n.trainIdx].pt
        matchesMask[i] = [1,0]
        goodMatches.append([m])
        ptsLeft.append(keyPointsLeft[m.queryIdx].pt)
        ptsRight.append(keyPointsRight[n.trainIdx].pt)

ptsLeft = np.int32(ptsLeft)
ptsRight = np.int32(ptsRight)
F, mask = cv2.findFundamentalMat(ptsLeft,ptsRight,cv2.FM_7POINT)

找到基本矩阵后,我试图通过极线约束方程验证点对应关系,即:

(1) p1T * F * p2 = 0

所以,假设我们在左侧图像上有点 p1 (x1,y1),在右侧图像上有点 p1 (x2,y2)。因此,如果我将极线方程 (1) 应用于这些点,我应该得到 0,或更接近于 0 的数字。

所以这个方程,可以这样写:

(2) 0 = x1*x2*F[0][0] + x1*y2*F[0][1] + x1*F[0][2] + y1*x2*F[1][0] + y1*y2*F[1][1] + y1*F[1][2] + x2*F[2][0] + y2*F[2][1] +  F[2][2]

通过使用等式(2),我试图用这个等式验证 flann 匹配的点。我打印了方程结果和同一行中的点,因为我的输入图像只是在它们之间进行了转换。

输出:

p1(82,340) --> p2(74,340)
p1T * F * p2 =  -0.7662387780488729
p1(355,240) --> p2(354,240)
p1T * F * p2 =  -0.0047911844235635215
p1(354,229) --> p2(349,229)
p1T * F * p2 =  0.11662882831689814
p1(377,175) --> p2(372,175)
p1T * F * p2 =  0.3450325352994703
p1(319,227) --> p2(311,227)
p1T * F * p2 =  0.19119563752361657
p1(276,171) --> p2(273,171)
p1T * F * p2 =  0.251353775637849
p1(371,259) --> p2(366,259)
p1T * F * p2 =  -0.019570666111391688
......
....
...

使用此输出,我无法验证这些点和我的基本矩阵。等式(1)在我的情况下不起作用,有时它给出更接近零的值,有时不是。是不是我做错了什么?

【问题讨论】:

    标签: python opencv computer-vision


    【解决方案1】:

    我不确定等式 1 是否可以写成等式 2。我肯定会推荐使用等式 1 和齐次坐标(z 值设置为 1)。您应该考虑对坐标进行归一化,因为 X 和 Y 会比 Z 大得多。这可以通过计算 Hartley、Zisserman 等建立的相似变换来完成。显示here: page 2

    之后,您可以使用 OpenCV Mat 直接计算结果。首先,我建议您尝试使用不同的方法来计算基本矩阵。由于您有很多由 ORB 生成的特征点,我会使用 CV_FM_RANSAC 例如reprojThreshold 为 3,置信度为 0.99。这已经可以解决问题了。

    一个简短的 C++ 代码示例:

    cv::Mat F = cv::findFundamentalMat(kp_left, kp_right, cv::RANSAC, 3.0, 0.999); # here you need to use your feature points cv::Point2f
    point_left = cv::Mat(cv::Point3d(82,340,1));
    point_right = cv::Mat(cv::Point3d(74,340,1));
    cv::Mat distance = point_left.t()*F*point_right;
    

    距离通常不会正好为 0,但现在应该接近它。

    【讨论】:

      猜你喜欢
      • 2014-09-07
      • 2019-11-06
      • 2014-02-17
      • 2014-05-11
      • 2011-01-12
      • 2013-08-03
      • 2013-04-11
      • 1970-01-01
      • 2018-12-23
      相关资源
      最近更新 更多