slambook2+ch7+orb_self代码理解

算法部分

  1. 获取关键点
    • 使用cv::FAST函数获取图像特征点,cv::FAST中自带高斯金字塔,实现了尺度不变性
  2. 计算描述子
    • 剔除边缘不稳定的关键点
    • 求关键点局部区域的旋转方向
    • 在关键点附近的局部区域(patch)组成的图像块,定义图像块的像素矩m01、m10,然后求图像块的像素质心(类似于重心)C=(m10/m_sqrt , m01/m_sqrt)
    • 连接图像块几何中心O与质心C,得到方向向量OC,定义特征点方向为 theta
    • 在关键点附近选取256对随机像素点(像素点对的选取方式为pattern,pattern服从随机分布、高斯分布等,特征点的分布方式不影响旋转结果),每对像素点都旋转 theat 角度。
    • 比较每对像素点,p大于q取1,小于取0。则每对关键点都由附近的像素点比较后组成了256位的描述子。
  3. 比较描述子
    • 每个特征点x(t)与所有x(t+1)计算汉明距离并排序,取最近点为匹配点
//
// Created by wcm on 2020/6/1.
//

//nmmintrin与SSE指令集有关
//SSE指令集提供标量和包裹式浮点运算
#include <opencv2/opencv.hpp>
#include <string>
#include <nmmintrin.h>
#include <chrono>

using namespace std;

//global variables
string first_file= "/home/automobile/wcm/slambook2/ch7/01.png";
string second_file= "/home/automobile/wcm/slambook2/ch7/02.png";

//Descriptor type
//32 bit unsigned int, will have 8, 8*32=256
typedef vector<uint32_t> DescType;

/**
 * compute descriptors of ORB keypoints
 * @param img input image
 * @param keypoints detected fast keypoints
 * @param descriptors descriptors
 *
 * Note:if a keypoint goes outside the image boundary(8 pixels),
 * descriptors will not be compute and leave as empty
 */
void ComputeORB(const cv::Mat &img, vector<cv::KeyPoint> &keypoints, vector<DescType> &descriptors);

/**
 * Brute-Force match two sets of descriptors
 * @param desc1 the first descriptors
 * @param desc2 the second descriptors
 * @param matches matches of two images
 */
void BfMatch(const vector<DescType> &desc1, const vector<DescType> &desc2, vector<cv::DMatch> &matches);

int main(int argc, char **argv){
   

    //load image
    cv::Mat first_image = cv::imread(first_file, CV_LOAD_IMAGE_COLOR);
    cv::Mat second_image = cv::imread(second_file, CV_LOAD_IMAGE_COLOR);
    assert(first_image.data != nullptr && second_image.data != nullptr );

    //detect fast keypoints using threshold=40
    //ORB使用FAST算法检测特征点
    //OpenCV中的ORB采用了图像金字塔来解决尺度变换一致性
    //自定义ComputeORB函数来描述ORB特征点,并旋转使其具备旋转尺度不变性
    chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
    vector<cv::KeyPoint> keypoints1;
    cv::FAST(first_image, keypoints1, 40);
    vector<DescType> descriptor1;
    ComputeORB(first_image, keypoints1, descriptor1);

    //same for the second
    vector<cv::KeyPoint> keypoints2;
    cv::FAST(second_image, keypoints2, 40);
    vector<DescType> descriptor2;
    ComputeORB(second_image, keypoints2, descriptor2);
    chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
    chrono::duration<double> time_used_extract = chrono::duration_cast<chrono::duration<double>>(t2 - t1);
    cout << " extract ORB cost = " << time_used_extract.count() << " seconds. "<< endl;

    //find matches
    //自定义BfMatch函数,匹配特征点
    vector<cv::DMatch> matches;
    chrono::steady_clock::time_point t3 = chrono::steady_clock::now();
    BfMatch(descriptor1, descriptor2, matches);
    chrono::steady_clock::time_point t4 = chrono::steady_clock::now();
    chrono::duration<double> time_used_match = chrono::duration_cast<chrono::duration<double>>(t4 - t3);
    cout << " match ORB cost " << time_used_match.count() << " seconds" <<endl;
    chrono::duration<double> ORB_total_time_used = chrono::duration_cast<chrono::duration<double>>(time_used_extract + time_used_match);
    cout << " extract and match ORB cost = " << ORB_total_time_used.count() << " seconds" <<endl;
    cout << " matches: " << matches.size() <<endl;



    //plot the matches
    cv::Mat image_show;
    cv::drawMatches(first_image, keypoints1, second_image, keypoints2, matches, image_show);
    cv::imshow("matches", image_show);
    cv::imwrite("matches.png", image_show);
    cv::waitKey(0);

    cout<<" done. "<<endl;
    return 0;
}

//-------------------------------------------------------------//
//ORB pattern
//特征点附近256次像素比较,每次比较两个像素点
//patter选取的两个像素点的分布方式,如高斯分布,随机分布,每种分布的结果应该差不多
int ORB_pattern[256 * 4] = {
   
        8, -3, 9, 5/*mean (0), correlation (0)*/,
        4, 2, 7, -12/*mean (1.12461e-05), correlation (0.0437584)*/,
        -11, 9, -8, 2/*mean (3.37382e-05), correlation (0.0617409)*/,
        7, -12, 12, -13/*mean (5.62303e-05), correlation (0.0636977)*/,
        2, -13, 2, 12/*mean (0.000134953), correlation (0.085099)*/,
        1, -7, 1, 6/*mean (0.000528565), correlation (0.0857175)*/,
        -2, -10, -2, -4/*mean (0.0188821), correlation (0.0985774)*/,
        -13, -13, -11, -8/*mean (0.0363135), correlation (0.0899616)*/,
        -13, -3, -12, -9/*mean (0.121806), correlation (0.099849)*/,
        10, 4, 11, 9/*mean (0.122065), correlation (0.093285)*/,
        -13, -8, -8, -9/*mean (0.162787), correlation (0.0942748)*/,
        -11, 7, -9, 12/*mean (0.21561), correlation (0.0974438)*/,
        7, 7, 12, 6/*mean (0.160583), correlation (0.130064)*/,
        -4, -5, -3, 0/*mean (0.228171), correlation (0.132998)*/,
        -13, 2, -12, -3/*mean (0.00997526), correlation (0.145926)*/,
        -9, 0, -7, 5/*mean (0.198234), correlation (0.143636)*/,
        12, -6, 12, -1/*mean (0.0676226), correlation (0.16689)*/,
        -3, 6, -2, 12/*mean (0.166847), correlation (0.171682)*/,
        -6, -13, -4, -8/*mean (0.101215), correlation (0.179716)*/,
        11, -13, 12, -8/*mean (0.200641), correlation (0.192279)*/,
        4, 7, 5, 1/*mean (0.205106), correlation (0.186848)*/,
        5, -3, 10, -3/*mean (0.234908), correlation (0.192319)*/,
        3, -7, 6, 12/*mean (0.0709964), correlation (0.210872)*/,
        -8, -7, -6, -2/*mean (0.0939834), correlation (0.212589)*/,
        -2, 11, -1, -10/*mean (0.127778), correlation (0.20866)*/,
        -13, 12, -8, 10/*mean (0.14783), correlation (0.206356)*/,
        -7, 3, -5, -3/*mean (0.182141), correlation (0.198942)*/,
        -4, 2, -3, 7/*mean (0.188237), correlation (0.21384)*/,
        -10, -12, -6, 11/*mea
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值