OPENCV下SIFT算法使用方法OpenCV2.4.13+vs2013--可运行

原文:http://www.cnblogs.com/cj695/p/4041478.html



这几天继续在看Lowe大神的SIFT神作,看的眼花手脚抽筋。也是醉了!!!!实在看不下去,来点干货。我们知道opencv下自带SIFT特征检测以及MATCH匹配的库,这些库完全可以让我们进行傻瓜似的操作。但实际用起来的时候还不是那么简单。下文将对一个典型的基于OPENCV的SIFT特征点提取以及匹配的例程进行分析,并由此分析详细的对OPENCV中SIFT算法的使用进行一个介绍。

OPENCV下SIFT特征点提取与匹配的大致流程如下:

读取图片-》特征点检测(位置,角度,层)-》特征点描述的提取(16*8维的特征向量)-》匹配-》显示

其中,特征点提取主要有两个步骤,见上行黄子部分。下面做具体分析。

1、使用opencv内置的库读取两幅图片

2、生成一个SiftFeatureDetector的对象,这个对象顾名思义就是SIFT特征的探测器,用它来探测衣服图片中SIFT点的特征,存到一个KeyPoint类型的vector中。这里有必要说keypoint的数据结构,涉及内容较多,具体分析查看opencv中keypoint数据结构分析,里面讲的自认为讲的还算详细(表打我……)。简而言之最重要的一点在于:

keypoint只是保存了opencv的sift库检测到的特征点的一些基本信息,但sift所提取出来的特征向量其实不是在这个里面,特征向量通过SiftDescriptorExtractor 提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。具体见后文对SiftDescriptorExtractor 所生成的对象的详解。

就因为这点没有理解明白耽误了一上午的时间。哭死!

3、对图像所有KEYPOINT提取其特征向量:

得到keypoint只是达到了关键点的位置,方向等信息,并无该特征点的特征向量,要想提取得到特征向量就还要进行SiftDescriptorExtractor 的工作,建立了SiftDescriptorExtractor 对象后,通过该对象,对之前SIFT产生的特征点进行遍历,找到该特征点所对应的128维特征向量。具体方法参见opencv中SiftDescriptorExtractor所做的SIFT特征向量提取工作简单分析。通过这一步后,所有keypoint关键点的特征向量被保存到了一个MAT的数据结构中,作为特征。

 4、对两幅图的特征向量进行匹配,得到匹配值。

两幅图片的特征向量被提取出来后,我们就可以使用BruteForceMatcher对象对两幅图片的descriptor进行匹配,得到匹配的结果到matches中,这其中具体的匹配方法暂没细看,过段时间补上。

至此,SIFT从特征点的探测到最后的匹配都已经完成,虽然匹配部分不甚了解,只扫对于如何使用OPENCV进行sift特征的提取有了一定的理解。接下来可以开始进行下一步的工作了。

附:使用OPENCV下SIFT库做图像匹配的例程



[cpp]  view plain  copy
  1. // opencv_empty_proj.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.    
  4. #include "stdafx.h"  
  5. #include <opencv2/opencv.hpp>  
  6. #include <opencv2/features2d/features2d.hpp>  
  7. #include<opencv2/nonfree/nonfree.hpp>  
  8. #include<opencv2/legacy/legacy.hpp>  
  9. #include<vector>  
  10. using namespace std;  
  11. using namespace cv;  
  12.    
  13. int _tmain(int argc, _TCHAR* argv[])  
  14. {  
  15.     const char* imagename = "img.jpg";  
  16.     
  17.     //从文件中读入图像  
  18.     Mat img = imread(imagename);  
  19.     Mat img2=imread("img2.jpg");  
  20.    
  21.     //如果读入图像失败  
  22.     if(img.empty())  
  23.     {  
  24.             fprintf(stderr, "Can not load image %s\n", imagename);  
  25.             return -1;  
  26.     }  
  27.     if(img2.empty())  
  28.     {  
  29.             fprintf(stderr, "Can not load image %s\n", imagename);  
  30.             return -1;  
  31.     }  
  32.     //显示图像  
  33.     imshow("image before", img);  
  34.     imshow("image2 before",img2);  
  35.        
  36.    
  37.     //sift特征检测  
  38.     SiftFeatureDetector  siftdtc;  
  39.     vector<KeyPoint>kp1,kp2;  
  40.    
  41.     siftdtc.detect(img,kp1);  
  42.     Mat outimg1;  
  43.     drawKeypoints(img,kp1,outimg1);  
  44.     imshow("image1 keypoints",outimg1);  
  45.     KeyPoint kp;  
  46.    
  47.     vector<KeyPoint>::iterator itvc;  
  48.     for(itvc=kp1.begin();itvc!=kp1.end();itvc++)  
  49.     {  
  50.         cout<<"angle:"<<itvc->angle<<"\t"<<itvc->class_id<<"\t"<<itvc->octave<<"\t"<<itvc->pt<<"\t"<<itvc->response<<endl;  
  51.     }  
  52.    
  53.     siftdtc.detect(img2,kp2);  
  54.     Mat outimg2;  
  55.     drawKeypoints(img2,kp2,outimg2);  
  56.     imshow("image2 keypoints",outimg2);  
  57.    
  58.    
  59.     SiftDescriptorExtractor extractor;  
  60.     Mat descriptor1,descriptor2;  
  61.     BruteForceMatcher<L2<float>> matcher;  
  62.     vector<DMatch> matches;  
  63.     Mat img_matches;  
  64.     extractor.compute(img,kp1,descriptor1);  
  65.     extractor.compute(img2,kp2,descriptor2);  
  66.    
  67.    
  68.     imshow("desc",descriptor1);  
  69.     cout<<endl<<descriptor1<<endl;  
  70.     matcher.match(descriptor1,descriptor2,matches);  
  71.    
  72.     drawMatches(img,kp1,img2,kp2,matches,img_matches);  
  73.     imshow("matches",img_matches);  
  74.    
  75.     //此函数等待按键,按键盘任意键就返回  
  76.     waitKey();  
  77.     return 0;  
  78. }  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值