OpenCV_局部映像特徵的提取與匹配_原始碼

來源:互聯網
上載者:User

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.2 

LocalFeature.h

//局部映像特徵提取與匹配//      Author:  www.icvpr.com//Blog  :  http://blog.csdn.net/icvpr#ifndef _FEATURE_H_ #define _FEATURE_H_#include <iostream>#include <vector>#include <string>#include <opencv2/opencv.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;};#endif

LocalFeature.cpp

//  局部映像特徵提取與匹配  //  Author:  www.icvpr.com//  Blog  :  http://blog.csdn.net/icvpr#include "LocalFeature.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);}


測試代碼, main.cpp

//  局部映像特徵提取與匹配  //  Author:  www.icvpr.com  //  Blog  : http://blog.csdn.net/icvpr      #include   #include   #include <opencv2/opencv.hpp>    using namespace cv;  using namespace std;    #include "LocalFeature.h"    int main(int argc, char** argv)  {  if (argc != 6)  {  cout << "wrong usage!" << endl;  cout << "usage: .exe FAST SIFT BruteForce queryImage trainImage" << endl;  return -1;  }    string detectorType = argv[1];  string extractorType = argv[2];  string matchType = argv[3];  string queryImagePath = argv[4];  string trainImagePath = argv[5];    Mat queryImage = imread(queryImagePath, CV_LOAD_IMAGE_GRAYSCALE);  if (queryImage.empty())  {  cout<<"read failed"<< endl;  return -1;  }    Mat trainImage = imread(trainImagePath, CV_LOAD_IMAGE_GRAYSCALE);  if (trainImage.empty())  {  cout<<"read failed"<< endl;  return -1;  }    Feature feature(detectorType, extractorType, matchType);    vector queryKeypoints, trainKeypoints;  feature.detectKeypoints(queryImage, queryKeypoints);  feature.detectKeypoints(trainImage, trainKeypoints);    Mat queryDescriptor, trainDescriptor;    feature.extractDescriptors(queryImage, queryKeypoints, queryDescriptor);  feature.extractDescriptors(trainImage, trainKeypoints, trainDescriptor);    vector matches;  feature.bestMatch(queryDescriptor, trainDescriptor, matches);    vector<vector> knnmatches;  feature.knnMatch(queryDescriptor, trainDescriptor, knnmatches, 2);    Mat outImage;  feature.saveMatches(queryImage, queryKeypoints, trainImage, trainKeypoints, matches, "../");    return 0;  }  


下面是對不同的局部映像特徵檢測運算元的實驗對比結果:

(說明:這裡只是簡單地對各個局部映像特徵檢測運算元進行了對比,實際應用中需要考慮不同檢測運算元的特點,以及所應用的情境來選擇。)

1. FAST+SIFT+FLANN (即局部映像特徵檢測運算元+特徵向量描述運算元+高維特徵向量匹配方法)

2. HARRIS+SIFT+FLANN

3. SURF+SIFT+FLANN

4. MSER+SIFT+FLANN

5. STAR+SIFT+FLANN

6.SIFT+SIFT+FLANN

7. ORB+ORB+FLANN



相關內容:www.icvpr.com

------------------------------------------

< 轉載請註明:http://blog.csdn.net/icvpr >


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.