Features2d【关键点检测】【关键点描述】【关键点匹配】

 【主代码】

#include 
#include 
#include 
using namespace cv;
int main()
{
    Mat img1 = imread("C:\\Users\\NeoFRS\\Desktop\\3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = imread("C:\\Users\\NeoFRS\\Desktop\\4.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    if(img1.empty() || img2.empty())
    {
        printf("Can't read one of the images\n");
        return -1;
    }
    // 关键点检测
    SurfFeatureDetector detector(400);
    vector<KeyPoint> keypoints1, keypoints2;
    detector.detect(img1, keypoints1);
    detector.detect(img2, keypoints2);
    // 计算关键点
    SurfDescriptorExtractor extractor;
    Mat descriptors1, descriptors2;
    extractor.compute(img1, keypoints1, descriptors1);
    extractor.compute(img2, keypoints2, descriptors2);
    // 匹配关键点
    BruteForceMatcher<L2<float> > matcher;
    vector<DMatch> matches;
    matcher.match(descriptors1, descriptors2, matches);
    // 画出结果
    namedWindow("matches", 1);
    Mat img_matches;
    drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
    imshow("matches", img_matches);
    waitKey(0);
}

【代码分析】

  • 读取两张图片
    Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
    if(img1.empty() || img2.empty())
    {
        printf("Can't read one of the images\n");
        return -1;
    }
  • 创建关键点检测器实例
    FastFeatureDetector detector(15);
    vector<KeyPoint> keypoints1, keypoints2;
    detector.detect(img1, keypoints1);
    detector.detect(img2, keypoints2);
  • 创建一个描述子提取器的实例
    SurfDescriptorExtractor extractor;
    Mat descriptors1, descriptors2;
    extractor.compute(img1, keypoints1, descriptors1);
    extractor.compute(img2, keypoints2, descriptors2);
    
  • 现在我们获取了两副图像的关键点的描述子,所以可以匹配它们了。首先创建一个匹配器,它可以从图像1中采用穷举法搜索图像2中最相似的关键点,采用的相似度量为欧氏度量。马氏距离和哈明(Hamming)距离也已被实现,可用于Brief描述子匹配。输出向量 matches 包含匹配好的点的索引对。
BruteForceMatcher<L2<float> > matcher;
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
  • 将匹配结果可视化
    namedWindow("matches", 1);
    Mat img_matches;
    drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
    imshow("matches", img_matches);
    waitKey(0);