opencv3.1.0 特征点检测与图像匹配(features2d、xfeatures2d)
2016-08-08 16:45
483 查看
特征检测与匹配,在物体检测,视觉跟踪,三维重建等领域都有广泛的应用。所以学习features2d、xfeatures2d中函数的使用,很有必要。
1、得到特征点与特征点描述(SIFT SURF ORB AKAZE)
(1)SIFT
(2)SURF(可以认为是尺度不变特征变换sift的加速版)
(3)ORB(实际来看,速度很快,但效果并不一定好)
(4)AKAZE(与ORB在同一个hpp中)
#include <opencv2\features2d\features2d.hpp>
Ptr<AKAZE> akaze = AKAZE::create();
akaze->detectAndCompute(image, noArray(), key_points, descriptor);
2、特征点匹配的几种方法
(1)与ORB结合使用,效果较好
(2)个人感觉这种方法,效果与暴力匹配法没啥区别,但是被注释掉的方法,效果不好
(3)也叫暴力匹配法,此种方法结合sift、surf用的比较多
3、进一步匹配(寻找源图与目标图像之间的透视变换)
效果如下所示(没有发现匹配不对的点)
1、得到特征点与特征点描述(SIFT SURF ORB AKAZE)
(1)SIFT
#include <opencv2\xfeatures2d\nonfree.hpp> vector<KeyPoint> key_points; Mat descriptor; Ptr<Feature2D> sift = xfeatures2d::SIFT::create(0, 3, 0.04, 10); sift->detectAndCompute(image, noArray(), key_points, descriptor);
(2)SURF(可以认为是尺度不变特征变换sift的加速版)
#include <opencv2\xfeatures2d\nonfree.hpp> Ptr<Feature2D> surf = xfeatures2d::SURF::create(); surf->detectAndCompute(image, noArray(), key_points, descriptor);
(3)ORB(实际来看,速度很快,但效果并不一定好)
#include <opencv2\features2d\features2d.hpp> Ptr<ORB> orb = ORB::create(5000); orb->detectAndCompute(image, noArray(), key_points, descriptor);
(4)AKAZE(与ORB在同一个hpp中)
#include <opencv2\features2d\features2d.hpp>
Ptr<AKAZE> akaze = AKAZE::create();
akaze->detectAndCompute(image, noArray(), key_points, descriptor);
2、特征点匹配的几种方法
(1)与ORB结合使用,效果较好
void match_features_knn(Mat& query, Mat& train, vector<DMatch>& matches) { flann::Index flannIndex(query,flann::LshIndexParams(12,20,2),cvflann::FLANN_DIST_HAMMING); Mat matchindex(train.rows,2,CV_32SC1); Mat matchdistance(train.rows, 2, CV_32FC1); flannIndex.knnSearch(train, matchindex, matchdistance,2,flann::SearchParams()); //根据劳氏算法 for (int i = 0; i < matchdistance.rows; i++) { if (matchdistance.at<float>(i, 0) < 0.6*matchdistance.at<float>(i, 1)) { DMatch dmatches(matchindex.at<int>(i, 0),i, matchdistance.at<float>(i, 0)); matches.push_back(dmatches); } } }
(2)个人感觉这种方法,效果与暴力匹配法没啥区别,但是被注释掉的方法,效果不好
void match_features_FLANN(Mat& query, Mat& train, vector<DMatch>& matches) { FlannBasedMatcher matcher; /*vector<DMatch> match; matcher.match(query, train, match); double max_dist = 0; double min_dist = 100; for (int i = 0; i < match.size(); i++) { double dist = match[i].distance; if (dist < min_dist) min_dist = dist; if (dist > max_dist) max_dist = dist; } for (int i = 0; i < match.size(); i++) { if (match[i].distance < 2 * min_dist) matches.push_back(match[i]); }*/ vector<vector<DMatch>> knn_matches; matcher.knnMatch(query, train, knn_matches, 2); //获取满足Ratio Test的最小匹配的距离 float min_dist = FLT_MAX; for (int r = 0; r < knn_matches.size(); ++r) { //Ratio Test if (knn_matches[r][0].distance > 0.6*knn_matches[r][1].distance) continue; float dist = knn_matches[r][0].distance; if (dist < min_dist) min_dist = dist; } matches.clear(); for (size_t r = 0; r < knn_matches.size(); ++r) { //排除不满足Ratio Test的点和匹配距离过大的点 if ( knn_matches[r][0].distance > 0.6*knn_matches[r][1].distance || knn_matches[r][0].distance > 5 * max(min_dist, 10.0f) ) continue; //保存匹配点 matches.push_back(knn_matches[r][0]); } }
(3)也叫暴力匹配法,此种方法结合sift、surf用的比较多
void match_features(Mat& query, Mat& train, vector<DMatch>& matches) { vector<vector<DMatch>> knn_matches; BFMatcher matcher(NORM_L2); matcher.knnMatch(query, train, knn_matches, 2); //获取满足Ratio Test的最小匹配的距离 float min_dist = FLT_MAX; for (int r = 0; r < knn_matches.size(); ++r) { //Ratio Test if (knn_matches[r][0].distance > 0.6*knn_matches[r][1].distance) continue; float dist = knn_matches[r][0].distance; if (dist < min_dist) min_dist = dist; } matches.clear(); for (size_t r = 0; r < knn_matches.size(); ++r) { //排除不满足Ratio Test的点和匹配距离过大的点 if ( knn_matches[r][0].distance > 0.6*knn_matches[r][1].distance || knn_matches[r][0].distance > 5 * max(min_dist, 10.0f) ) continue; //保存匹配点 matches.push_back(knn_matches[r][0]); } }看下面的效果图,会发现大部分点都是匹配正确的。但是,依然有少部分点匹配的明显不正确。
3、进一步匹配(寻找源图与目标图像之间的透视变换)
bool refineMatchesWithHomography(const std::vector<cv::KeyPoint>& queryKeypoints,const std::vector<cv::KeyPoint>& trainKeypoints, float reprojectionThreshold,std::vector<cv::DMatch>& matches,cv::Mat& homography) { const int minNumberMatchesAllowed = 8; if (matches.size() < minNumberMatchesAllowed) return false; // Prepare data for cv::findHomography std::vector<cv::Point2f> srcPoints(matches.size()); std::vector<cv::Point2f> dstPoints(matches.size()); for (size_t i = 0; i < matches.size(); i++) { srcPoints[i] = trainKeypoints[matches[i].trainIdx].pt; dstPoints[i] = queryKeypoints[matches[i].queryIdx].pt; //srcPoints[i] = trainKeypoints[i].pt; //dstPoints[i] = queryKeypoints[i].pt; } // Find homography matrix and get inliers mask std::vector<unsigned char> inliersMask(srcPoints.size()); homography = cv::findHomography(srcPoints,dstPoints,CV_FM_RANSAC,reprojectionThreshold,inliersMask); std::vector<cv::DMatch> inliers; for (size_t i = 0; i<inliersMask.size(); i++) { if (inliersMask[i]) inliers.push_back(matches[i]); } matches.swap(inliers); return matches.size() > minNumberMatchesAllowed; }
效果如下所示(没有发现匹配不对的点)
相关文章推荐
- OpenCV: 特征点检测与图像匹配
- OpenCV之feature2d 模块. 2D特征框架(2)特征描述 使用FLANN进行特征点匹配 使用二维特征点(Features2D)和单映射(Homography)寻找已知物体 平面物体检测
- OpenCV成长之路(9):特征点检测与图像匹配
- OpenCV学习笔记(四十六)——FAST特征点检测features2D
- OpenCV成长之路(9):特征点检测与图像匹配
- OpenCV成长之路(9):特征点检测与图像匹配
- OpenCV 特征点检测与图像匹配
- OpenCV: Features2D Features FrameWork 图像二维特征检测、描述以及匹配框架的层次解析
- OpenCV特征点检测匹配图像-----添加包围盒
- OpenCV -- 特征点检测与图像匹配
- OpenCV特征点检测匹配图像-----添加包围盒
- OpenCV成长之路(9):特征点检测与图像匹配
- OpenCV特征点检测匹配图像-----添加包围盒
- OpenCV成长之路:特征点检测与图像匹配
- OpenCV成长之路(9):特征点检测与图像匹配
- OpenCV:特征点检测与图像匹配
- OpenCV成长之路(9):特征点检测与图像匹配
- OpenCV特征点检测匹配图像-----添加包围盒
- opencv图像特征检测及匹配(harris,sift,surf,fast,breif,orb,BFmatch,FlannBasedMatcher)
- OpenCV--特征点检测与图像匹配