当尝试在不同图像之间进行特征匹配时,通常会遇到图像的大小、方向等参数发生改变的问题,简而言之,就是尺度变化的问题。每幅图像在拍摄时与目标物体的距离是不同的,因此要识别的目标物体在图像中自然会存在不同的尺寸。
因此,计算机视觉中引入尺度不变的特征,主要的思想是每个检测到的特征点都伴随对应的尺度因子。著名的尺度不变特征检测器SIFT(scale invariant feature transform),具有尺度,旋转,仿射,视角,光照不变性。而加速鲁棒特性特征SURF(Speeded Up Robust Features)算法是SIFT的高效变种。
关于SIFT和SURF的特征介绍,已经有很多的blog对其进行简介了,见参考的blog。由于还没有将2004年那篇原文精细看完,这里只是提供在OpenCV中如何实现这两种算法的特征检测。这里使用的开发平台是Qt5.3.2+OpenCV2.4.9。SURF、SIFT特征在OpenCV中的实现均使用了cv::FeatureDetector接口。在这里,特征点的计算基于浮点核,因此这两种算法相比其他算法在空间和尺度检测上更加精确,但相对耗时。
至于理论部分有待更新。
一、SIFT特征
直接在Qt中创建一个控制台项目,在main函数中添加:
#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 读入图像
cv::Mat image= cv::imread("c:/018.jpg",0);
cv::namedWindow("Original Image");
cv::imshow("Original Image", image);
// 特征点的向量
std::vector<cv::KeyPoint>keypoints;
// 构造SIFT特征检测器
cv::SiftFeatureDetector sift(
0.03, // 特征的阈值
10.); // 用于降低
// 检测SIFT特征值
sift.detect(image,keypoints);
cv::drawKeypoints(image, // 原始图像
keypoints, // 特征点的向量
featureImage, // 生成图像
cv::Scalar(255,255,255), // 特征点的颜色
cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); // 标志位
cv::namedWindow("SIFT Features");
cv::imshow("SIFT Features",featureImage);
return a.exec();
}
效果如下,在函数cv::drawKeypoints中我们使用cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS作为标志位,这样唉使用DRAW_RICH_KEYPOINTS之后每个关键点上圆圈的尺寸与特征的尺度成正比:
二、SURF特征
#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 读入图像
cv::Mat image= cv::imread("c:/018.jpg",0);
cv::namedWindow("Original Image");
cv::imshow("Original Image", image);
// 特征点的向量
std::vector<cv::KeyPoint>keypoints;
// 构造SURF特征检测器
cv::SurfFeatureDetector surf(2500);
// 检测SURF特征
surf.detect(image,keypoints);
cv::Mat featureImage;
cv::drawKeypoints(image, // 原始图像
keypoints, // 特征点的向量
featureImage, // 生成图像
cv::Scalar(255,255,255), // 特征点的颜色
cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); // 标志位
cv::namedWindow("SURF Features");
cv::imshow("SURF Features",featureImage);
return a.exec();
}
效果:
相比SIFT特征,SURF牺牲了一定的精度换取了计算效率的提高。关于这两种算法的理论部分有待进一步的探讨和更新…
参考blog:
http://blog.csdn.net/xiaowei_cqu/article/details/8069548
http://www.cnblogs.com/tornadomeet/archive/2012/08/16/2643168.html
原文地址:http://blog.csdn.net/liyuefeilong/article/details/44166069