OPENCV下SIFT算法使用方法笔记

这几天继续在看Lowe大神的SIFT神作,看的眼花手脚抽筋。也是醉了!!!!实在看不下去,来点干货。我们知道opencv下自带SIFT特征检测以及MATCH匹配的库,这些库完全可以让我们进行傻瓜似的操作。但实际用起来的时候还不是那么简单。下文将对一个典型的基于OPENCV的SIFT特征点提取以及匹配的例程进行分析,并由此分析详细的对OPENCV中SIFT算法的使用进行一个介绍。

OPENCV下SIFT特征点提取与匹配的大致流程如下:

读取图片-》特征点检测(位置,角度,层)-》特征点描述的提取(16*8维的特征向量)-》匹配-》显示

其中,特征点提取主要有两个步骤,见上行黄子部分。下面做具体分析。

1、使用opencv内置的库读取两幅图片

2、生成一个SiftFeatureDetector的对象,这个对象顾名思义就是SIFT特征的探测器,用它来探测衣服图片中SIFT点的特征,存到一个KeyPoint类型的vector中。这里有必要说keypoint的数据结构,涉及内容较多,具体分析查看opencv中keypoint数据结构分析,里面讲的自认为讲的还算详细(表打我……)。简而言之最重要的一点在于:

keypoint只是保存了opencv的sift库检测到的特征点的一些基本信息,但sift所提取出来的特征向量其实不是在这个里面,特征向量通过SiftDescriptorExtractor 提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。具体见后文对SiftDescriptorExtractor 所生成的对象的详解。

就因为这点没有理解明白耽误了一上午的时间。哭死!

3、对图像所有KEYPOINT提取其特征向量:

得到keypoint只是达到了关键点的位置,方向等信息,并无该特征点的特征向量,要想提取得到特征向量就还要进行SiftDescriptorExtractor 的工作,建立了SiftDescriptorExtractor 对象后,通过该对象,对之前SIFT产生的特征点进行遍历,找到该特征点所对应的128维特征向量。具体方法参见opencv中SiftDescriptorExtractor所做的SIFT特征向量提取工作简单分析。通过这一步后,所有keypoint关键点的特征向量被保存到了一个MAT的数据结构中,作为特征。

4、对两幅图的特征向量进行匹配,得到匹配值。

两幅图片的特征向量被提取出来后,我们就可以使用BruteForceMatcher对象对两幅图片的descriptor进行匹配,得到匹配的结果到matches中,这其中具体的匹配方法暂没细看,过段时间补上。

至此,SIFT从特征点的探测到最后的匹配都已经完成,虽然匹配部分不甚了解,只扫对于如何使用OPENCV进行sift特征的提取有了一定的理解。接下来可以开始进行下一步的工作了。

附:使用OPENCV下SIFT库做图像匹配的例程

