Opencv 基本操作九 图像特征点提取

opencv中提取图像特征点的方式比较多,有ORB、FastFeatureDetector、BRISK、MSER、MSDDetector、KAZE、AKAZE、AgastFeatureDetector、GFTTDetector、SURF、SIFT等具体可以参考
https://www.p-chao.com/2017-06-14/opencv%E7%89%B9%E5%BE%81%E7%82%B9%E6%8F%90%E5%8F%96%E7%AE%97%E6%B3%95%E5%AF%B9%E6%AF%94/#Dense_SIFT
这里针对每个方法提取的特征点进行对比(包括点数、执行时间和可视化效果)
以下代码中Mattool.hpp的内容为 https://hpg123.blog.csdn.net/article/details/126427923 博文中代码。

关于上述特征点提取方法中,可用于计算特征向量的方法有以下6中

    freak->compute(src1, keyPoint1, descriptors_1);
    brief->compute(src1, keyPoint1, descriptors_1);
    surf->compute(src1, keyPoint1, descriptors_1);
    sift->compute(src1, keyPoint1, descriptors_1);
    orb->compute(src1, keyPoint1, descriptors_1);
    brisk->compute(src1, keyPoint1, descriptors_1);
#include"opencv2/core.hpp"
#include"opencv2/core/utility.hpp"
#include"opencv2/highgui.hpp"
#include"opencv2/features2d.hpp"
#include"opencv2/xfeatures2d.hpp"
#include"opencv2/imgproc.hpp"
#include"opencv2/flann.hpp"

#include "Mattool.hpp"
using namespace cv;
using namespace std;

template <class T>
std::string convertToString(T& value)
{
    
    
    std::ostringstream oss;
    oss << value;
    std::string str(oss.str());
    return str;
}
void showKeyPoint(string tilte,Mat src, vector<KeyPoint> &keyPoint1) {
    
    
    Mat result1;
    int kpSize = int(keyPoint1.size());
    string kpSizeStr = convertToString(kpSize);
    drawKeypoints(src, keyPoint1, result1, Scalar(0, 0, 255), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);//画出特征点
    imshow(tilte+" "+ kpSizeStr, result1);
    keyPoint1.clear();
}
std::chrono::steady_clock::time_point before, now;
//计算特征检测时间,绘制特征点并添加到vector中
void dear_kp(string ftype,Mat src1,vector<KeyPoint> keyPoint1, vector<Mat> &vms) {
    
    
    now = std::chrono::steady_clock::now();
    double duration_millsecond = std::chrono::duration<double, std::milli>(now- before).count();
    std::cout << ftype <<"\t 提取特征数:\t" << keyPoint1.size() << "\t 执行时间:\t" << duration_millsecond << "毫秒" << std::endl;
    Mat  dkp;
    drawKeypoints(src1, keyPoint1, dkp, Scalar(0, 0, 255), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);//画出特征点
    vms.push_back(dkp);
    keyPoint1.clear();
    before = std::chrono::steady_clock::now();
}
int main(int argc, char** argv) {
    
    
    vector<Mat> vms;
    Mat src1,dkp;
    src1 = imread("d\\6.jpg", 1);
    resize(src1, src1, {
    
     256,256 });
    vms.push_back(src1);

    before = std::chrono::steady_clock::now();
    vector<KeyPoint> keyPoint1;
    //特征点检测算子
    Ptr<Feature2D> orb = ORB::create();
    orb->detect(src1, keyPoint1);//compute
    dear_kp("orb", src1, keyPoint1, vms);

    Ptr<Feature2D> fast = FastFeatureDetector::create(600);
    fast->detect(src1, keyPoint1);
    dear_kp("fast", src1, keyPoint1, vms);

    Ptr<Feature2D> brisk = BRISK::create(100);
    brisk->detect(src1, keyPoint1);//compute
    dear_kp("brisk", src1, keyPoint1, vms);
    
    Ptr<Feature2D> mser = MSER::create();
    mser->detect(src1, keyPoint1);
    dear_kp("mser", src1, keyPoint1, vms);

    Ptr<Feature2D> msd = xfeatures2d::MSDDetector::create();
    msd->detect(src1, keyPoint1);
    dear_kp("msd", src1, keyPoint1, vms);

    Ptr<Feature2D> kaze = KAZE::create();//900ms
    kaze->detect(src1, keyPoint1);
    dear_kp("kaze", src1, keyPoint1, vms);

    Ptr<Feature2D> akaze = AKAZE::create();//400ms
    akaze->detect(src1, keyPoint1);
    dear_kp("akaze", src1, keyPoint1, vms);

    Ptr<Feature2D> agast = AgastFeatureDetector::create();//~0ms
    agast->detect(src1, keyPoint1);
    dear_kp("agast", src1, keyPoint1, vms);

    Ptr<Feature2D> gftt = GFTTDetector::create();//200ms
    gftt->detect(src1, keyPoint1);
    dear_kp("gftt", src1, keyPoint1, vms);

    Ptr<Feature2D>surf = xfeatures2d::SURF::create(800);
    surf->detect(src1, keyPoint1);
    dear_kp("surf", src1, keyPoint1, vms);

    Ptr<Feature2D>sift = SIFT::create();
    sift->detect(src1, keyPoint1);
    dear_kp("sift", src1, keyPoint1, vms);

    imshows("key point", vms,4);

    //计算描述算子,可以试一下其他的描述算子、orb
    surf->detect(src1, keyPoint1);
    Ptr<Feature2D> freak = xfeatures2d::FREAK::create();
    Ptr<Feature2D> brief = xfeatures2d::BriefDescriptorExtractor::create();
    Mat descriptors_1;
    freak->compute(src1, keyPoint1, descriptors_1);
    brief->compute(src1, keyPoint1, descriptors_1);
    surf->compute(src1, keyPoint1, descriptors_1);
    sift->compute(src1, keyPoint1, descriptors_1);
    orb->compute(src1, keyPoint1, descriptors_1);
    brisk->compute(src1, keyPoint1, descriptors_1);
    waitKey();
    return 0;
}

代码执行效果如下所示
在这里插入图片描述

针对不同特征点的输出信息如下所示

orb      提取特征数:   500      执行时间:     155.222毫秒
fast     提取特征数:   4789     执行时间:     0.9115毫秒
brisk    提取特征数:   6335     执行时间:     74.3206毫秒
mser     提取特征数:   222      执行时间:     92.924毫秒
msd      提取特征数:   1147     执行时间:     97.3641毫秒
kaze     提取特征数:   1465     执行时间:     151.281毫秒
akaze    提取特征数:   878      执行时间:     27.2064毫秒
agast    提取特征数:   4746     执行时间:     4.1234毫秒
gftt     提取特征数:   1000     执行时间:     7.2168毫秒
surf     提取特征数:   3277     执行时间:     14.6069毫秒
sift     提取特征数:   1830     执行时间:     37.5664毫秒

猜你喜欢

转载自blog.csdn.net/a486259/article/details/128552642
今日推荐