OpenCV_局部图像特征的提取与匹配_源代码
2015-08-12 08:27
661 查看
OpenCV的feature2d module中提供了从局部图像特征(Local image feature)的检测、特征向量(feature vector)的提取,到特征匹配的实现。其中的局部图像特征包括了常用的几种局部图像特征检测与描述算子,如FAST、SURF、SIFT、以及ORB。对于高维特征向量之间的匹配,OpenCV主要有两种方式:1)BruteForce穷举法;2)FLANN近似K近邻算法(包含了多种高维特征向量匹配的算法,例如随机森林等)。
feature2d module: http://docs.opencv.org/modules/features2d/doc/features2d.html
OpenCV FLANN: http://docs.opencv.org/modules/flann/doc/flann.html
FLANN: http://www.cs.ubc.ca/~mariusm/index.php/FLANN/FLANN
下面的这段代码实现了基于OpenCV的局部图像特征检测、特征向量提取、以及高维特征向量的匹配功能。
版本:OpenCV2.4.6
下面是对不同的局部图像特征检测算子的实验对比结果:
(说明:这里只是简单地对各个局部图像特征检测算子进行了对比,实际应用中需要考虑不同检测算子的特点,以及所应用的场景来选择。)
1. FAST+SIFT+FLANN (即局部图像特征检测算子+特征向量描述算子+高维特征向量匹配方法)
![](http://img.my.csdn.net/uploads/201301/10/1357822434_8068.jpg)
2. HARRIS+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822461_6110.jpg)
3. SURF+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822485_9162.jpg)
4. MSER+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822498_5562.jpg)
5. STAR+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822514_3250.jpg)
6.SIFT+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822529_5606.jpg)
7. ORB+ORB+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822548_8848.jpg)
< 转载请注明:http://blog.csdn.net/icvpr >
feature2d module: http://docs.opencv.org/modules/features2d/doc/features2d.html
OpenCV FLANN: http://docs.opencv.org/modules/flann/doc/flann.html
FLANN: http://www.cs.ubc.ca/~mariusm/index.php/FLANN/FLANN
下面的这段代码实现了基于OpenCV的局部图像特征检测、特征向量提取、以及高维特征向量的匹配功能。
版本:OpenCV2.4.6
#pragma once #include <iostream> #include <vector> #include <string> #include <opencv2/opencv.hpp> #include <opencv2/nonfree/nonfree.hpp> using namespace cv; using namespace std; class Feature { public: Feature(); ~Feature(); Feature(const string& detectType, const string& extractType, const string& matchType); public: void detectKeypoints(const Mat& image, vector<KeyPoint>& keypoints); // 检测特征点 void extractDescriptors(const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptor); // 提取特征向量 void bestMatch(const Mat& queryDescriptor, Mat& trainDescriptor, vector<DMatch>& matches); // 最近邻匹配 void knnMatch(const Mat& queryDescriptor, Mat& trainDescriptor, vector<vector<DMatch>>& matches, int k); // K近邻匹配 void saveKeypoints(const Mat& image, const vector<KeyPoint>& keypoints, const string& saveFileName = ""); // 保存特征点 void saveMatches(const Mat& queryImage, const vector<KeyPoint>& queryKeypoints, const Mat& trainImage, const vector<KeyPoint>& trainKeypoints, const vector<DMatch>& matches, const string& saveFileName = ""); // 保存匹配结果到图片中 private: Ptr<FeatureDetector> m_detector; Ptr<DescriptorExtractor> m_extractor; Ptr<DescriptorMatcher> m_matcher; string m_detectType; string m_extractType; string m_matchType; };Feature.cpp:
#include "Feature.h" Feature::Feature() { m_detectType = "SIFT"; m_extractType = "SIFT"; m_matchType = "FruteForce"; initModule_nonfree(); } Feature::~Feature() { } Feature::Feature(const string& detectType, const string& extractType, const string& matchType) { assert(!detectType.empty()); assert(!extractType.empty()); assert(!matchType.empty()); m_detectType = detectType; m_extractType = extractType; m_matchType = matchType; initModule_nonfree(); } void Feature::detectKeypoints(const Mat& image, std::vector<KeyPoint>& keypoints) { assert(image.type() == CV_8UC1); assert(!m_detectType.empty()); keypoints.clear(); m_detector = FeatureDetector::create(m_detectType); m_detector->detect(image, keypoints); } void Feature::extractDescriptors(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptor) { assert(image.type() == CV_8UC1); assert(!m_extractType.empty()); m_extractor = DescriptorExtractor::create(m_extractType); m_extractor->compute(image, keypoints, descriptor); } void Feature::bestMatch(const Mat& queryDescriptor, Mat& trainDescriptor, std::vector<DMatch>& matches) { assert(!queryDescriptor.empty()); assert(!trainDescriptor.empty()); //assert(!m_matchType.empty()); matches.clear(); m_matcher = DescriptorMatcher::create(m_matchType); m_matcher->add(std::vector<Mat>(1, trainDescriptor)); m_matcher->train(); m_matcher->match(queryDescriptor, matches); } void Feature::knnMatch(const Mat& queryDescriptor, Mat& trainDescriptor, std::vector<std::vector<DMatch>>& matches, int k) { assert(k > 0); assert(!queryDescriptor.empty()); assert(!trainDescriptor.empty()); assert(!m_matchType.empty()); matches.clear(); m_matcher = DescriptorMatcher::create(m_matchType); m_matcher->add(std::vector<Mat>(1, trainDescriptor)); m_matcher->train(); m_matcher->knnMatch(queryDescriptor, matches, k); } void Feature::saveKeypoints(const Mat& image, const vector<KeyPoint>& keypoints, const string& saveFileName) { assert(!saveFileName.empty()); Mat outImage; cv::drawKeypoints(image, keypoints, outImage, Scalar(255,255,0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS ); // string saveKeypointsImgName = saveFileName + "_" + m_detectType + ".jpg"; imwrite(saveKeypointsImgName, outImage); } void Feature::saveMatches(const Mat& queryImage, const vector<KeyPoint>& queryKeypoints, const Mat& trainImage, const vector<KeyPoint>& trainKeypoints, const vector<DMatch>& matches, const string& saveFileName) { assert(!saveFileName.empty()); Mat outImage; cv::drawMatches(queryImage, queryKeypoints, trainImage, trainKeypoints, matches, outImage, Scalar(255, 0, 0), Scalar(0, 255, 255), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); // string saveMatchImgName = saveFileName + "_" + m_detectType + "_" + m_extractType + "_" + m_matchType + ".jpg"; imwrite(saveMatchImgName, outImage); // imshow(saveMatchImgName, outImage); // waitKey(0); }
下面是对不同的局部图像特征检测算子的实验对比结果:
(说明:这里只是简单地对各个局部图像特征检测算子进行了对比,实际应用中需要考虑不同检测算子的特点,以及所应用的场景来选择。)
1. FAST+SIFT+FLANN (即局部图像特征检测算子+特征向量描述算子+高维特征向量匹配方法)
![](http://img.my.csdn.net/uploads/201301/10/1357822434_8068.jpg)
2. HARRIS+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822461_6110.jpg)
3. SURF+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822485_9162.jpg)
4. MSER+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822498_5562.jpg)
5. STAR+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822514_3250.jpg)
6.SIFT+SIFT+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822529_5606.jpg)
7. ORB+ORB+FLANN
![](http://img.my.csdn.net/uploads/201301/10/1357822548_8848.jpg)
< 转载请注明:http://blog.csdn.net/icvpr >
相关文章推荐
- IntelliJ IDEA 14.x 创建工作空间与多个Java Web项目
- jdists 一款强大的代码块预处理工具
- 零基础学python-2.11 回到我们的游戏 加入条件判断
- 零基础学python-2.11 回到我们的游戏 加入条件判断
- 零基础学python-2.10 条件判断 if语句
- 零基础学python-2.10 条件判断 if语句
- 杭电ACM2044java做法
- 黑马程序员——C语言笔记之数组
- 零基础学python-2.9 代码块与缩进
- 零基础学python-2.8 字典
- 零基础学python-2.8 字典
- 零基础学python-2.9 代码块与缩进
- PHP中“简单工厂模式”实例讲解
- PHP 单例模式解析和实战
- C语言的数组
- 内存中OLTP(Hekaton)里的事务日志记录
- Qt打开外部程序的三种方法(两种阻塞,一种不阻塞)
- C++ Memory Management C++ 内存管理
- Java中this关键字用法详解
- java中static关键字的用法详解