Opencv(C++)学习系列---特征点检测和匹配

这篇具有很好参考价值的文章主要介绍了Opencv(C++)学习系列---特征点检测和匹配。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关于特征检测和匹配的具体原理会在后续的文章中具体讲解,本文主要介绍Opencv实现的简单过程:
第一步:定义特征检测器(SIFT,SURF,ORB等)。

第二步:对图像中特征点进行检测,并将特征点存储在Keypoints中。

第三步:提取特征点的描述信息。

第四步:定义特征匹配器(特征匹配的方法主要有两种分别为暴力匹配BFmatch和FlannBased)。

第五步:过滤掉较差的匹配点位(一般根据临近两点的距离进行过滤)

主要是根据DMatch中的distance进行过滤,对于distance可以抽象理解为匹配的分值,distance越小说明检测点的相似度越高,效果越好。

第六步:对匹配的特征点显示。

代码1(未滤波,只限制筛选点数为20)

#include <iostream>
#include <opencv2/opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include <opencv2/xfeatures2d.hpp>


using namespace cv;  //包含cv命名空间
using namespace std;
using namespace xfeatures2d;


int main() {

	system("color 2E");
	//载入图片
	Mat src1 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\3.jpg",1);
	Mat src2 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\4.jpg", 1);

	//显示原图
	imshow("原图1",src1);
	imshow("原图2", src2);

	//定义变量
	vector<KeyPoint> keypoints1, keypoints2;//定义检测的特征点存储容器
	Mat descriptors1,descriptors2;//定义特征点描述信息为Mat类型
	Mat result_img;//匹配结果图片

	//创建sift特征检测器实例
	//将SIFT可以换位SURF、ORB
	Ptr<SIFT>detector = SIFT::create();
	//提取特征点
	detector->detect(src1,keypoints1,noArray());
	detector->detect(src2, keypoints2, Mat());


	//获取特征点的描述信息=>特征向量
	detector->compute(src1,keypoints1,descriptors1);
	detector->compute(src2, keypoints2, descriptors2);


	//定义匹配器的实例化=>方法为暴力匹配法
	Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE);//create中的参数可以填string FlannBased等匹配方法

	//第二种实例化方法
	//BFMatcher matcher;

	//进行暴力匹配
	vector<DMatch> matches;

	//第一个参数为queryDescription为目标,第二个参数为trainDescription模板
	matcher->match(descriptors1,descriptors2,matches);


	//限制特征点匹配数量=》只匹配前20个较好的特征点
	int num = 20;
	nth_element(matches.begin(), matches.begin()+num,matches.end());
	//vector去除20以后的元素
	matches.erase(matches.begin()+num,matches.end());
	

	//输出关键点和匹配结果
	//其中右侧图为trainDescription模板,左侧图为queryDescription目标
	//左图中的点与右图中进行匹配对应
	drawMatches(src1,keypoints1,src2,keypoints2, matches,result_img);
	drawKeypoints(src1,keypoints1,src1);
	drawKeypoints(src2,keypoints2,src2);
	
	imshow("匹配结果",result_img);
	imshow("特征点1",src1);
	imshow("特征点2",src2);

	waitKey(0);
	system("pause");
	return 0;
}

运行结果为:

Opencv(C++)学习系列---特征点检测和匹配

代码2(通过距离进行滤波)

#include <iostream>
#include <opencv2/opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include <opencv2/xfeatures2d.hpp>


using namespace cv;  //包含cv命名空间
using namespace std;
using namespace xfeatures2d;