// opencv_empty_proj.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#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 _tmain(int argc, _TCHAR* argv[])
{
	const char* imagename = "img.jpg";

	//从文件中读入图像
	Mat img = imread(imagename);
	Mat img2=imread("img2.jpg");

	//如果读入图像失败
	if(img.empty())
	{
			fprintf(stderr, "Can not load image %s\n", imagename);
			return -1;
	}
	if(img2.empty())
	{
			fprintf(stderr, "Can not load image %s\n", 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<<"\t"<<itvc->class_id<<"\t"<<itvc->octave<<"\t"<<itvc->pt<<"\t"<<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;
}

  

时间: 2024-10-13 17:50:49

OPENCV下SIFT算法使用方法笔记的相关文章

java 在centos6.5+eclipse环境下调用opencv实现sift算法

java 在centos6.5+eclipse环境下调用opencv实现sift算法,代码如下: import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfKeyPoint; import org.opencv.highgui.Highgui; import org.opencv.features2d.*; public class ExtractSIFT{ public static

[opencv]空洞填充算法

在Matlab下,使用imfill可以很容易的完成孔洞填充操作,感觉这是一个极为常用的方法,然而不知道为什么Opencv里面却没有集成这个函数.在网上查了好多关于Opencv下的孔洞填充方法,大部分使用轮廓查找方法去做的,但对于这种方法,总感觉不是特别好.之前了解过冈萨雷斯那本书上的孔洞填充算法,所以想着手重新写一个.这里借鉴了冈萨雷斯书上的集合运算方法(并不完全一样) 大致思路如下: 0, 设原图像为 A. 1, 首先A向外延展一到两个像素,并将值填充为背景色(0),标记为B. 2, 使用fl

在linux环境下编译运行OpenCV程序的两种方法

原来以为在Ubuntu下安装好了OpenCV之后,自己写个简单的程序应该很容易吧,但是呢,就是为了编译一个简单的显示图片的程序我都快被弄崩溃了. 在谷歌和上StackOverFlow查看相关问题解答之后,我下面就介绍Command Line和CMake两种方式. 首先我先粘上我测试的代码吧,文件名为Test.c 1 #include <highgui.h> 2 3 int main(int argc,char ** argv) { 4 5 IplImage* img = cvLoadImage

SIFT算法的应用--目标识别之Bag-of-words模型

原文:http://blog.csdn.net/v_JULY_v/article/details/6555899 SIFT算法的应用 -目标识别之用Bag-of-words模型表示一幅图像 作者:wawayu,July.编程艺术室出品. 出处:http://blog.csdn.net/v_JULY_v . 引言 本blog之前已经写了四篇关于SIFT的文章,请参考九.图像特征提取与匹配之SIFT算法,九(续).sift算法的编译与实现,九(再续).教你一步一步用c语言实现sift算法.上,及九(

SIFT算法的Matlab实现

个人博客原文:http://www.sun11.me/blog/2016/sift-implementation-in-matlab/ 这是一次作业,内容是给出两张图像,检测特征点和匹配特征点.要求不能用诸如OpenCV的现成特征点检测函数.于是就只能造轮子了,写了这个Matlab版的sift.(其实就是把c语言的opensift翻译成了matlab 以下是算法流程,其实网上的类似博文已经很多了,只不过我看的过程中也看得不很明白,只能对照着好几个看,所以干脆自己又写了一遍.下面的图均来自于参考资

【OpenCV】SIFT原理与源码分析:DoG尺度空间构造

<SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 尺度空间理论 自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形容建筑物用“米”,观测分子.原子等用“纳米”.更形象的例子比如Google地图,滑动鼠标轮可以改变观测地图的尺度,看到的地图绘制也不同:还有电影中的拉伸镜头等等…… 尺度空间中各尺度图像的模糊程度逐渐变大,能够模拟人在距离目标由近到远时目标在视网膜上的形成过程.尺度越大图像越模糊. 为什么要

SIFT算法原理(2)-极值点的精确定位

在SIFT解析(一)建立高斯金字塔中,我们得到了高斯差分金字塔: 检测DOG尺度空间极值点 SIFT关键点是由DOG空间的局部极值点组成的.以中心点进行3X3X3的相邻点比较,检测其是否是图像域和尺度域的相邻点的极大值或极小值. (1)为了确保不是噪声我们先进型阈值二值化: n和S一样,你想提取多少个图片的特征:(n)S表示每组提取多少层 (2)在差分金字塔中找极值点 特征点是由DOG空间的局部极值点组成的.为了寻找DoG函数的极值点,每一个像素点要和它所有的相邻点比较,看其是否比它的图像域和尺

SIFT算法详解(转)

http://blog.csdn.net/zddblog/article/details/7521424 目录(?)[-] 尺度不变特征变换匹配算法详解 Scale Invariant Feature TransformSIFT Just For Fun zdd  zddmailgmailcom or zddhubgmailcom SIFT综述 高斯模糊 1二维高斯函数 2 图像的二维高斯模糊 3分离高斯模糊 1 尺度空间理论 2 尺度空间的表示 3 高斯金字塔的构建 尺度空间在实现时使用高斯金

OpenCV:Mat元素访问方法、性能、代码复杂度以及安全性分析

欢迎转载,尊重原创,所以转载请注明出处: http://blog.csdn.net/bendanban/article/details/30527785 本文讲述了OpenCV中几种访问矩阵元素的方法,在指定平台上给出性能比较,分析每种矩阵元素访问方法的代码复杂度,易用性. 一.预备设置 本文假设你已经正确配置了OpenCV的环境,为方便大家实验,在文中也给出了编译源程序的Makefile,其内容如代码段1所示. 采用如代码段2所示的计时函数,这段代码你可以在我之前的博文中找到,abtic()