2 OpenCV实现的F矩阵+RANSAC原理与实践

前文
1 基于SIFT图像特征识别的匹配方法比较与实现

1 RANSAC 筛选

1.1 大致原理

Random sample consensus (RANSAC),即随机抽样一致性,其是一种用于估计模型参数的迭代方法,特别适用于处理包含离群点(outliers)的数据集

RANSAC 的主要思想是随机采样数据点,用这些采样点拟合一个模型,然后计算其他数据点到这个模型的拟合误差;根据误差和阈值,将数据点分为内点(inliers)外点(outliers);重复这个过程多次,选择具有最多内点的模型作为最终的估计

大致步骤为:

  1. 随机采样

    从数据集中随机选择一小部分数据点,通常是与所估计模型参数数量相等的数据点

  2. 模型拟合

    使用这些随机采样的数据点拟合一个模型,例如直线

  3. 内点检测

    计算所有数据点到模型的拟合误差,并将与模型拟合误差小于某个阈值的数据点标记为内点

  4. 判断是否满足条件

    如果内点的数量达到了某个设定的阈值,且模型参数的估计是合理的(例如,模型的拟合误差小于一定阈值),则认为找到了一个满足条件的模型

  5. 重复迭代

    重复上述过程多次(通常几百甚至上千次),并且记录具有最多内点的模型,以及该模型估计的内点

  6. 输出最佳模型

    在所有迭代中,选择具有最多内点的模型作为最终的估计模型。这些内点被认为是满足模型的数据点

1.2 优缺点

RANSAC 的一个优点是它能够对模型参数进行鲁棒估计,能够在存在大量噪声的情况下找到合适的模

RANSAC 的缺点是计算这些参数所需的时间没有上限,其需要进行大量的随机采样和模型拟合,因此对于大规模数据集来说,计算复杂度较高,可能需要较长的时间来运行

1.3 实践效果

请见 3 实践操作 步骤二

2 F矩阵

2.1 基本原理

基本矩阵(Fundamental Matrix)描述了两个摄像机之间的基本几何关系

在对极几何中,对于立体图像对中对应点的齐次图像坐标 p1p2F*p1描述了另一图像上的对应点 p2 必须位于其上的线(对极线)这意味着,对于所有对应点对都成立:
p 2 T ∗ F ∗ p 1 = 0 p_2^T * F * p_1 = 0 p2TFp1=0

2.2 函数实现

在 OpenCV 中,提供了 findFundamentalMat 函数,用于估计两幅图像之间的F矩阵

以下是 findFundamentalMat 函数的基本用法:

Mat fundamental_matrix = findFundamentalMat(points1, points2, mask, method, ransacReprojThreshold, confidence);

其中各参数的含义如下:

  • points1points2:两幅图像中的匹配点坐标,通常是 vector<Point2f> 类型,表示两幅图像中匹配点的像素坐标
  • mask:是一个输出数组通常是 vector<uchar> 类型,用于指示哪些匹配点被视为内点(inliers)和哪些被视为外点(outliers
  • method:用于指定计算基本矩阵的方法,可以是以下几种选项之一:
    • cv::FM_RANSAC:使用 RANSAC 算法进行估计,用于排除离群点
    • cv::FM_LMEDS:使用最小中值误差估计方法
    • cv::FM_8POINT:使用 8 点法估计基本矩阵
  • ransacReprojThreshold:RANSAC 算法中的重投影误差阈值,用于判断内点和外点,通常需要根据具体问题来选择适当的阈值,默认值为 3.0
  • confidence:置信度,通常为默认值 0.99

3 实践操作

之前通过SIFT+Flann+ratio=0.7的图像匹配和初步筛选,得到了 good_matchesvector<DMatch> 类型)

步骤一:保存匹配点对坐标

vector<DMatch> 类型的 good_matches 中的坐标信息提取出来存入 vector<Point2f> 类型的 matchedPoints1/2 ;以便于后续的几何计算将匹配点对的坐标提取出来,以便于后续的几何计算

// 声明用于保存匹配点对的容器
vector<Point2f> matchedPoints1, matchedPoints2;
for (int i = 0; i < good_matches.size(); ++i)
{
    matchedPoints1.push_back(keypoints1[good_matches[i].queryIdx].pt);
    matchedPoints2.push_back(keypoints2[good_matches[i].trainIdx].pt);
}
步骤二:进行基本矩阵F的估计

直接使用 findFundamentalMat 函数

这个函数在内部已经包含了 RANSAC 筛选步骤;具体来说,findFundamentalMat 函数会计算基本矩阵 F,同时使用 RANSAC 迭代方法来排除离群点,确保得到的基本矩阵对于图像匹配是稳健的