int main() {

	system("color 2E");
	//载入图片
	Mat src1 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\3.jpg",1);
	Mat src2 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\4.jpg", 1);

	//显示原图
	imshow("原图1",src1);
	imshow("原图2", src2);

	//定义变量
	vector<KeyPoint> keypoints1, keypoints2;//定义检测的特征点存储容器
	Mat descriptors1,descriptors2;//定义特征点描述信息为Mat类型
	Mat result_img;//匹配结果图片

	//创建sift特征检测器实例
	//将SIFT可以换位SURF、ORB
	Ptr<SIFT>detector = SIFT::create();
	//提取特征点
	detector->detect(src1,keypoints1,noArray());
	detector->detect(src2, keypoints2, Mat());


	//获取特征点的描述信息=>特征向量
	detector->compute(src1,keypoints1,descriptors1);
	detector->compute(src2, keypoints2, descriptors2);


	//定义匹配器的实例化=>方法为暴力匹配法
	Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE);//create中的参数可以填string FlannBased等匹配方法

	//第二种实例化方法
	//BFMatcher matcher;

	//进行暴力匹配
	vector<DMatch> matches;

	//第一个参数为queryDescription为目标,第二个参数为trainDescription模板
	matcher->match(descriptors1,descriptors2,matches);


	//限制特征点匹配数量=》只匹配前20个较好的特征点
	int num = 20;
	nth_element(matches.begin(), matches.begin()+num,matches.end());
	//vector去除20以后的元素
	matches.erase(matches.begin()+num,matches.end());
	
	double Max_distance = matches[1].distance;
	double Min_distance = matches[1].distance;
	vector<DMatch> goodfeatrues;
	
	//根据特征点的距离去筛选
	for (int i = 0; i < matches.size(); i++)
	{
		double dist = matches[i].distance;
		if (dist>Max_distance)
		{
			Max_distance = dist;
		}
		if (dist<Min_distance)
		{
			Min_distance = dist;
		}
		
	}

	cout << "匹配点的最大距离:" << Max_distance << endl;
	cout << "匹配点的最小距离:" << Min_distance << endl;

	//M为距离阈值,M越大点数越多
	double M = 1.3;
	for (int  i = 0; i < matches.size(); i++)
	{
		double dist = matches[i].distance;
		if (dist<M*Min_distance)		{
			goodfeatrues.push_back(matches[i]);
		}
	}
	cout << "最终选取特征点的数量为:" << matches.size() << endl;

	//输出关键点和匹配结果
	//其中右侧图为trainDescription模板,左侧图为queryDescription目标
	//左图中的点与右图中进行匹配对应
	drawMatches(src1,keypoints1,src2,keypoints2, goodfeatrues,result_img);
	drawKeypoints(src1,keypoints1,src1);
	drawKeypoints(src2,keypoints2,src2);
	
	imshow("匹配结果",result_img);
	imshow("特征点1",src1);
	imshow("特征点2",src2);

	waitKey(0);
	system("pause");
	return 0;
}

运行结果为:

Opencv(C++)学习系列---特征点检测和匹配

 代码3(通过knnMatch匹配,可以通过对distance设置阈值进行滤波,效果最好)

#include <iostream>
#include <opencv2/opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include <opencv2/xfeatures2d.hpp>


using namespace cv;  //包含cv命名空间
using namespace std;
using namespace xfeatures2d;


int main() {

	system("color 2E");
	//载入图片
	Mat src1 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\3.jpg",1);
	Mat src2 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\4.jpg", 1);

	//显示原图
	imshow("原图1",src1);
	imshow("原图2", src2);

	//定义变量
	vector<KeyPoint> keypoints1, keypoints2;//定义检测的特征点存储容器
	Mat descriptors1,descriptors2;//定义特征点描述信息为Mat类型
	Mat result_img;//匹配结果图片

	//创建sift特征检测器实例
	//将SIFT可以换位SURF、ORB
	Ptr<SIFT>detector = SIFT::create();
	//提取特征点
	detector->detect(src1,keypoints1,noArray());
	detector->detect(src2, keypoints2, Mat());


	//获取特征点的描述信息=>特征向量
	detector->compute(src1,keypoints1,descriptors1);
	detector->compute(src2, keypoints2, descriptors2);


	//定义匹配器的实例化=>方法为暴力匹配法
	Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE);//create中的参数可以填string FlannBased等匹配方法

	//第二种实例化方法
	//BFMatcher matcher;

	//进行暴力匹配
	vector<DMatch> matches;

	vector<Mat>train_desc(1, descriptors2);
	matcher->add(train_desc);
	matcher->train();

	vector<vector<DMatch>> matchpoints;
	matcher->knnMatch(descriptors1,matchpoints,2);

	vector<DMatch> goodfeatur;
	for (int i = 0; i < matchpoints.size(); i++)
	{
		if (matchpoints[i][0].distance<0.15*matchpoints[i][1].distance)
		{
			goodfeatur.push_back(matchpoints[i][0]);
		}

	}
	cout << "筛选后的特征点数量为: " << goodfeatur.size() << endl;

	//输出关键点和匹配结果
	//其中右侧图为trainDescription模板,左侧图为queryDescription目标
	//左图中的点与右图中进行匹配对应
	drawMatches(src1,keypoints1,src2,keypoints2, goodfeatur,result_img);
	drawKeypoints(src1,keypoints1,src1);
	drawKeypoints(src2,keypoints2,src2);
	
	namedWindow("匹配结果",WINDOW_NORMAL);
	resizeWindow("匹配结果",500,500);
	imshow("匹配结果",result_img);

	waitKey(0);
	system("pause");
	return 0;
}

运行结果为:

Opencv(C++)学习系列---特征点检测和匹配文章来源地址https://www.toymoban.com/news/detail-440522.html

