尺度空间:
自然界中的物体随着观测尺度不同有不同的表现形态。例如我们形容建筑物用“米”,观测分子、原子等用“纳米”。更形象的例子比如Google地图,滑动鼠标轮可以改变观测地图的尺度,看到的地图绘制也不同;还有电影中的拉伸镜头等等……
尺度空间中各尺度图像的模糊程度逐渐变大,能够模拟人在距离目标由近到远时目标在视网膜上的形成过程。
用机器视觉系统分析未知场景时,计算机并不预先知道图像中物体的尺度。我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的最佳尺度。另外,如果不同的尺度下都有同样的关键点,那么在不同的尺度的输入图像下就都可以检测出来关键点,也就是尺度不变性。图像的尺度空间表达就是图像在所有尺度下的描述。
SIFT算法:
尺度不变特征转换即SIFT (Scale-invariant feature transform)是一种计算机视觉的算法。它用来侦测与描述图像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量,此算法由 David Lowe在1999年所发表,2004年完善总结。 其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。
局部图像特征的描述与侦测可以帮助辨识物体,SIFT特征是基于物体上的一些局部外观的兴趣点而与图像的大小和旋转无关。对于光线、噪声、些微视角改变的容忍度也相当高。基于这些特性,它们是高度显著而且相对容易撷取,在母数庞大的特征数据库中,很容易辨识物体而且鲜有误认。SIFT算法的实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点。
SIFT算法原理:
参考以下博文即可:
Sift中尺度空间、高斯金字塔、差分金字塔(DOG金字塔)、图像金字塔 - 牧野的博客 - CSDN博客 https://blog.csdn.net/dcrmg/article/details/52561656
SIFT特征点提取 - PineTree的博客 - CSDN博客 https://blog.csdn.net/lingyunxianhe/article/details/79063547
API:
代码展示:
#include "pch.h"
#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv2/xfeatures2d.hpp>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
Mat src;
int nfeatures = 100;
int maxTrackbarNum = 500;
void SiftDecetor_demo(int pos, void* data);
int main()
{
//待检测图像
src = imread("F:\\visual studio\\Image\\hand4.jpg");
if (src.empty())
{
cout << "Can't load the image" << endl;
return -1;
}
imshow("src", src);
namedWindow("SIFT_feature", WINDOW_AUTOSIZE);
createTrackbar("nfeatures", "SIFT_feature", &nfeatures, maxTrackbarNum, SiftDecetor_demo);
SiftDecetor_demo(0, 0);
waitKey(0);
}
void SiftDecetor_demo(int pos, void* data)
{
//SIFT特征检测
Ptr<SIFT> detector = SIFT::create(nfeatures);
vector<KeyPoint> keypoints;
detector->detect(src, keypoints, Mat());
//绘制
Mat kp_img;
drawKeypoints(src, keypoints, kp_img, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("SIFT_feature", kp_img);
}
效果展示: