今天开始,要整理一下之前看过的一些特征提取描述算法,并记录下自己的总结。由于这些算法往深处探索的时候都涉及到了非常多与数学相关的内容,而这些内容对于像我一样数学功底不够深厚的人来说是比较难完全理解的,所以我的笔记只记录个人对每个算法大致流程的理解。下面就开始吧!!!
对于一幅图像中的内容,存在各种各样的特征,例如有点特征、线特征和块特征等等。其中,特征点是图像中非常重要的一个局部特征,它集中了很多的形状信息,特征点反映的是二维图像中灰度变化极其剧烈的点,或者是图像边缘曲线中曲率极大值的点,如角点。而当我们需要对图像中的内容进行分析时,这些特征就派上了很大的用场,能够帮助我们比较好的找出我们的目标对象,对目标对象进行识别和分析等操作。特征点广泛应用在目标检测与识别、图像重构、图像匹配等方面。
那么,想要通过目标的特征来进行下一步操作,首先就是要找出目标的特征,这里主要可以分为两个步骤,第一个是目标特征的提取,第二个就是对目标特征进行描述。
所谓特征提取,就是在图像中根据像素点的梯度、灰度值、邻域像素关系等因素,来将某些与其他像素点具有明显差异的像素点区分出来,并将这些像素点提取出来作为一个点集,这就是我们找到的候补特征点集。这些特征点一般是在图像中梯度比较大、或者灰度值变化比较大的区域,通过进一步地筛选,我们能够得到位于我们的目标区域中的候选特征点,从而进一步提取出我们目标对象的特征点。
既然我们找到了目标对象的特征点,那就要给这些特征点都起一个名字,这样我们就能够通过它们的名字来区分它们。例如图像A中存在一只猫作为我们的目标对象,我们在这只猫的区域中提取到的特征点给它命名为“喵”,随后再给出一张图像B,当我们获取图像B中的所有特征点后通过比对这些特征点中是否存在名为“喵”的特征点,如果存在则证明图像B中很可能也包含了一只猫的内容,如果不存在则证明图像B中很可能不包含有猫的内容。
于是对特征点进行命名的过程,我们就说这是特征描述。我们通过某种编码的格式来对得到的特征点进行编码,从而得到一个特征描述子,下一步就可以通过这个描述子来比对不同图像的内容了。
特征提取与描述的主要步骤可以归结如下:
1、 找到同一目标物体在不同成像条件、视角变化和存在噪声的情况下都能够可靠定位的一组独特关键点KeyPoints,也叫特征点;
2、以比例或仿射不变的方式在每个特征点周围定义一个区域,也就是选取特征点的邻域;
3、提取并通过某种方式来规范化每个特征点邻域的内容;
4、从规范化的每个特征点邻域的内容中来计算该特征点的描述子;
5、将计算得到的一系列目标对象的特征描述子与模板的特征描述子相对比,进行特征匹配。
在特征提取与描述算法中,最经典的应该算是SIFT(Scale-invariant feature transform-尺度不变特征转换)特征检测算法,在SIFT算法的基础上还演化出了不少的改进版本。在我的理解中,SIFT算法可以分为以下这几个步骤:
至此就是SIFT算法的大致流程了,当然其中还包含了许多的细节部分和数学内容,如果对算法的细节部分感兴趣的话可以看这篇博文《Scale Invariant Feature Transform(SIFT)——尺度不变特征变换匹配算法详解》,这个博主很厉害几乎把SIFT算法的paper给摸透了。
而在OpenCV中,原本是提供了SIFT算法的API实现,但是由于专利的问题,在之前的某一个版本以后已经把这个算法给移出到了xfeature2d模块,也就是非正式模块。如果想要使用这种算法的话,就得去OpenCV官网自己下载xfeature2d模块的源文件,然后进行编译。本来我是打算操作一波的,连带着cuda、openVINO和xfeature2d一起进行编译,然而由于Github那令人感动的网速,一直下载不了那两份代码,修改了系统host文件后进度条也还是一动不动(进度条:我不敢动。。不敢动。。)
罢了罢了,所以今天的笔记就没有代码演示了,不过在OpenCV中特征算法的使用都大同小异,以后整理其他特征算法的时候再做代码演示吧~
今天的笔记到到此为止,谢谢阅读~
补充OpenCV中SIFT算法的调用演示:
auto sift = SIFT::create();
Mat tem = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\dog.jpg");
vector<KeyPoint>keyPoints;
Mat descriptors;
sift->detectAndCompute(tem, Mat(), keyPoints, descriptors);
drawKeypoints(tem, keyPoints, tem, Scalar::all(-1), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
imshow("tem", tem);
PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!