BFMatcher
OpenCV中KeyPoint Matching的方法有两种Matching方式 :
- Brute-force matcher (cv::BFMatcher)
- Flann-based matcher (cv::FlannBasedMatcher)
Brute Force匹配是opencv二维特征点匹配常见的办法,BFMatcher总是尝试所有可能的匹配,从而使得它总能够找到最佳匹配,这也是Brute Force(暴力法)的原始含义。
实现原理
- 发现两幅图片分别提取出来N,M个特征向量
- 然后对N和M的特征向量进行匹配,找到最佳匹配
- 然后再画出匹配的特征显示出来
-
void match(
-
InputArray
queryDescriptors, 特征描述子1(待查询)
InputArray trainDescriptors, 特征描述子2
CV_OUT std::vector& matches, 匹配的特征
InputArray mask= noArray() 掩码
) const
-
void drawMatches(
-
InputArray
img1, 源图像1
const std::vector& keypoints1, 源图像1的特征描述子
InputArray img2, 源图像2
const std::vector& keypoints2, 源图像1的特征描述子
const std::vector& matches1to2, 特征1 与特征2 匹配的特征点[matches[i]]
InputOutputArray outImg, 输出图像
const Scalar& matchColor= Scalar::all(-1), 匹配点的颜色 (默认随机)
const Scalar& singlePointColor= Scalar::all(-1), 单个点的颜色 (默认随机)
const std::vector& matchesMask= std::vector(), 掩码
DrawMatchesFlags flags= DrawMatchesFlags::DEFAULT 绘制模式
)
实现流程:
- 以灰度图形式读入src1(待匹配图像)和src2。
- 通过用SURF的特征检测,把我们对两张图片获取的KeyPoint放到各自对应的descriptor里面。
- 根据上一步已经提取出的descriptor的两个Mat, 通过BFMatcher进行最佳匹配,存放到DMatch里面。
- 定义输出图像matchImg, 然后通过drawMatches的方法,把两个图片中的特征点和匹配的结果画出Matches,并显示。
头文件 image_feature_all.h
:声明类与公共函数
#pragma once
#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/xfeatures2d.hpp> //新增引入库
using namespace cv;
using namespace std;
class ImageFeature {
public:
void BFMatch_demo(Mat& image, Mat& image2);
};
主函数main.cpp
调用该类的公共成员函数
#include "image_feature_all.h"
int main(int argc, char** argv) {
const char* img_path = "D:\\Desktop\\match_dst.jpg";
const char* img_path2 = "D:\\Desktop\\match_raw.jpg";
Mat image = imread(img_path, IMREAD_GRAYSCALE);
Mat image2 = imread(img_path2, IMREAD_GRAYSCALE);
if (image.empty() || image2.empty()) {
cout << "图像数据为空,读取文件失败!" << endl;
}
ImageFeature imgfeature;
imgfeature.BFMatch_demo(image, image2);
waitKey(0);
destroyAllWindows();
return 0;
}
演示SURF–BFMatch
源文件 feature_extract.cpp
:实现类与公共函数
void ImageFeature::BFMatch_demo(Mat& image, Mat& image2) {
int minHessian = 400;
Ptr<xfeatures2d::SURF> detector = xfeatures2d::SURF::create(minHessian);
vector<KeyPoint> keypoints1, keypoints2;
Mat descriptor1, descriptor2;
detector->detectAndCompute(image, Mat(), keypoints1, descriptor1);
detector->detectAndCompute(image2, Mat(), keypoints2, descriptor2);
//cout << "keypoints1=" << keypoints1.size() << endl;
//cout << "keypoints2=" << keypoints2.size() << endl;
BFMatcher matcher(NORM_L2);
vector<DMatch> matches;
matcher.match(descriptor1, descriptor2, matches);
Mat matchImg;
drawMatches(image, keypoints1, image2, keypoints2, matches, matchImg);
imshow("matchImg", matchImg);
}
查看keypoints1第0个元素的属性如下:
原图1
原图2
匹配图