OpenCV检测图像SURF特征

SURF特征

SURF特征——speeded up robust features 加速鲁棒特征。具有尺度不变性,计算相对高效。
所谓尺度不变性,在特征点匹配上,个人比较白话的理解是:
相同内容的不同尺度的两张图片(例,图像1:张三的正面照。图像2:张三正面照缩小一半。)。
假设两张图片上张三的鼻子中心是一个特征点,那么这两张图片,在该点处的SURF特征,应该相互匹配(确切说是SURF特征描述子匹配)。也就是说,大小变化,特征匹配不变。不管物体大小如何变化,同一物体在不同大小下具有的SURF特征,这些特征点(描述子)相互匹配。
SURF特征,具有尺寸和方向,使其具有方向不变性和尺寸不变性。
该博客讲了SURF特征原理,可以参看。
http://www.cnblogs.com/tornadomeet/archive/2012/08/17/2644903.html
这里只简单讲下,SURF特征,大体是怎么回事

SURF特征,定义特征点为具有较高局部曲率的点。
怎么计算局部曲率?通过Hessian矩阵。
这里写图片描述
该矩阵的行列式给出了曲率的强度,也就是,矩阵的行列式越大,曲率强度越高。具体计算特征点时,要考虑用不同尺寸高斯核滤波产生的金塔字上下层的曲率值,用当前层某点的曲率值,和本层、上层、下层一定范围进行比较。(说起来好麻烦,具体的看SURF算法,网上很多资料)。
特征怎么具有尺寸不变性?
SURF,通过对图片用不同尺寸的高斯核滤波,然后计算其Hessian矩阵(类似高斯金字塔,但图像的尺寸不变)。实际应用中,为了加快计算速度,常常用近似的高斯核,直接计算Hessian矩阵中的值。
对y二阶导相当于:
这里写图片描述
对xy二阶导相当于:
这里写图片描述
这样,不同尺寸高斯核下的Hessian矩阵,便计算出来。
为了说明白尺寸不变,以下是个人的简单理解,可能跟算法实际过程不同(仅为好理解,勿喷)
1:一张图片,在尺寸为NxN的高斯核下,检测到了一个SURF特征点。那么这个检测到的特征点,与N成正比,也可以说特征点的尺寸与N成正比。
2:假设,图片缩小一半,拍摄角度不变。那么在尺寸为(N/2)的高斯核下,检测到一个SURF特征点(同1,为同一物体的同一点)。该特征点的尺寸与N/2成正比。
也就是说,当图像缩减一半时,该特征点的尺寸也缩减一半。那么在匹配这两个不同尺度的特征点时,由于考虑到了尺寸的变化(原来的1/2),那么匹配时,他们的强度模版就不会出错。(再简单的理解,计算特征点的描述子时,由于不了解物体尺寸的变换,所以往往会出错。但是,SURF特征包含了尺寸变化的信息,从而让同一物体的同一点在不同尺寸下的SURF特征(点)描述子(向量)相互匹配)
这里,只讲了SURF个人的大体理解,其实我看该算法时也挺蒙,有些地方来回看了几遍。个人理解肯定由疏漏、不准确的地方,推荐去系统学习一下SURF详细原理。
示例:

#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2\legacy\legacy.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <iostream>
int main()
{
	//两张同一物体,不同尺寸的图片
	cv::Mat image = cv::imread("D:/images/church01.jpg");
	cv::Mat image1 = cv::imread("D:/images/church03.jpg");
	///计算SURF特征点
	std::vector<cv::KeyPoint> pts;
	std::vector<cv::KeyPoint> pts1;
	//定义SURF特征检测类 对象,阈值设置为2500
	cv::SurfFeatureDetector surf(2500.);
	surf.detect(image, pts);
	surf.detect(image1, pts1);

	///提取SURF特征点的描述子
	cv::SurfDescriptorExtractor surfD;
	//特征点集合的描述子以矩阵形式保存
	cv::Mat descri;
	cv::Mat descri1;
	surfD.compute(image, pts, descri);
	surfD.compute(image1, pts1, descri1);

	//利用描述子,匹配两张图像中的SURF特点
	cv::BruteForceMatcher<cv::L2<float>>mather;
	std::vector<cv::DMatch>matches;
	//matches,保存匹配结果
	mather.match(descri, descri1, matches);

	//选取匹配值最高的25个点
	std::nth_element(matches.begin(), matches.begin() + 24, matches.end());
	matches.erase(matches.begin() + 25, matches.end());
	//画出匹配图像
	cv::Mat imageMatches;
	cv::drawMatches(image, pts, image1, pts1,
		matches, imageMatches, cv::Scalar(255, 0, 0));
	//显示结果
	cv::namedWindow("Match", CV_WINDOW_FREERATIO);
	cv::imshow("Match", imageMatches);
	cv::waitKey(0);
	return 0;
}

这里写图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林多

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

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

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

打赏作者

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

抵扣说明:

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

余额充值