C/C++ 图像处理(10)------相近图像の匹配

   近期做项目调研的时候刚刚好需要用到图像匹配相关的算法,因此在这里做下记录。
   相近图像的匹配,其实归根结底只有一个目的,就是找到两张图像中反映相同现实位置的几个像素点,然后获得到这些像素点的坐标,以供后面仿射变换等算法进行处理。
   其基本思路如下:
1. 检测两张图像的特征点
2. 匹配检测到的特征点
3. 对匹配到的特征点对进行排序
4. 得到匹配度高的前n对特征点
5. 在两张图像中画出特征点并画出前n对特征点的对应关系(这一步可以不用,不过为了看着方便而已)
6. 获得前n对特征点的坐标
   OK,思路大概就是这些,具体的实现我是用OpenCV做的,如果后面需要进行详细的研究将会自己实现并把心得写在这篇博文中。
   本文的实现参考了浅墨的这篇文章,用的图也是他的文章给的DEMO中的图像。我在自己的图像上测试也没什么问题,下面将贴出实现代码:

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/legacy/legacy.hpp"
#include "iostream"
#include "time.h"
using namespace cv;

int main( )
{
    long time = clock();
    Mat image1 = imread("1.jpg");
    Mat image2 = imread("2.jpg");
    // 检测surf特征点
    vector keypoints1, keypoints2;
    SurfFeatureDetector detector(700);
    detector.detect(image1, keypoints1);
    detector.detect(image2, keypoints2);
    // 计算特征描述点
    SurfDescriptorExtractor surfDesc;
    Mat descriptros1, descriptros2;
    surfDesc.compute(image1, keypoints1, descriptros1);
    surfDesc.compute(image2, keypoints2, descriptros2);
    // 计算匹配点数
    BruteForceMatcherfloat>>matcher;
    vector matches;
    matcher.match(descriptros1, descriptros2, matches);//匹配特征向量
    // 对找到的匹配特征向量进行二分排序,将匹配度强的n个向量放到前面
    std::nth_element(matches.begin(), matches.begin() + 2, matches.end());
    matches.erase(matches.begin() + 3, matches.end());//擦除排序在阈值后面的所有匹配点
    // 画出匹配图
    Mat imageMatches;
    drawMatches(image1, keypoints1, image2, keypoints2, matches,imageMatches, Scalar(255, 0, 0));//进行绘制
    //获得并打印两张图匹配点的坐标
    vector ::iterator itor;//容器迭代器  
    printf("左边图像\n");
    itor = matches.begin();
    while (itor != matches.end())
    {
        printf("x:%.2f,y:%.2f\n", keypoints1[itor->queryIdx].pt.x, keypoints1[itor->queryIdx].pt.y);
        itor++;
    }
    printf("右边图像\n");
    itor = matches.begin();
    while (itor != matches.end())
    {
        printf("x:%.2f,y:%.2f\n", keypoints2[itor->trainIdx].pt.x, keypoints2[itor->trainIdx].pt.y);//注意这里用的是trainIdx,其保存着右边图像匹配点的序号,而上边的queryIdx保存着左边图像匹配点的序号
        itor++;
    }
    printf("匹配花费时间%dms", clock() - time);
    imshow("image2", imageMatches);
    waitKey();
    return 0;
}

   实现结果如下:

C/C++ 图像处理(10)------相近图像の匹配_第1张图片

你可能感兴趣的:(图像处理,C++,机器视觉)