opencv下SIFT使用
2015-03-12 10:52
295 查看
OPENCV下SIFT特征点提取与匹配的大致流程如下:
读取图片-》特征点检测(位置,角度,层)-》特征点描述的提取(16*8维的特征向量)-》匹配-》显示
其中,特征点提取主要有两个步骤,见上行黄子部分。下面做具体分析。
1、使用opencv内置的库读取两幅图片
2、生成一个SiftFeatureDetector的对象,这个对象顾名思义就是SIFT特征的探测器,用它来探测衣服图片中SIFT点的特征,存到一个KeyPoint类型的vector中。简而言之最重要的一点在于:
keypoint只是保存了opencv的sift库检测到的特征点的一些基本信息,但sift所提取出来的特征向量其实不是在这个里面,特征向量通过SiftDescriptorExtractor 提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。具体见后文对SiftDescriptorExtractor 所生成的对象的详解。
就因为这点没有理解明白耽误了一上午的时间。哭死!
3、对图像所有KEYPOINT提取其特征向量:
得到keypoint只是达到了关键点的位置,方向等信息,并无该特征点的特征向量,要想提取得到特征向量就还要进行SiftDescriptorExtractor 的工作,建立了SiftDescriptorExtractor 对象后,通过该对象,对之前SIFT产生的特征点进行遍历,找到该特征点所对应的128维特征向量。通过这一步后,所有keypoint关键点的特征向量被保存到了一个MAT的数据结构中,作为特征。
4、对两幅图的特征向量进行匹配,得到匹配值。
opencv中keypoint数据结构分析:
分析opencv中keypoint数据结构的相关信息,找到opencv的document(http://docs.opencv.org/java/org/opencv/features2d/KeyPoint.html)。可以看到KeyPoint这数据结构中有如下数据结构:
angle:角度,表示关键点的方向,通过Lowe大神的论文可以知道,为了保证方向不变形,SIFT算法通过对关键点周围邻域进行梯度运算,求得该点方向。-1为初值。
class_id:当要对图片进行分类时,我们可以用class_id对每个特征点进行区分,未设定时为-1,需要靠自己设定
octave:代表是从金字塔哪一层提取的得到的数据。
pt:关键点点的坐标
response:响应程度,代表该点强壮大小,一开始我也理解不了,看到两位stackoverflow大大的原话(http://stackoverflow.com/questions/10328298/what-does-size-and-response-exactly-represent-in-a-surf-keypoint,http://stackoverflow.com/questions/24699495/opencv-keypoints-response-greater-or-less?lq=1)——response代表着该关键点how
good,更确切的说,是该点角点的程度。瞬间明白。
size:该点直径的大小
注意一个问题:keypoint只是保存了opencv的sift库检测到的特征点的一些基本信息,也就上面所说的这些,但sift所提取出来的特征向量其实不是在这个里面,特征向量通过SiftDescriptorExtractor 提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。具体见后文对SiftDescriptorExtractor 所生成的对象的详解。
opencv中SiftDescriptorExtractor所做的SIFT特征向量提取工作简单分析:
SiftDescriptorExtractor对应于SIFT算法中特征向量提取的工作,通过他对关键点周围邻域内的像素分块进行梯度运算,得到128维的特征向量。具体有如下几个操作:
0、首先,我们假设在之前关键点提取的步骤中,我们对一个三角形提取关键点,检测到其中一个关键点的坐标为三角形的一个角(如下面用红圈圈出的),如下图
放大看,假设检测到该关键点的方向如下图:
1、将关键点周围的像素旋转到一个统一的方向,以保证方向不变性。如下图
2、将这些像素分成4X4的小块
对每个格子进行分析,将格子中的像素计算梯度,映射到8个方向上,对于每一个格子,可以得到一个8维的向量,对于一个关键点周围16个格子,则得到了16X8=128维的向量,这就是一个关键点特征向量。
使用举一个实际的例子分析:
用opencv对一个三角形进行特征点检测,得到如下结果:
提取特征向量,得到如下结果:
这幅图的每一行就是一个128维的特征向量,维度用0-255表示。黑一些就是小,白就是大。
粗略可以看出,这些特征点排布较为相似,因为都是角
再来一个:
引自:http://www.cnblogs.com/cj695/p/4041478.html
附:使用OPENCV下SIFT库做图像匹配的例程
读取图片-》特征点检测(位置,角度,层)-》特征点描述的提取(16*8维的特征向量)-》匹配-》显示
其中,特征点提取主要有两个步骤,见上行黄子部分。下面做具体分析。
1、使用opencv内置的库读取两幅图片
2、生成一个SiftFeatureDetector的对象,这个对象顾名思义就是SIFT特征的探测器,用它来探测衣服图片中SIFT点的特征,存到一个KeyPoint类型的vector中。简而言之最重要的一点在于:
keypoint只是保存了opencv的sift库检测到的特征点的一些基本信息,但sift所提取出来的特征向量其实不是在这个里面,特征向量通过SiftDescriptorExtractor 提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。具体见后文对SiftDescriptorExtractor 所生成的对象的详解。
就因为这点没有理解明白耽误了一上午的时间。哭死!
3、对图像所有KEYPOINT提取其特征向量:
得到keypoint只是达到了关键点的位置,方向等信息,并无该特征点的特征向量,要想提取得到特征向量就还要进行SiftDescriptorExtractor 的工作,建立了SiftDescriptorExtractor 对象后,通过该对象,对之前SIFT产生的特征点进行遍历,找到该特征点所对应的128维特征向量。通过这一步后,所有keypoint关键点的特征向量被保存到了一个MAT的数据结构中,作为特征。
4、对两幅图的特征向量进行匹配,得到匹配值。
opencv中keypoint数据结构分析:
分析opencv中keypoint数据结构的相关信息,找到opencv的document(http://docs.opencv.org/java/org/opencv/features2d/KeyPoint.html)。可以看到KeyPoint这数据结构中有如下数据结构:
angle:角度,表示关键点的方向,通过Lowe大神的论文可以知道,为了保证方向不变形,SIFT算法通过对关键点周围邻域进行梯度运算,求得该点方向。-1为初值。
class_id:当要对图片进行分类时,我们可以用class_id对每个特征点进行区分,未设定时为-1,需要靠自己设定
octave:代表是从金字塔哪一层提取的得到的数据。
pt:关键点点的坐标
response:响应程度,代表该点强壮大小,一开始我也理解不了,看到两位stackoverflow大大的原话(http://stackoverflow.com/questions/10328298/what-does-size-and-response-exactly-represent-in-a-surf-keypoint,http://stackoverflow.com/questions/24699495/opencv-keypoints-response-greater-or-less?lq=1)——response代表着该关键点how
good,更确切的说,是该点角点的程度。瞬间明白。
size:该点直径的大小
注意一个问题:keypoint只是保存了opencv的sift库检测到的特征点的一些基本信息,也就上面所说的这些,但sift所提取出来的特征向量其实不是在这个里面,特征向量通过SiftDescriptorExtractor 提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。具体见后文对SiftDescriptorExtractor 所生成的对象的详解。
opencv中SiftDescriptorExtractor所做的SIFT特征向量提取工作简单分析:
SiftDescriptorExtractor对应于SIFT算法中特征向量提取的工作,通过他对关键点周围邻域内的像素分块进行梯度运算,得到128维的特征向量。具体有如下几个操作:
0、首先,我们假设在之前关键点提取的步骤中,我们对一个三角形提取关键点,检测到其中一个关键点的坐标为三角形的一个角(如下面用红圈圈出的),如下图
放大看,假设检测到该关键点的方向如下图:
1、将关键点周围的像素旋转到一个统一的方向,以保证方向不变性。如下图
2、将这些像素分成4X4的小块
对每个格子进行分析,将格子中的像素计算梯度,映射到8个方向上,对于每一个格子,可以得到一个8维的向量,对于一个关键点周围16个格子,则得到了16X8=128维的向量,这就是一个关键点特征向量。
使用举一个实际的例子分析:
用opencv对一个三角形进行特征点检测,得到如下结果:
提取特征向量,得到如下结果:
这幅图的每一行就是一个128维的特征向量,维度用0-255表示。黑一些就是小,白就是大。
粗略可以看出,这些特征点排布较为相似,因为都是角
再来一个:
引自:http://www.cnblogs.com/cj695/p/4041478.html
附:使用OPENCV下SIFT库做图像匹配的例程
// FeatureDetector.cpp : Defines the entry point for the console application. #include<opencv2/nonfree/features2d.hpp> //使用SiftFeatureDetector需要加上此头文件 #include<opencv2\opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main(int argc, char* argv[]) { //Load Image Mat c_src1 = imread("image1.jpg"); Mat c_src2 = imread("image2.jpg"); Mat src1 = imread("image1.jpg", CV_LOAD_IMAGE_GRAYSCALE); Mat src2 = imread("image2.jpg", CV_LOAD_IMAGE_GRAYSCALE); if (!src1.data || !src2.data) { std::cout << " --(!) Error reading images " << std::endl; return -1; } //sift feature detect SiftFeatureDetector detector; vector<KeyPoint> kp1, kp2; detector.detect(src1, kp1); detector.detect(src2, kp2); SiftDescriptorExtractor extractor; Mat des1, des2;//descriptor extractor.compute(src1, kp1, des1); extractor.compute(src2, kp2, des2); Mat res1, res2; int drawmode = DrawMatchesFlags::DRAW_RICH_KEYPOINTS; drawKeypoints(c_src1, kp1, res1, Scalar::all(-1), drawmode);//在内存中画出特征点 drawKeypoints(c_src2, kp2, res2, Scalar::all(-1), drawmode); cout << "size of description of Img1: " << kp1.size() << endl; cout << "size of description of Img2: " << kp2.size() << endl; BFMatcher matcher(NORM_L2); vector<DMatch> matches; matcher.match(des1, des2, matches); Mat img_match; drawMatches(src1, kp1, src2, kp2, matches, img_match);//,Scalar::all(-1),Scalar::all(-1),vector<char>(),drawmode); cout << "number of matched points: " << matches.size() << endl; imshow("matches", img_match); cvWaitKey(); cvDestroyAllWindows(); return 0; }
相关文章推荐
- opencv2.4.6版本下使用sift等特征
- OpenCV2.4.9新版本使用问题---sift,surf无法使用
- OpenCV3.1使用SIFT
- android opencv2.4.10使用SIFT编译出libnonfree.so
- 使用RANSAC提纯SIFT和SURF特征点,达到鲁棒匹配的效果(OpenCV 2.4.13下,源码)
- opencv 中sift 的使用
- 使用OPENCV自带的sift提取特征
- OpenCV3如何使用SIFT和SURF Where did SIFT and SURF go in OpenCV 3?
- opencv中SIFT匹配对于误匹配点RANSAC算法接口的使用
- 使用Opencv2.4.9进行SIFT特征点提取和匹配
- OPENCV下SIFT算法使用方法笔记
- opencv SURF、SIFT的使用
- OPENCV下SIFT算法使用方法笔记
- OPENCV下SIFT算法使用方法笔记
- 基于Opencv的SIFT代码,使用FLANN匹配
- SIFT:第一步使用OpenCV构建DOG金字塔
- 在OpenCV3.1.0中使用SIFT,SURF算法
- python3.5 opencv3.1 不能使用sift, surf。
- 使用openCV提取sift;surf;hog特征
- OpenCV中SUFR、SIFT无法使用的原因及解决办法