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

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个元素的属性如下:
在这里插入图片描述

原图1
在这里插入图片描述
原图2
在这里插入图片描述
匹配图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SongpingWang

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值