使用OpenCV自带函数实现特征点和描述子的计算,对比运行速度

环境

我在XP(32bit)电脑上搭建了Visual Studio 2010和OpenCV-3.1.0,OpenCV包含了OpenCV_contrib这个包。

OpenCV-3.1.0自带了6种能同时计算特征点和描述子的算法(笔者浏览了一遍,目测有6个函数)。分别是cv::xfeatures2d::SIFT、cv::xfeatures2d::SURF、cv::AKAZE、cv::BRISK、cv::KAZE、cv::ORB。

使用cv::xfeatures2d::SIFT、cv::xfeatures2d::SURF盈利的话,传闻是有专利问题的。

代码和图片来源

在OpenCV-3.1.0的说明文档找到SURF例程,此处是链接。稍作修改,就可以编写一段对比多种算法的程序。而图片直接使用TUM的rgbd-dataset。此处是链接

经过修改后的代码

以下直接上代码。代码介绍:使用dataset内,最简单的一段“xyz”。读取头两帧RGB图像。分别用上述六种方法计算特征点和描述子。对比不同方法的速度。

#include <stdio.h>
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/highgui.hpp"

#include <ctime>
using namespace cv;
using namespace cv::xfeatures2d;
void readme();
/* @function main */
int main( int argc, char** argv )
{
	
  std::cout << std::endl << "< Reading images..." << std::endl;  

  Mat img_1 = imread( "D:\\rgbd_dataset_freiburg1_xyz\\rgb\\1305031102.175304.png", IMREAD_GRAYSCALE );
  Mat img_2 = imread( "D:\\rgbd_dataset_freiburg1_xyz\\rgb\\1305031102.211214.png", IMREAD_GRAYSCALE );
  if( argc == 3 )
  { 
	  Mat img_1 = imread( argv[1], IMREAD_GRAYSCALE );
	  Mat img_2 = imread( argv[2], IMREAD_GRAYSCALE );
	  //readme(); return -1; 
  }
  else
  {
	  //readme();	  
  }

  if( !img_1.data || !img_2.data )
  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }

  //-- Step 1: Detect the keypoints using SURF Detector
  int minHessian = 400;
  //Ptr<SURF> detector = SURF::create( minHessian );


  std::vector<KeyPoint> keypoints_1, keypoints_2;
  std::vector<KeyPoint> keypoints_11, keypoints_22;
  std::vector<KeyPoint> keypoints_111, keypoints_222;
  std::vector<KeyPoint> keypoints_1111, keypoints_2222;
  std::vector<KeyPoint> keypoints_11111, keypoints_22222;
  std::vector<KeyPoint> keypoints_111111, keypoints_222222;

  
  clock_t time_stt = clock();
  std::cout << std::endl << "< Extracting keypoints from images using SIFT..." << std::endl;  
  Ptr<SIFT> detector = SIFT::create(  );
  detector->detect( img_1, keypoints_1 );
  detector->detect( img_2, keypoints_2 );  
  std::cout <<"img1:"<< keypoints_1.size() << " points  img2:" <<keypoints_2.size()   
        << " points" << std::endl;
  std::cout << "time use in SIFT is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms" << std::endl;  
  std::cout << "time of per keypoints is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC / (keypoints_1.size() + keypoints_2.size()) << "ms" << std::endl;
  std::cout <<  ">" << std::endl; 

  time_stt = clock();
  std::cout << std::endl << "< Extracting keypoints from images using SURF..." << std::endl;  
  Ptr<SURF> detectorSURF = SURF::create(  );
  detectorSURF->detect( img_1, keypoints_11 );
  detectorSURF->detect( img_2, keypoints_22 );
  std::cout <<"img11:"<< keypoints_11.size() << " points  img22:" <<keypoints_22.size()   
        << " points" << std::endl << ">" << std::endl;  
  std::cout << "time use in SURF is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms" << std::endl;
  std::cout << "time of per keypoints is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC / (keypoints_11.size() + keypoints_22.size()) << "ms" << std::endl;
  std::cout <<  ">" << std::endl; 

  
  time_stt = clock();
  std::cout << std::endl << "< Extracting keypoints from images using ORB..." << std::endl;  
  Ptr<ORB> detectorORB = ORB::create(  );
  detectorORB->detect( img_1, keypoints_111 );
  detectorORB->detect( img_2, keypoints_222 );
  std::cout <<"img111:"<< keypoints_111.size() << " points  img222:" <<keypoints_222.size()   
        << " points" << std::endl ;
  std::cout << "time use in ORB is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms" << std::endl;
  std::cout << "time of per keypoints is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC / (keypoints_111.size() + keypoints_222.size()) << "ms" << std::endl;
  std::cout <<  ">" << std::endl; 
  
  time_stt = clock();
  std::cout << std::endl << "< Extracting keypoints from images using AKAZE..." << std::endl;  
  Ptr<AKAZE> detectorAKAZE = AKAZE::create(  );
  detectorAKAZE->detect( img_1, keypoints_1111 );
  detectorAKAZE->detect( img_2, keypoints_2222 );
  std::cout <<"img1111:"<< keypoints_1111.size() << " points  img2222:" <<keypoints_2222.size()   
        << " points" << std::endl; 
  std::cout << "time use in AKAZE is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms" << std::endl;
  std::cout << "time of per keypoints is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC / (keypoints_1111.size() + keypoints_2222.size()) << "ms" << std::endl;
  std::cout <<  ">" << std::endl; 
  
  time_stt = clock();
  std::cout << std::endl << "< Extracting keypoints from images using BRISK..." << std::endl;  
  Ptr<BRISK> detectorBRISK = BRISK::create(  );
  detectorBRISK->detect( img_1, keypoints_11111 );
  detectorBRISK->detect( img_2, keypoints_22222 );
  std::cout <<"img11111:"<< keypoints_11111.size() << " points  img22222:" <<keypoints_22222.size()   
        << " points" << std::endl;
  std::cout << "time use in BRISK is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms" << std::endl;
  std::cout << "time of per keypoints is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC / (keypoints_11111.size() + keypoints_22222.size()) << "ms" << std::endl;
  std::cout <<  ">" << std::endl; 

  
  time_stt = clock();
  std::cout << std::endl << "< Extracting keypoints from images using KAZE..." << std::endl;  
  Ptr<KAZE> detectorKAZE = KAZE::create(  );
  detectorKAZE->detect( img_1, keypoints_111111 );
  detectorKAZE->detect( img_2, keypoints_222222 );
  std::cout <<"img111111:"<< keypoints_111111.size() << " points  img222222:" <<keypoints_222222.size()   
        << " points" << std::endl;  
  std::cout << "time use in KAZE is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms" << std::endl;
  std::cout << "time of per keypoints is " << 1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC / (keypoints_111111.size() + keypoints_222222.size()) << "ms" << std::endl;
  std::cout <<  ">" << std::endl; 
  


  //-- Draw keypoints
  Mat img_keypoints_1; 
  Mat img_keypoints_2;
  Mat img_keypoints_11; 
  Mat img_keypoints_22;
  Mat img_keypoints_111; 
  Mat img_keypoints_222;
  Mat img_keypoints_1111; 
  Mat img_keypoints_2222;
  Mat img_keypoints_11111; 
  Mat img_keypoints_22222;
  Mat img_keypoints_111111; 
  Mat img_keypoints_222222;
  drawKeypoints( img_1, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_2, keypoints_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_1, keypoints_11, img_keypoints_11, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_2, keypoints_22, img_keypoints_22, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_1, keypoints_111, img_keypoints_111, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_2, keypoints_222, img_keypoints_222, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_1, keypoints_1111, img_keypoints_1111, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_2, keypoints_2222, img_keypoints_2222, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_1, keypoints_11111, img_keypoints_11111, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_2, keypoints_22222, img_keypoints_22222, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_1, keypoints_111111, img_keypoints_111111, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_2, keypoints_222222, img_keypoints_222222, Scalar::all(-1), DrawMatchesFlags::DEFAULT );


  //-- Show detected (drawn) keypoints
  
  imshow("Keypoints 1", img_keypoints_1 );
  imshow("Keypoints 2", img_keypoints_2 );
  /*
  imshow("Keypoints 11", img_keypoints_11 );
  imshow("Keypoints 22", img_keypoints_22 );
  imshow("Keypoints 111", img_keypoints_111 );
  imshow("Keypoints 222", img_keypoints_222 );
  imshow("Keypoints 1111", img_keypoints_1111 );
  imshow("Keypoints 2222", img_keypoints_2222 );
  imshow("Keypoints 11111", img_keypoints_11111 );
  imshow("Keypoints 22222", img_keypoints_22222 );
  imshow("Keypoints 111111", img_keypoints_111111 );
  imshow("Keypoints 222222", img_keypoints_222222 );
  */
  waitKey(0);
  return 0;
  }
  /* @function readme */
  void readme()
  { std::cout << " Usage: ./SURF_detector <img1> <img2>" << std::endl; }

程序运行结果见下表。

OpenCV自带6个计算特征点和描述子的函数之运算速度对比
函数计算得到图片1的特征点数量(个)计算得到图片1的特征点数量(个)耗时(ms)平均每个特征点耗时(ms)
SIFT2006159621250.6030
SURF190816867350.2045
ORB5005001090.1100
AKAZE1454128017500.6456
BRISK2516192810780.2568
KAZE1742155659371.8193

由于是同时计算两张图片,对比之前翻过的其他前辈做过的实验,耗时比较长。

本机XP,CPU是 Intel Core 2 DUo CPU E7300 @2.66GHz。2G内存。

本文没有干货……干货请看参考资料。

 

参考1:Feature Description,https://docs.opencv.org/3.1.0/d5/dde/tutorial_feature_description.html

参考2:RGB-D SLAM Dataset and Benchmark,https://vision.in.tum.de/data/datasets/rgbd-dataset

参考3:OpenCV特征点提取算法对比,http://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/

参考4:学习OpenCV——BOW特征提取函数(特征点篇),http://www.cnblogs.com/GarfieldEr007/p/5401859.html

参考5:Oriented FAST and Rotated BRIEF,http://www.cnblogs.com/ronny/p/4083537.html

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值