1. 程式人生 > >opencv3 SIFT特徵提取方法和RANSAC(隨機抽樣一致性方法)進行剔除無匹配點

opencv3 SIFT特徵提取方法和RANSAC(隨機抽樣一致性方法)進行剔除無匹配點

最近整理一下利用SIFT特徵提取方法和RANSAC(隨機抽樣一致性方法)進行剔除無匹配點的內容

    //讀取影象
    Mat img01=imread("3.png");
    Mat img02=imread("4.png");
    imshow("original image1",img01);
    imshow("original image2",img02);

    //SIFT特徵檢測
    SiftFeatureDetector detector;        //定義特點點檢測器
    vector<KeyPoint> keypoint01,keypoint02;//定義兩個容器存放特徵點
    detector.detect(img01,keypoint01);
    detector.detect(img02,keypoint02);

    //在兩幅圖中畫出檢測到的特徵點
    Mat out_img01;
    Mat out_img02;
    drawKeypoints(img01,keypoint01,out_img01);
    drawKeypoints(img02,keypoint02,out_img02);
    imshow("特徵點圖01",out_img01);
    imshow("特徵點圖02",out_img02);

    //提取特徵點的特徵向量(128維)
    SiftDescriptorExtractor extractor;
    Mat descriptor01,descriptor02;
    extractor.compute(img01,keypoint01,descriptor01);
    extractor.compute(img02,keypoint02,descriptor02);

    //匹配特徵點,主要計算兩個特徵點特徵向量的歐式距離,距離小於某個閾值則認為匹配

    BruteForceMatcher<L2<float>> matcher;
    vector<DMatch> matches;
    Mat img_matches;
    matcher.match(descriptor01,descriptor02,matches);
    drawMatches(img01,keypoint01,img02,keypoint02,matches,img_matches);
    imshow("誤匹配消除前",img_matches);

下面是利用RANSAC進行消除無匹配點:

    //RANSAC 消除誤匹配特徵點 主要分為三個部分:
    //1)根據matches將特徵點對齊,將座標轉換為float型別
    //2)使用求基礎矩陣方法 findFundamentalMat,得到RansacStatus
    //3)根據RansacStatus來將誤匹配的點也即RansacStatus[i]=0的點刪除

    //根據matches將特徵點對齊,將座標轉換為float型別
    vector<KeyPoint> R_keypoint01,R_keypoint02;
    for (size_t i=0;i<matches.size();i++)   
    {
        R_keypoint01.push_back(keypoint01[matches[i].queryIdx]);
        R_keypoint02.push_back(keypoint02[matches[i].trainIdx]);
        //這兩句話的理解:R_keypoint1是要儲存img01中能與img02匹配的特徵點,
        //matches中儲存了這些匹配點對的img01和img02的索引值
    }

    //座標轉換
    vector<Point2f>p01,p02;
    for (size_t i=0;i<matches.size();i++)
    {
        p01.push_back(R_keypoint01[i].pt);
        p02.push_back(R_keypoint02[i].pt);
    }

    //利用基礎矩陣剔除誤匹配點
    vector<uchar> RansacStatus;
    Mat Fundamental= findFundamentalMat(p01,p02,RansacStatus,FM_RANSAC);


    vector<KeyPoint> RR_keypoint01,RR_keypoint02;
    vector<DMatch> RR_matches;            //重新定義RR_keypoint 和RR_matches來儲存新的關鍵點和匹配矩陣
    int index=0;
    for (size_t i=0;i<matches.size();i++)
    {
        if (RansacStatus[i]!=0)
        {
            RR_keypoint01.push_back(R_keypoint01[i]);
            RR_keypoint02.push_back(R_keypoint02[i]);
            matches[i].queryIdx=index;
            matches[i].trainIdx=index;
            RR_matches.push_back(matches[i]);
            index++;
        }
    }
    Mat img_RR_matches;
    drawMatches(img01,RR_keypoint01,img02,RR_keypoint02,RR_matches,img_RR_matches);
    imshow("消除誤匹配點後",img_RR_matches);

本文來自 上善若水道法自然 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/liuhaitaowq/article/details/52503806?utm_source=copy