FLANN_Based SURF特征匹配
介绍
FLANN(Fast Library for Approximate Nearest Neighbors)在一个描述符集合(询问集)中找另一个集合(相当于训练集)的最近邻。
例子
#include <iostream>
#include <vector>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
int main()
{
Mat img1 = imread("../res/box.png", cv::IMREAD_GRAYSCALE);
Mat img2 = imread("../res/box_in_scene.png", cv::IMREAD_GRAYSCALE);
if(img1.empty()||img2.empty())
{
cout << "can't load image" << endl;
return -1;
}
//计算 keypoints and descriptor
int minHessian = 400;
Ptr<SURF> detector = SURF::create(minHessian);
std::vector<KeyPoint> keypoint1, keypoint2;
Mat descriptor1, descriptor2;
detector->detectAndCompute(img1, noArray(), keypoint1, descriptor1);
detector->detectAndCompute(img2, noArray(), keypoint2, descriptor2);
//匹配
Ptr<cv::DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED); // 基于FLANN匹配
vector<std::vector<DMatch>> knn_matches; // 因为要为每个descriptor找到最佳的k 个匹配, 对于每个descriptor来说,又是vector<DMatch>
matcher->knnMatch(descriptor1, descriptor2, knn_matches, 2);
//筛选最好的
const float ratio_thresh = 0.7f;
vector<DMatch> good_matchers;
for(int i=0; i<knn_matches.size(); i++)
{
if(knn_matches[i][0].distance < ratio_thresh*knn_matches[i][1].distance)// 最佳匹配距离/第二佳的匹配距离 < 0.7
{
good_matchers.push_back(knn_matches[i][0]); // 满足以上条件,最佳匹配才是我们需要的
}
}
//展示
Mat img_matchers;
drawMatches(img1, keypoint1, img2, keypoint2, good_matchers, img_matchers, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
imshow("Good Matchers", img_matchers);
waitKey();
return 0;
}
OpenCV API
- 画特征点、匹配( feature2d.hpp )
(
InputArray image, // source image
const std::vector< KeyPoint > & keypoints, // KeyPoints from the source image
InputOutputArray outImage, // 输出图像
const Scalar & color = Scalar::all(-1), // color for keypoints ,default (-1)随机
DrawMatchesFlags flags = DrawMatchesFlags::DEFAULT //画图的方式,默认就行, 或者NOT_DRAW_SINGLE_POINTS:没有匹配的点不画出来
)
(
InputArray img1, //first source image
const std::vector< KeyPoint > & keypoints1, //Keypoints from the first source image.
InputArray img2, // Second source image.
const std::vector< KeyPoint > & keypoints2, // Keypoints from the second source image.
const std::vector< DMatch > & matches1to2, // 两源图之间的匹配
InputOutputArray outImg, //输出图像
const Scalar & matchColor = Scalar::all(-1), // 随机颜色
const Scalar & singlePointColor = Scalar::all(-1), // 没有匹配的点的颜色
const std::vector< char > & matchesMask = std::vector< char >(), // Mask决定哪些点画,如果为空,全都画
DrawMatchesFlags flags = DrawMatchesFlags::DEFAULT //画图方式,如上API
)
- 从候选匹配中,为每个匹配找到最佳的k个匹配
void cv::DescriptorMatcher::knnMatch
(
InputArray queryDescriptors, // 第一张图片的匹配
InputArray trainDescriptors, // 第二张图片的匹配
std::vector< std::vector< DMatch > > & matches, // 存的匹配结果
int k, // 前k个最佳匹配,
InputArray mask = noArray(),
bool compactResult = false
) const