OBR特征点匹配

这篇博客介绍了ORB特征,包括Oriented FAST关键点和BRIEF描述子的提取过程。接着,解释了暴力匹配的概念,即通过计算描述子间的距离找到最佳匹配点。文章还提供了实现ORB特征点匹配的代码流程,从准备图片到运行结果的展示。
摘要由CSDN通过智能技术生成

一、什么是ORB特征

ORB 特征亦由关键点和描述子两部分组成。它的关键点称为“Oriented FAST”,是一种改进的 FAST 角点,什么是 FAST 角点我们将在下文介绍。它的描述子称为 BRIEF(Binary Robust Independent Elementary Features)。因此,提取 ORB 特征分为两个步骤:
1)FAST 角点提取:找出图像中的” 角点”。相较于原版的 FAST, ORB 中计算了特征点的主方向,为后续的 BRIEF 描述子增加了旋转不变特性。
2)BRIEF 描述子:对前一步提取出特征点的周围图像区域进行描述。

二、什么是暴力匹配

**即对每一个特征点 xmt ,与所有的 xnt+1测量描述子的距离,然后排序,取最近的一个作为匹配点。**描述子距离表示了两个特征之间的相似程度,不过在实际运用中还可以取不同的距离度量范数。对于浮点类型的描述子,使用欧氏距离进行度量即可。而对于二进制的描述子(比如 BRIEF 这样的),我们往往使用汉明距离(Hamming distance)做为度量——两个二进制串之间的汉明距离,指的是它们不同位数的个数。

三、实现代码

1.准备图片
在这里插入图片描述
2.创建文件

gedit computeORB2.cpp

3.完整代码

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <string>
#include<sstream>
#include <fstream>
using namespace cv;
using namespace std;
// global variables

const double pi = 3.1415926;    // pi
 
// TODO implement this function
/**
 * compute the angle for ORB descriptor
 * @param [in] image input image
 * @param [in|out] detected keypoints
 */
void computeAngle(const cv::Mat &image, vector<cv::KeyPoint> &keypoints);
 
// TODO implement this function
/**
 * compute ORB descriptor
 * @param [in] image the input image
 * @param [in] keypoints detected keypoints
 * @param [out] desc descriptor
 */
typedef vector<bool> DescType;  // type of descriptor, 256 bools
void computeORBDesc(const cv::Mat &image, vector<cv::KeyPoint> &keypoints, vector<DescType> &desc);
 
// TODO implement this function
/**
 * brute-force match two sets of descriptors
 * @param desc1 the first descriptor
 * @param desc2 the second descriptor
 * @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) {
   
    std::string pattern_jpg ="./kitti_Image/Kitti_image_2/*.png";
    std::vector<cv::String> image_files;
    cv::glob(pattern_jpg, image_files);
    for (unsigned int frame = 0; frame < image_files.size(); ++frame) {
   //image_file.size()代表文件中总共的图片个数
		//imshow("1", image);
		//imshow("2", image1);
		//waitKey(30);
          // load image
        cv::Mat first_image = cv::imread(image_files[frame], 0);    // load grayscale image
        cv::Mat second_image = cv::imread(image_files[frame+1], 0);  // load grayscale image
 
    // plot the image
        //cv::imshow("first image", first_image);
        //cv::imshow("second image", second_image);
        //cv::waitKey(0);
    // detect FAST keypoints using threshold=40
        vector<cv::KeyPoint> keypoints;
        cv::FAST(first_image, keypoints, 40);
        cout << "keypoints: " << keypoints.size() << endl;
 
    // compute angle for each keypoint
        computeAngle(first_image, keypoints);
 
    // compute ORB descriptors
         vector<DescType> descriptors;
        computeORBDesc(first_image, keypoints, descriptors);
 
    // plot the keypoints
        cv::Mat image_show;
        cv::drawKeypoints(first_image, keypoints, image_show, cv::Scalar::all(-1),
                      cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
        string a="feature";
        string b=".png";
        stringstream ss;
        ss<<a<<frame<<b;
       // cv::imshow(ss.str(), image_show);
      
        cv::imwrite(ss.str(), image_show);
        cv::waitKey(0);
 
    // we can also match descriptors between images
    // same for the second
        vector<cv::KeyPoint> keypoints2;
        cv::FAST(second_image, keypoints2, 40);
        cout << "keypoints: " << keypoints2.size() << endl;
 
    // compute angle for each keypoint
        computeAngle(second_image, keypoints2);
 
    // compute ORB descriptors
        vector<DescType> descriptors2;
        computeORBDesc(second_image, keypoints2, descriptors2);
 
    // find matches
        vector<cv::DMatch> matches;
        bfMatch(descriptors, descriptors2, matches);
        if (matches.size()<4)
        {
   
            cout<<"匹配点过少!"<<endl;
        }
        cout << "matches: " << matches.size() << endl;
 
    // plot the matches
        cv::drawMatches(first_image, keypoints, second_image, keypoints2, matches, image_show);
        string c="matches";
        string d=".png";
        stringstream sb;
        sb<<c<<frame<<d;
        cv::imshow(sb.str(), image_show);
        cv::imwrite(sb.str(), image_show);
        cv::waitKey(0);
 
        cout << "done." << endl;
        cout<<endl;
	}
 
    return 0;
}
 
// -------------------------------------------------------------------------------------------------- //
 
// compute the angle
void computeAngle(const cv::Mat &image, vector<cv::KeyPoint> &keypoints) {
   
    int half_patch_size = 8;
    for (auto &kp : keypoints) {
   
    // START YOUR CODE HERE (~7 lines)
//        kp.angle = 0; // compute kp.angle
        double m10 = 0;
        double m01 = 0;
        int x =cvRound(kp.pt.x);
        int y =cvRound(kp.pt.y);
        if(x-half_patch_size<0||x+half_patch_size>image.cols||
           y-half_patch_size<0||y+half_patch_size>image.rows)
            continue;
        for(int u = x - half_patch_size;u<x + half_patch_size;++u)
        {
   
            for(int v = y -half_patch_size;v< y + half_patch_size;++v)
            {
   
                m10 +=  (u-x)*image.at<uchar>(v,u);
                m01 +=  (v-y)*image.at<uchar>(v,u);
            }
        }
 
        double theta = std::atan(m01/m10);
        kp.angle = theta * 180/pi;
        cout<<"kp.angel:"<<kp.angle<<endl;
//         END YOUR CODE HERE
    }
    return;
}
 
// -------------------------------------------------------------------------------------------------- //
// ORB pattern
int ORB_pattern[256 * 4] = {
   
        8, -3, 9, 5/*mean (0), correlation (0)*/,
        4, 2, 7, -</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值