OpenCV角点检测—ORB(8)

ORB特征提取

1.1 ORB算法概述

ORB是Oriented Brief的简称,是brief的改进版本(在原有的描述子的基础上增加了旋转不变性,ORB算法综合性能在各种评测里相较于其他特征提取算法是最好的。

1.1.1 相关概念认识

1.Brief描述子
Brief(Binary Robust Independent Elementary Feature)的缩写。描述子选取的主要思路:在特征点的附近随机的选取若干个点对,将这些点的灰度值的大小,组合成一个二进制串,并将这个二进制串作为特征点的特征描述子
BRIEF的优点在于速度,缺点:

  • 不具备旋转不变性;
  • 对噪声敏感;
  • 不具备尺度不变性;
    而ORB算法就是试图为解决上述的1,2问题而提出的。

2.尺度不变性
ORB没有解决尺度不变性,因为FAST本就不具备尺度不变性,但是对于以速度为主的描述子,一般应用于实时的视频处理中。

3.计算速度
ORB算法的执行速度是SIFT的100倍,是SURF的10倍。

1.1.2 ORB类相关源码分析

从opencv3.4.15源码路径下的features2d.hpp文件中可以看到:
在这里插入图片描述

1.1.3 实例:ORB算法描述和匹配

该实例采用摄像头获取检测图像,使用FLANN-LSH进行匹配。
实现代码:

#include<opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>

using namespace std;
using namespace cv;

int main()
{
    //[0]载入原图,并转化为灰度图
    Mat srciamge = imread("../3.png");
    imshow("原始图", srciamge);
    Mat grayImage;
    cvtColor(srciamge, grayImage, COLOR_BGR2GRAY);

    //[1]参数定义
    Ptr<ORB> featureDector = ORB::create();
    vector<KeyPoint> keypoints;
    Mat descriptors;

    //[2]调用detect函数检测出特征关键点,保存在keypoints中
    featureDector->detect(grayImage, keypoints);
    cout << "========" << keypoints.size() << endl;
    

    //[3]计算描述符(特征向量)
    Ptr<ORB> descriptor = ORB::create();
    descriptor->compute(grayImage, keypoints, descriptors);

    //[4]基于FLANN的描述符对象匹配
    flann::Index flannindex(descriptors, flann::LshIndexParams(12, 20, 2), cvflann::FLANN_DIST_HAMMING);
    // Ptr<DescriptorMatcher>  flannindex= DescriptorMatcher::create("FlannBased");

    //[5]初始化视频采集对象
    VideoCapture cap(0);
    cap.set(CAP_PROP_FRAME_WIDTH, 360);  //设置采集视频的宽度
    cap.set(CAP_PROP_FRAME_HEIGHT, 800);  //高度

    unsigned int frameCount = 0; // 帧数

    // [6]轮询,直接按下ESC退出循环
    while(1) {
        double time0 = static_cast<double>(getTickCount());  //记录其实时间
        Mat captureImage, captureImage_gray;//用于视频采集
        cap >> captureImage;  //采集视频帧
        if(captureImage.empty()) 
            continue;
        cvtColor(captureImage, captureImage_gray, COLOR_BGR2GRAY);

        //[7]绘制SIFT关键点并提取测试图像中的描述符
        vector<KeyPoint> capturekeypoints;
        Mat captureDescription;

        //[8]调用detecta函数检测出关键点,并保存在容器中
        featureDector->detect(captureImage_gray, capturekeypoints);

        //[9]计算描述符
        descriptor->compute(captureImage_gray, capturekeypoints, captureDescription);
        imshow("x", captureImage_gray);

        //[10]匹配和测试描述子,获取两个最近的描述子
        Mat matchIndex(captureDescription.rows, 2, CV_32SC1);
        Mat matchDistance(captureDescription.rows, 2, CV_32FC1);

        flannindex.knnSearch(captureDescription, matchIndex, matchDistance, 2, flann::SearchParams());

        //[11]根据劳式算法选出优秀的匹配
        vector<DMatch> goodMatches;
        for(int i=0 ; i< matchDistance.rows; i++)
        {
            if(matchDistance.at<float>(i,0) < 0.6 * matchDistance.at<float>(i,1)) {
                DMatch dmatches(i, matchIndex.at<int>(i, 0), matchDistance.at<float>(i,0));
                goodMatches.push_back(dmatches);
            }
        }

        //[12] 绘制并显示匹配框口
        Mat resultImage;
        drawMatches(captureImage, capturekeypoints, srciamge, keypoints, goodMatches,resultImage);
        
        imshow("匹配窗口", resultImage);

        //[13]显示帧率
        cout << "帧率:" << getTickCount() / (getTickCount() - time0) << endl;

        // 按下ESC退出
        if(char (waitKey(1) == 27)) break;

    }
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE "Debug")
find_package(OpenCV 3.4 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(open  1.cpp)
target_link_libraries(open ${OpenCV_LIBS})

在这里插入图片描述
knnSearch函数解析:
void cv::flann::GenericIndex<Distance>::knnSearch(const Mat& queries, Mat &indices, Mat &dists, int knn, const ::cvflann::SearchParams &params);
使用索引对给定查询点执行k-最邻近搜索。
参数:

  • 参数一:查询点
  • 参数二:将包含找到的k最邻近的索引向量。必须至少有knn大小
  • 参数三:将包含于K最近的距离向量,必须至少有knn大小
  • 参数四:要搜索的最近邻数
  • 参数四:搜索参数
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇

)">
下一篇>>