文章目录

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   绘制模式


)


实现流程:

  1. 以灰度图形式读入src1(待匹配图像)和src2。
  2. 通过用SURF的特征检测,把我们对两张图片获取的KeyPoint放到各自对应的descriptor里面。
  3. 根据上一步已经提取出的descriptor的两个Mat, 通过BFMatcher进行最佳匹配,存放到DMatch里面。
  4. 定义输出图像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个元素的属性如下:

OpenCV + CPP 系列(四十)图像特征匹配( BFMatcher 暴力匹配)_opencv

原图1

OpenCV + CPP 系列(四十)图像特征匹配( BFMatcher 暴力匹配)_opencv_02


原图2

OpenCV + CPP 系列(四十)图像特征匹配( BFMatcher 暴力匹配)_opencv_03


匹配图

OpenCV + CPP 系列(四十)图像特征匹配( BFMatcher 暴力匹配)_opencv_04