// 使用RANSAC进行基本矩阵F的估计
Mat F;
vector<uchar> inliers;
F = findFundamentalMat(matchedPoints1, matchedPoints2, inliers, RANSAC);
  • 为了查看 RANSAC 筛选的效果我们进行如下操作
    inliers 是一个二进制向量,指示哪些匹配点对被视为内点(符合基本矩阵约束),哪些被视为外点;我们接下来使用内点来进一步筛选匹配,只保留通过 RANSAC 筛选的匹配对在ransac_filtered_matches中,并打印出来

    // 进一步筛选匹配
    vector<DMatch> ransac_filtered_matches;
    for (int i = 0; i < inliers.size(); ++i)
    {
        if (inliers[i])
        {
            ransac_filtered_matches.push_back(good_matches[i]);
        }
    }
    // ransac_filtered_matches 包含了通过RANSAC筛选后的匹配对
    Mat ransac_filtered_img_matches;
    drawMatches(img1, keypoints1, img2, keypoints2, ransac_filtered_matches, ransac_filtered_img_matches);    
    imwrite(SAVE_PATH, ransac_filtered_img_matches);
    
    匹配点数量图像效果
    RANSAC 筛选前2949img_matches_3&4
    RANSAC 筛选后2581img_matches_3&4_

    可以明显看出,在 RANSAC 筛选后,消除了 368 对离群匹配,达到了非常好的匹配效果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: SIFT(尺度不变特征转换)是一种图像特征提取算法,而RANSAC(随机抽样一致性)是一种用于剔除误匹配点的算法。下面是关于如何在OpenCV 3.0中实现这两种算法的简要步骤。 首先,打开一个图像并加载其所需的库: ``` import cv2 import numpy as np ``` 然后,我们可以从图像中提取SIFT特征: ``` # 加载图像 img = cv2.imread('image.jpg',0) # 创建SIFT对象 sift = cv2.xfeatures2d.SIFT_create() # 检测并计算SIFT特征 keypoints, descriptors = sift.detectAndCompute(img, None) ``` 接下来,我们可以使用RANSAC算法来剔除误匹配点: ``` # 创建FLANN匹配器对象 FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) # 在两幅图像之间匹配特征点 matches = flann.knnMatch(descriptors1, descriptors2, k=2) # 进行RANSAC过滤 good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) # 绘制匹配结果 result = cv2.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, None, flags=2) cv2.imshow('Matches', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,我们首先创建了一个FLANN(快速最近邻搜索)匹配器对象,然后使用`knnMatch`函数在两幅图像之间进行特征点的匹配。最后,我们使用RANSAC算法对匹配点进行过滤,并将结果绘制出来。 以上是在OpenCV 3.0中实现SIFT特征提取和RANSAC误匹配点剔除的简要步骤。实际操作中还可以进行更详细的参数设置和优化,以便得到更好的匹配结果。 ### 回答2: OpenCV 3.0 是一个非常强大的计算机视觉库,它提供了许多功能来处理图像处理和计算机视觉任务。其中包括使用SIFT算法进行特征提取和使用RANSAC算法进行误匹配点的剔除。 首先,SIFT(尺度不变特征变换)是一种用于在图像中检测和描述关键点的算法。在OpenCV 3.0中,你可以使用`cv2.xfeatures2d.SIFT_create()`来创建一个SIFT对象。然后,你可以使用`detectAndCompute()`方法来检测并计算图像的关键点和特征描述符。通过调用这个方法,你将得到检测到的关键点和对应的特征描述符。 接下来,我们可以使用RANSAC(随机样本一致性)算法来剔除误匹配点。RANSAC算法能够通过随机选择样本子集并估计模型参数来寻找数据中的局内点。在OpenCV 3.0中,你可以使用`cv2.RANSAC`作为参数来创建一个RANSAC对象。然后,你可以使用`findHomography()`方法来计算通过RANSAC算法筛选后的匹配点之间的透视变换矩阵。这个矩阵可以用来剔除误匹配点。 总结一下,OpenCV 3.0可以通过`cv2.xfeatures2d.SIFT_create()`方法进行SIFT特征提取,并使用RANSAC算法来剔除误匹配点。这两个功能都是非常有用的计算机视觉任务,能够帮助我们更好地处理和分析图像。 ### 回答3: 在OpenCV 3.0中,可以使用SIFT算法进行图像的特征提取,并采用RANSAC算法剔除误匹配点。 SIFT(Scale-Invariant Feature Transform)特征提取算法是一种基于尺度空间的特征提取方法,它可以提取图像中的稳定特征点和其对应的描述子。在OpenCV中,可以使用sift.detectAndCompute()函数来提取图像的SIFT特征点和描述子。 RANSACRandom Sample Consensus)算法是一种鲁棒的参数估计算法,它可以从一组数据中剔除异常点,从而得到准确的模型参数。在特征匹配中,可以使用RANSAC算法来剔除误匹配点,以提高匹配的准确性。 具体实现的步骤如下: 1. 导入OpenCV和Numpy库,并读取需要进行特征匹配的两幅图像。 ```python import cv2 import numpy as np img1 = cv2.imread('image1.jpg', 0) img2 = cv2.imread('image2.jpg', 0) ``` 2. 创建SIFT对象,并使用sift.detectAndCompute()函数提取图像的SIFT特征点和描述子。 ```python sift = cv2.SIFT_create() kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) ``` 3. 使用FLANN匹配器对两幅图像的描述子进行匹配。 ```python FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1, des2, k=2) ``` 4. 运用RANSAC算法剔除误匹配点。 ```python good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) ``` 通过以上步骤,我们可以得到经过RANSAC算法筛选后的匹配点,并且可以通过M矩阵获取图像的对应关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值