为什么RANSAC不删除SIFT匹配中的所有异常值?

时间:2016-03-16 06:31:55

标签: opencv computer-vision feature-detection sift ransac

我使用SIFT来检测,描述两个图像中的特征点如下。

void FeaturePointMatching::SIFTFeatureMatchers(cv::Mat imgs[2], std::vector<cv::Point2f> fp[2])
{
    cv::SiftFeatureDetector  dec;
    std::vector<cv::KeyPoint>kp1, kp2;

    dec.detect(imgs[0], kp1);
    dec.detect(imgs[1], kp2);

    cv::SiftDescriptorExtractor ext;
    cv::Mat desp1, desp2;

    ext.compute(imgs[0], kp1, desp1);
    ext.compute(imgs[1], kp2, desp2);

    cv::BruteForceMatcher<cv::L2<float> > matcher;
    std::vector<cv::DMatch> matches;
    matcher.match(desp1, desp2, matches);

    std::vector<cv::DMatch>::iterator iter;

    fp[0].clear();
    fp[1].clear();
    for (iter = matches.begin(); iter != matches.end(); ++iter)
    {
        //if (iter->distance > 1000)
        //  continue;
        fp[0].push_back(kp1.at(iter->queryIdx).pt);
        fp[1].push_back(kp2.at(iter->trainIdx).pt);
    }

    // remove outliers
    std::vector<uchar> mask;
    cv::findFundamentalMat(fp[0], fp[1], cv::FM_RANSAC, 3, 1, mask);

    std::vector<cv::Point2f> fp_refined[2];
    for (size_t i = 0; i < mask.size(); ++i)
    {
        if (mask[i] != 0)
        {
            fp_refined[0].push_back(fp[0][i]);
            fp_refined[1].push_back(fp[1][i]);
        }
    }

    std::swap(fp_refined[0], fp[0]);
    std::swap(fp_refined[1], fp[1]);
}

在上面的代码中,我使用findFundamentalMat()删除异常值,但在结果img1img2中仍然存在一些不匹配。在图像中,每条绿线连接匹配的特征点对。请忽略红色标记。我找不到任何错误,有人能给我一些提示吗?提前谢谢。

3 个答案:

答案 0 :(得分:1)

RANSAC只是一个强大的估算器。原则上,人们可以使用各种各样的,但只要输入数据不受异常值支配,RANSAC就可以很好地工作。您可以在RANSAC上查看其他变体,如MSAC,MLESAC,MAPSAC等,这些变体还有其他一些有趣的属性。您可能会发现此CVPR演示文稿很有趣(http://www.imgfsr.com/CVPR2011/Tutorial6/RANSAC_CVPR2011.pdf

根据输入数据的质量,您可以估算此处所述的最佳RANSAC迭代次数(https://en.wikipedia.org/wiki/RANSAC#Parameters

同样,它是一种强大的估算方法。您可以采用其他统计方法,例如使用重尾分布建模数据,修剪最小二乘法等。

在您的代码中,您缺少RANSAC步骤。 RANSAC基本上有两个步骤:

generate hypothesis (do a random selection of data points necessary to fit your mode: training data).
model evaluation (evaluate your model on the rest of the points: testing data)
iterate and choose the model that gives the lowest testing error. 

答案 1 :(得分:0)

RANSAC代表RANdom SAmple Consensus,它不会删除异常值,它会选择一组点来计算该组点的基本矩阵。然后,您需要使用刚刚使用RANSAC计算的基本矩阵进行重新投影,以消除异常值。

答案 2 :(得分:0)

与任何算法一样,ransac并不完美。您可以尝试运行其他不可思议的(在opencv实现中)强大的算法,如LMEDS。您可以重申,使用标记为内点的最后一点作为新估算的输入。您可以改变阈值和置信度。我建议运行ransac 1~3次,然后运行LMEDS,不需要阈值,但只适用于至少+ 50%的内部。

而且,您可能遇到几何订单问题:

*如果两个立体声之间的基线太小,基本矩阵估计可能不可靠,并且为了您的目的,最好使用findHomography()代替。

*如果你的图像有一些桶状/ pincushin失真,它们不符合极线几何,基本矩阵不是连接匹配的正确数学模型。在这种情况下,您可能需要校准相机,然后运行undistort()然后处理输出图像。