到了这里,关于Opencv(C++)学习系列---特征点检测和匹配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV(图像处理)-基于Python-特征检测-特征点匹配

    图像特征就是指有意义的图像区域,具有独特性,易于识别性,比如角点、斑点以及高密度区。而为什么角点具有重要的特征呢? 看下图: 观察ABD三张图片,我们不容易得知图像的位置,而CEF三张图我们特别容易找到它们在原图中对应的位置,这是因为ABD比较平滑,我们不

    2024年02月03日
    浏览(55)
  • opencv学习-特征匹配

    opencv特征匹配方法有两种,分别是: BF(Brute-Force),暴力特征匹配方法。它使用第一组中的每个特征的描述子,与第二组中的所有特征描述子进行匹配,计算它们之间的差距,然后将最接近一个匹配返回。 在进行批量特征匹配时,FLANN速度更快。 由于它使用的是邻近近似值

    2024年02月13日
    浏览(38)
  • opencv基础57-模板匹配cv2.matchTemplate()->(目标检测、图像识别、特征提取)

    OpenCV 提供了模板匹配(Template Matching)的功能,它允许你在图像中寻找特定模板(小图像)在目标图像中的匹配位置。模板匹配在计算机视觉中用于目标检测、图像识别、特征提取等领域。 以下是 OpenCV 中使用模板匹配的基本步骤: 加载图像 : 首先,加载目标图像和要匹配

    2024年02月13日
    浏览(48)
  • 特征点的检测与匹配(ORB,SIFT,SURFT比较)[opencv-python]

    本文旨在总结opencv-python上特征点的检测和匹配。 1、特征点的检测(包括:ORB,SIFT,SURFT) 2、特侦点匹配方法 (包括:暴力法,FLANN,以及随机抽样一致性优化RANSAC算法) 注:由于SURF专利问题,所以opencv官方包目前不支持SURF但支持ORB和SIFT,安装opencv-contrib-python包就可以解决 一

    2024年02月06日
    浏览(50)
  • opencv基础49-图像轮廓02-矩特征cv2.moments()->(形状分析、物体检测、图像识别、匹配)

    矩特征(Moments Features)是用于图像分析和模式识别的一种特征表示方法,用来描述图像的形状、几何特征和统计信息。矩特征可以用于识别图像中的对象、检测形状以及进行图像分类等任务。 矩特征通过计算图像像素的高阶矩来提取特征。这些矩可以表示图像的中心、尺度

    2024年02月13日
    浏览(45)
  • 【课程介绍】OpenCV 基础入门教程:图像读取、显示、保存,图像处理和增强(如滤波、边缘检测、图像变换),特征提取和匹配,目标检测和跟踪

    [ 专栏推荐 ] 😃 《视觉探索: OpenCV 基础入门教程》 😄 ❤️【简介】: Opencv 入门课程适合初学者,旨在介绍 Opencv 库的基础知识和核心功能。课程包括图像读取、显示、保存,图像处理和增强(如滤波、边缘检测、图像变换),特征提取和匹配,目标检测和跟踪等内容。学

    2024年02月16日
    浏览(398)
  • OpenCV图像特征提取学习五,HOG特征检测算法

    一、HOG向梯度直方图概述   向梯度直方图(Histogram of Oriented Gradient, HOG)特征是基于对稠密网格中归一化的局部方向梯度直方图的计算。此方法的基本观点是:局部目标的外表和形状可以被局部梯度或边缘方向的分布很好的描述,即使我们不知道对应的梯度和边缘的位置。在

    2024年02月04日
    浏览(48)
  • 学习opencv.js之基本使用方法(读取,显示,灰度化,边缘检测,特征值点检测)

    OpenCV.js 是 OpenCV(Open Source Computer Vision Library)的 JavaScript 版本。OpenCV 是一个广泛使用的计算机视觉和图像处理库,提供了一系列功能强大的算法和工具,用于处理图像、视频、特征提取、对象识别等计算机视觉任务。 OpenCV.js 是将 OpenCV 库编译为 JavaScript 的版本,使得开发者

    2024年02月16日
    浏览(44)
  • opencv特征匹配算法原理

    算法步骤: FAST进行特征点提取是根据当前点领域内的点的差值作为特征点的筛选标准 ( 1 ) 选择像素 p ,该像素值为 I p ,确定筛选阈值 T ( 2 ) 计算以 p 为圆心 3 为半径的 16 个像素点的灰度值 I x 和圆心 p 的灰度值 I p 的差值,如果存在连续 n 个点(算法第一个版本为 12 ) 满

    2024年02月03日
    浏览(47)
  • OpenCV实战(18)——特征匹配

    在关键点检测一节中,我们学习了如何检测图像中的关键点,其目的是用于执行局部图像分析。这些关键点需要足够独特,以便在具有相同对象的不同图像中能够检测到相同的点。 基于关键点执行图像分析需要构建丰富的表示来唯一地描述这些关键点,本节将重点介绍如何从

    2024年02月03日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包