博客
关于我
高翔Slambook第七讲代码解读(特征点提取)
阅读量:324 次
发布时间:2019-03-04

本文共 3006 字,大约阅读时间需要 10 分钟。

作为一个视觉SLAM的入门学徒,我看完了高翔的书,学习了视频,也在自己的电脑上运行了一遍代码。但是感觉学习内容还是有些空洞,像是在走过场一样。于是,我决定真正从代码入手,尽管自己对编程基础较为薄弱。

特征点提取是整个程序的基础,通常作为一个封装好的函数来调用。所以我决定先从这个基础程序开始学习。

特征点提取的目的与步骤

特征点的提取目的是在每张图像中找到“区分度较高”的像素点,这里的“区分度较高”具体指的是FAST角点。FAST角点是一种在图像中能够有效地区分不同区域的点。

从代码注释来看,特征点提取的步骤基本上可以分为以下几个部分:

  • 读取图像:使用OpenCV中的imread函数读取两张图像。
  • 初始化存储特征点数据的变量:准备好两个向量keypoints_1keypoints_2来存储两张图像中的特征点。
  • 提取每张图像的FAST角点:使用FAST算法检测图像中的角点位置。
  • 计算每张图像每个FAST角点的BRIEF描述子:根据提取到的角点位置,计算其BRIEF描述子。
  • 根据刚刚计算好的BRIEF描述子,对两张图的角点进行匹配:使用BFMatcher进行特征点匹配。
  • 筛去匹配度较差的角点配对:根据特征点之间的距离进行筛选,保留匹配度较高的点对。
  • 绘制匹配结果:将匹配点对绘制到图像中,展示结果。
  • 代码解读与理解

    接下来,我开始逐行分析代码。

    #include 
    #include
    #include
    #include
    using namespace std; using namespace cv;

    这些是OpenCV的基本头文件包含,using namespace std; using namespace cv;使代码更简洁易读。

    int main ( int argc, char** argv ){
    if ( argc != 3 ) {
    cout << "usage: feature_extraction img1 img2" << endl;
    return 1;
    }

    程序需要三个参数:两个图像文件名和一个输出窗口名。参数个数检查后,继续执行。

    Mat img_1 = imread ( argv[1], CV_LOAD_IMAGE_COLOR );
    Mat img_2 = imread ( argv[2], CV_LOAD_IMAGE_COLOR );

    使用imread函数读取两张图像,CV_LOAD_IMAGE_COLOR表示读取彩色图像。

    vector
    keypoints_1, keypoints_2;
    Mat descriptors_1, descriptors_2;
    Ptr
    detector = ORB::create();
    Ptr
    descriptor = ORB::create();
    Ptr
    matcher = DescriptorMatcher::create ("BruteForce-Hamming");

    定义了两个向量keypoints_1keypoints_2,以及用于存储描述子的矩阵descriptors_1descriptors_2。创建了ORB特征检测器和描述子提取器,以及匹配器。

    detector->detect ( img_1, keypoints_1 );
    detector->detect ( img_2, keypoints_2 );

    使用detect方法分别在两张图像中检测出FAST角点,并存储到keypoints_1keypoints_2中。

    descriptor->compute ( img_1, keypoints_1, descriptors_1 );
    descriptor->compute ( img_2, keypoints_2, descriptors_2 );

    计算每个角点的BRIEF描述子,并存储到descriptors_1descriptors_2中。

    Mat outimg1;
    drawKeypoints( img_1, keypoints_1, outimg1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
    imshow("ORB特征点", outimg1);

    绘制图像img_1中的特征点,并显示窗口。

    vector
    matches;
    matcher->match ( descriptors_1, descriptors_2, matches );

    使用BFMatcher对描述子进行匹配,存储匹配结果。

    double min_dist = 10000, max_dist = 0;
    for ( int i = 0; i < descriptors_1.rows; i++ ) {
    double dist = matches[i].distance;
    if ( dist < min_dist ) min_dist = dist;
    if ( dist > max_dist ) max_dist = dist;
    }
    printf ( "-- Max dist : %f \n", max_dist );
    printf ( "-- Min dist : %f \n", min_dist );

    计算特征点匹配的最小距离和最大距离,并输出结果。

    std::vector
    good_matches;
    for ( int i = 0; i < descriptors_1.rows; i++ ) {
    if ( matches[i].distance <= max ( 2*min_dist, 30.0 ) ) {
    good_matches.push_back ( matches[i] );
    }
    }

    筛选匹配距离在一定范围内的点对,存储到good_matches中。

    Mat img_match;
    drawMatches ( img_1, keypoints_1, img_2, keypoints_2, matches, img_match );
    imshow ( "所有匹配点对", img_match );
    imshow ( "优化后匹配点对", img_goodmatch );
    waitKey(0);
    return 0;

    绘制所有匹配点对和优化后的匹配点对,并显示窗口。

    代码运行与理解

    通过上述代码,可以实现以下功能:

  • 读取两张图像。
  • 在每张图像中检测出FAST角点。
  • 计算每个角点的BRIEF描述子。
  • 使用BFMatcher对描述子进行匹配。
  • 筛选匹配度较高的特征点对。
  • 绘制匹配点对并展示。
  • 总结与展望

    通过学习和分析上述代码,我对特征点提取有了更深入的理解。虽然代码基础较弱,但通过不断的学习和实践,相信自己能够逐步掌握视觉SLAM相关技术。

    转载地址:http://xpaq.baihongyu.com/

    你可能感兴趣的文章
    Nodejs process.nextTick() 使用详解
    查看>>
    NodeJS yarn 或 npm如何切换淘宝或国外镜像源
    查看>>
    nodejs 中间件理解
    查看>>
    nodejs 创建HTTP服务器详解
    查看>>
    nodejs 发起 GET 请求示例和 POST 请求示例
    查看>>
    NodeJS 导入导出模块的方法( 代码演示 )
    查看>>
    nodejs 开发websocket 笔记
    查看>>
    nodejs 的 Buffer 详解
    查看>>
    NodeJS 的环境变量: 开发环境vs生产环境
    查看>>
    nodejs 读取xlsx文件内容
    查看>>
    nodejs 运行CMD命令
    查看>>
    Nodejs+Express+Mysql实现简单用户管理增删改查
    查看>>
    nodejs+nginx获取真实ip
    查看>>
    nodejs-mime类型
    查看>>
    NodeJs——(11)控制权转移next
    查看>>
    NodeJS、NPM安装配置步骤(windows版本)
    查看>>
    NodeJS、NPM安装配置步骤(windows版本)
    查看>>
    nodejs下的express安装
    查看>>
    nodejs与javascript中的aes加密
    查看>>
    nodejs中Express 路由统一设置缓存的小技巧
    查看>>