• SIFT


    1. 简介

    SIFT(scale invariant feature transform)——尺度不变特征转换,用来检测和描述局部特征,运用范围包括object recognition(目标检测), robotic mapping and navigation(机器人地图感知与导航), image stitching(图像拼接), 3D modeling(3D建模), gesture recognition(手势识别), video tracking(视频追踪), individual identification of wildlife(野生物个体识别) and match moving(动作匹配)

         2.  特点   

               (1)Sift特征是图像的局部特征,对平移、旋转、尺度缩放、亮度变化、遮挡和噪声等具有良好的不变性,对视觉变化、仿射变换也保持一定程度的稳定性。

               (2)独特性好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配。

               (3)多量性,即使少数的几个物体也可以产生大量Sift特征向量。

               (4)速度相对较快,经优化的Sift匹配算法甚至可以达到实时的要求。

               (5)可扩展性强,可以很方便的与其他形式的特征向量进行联合。

         3.  算法

               3.1. 构造高斯差分空间图像。

      Sift特征点的检测时在DOG(difference of gausssian)图像上进行的,DOG图像是将相邻尺度空间图像相减得到的。且金字塔的每一层都要构造一个DOG空间图像。默认参数是金字塔4层,即4个octave,每一个octave中有5张不同尺度的图片,不同octave的图片尺寸大小不同,所以每一层中就会得到4幅DOG图像。

    高斯金字塔的第1层第1副原图像是将原图像放大2倍且sigma(sigma=1.6)模糊,第2幅图像是k*sigma(k等于根号2)模糊,第3幅是k*k*sigma模糊,后面类推…

         高斯金字塔第2层第1幅图是选择金字塔上一层(这里是第1层)中尺度空间参数为k*k*sigma的那幅图(实际上是2倍的尺度空间)进行降采样(尺寸大小为原来的1/4倍)得到,如果k不等于根号2,那么取原图的2*sigma降采样得到。第2层第2幅图是在本层第一幅图尺度模糊系数增加k倍模糊后的图像,后面类似…

      示意图如下所示:

      

    3.2、寻找极大极小值点。

      将每个像素点与其所在的那幅图像邻域的8个像素,它所在的向量尺度空间上下2幅图对应位置邻域各9个点,总共26个点进行像素值比较,如果该点是最大或者最小点,则改点就暂时列为特征点。

      其邻图如下:

      

     

      3.3、精确定位极值点

      子像素级极值点:

      由于上面找到的近似极值点落在像素点的位置上,实际上我们在像素点附近如果用空间曲面去拟合的话,很多情况下极值点都不是恰好在像素点上,而是在附近。所以sift算法提出的作者用泰勒展开找到了亚像素级的特征点。这种点更稳定,更具有代表性。

      消除对比度低的特征点:

      对求出亮度比较低的那些点直接过滤点,程序中的阈值为0.03.

      消除边界上的点:

      处理方法类似harrs角点,把平坦区域和直线边界上的点去掉,即对于是边界上的点但又不是直角上的点,sift算法是不把这些点作为特征点的。

     

      3.4、选取特征点主方向

      在特征点附近选取一个区域,该区域大小与图图像的尺度有关,尺度越大,区域越大。并对该区域统计36个bin的方向直方图,将直方图中最大bin的那个方向作为该点的主方向,另外大于最大bin80%的方向也可以同时作为主方向。这样的话,由于1个特征点有可能有多个主方向,所以一个特征点有可能有多个128维的描述子。如下图所示:

      

     

         3.5、 构造特征点描述算子。

         以特征点为中心,取领域内16*16大小的区域,并把这个区域分成4*4个大小为4*4的小区域,每个小区域内计算加权梯度直方图,该权值分为2部分,其一是该点的梯度大小,其二是改点离特征点的距离(二维高斯的关系),每个小区域直方图分为8个bin,所以一个特征点的维数=4*4*8=128维。示意图如下(该图取的领域为8*8个点,因此描述子向量的维数为32维):

      

     4.  在opencv中的使用

          

    // opencv_empty_proj.cpp : 定义控制台应用程序的入口点。
    //
    
    
    #include <opencv2/opencv.hpp>
    #include <opencv2/features2d/features2d.hpp>
    #include<opencv2/nonfree/nonfree.hpp>
    #include<opencv2/legacy/legacy.hpp>
    #include<vector>
    using namespace std;
    using namespace cv;
    int main()
    {
    	const char* imagename = "SIFT.bmp";
    
    	//从文件中读入图像
    	Mat img = imread(imagename);
    	Mat img2=imread("SIFT1.bmp");
    
    	//如果读入图像失败
    	if(img.empty())
    	{
    		fprintf(stderr, "Can not load image %s
    ", imagename);
    		return -1;
    	}
    	if(img2.empty())
    	{
    		fprintf(stderr, "Can not load image %s
    ", imagename);
    		return -1;
    	}
    	//显示图像
    	imshow("image before", img);
    	imshow("image2 before",img2);
    
    
    	//sift特征检测
    	SiftFeatureDetector  siftdtc;
    	vector<KeyPoint>kp1,kp2;
    	
    	siftdtc.detect(img,kp1);
    	Mat outimg1;
    	drawKeypoints(img,kp1,outimg1);
    	imshow("image1 keypoints",outimg1);
    	KeyPoint kp;
    
    	vector<KeyPoint>::iterator itvc;
    	for(itvc=kp1.begin();itvc!=kp1.end();itvc++)
    	{
    		cout<<"angle:"<<itvc->angle<<"	"<<itvc->class_id<<"	"<<itvc->octave<<"	"<<itvc->pt<<"	"<<itvc->response<<endl;
    	}
    
    	siftdtc.detect(img2,kp2);
    	Mat outimg2;
    	drawKeypoints(img2,kp2,outimg2);
    	imshow("image2 keypoints",outimg2);
    
    
    	SiftDescriptorExtractor extractor;
    	Mat descriptor1,descriptor2;
    	BruteForceMatcher<L2<float>> matcher;
    	vector<DMatch> matches;
    	Mat img_matches;
    	extractor.compute(img,kp1,descriptor1);
    	extractor.compute(img2,kp2,descriptor2);
    
    
    	imshow("desc",descriptor1);
    	cout<<endl<<descriptor1<<endl;
    	matcher.match(descriptor1,descriptor2,matches);
    
    	drawMatches(img,kp1,img2,kp2,matches,img_matches);
    	imshow("matches",img_matches);
    
    	//此函数等待按键,按键盘任意键就返回
    	waitKey();
    	return 0;
    }
    

      

     
  • 相关阅读:
    Scale-Invariant Error
    Regularizing Deep Networks with Semantic Data Augmentation
    BBN: Bilateral-Branch Network with Cumulative Learning for Long-Tailed Visual Recognition
    2021.5.17
    2021.5.14
    2021.5.13
    2021.5.12
    2021.5.8
    2021.5.7 团队冲刺第十天
    2021.5.6 团队冲刺第九天
  • 原文地址:https://www.cnblogs.com/yssongest/p/4359058.html
Copyright © 2020-2023  润新知