问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

怎样使用opencv中的sift和surf函数来检测特征点和描述特征点

发布网友 发布时间:2022-04-26 02:33

我来回答

2个回答

懂视网 时间:2022-04-15 01:01

概述 之前的文章SURF和SIFT算子实现特征点检测简单地讲了利用SIFT和SURF算子检测特征点,在检测的基础上可以使用SIFT和SURF算子对特征点进行特征提取并使用匹配函数进行特征点的匹配。具体实现是首先采用SurfFeatureDetector检测特征点,再使用SurfDescripto

概述

之前的文章SURF和SIFT算子实现特征点检测简单地讲了利用SIFT和SURF算子检测特征点,在检测的基础上可以使用SIFT和SURF算子对特征点进行特征提取并使用匹配函数进行特征点的匹配。具体实现是首先采用SurfFeatureDetector检测特征点,再使用SurfDescriptorExtractor计算特征点的特征向量,最后采用BruteForceMatcher暴力匹配法或者FlannBasedMatcher选择性匹配法(二者的不同)来进行特征点匹配。

实验所用环境是opencv2.4.0+vs2008+win7,需要注意opencv2.4.X版本中SurfFeatureDetector是包含在opencv2/nonfree/features2d.hpp中,BruteForceMatcher是包含在opencv2/legacy/legacy.hpp中,FlannBasedMatcher是包含在opencv2/features2d/features2d.hpp中。

BruteForce匹配法

首先使用BruteForceMatcher暴力匹配法,代码如下:

/**
* @采用SURF算子检测特征点,对特征点进行特征提取,并使用BruteForce匹配法进行特征点的匹配
* @SurfFeatureDetector + SurfDescriptorExtractor + BruteForceMatcher
* @author holybin
*/

#include 
#include 
#include "opencv2/core/core.hpp"
#include "opencv2/nonfree/features2d.hpp"	//SurfFeatureDetector实际在该头文件中
#include "opencv2/legacy/legacy.hpp"	//BruteForceMatcher实际在该头文件中
//#include "opencv2/features2d/features2d.hpp"	//FlannBasedMatcher实际在该头文件中
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
	Mat src_1 = imread( "D:\opencv_pic\cat3d120.jpg", CV_LOAD_IMAGE_GRAYSCALE );
	Mat src_2 = imread( "D:\opencv_pic\cat0.jpg", CV_LOAD_IMAGE_GRAYSCALE );

	if( !src_1.data || !src_2.data )
	{ 
		cout<< " --(!) Error reading images "< keypoints_1, keypoints_2;
	detector.detect( src_1, keypoints_1 );
	detector.detect( src_2, keypoints_2 );
	cout<<"img1--number of keypoints: "< > matcher;
	vector< DMatch > matches;
	matcher.match( descriptors_1, descriptors_2, matches );
	cout<<"number of matches: "<

实验结果:



FLANN匹配法

使用暴力匹配的结果不怎么好,下面使用FlannBasedMatcher进行特征匹配,只保留好的特征匹配点,代码如下:

/**
* @采用SURF算子检测特征点,对特征点进行特征提取,并使用FLANN匹配法进行特征点的匹配
* @SurfFeatureDetector + SurfDescriptorExtractor + FlannBasedMatcher
* @author holybin
*/

#include 
#include 
#include "opencv2/core/core.hpp"
#include "opencv2/nonfree/features2d.hpp"	//SurfFeatureDetector实际在该头文件中
//#include "opencv2/legacy/legacy.hpp"	//BruteForceMatcher实际在该头文件中
#include "opencv2/features2d/features2d.hpp"	//FlannBasedMatcher实际在该头文件中
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
	Mat src_1 = imread( "D:\opencv_pic\cat3d120.jpg", CV_LOAD_IMAGE_GRAYSCALE );
	Mat src_2 = imread( "D:\opencv_pic\cat0.jpg", CV_LOAD_IMAGE_GRAYSCALE );

	if( !src_1.data || !src_2.data )
	{ 
		cout<< " --(!) Error reading images "< keypoints_1, keypoints_2;
	detector.detect( src_1, keypoints_1 );
	detector.detect( src_2, keypoints_2 );
	cout<<"img1--number of keypoints: "< allMatches;
	matcher.match( descriptors_1, descriptors_2, allMatches );
	cout<<"number of matches before filtering: "< maxDist )
			maxDist = dist;
	}
	printf("	max dist : %f 
", maxDist );
	printf("	min dist : %f 
", minDist );

	//-- 过滤匹配点,保留好的匹配点(这里采用的标准:distance<2*minDist)
	vector< DMatch > goodMatches;
	for( int i = 0; i < descriptors_1.rows; i++ )
	{
		if( allMatches[i].distance < 2*minDist )
			goodMatches.push_back( allMatches[i]); 
	}
	cout<<"number of matches after filtering: "<(), 
		DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS //不显示未匹配的点
		); 
	imshow("matching result", matchImg );
	//-- 
输出匹配点的对应关系 for( int i = 0; i < goodMatches.size(); i++ ) printf( " good match %d: keypoints_1 [%d] -- keypoints_2 [%d] ", i, goodMatches[i].queryIdx, goodMatches[i].trainIdx ); waitKey(0); return 0; }

