0

SIFT を使用して、次のように 2 つの画像の特徴点を検出、記述します。

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には、まだいくつかの不適切な一致があります。画像では、それぞれの緑色の線が、一致した特徴点のペアを結んでいます。赤いマークは無視してください。私は何か間違っていることを見つけることができません。前もって感謝します。

4

3 に答える 3

1

RANSAC は、堅牢な推定器の 1 つにすぎません。原則として、それらのさまざまなものを使用できますが、RANSAC は、入力データが外れ値に支配されていない限り、非常にうまく機能することが示されています。MSAC、MLESAC、MAPSAC などの RANSAC の他のバリアントも確認できます。これらには、他にもいくつかの興味深いプロパティがあります。この CVPR プレゼンテーションは興味深いかもしれません ( http://www.imgfsr.com/CVPR2011/Tutorial6/RANSAC_CVPR2011.pdf )

入力データの品質に応じて、ここ ( https://en.wikipedia.org/wiki/RANSAC#Parameters )で説明されているように、最適な RANSAC 反復回数を見積もることができます。

繰り返しますが、これはロバストな推定方法の 1 つです。重い裾の分布、トリムされた最小二乗法などを使用してデータをモデル化するなど、他の統計的アプローチを採用することもできます。

コードに RANSAC ステップがありません。RANSAC には基本的に 2 つのステップがあります。

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. 
于 2016-03-16T07:22:50.017 に答える
0

他のアルゴリズムと同様に、ransac も完璧ではありません。LMEDS など、他の不当な (opencv 実装での) 堅牢なアルゴリズムの実行を試みることができます。そして、インライアとしてマークされた最後のポイントを新しい推定への入力として使用して、繰り返すことができます。また、しきい値と信頼レベルを変更できます。ransac を 1 ~ 3 回実行してから、しきい値を必要としない LMEDS を実行することをお勧めしますが、少なくとも +50% のインライアでのみうまく機能します。

また、幾何学的順序の問題が発生する可能性があります。

* 2 つのステレオ間のベースラインが小さすぎる場合、基本的な行列推定は信頼できない可能性があり、代わりに findHomography() を使用することをお勧めします。

*画像にバレル/ピンカシンの歪みがある場合、それらはエピポーラ ジオメトリに準拠しておらず、基本行列は一致をリンクするための正しい数学的モデルではありません。この場合、カメラを調整して undistort() を実行し、出力画像を処理する必要があります。

于 2016-03-16T11:23:33.760 に答える