实验结果:



从第二个实验结果可以看出,经过过滤之后特征点数目从49减少到33,匹配的准确度有所上升。当然也可以使用SIFT算子进行上述两种匹配实验,只需要将SurfFeatureDetector换成SiftFeatureDetector,将SurfDescriptorExtractor换成SiftDescriptorExtractor即可。


拓展

在FLANN匹配法的基础上,还可以进一步利用透视变换和空间映射找出已知物体(目标检测),具体来说就是利用findHomography函数利用匹配的关键点找出相应的变换,再利用perspectiveTransform函数映射点群。具体可以参考这篇文章:OpenCV中feature2D学习——SIFT和SURF算法实现目标检测。

热心网友 时间:2022-04-14 22:09

没看过这个源码,猜的
1 这里应该是只用了距离的部分,没有用旋转的部分。只为了求中心点位置,所以最后画出来的框应该没有角度倾斜的。
2 不知道
3
OpenCV中的SIFT SURF都很慢,做不到实时的。SIFT的特征点提取太慢了,而且描述默认128个float导致匹配也比较慢,除非修改算法部分。如果是跟踪的话,用OpenCV的KLT光流,或者模版匹配都能快很多(20ms以内)。

findHomography这个最后一个参数,可以修改为RANSAC或者PROSAC的实现版本。比LMEDS快好多倍。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
AFK半年后回归WOW,但发现好多东西搞不清楚了,求指教,多问题高分_百度知 ... wow85级什么本可以打378的猎人饰品 落花流水(打一动物)谜底及原因 办理买房按揭贷款需要多长时间啊 一手房如何办按揭 一手房按揭贷款申请条件 怎么把微信好友转移到另一个微信号上? 高铁站没有身份证可以进站吗 京东Plus会员每月优惠券去哪领?Plus会员哪里买最便宜? 京东plus会员优惠券在哪里领?怎么用? Opencv中得到的光流数据是不是有问题 如果一机器人跟踪人,它用什么识别人并跟踪特定的人呢? 单目视觉里程计,此方法可以用于什么方面 顺丰公开暴力分拣识别方法相关专利,你收到过破损快递吗? 基于特征光流法的运动汽车视觉跟踪设计(非专业人士勿扰) 视觉追踪的典型算法 怎么将光电流数据转化成图? 我用光流法进行运动目标的检测,检测出来的是特征点,如何用Opencv把特征点包含在一个方框内啊? openCV光流法的处理方法,怎么用它来进一步提取特征信息? 命运神界是哪家公司的? 命运神界突破源晶怎么获得? 老赖黑名单排行榜如何查询 黑名单在线查询看看都有谁 在家里制作凉皮,蒸的凉皮不起泡还裂,这是什么原因呢? 带龙的社团起名 免费邮箱申请 给饭店取名,带龙字的 TOM邮箱怎么样?可以不可以批量注册邮箱? 以龙字给品牌命名我想以龙字给我的产品起个名字做为自己的自助品牌 姓李男孩正月十五出生最后一字带龙字的怎么起名字~~~ QQ怎么取消关注!!! 运动侦测的实际应用 求助!光流法quiver画图问题。 电脑出现黑屏带英文文字 怎么解决 电脑打开黑屏显示英文怎么回事 电脑重启后黑屏显示英文字母怎么办? 电脑开机黑屏,显示一堆英文,是什么原因? 电脑一开机就进入黑屏出现英文怎么办 喝什么茶叶不会减肥 什么茶叶喝了最减肥,也不伤皮肤? 喝什么茶减肥不反弹? 哪种茶叶可以减肥不伤胃 喝什么茶叶可以减肥 什么茶叶最减肥啊。普洱茶刷不刷油啊 喝什么茶叶有减肥的作用 喝什么茶叶最减肥 败火的食物有哪些 败火的食物都有哪些? 上火了怎么办?有哪些食物有助于降火? 梦见自己结婚下雨