当前位置:首页 » 操作系统 » 特征提取的算法sift

特征提取的算法sift

发布时间: 2024-02-07 18:16:54

java 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库做图像匹配的例程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// opencv_empty_proj.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include opencv.hpp>
#include features2d/features2d.hpp>
#includenonfree/nonfree.hpp>
#includelegacy/legacy.hpp>
#include
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;
vectorkp1,kp2;

siftdtc.detect(img,kp1);
Mat outimg1;
drawKeypoints(img,kp1,outimg1);
imshow("image1 keypoints",outimg1);
KeyPoint kp;

vector::iterator itvc;
for(itvc=kp1.begin();itvc!=kp1.end();itvc++)
{
cout<<"angle:"<angle<<"\t"<class_id<<"\t"<octave<<"\t"<pt<<"\t"<response<<endl;
}

siftdtc.detect(img2,kp2);
Mat outimg2;
drawKeypoints(img2,kp2,outimg2);
imshow("image2 keypoints",outimg2);

SiftDescriptorExtractor extractor;
Mat descriptor1,descriptor2;
BruteForceMatcher<L2> matcher;
vector 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;
}

㈡ OpenCV-Python之——图像SIFT特征提取

在一定的范围内,无论物体是大还是小,人眼都可以分辨出来。然而计算机要有相同的能力却不是那么的容易,在未知的场景中,计算机视觉并不能提供物体的尺度大小,其中的一种方法是把物体不同尺度下的图像都提供给机器,让机器能够对物体在不同的尺度下有一个统一的认知。在建立统一认知的过程中,要考虑的就是在图像在不同的尺度下都存在的特征点。

在早期图像的多尺度通常使用图像金字塔表示形式。图像金字塔是同一图像在不同的分辨率下得到的一组结果其生成过程一般包括两个步骤:

多分辨率的图像金字塔虽然生成简单,但其本质是降采样,图像的局部特征则难以保持,也就是无法保持特征的尺度不变性。

我们还可以通过图像的模糊程度来模拟人在距离物体由远到近时物体在视网膜上成像过程,距离物体越近其尺寸越大图像也越模糊,这就是高斯尺度空间,使用不同的参数模糊图像(分辨率不变),是尺度空间的另一种表现形式。

构建尺度空间的目的是为了检测出在不同的尺度下都存在的特征点,而检测特征点较好的算子是Δ^2G(高斯拉普拉斯,LoG)
使用LoG虽然能较好的检测到图像中的特征点,但是其运算量过大,通常可使用DoG(差分高斯,Difference of Gaussina)来近似计算LoG。

从上式可以知道,将相邻的两个高斯空间的图像相减就得到了DoG的响应图像。为了得到DoG图像,先要构建高斯尺度空间,而高斯的尺度空间可以在图像金字塔降采样的基础上加上高斯滤波得到,也就是对图像金字塔的每层图像使用不同的参数σ进行高斯模糊,使每层金字塔有多张高斯模糊过的图像。
如下图,octave间是降采样关系,且octave(i+1)的第一张(从下往上数)图像是由octave(i)中德倒数第三张图像降采样得到。octave内的图像大小一样,只是高斯模糊使用的尺度参数不同。

对于一幅图像,建立其在不同尺度scale下的图像,也称为octave,这是为了scale-invariant,也就是在任何尺度都能有对应的特征点。下图中右侧的DoG就是我们构建的尺度空间。

为了寻找尺度空间的极值点,每一个采样点要和它所有的相邻点比较,看其是否比它的图像域和尺度域的相邻点大或者小。如图所示,中间的检测点和它同尺度的8个相邻点和上下相邻尺度对应的9×2个点共26个点比较,以确保在尺度空间和二维图像空间都检测到极值点。 一个点如果在DOG尺度空间本层以及上下两层的26个领域中是最大或最小值时,就认为该点是图像在该尺度下的一个特征点。下图中将叉号点要比较的26个点都标为了绿色。

找到所有特征点后, 要去除低对比度和不稳定的边缘效应的点 ,留下具有代表性的关键点(比如,正方形旋转后变为菱形,如果用边缘做识别,4条边就完全不一样,就会错误;如果用角点识别,则稳定一些)。去除这些点的好处是增强匹配的抗噪能力和稳定性。最后,对离散的点做曲线拟合,得到精确的关键点的位置和尺度信息。

近来不断有人改进,其中最着名的有 SURF(计算量小,运算速度快,提取的特征点几乎与SIFT相同)和 CSIFT(彩色尺度特征不变变换,顾名思义,可以解决基于彩色图像的SIFT问题)。

其中sift.detectAndCompute()函数返回kp,des。

上图dog的shape为(481, 500, 3),提取的特征向量des的shape为(501, 128),501个128维的特征点。

该方法可以在特征点处绘制一个小圆圈。

https://blog.csdn.net/happyer88/article/details/45817305
https://www.jianshu.com/p/d94e558ebe26
https://www.cnblogs.com/wangguchangqing/p/4853263.html

㈢ sift算法是什么

Sift算法是David Lowe于1999年提出的局部特征描述子,并于2004年进行了更深入的发展和完善。Sift特征匹配算法可以处理两幅图像之间发生平移、旋转、仿射变换情况下的匹配问题,具有很强的匹配能力。

这一算法的灵感也十分的直观,人眼观测两张图片是否匹配时会注意到其中的典型区域(特征点部分),如果我们能够实现这一特征点区域提取过程,再对所提取到的区域进行描述就可以实现特征匹配了。

sift算法的应用

SIFT算法目前在军事、工业和民用方面都得到了不同程度的应用,其应用已经渗透了很多领域,典型的应用如下:物体识别;机器人定位与导航;图像拼接;三维建模;手势识别;视频跟踪;笔记鉴定;指纹与人脸识别;犯罪现场特征提取。

㈣ HartSift: 一种基于GPU的高准确性和实时SIFT

尺度不变特征变换 (SIFT) 是最流行和最强大的特征提取算法之一,因为它对尺度、旋转和光照保持不变。它已被广泛应用于视频跟踪、图像拼接、同时定位和映射(SLAM)、运动结构(SFM)等领域。然而,高计算复杂度限制了其在实时系统中的进一步应用。这些系统必须在准确性和性能之间进行权衡以实现实时特征提取。他们采用其他更快但精度较低的算法,如 SURF 和 PCA-SIFT。为了解决这个问题,本文提出了一种使用 CUDA 的 GPU 加速 SIFT,命名为 HartSift,充分利用单机CPU和GPU的计算资源,实现高精度、实时的特征提取。实验表明,在 NIVDIA GTX TITAN Black GPU 上,HartSift 可以根据图像的大小在 3.14-10.57ms (94.61-318.47fps) 内处理图像。此外,HartSift 分别比 OpenCV-SIFT(CPU 版本)和 SiftGPU(GPU 版本)快 59.34-75.96 倍和 4.01-6.49 倍。同时,HartSift 的性能和 CudaSIFT(迄今为止最快的 GPU 版本)的性能几乎相同,而 HartSift 的准确度远高于 CudaSIFT。

SIFT算法可以提取大量显着特征,这些特征在缩放、旋转、光照和3D视点保持不变,还提供了跨越噪声和仿射失真的稳健匹配。但SIFT的高计算复杂度限制了其在大规模数据和实时系统中的进一步应用。而复杂度较低的算法,如SURF、PCA-SIFT的准确性又不太高。因此,在主流计算平台上实现高精度、实时的SIFT是一个重要而有意义的研究课题。

而SIFT算法具有很好的并行性,可以正确移植到GPU上。因此,在配备GPU的异构计算系统上实现高性能的SIFT具有重要的实用价值。

SIFT 算法包含三个阶段,包括高斯差分(DoG)金字塔的构建、精确的关键点定位和 128 维描述符生成。由于每个阶段都有自己的并行特性,因此必须使用不同的并行粒度和优化来实现高性能。尤其是后两个阶段,负载不平衡不利于GPU优化,会导致性能下降。

本文的主要贡献和创新可以概括如下:

有许多工作尝试在GPU上使用SIFT算法。

然而,为了实现高性能,他们省略了 SIFT 算法的一些重要步骤,例如将输入图像加倍、保持尺度变化的连续性和拟合二次函数以定位准确的关键点信息。作者的实验表明,这些遗漏会导致 SIFT 丢失很多关键点和准确性。

Lowe将输入图像尺寸加倍作为高斯金字塔 的最底层,每个尺度 通过高斯卷积产生:

高斯金字塔确定之后,利用相同Octave的层级相减,得到差分金字塔:

其中 ,在本文中, .

检测尺度空间极值

将DoG金字塔每个像素与相邻像素比较,同层8个,上下层9个,若像素是局部最大值或局部最小值,将其视为关键点候选。

去除无效关键点

去除较低对比度和不稳定边缘响应的候选关键点,通过将3D二次函数拟合到附近数据执行子像素插值,以获取精确的位置、比例和主曲率比。

方向分配

将候选关键点周围的梯度累积到36 bins的直方图中,根据每层的尺度计算搜索半径。每个紧邻像素由一个高斯加权窗口加权,梯度方向累计到36 bins的方向直方图中。峰值为主要梯度方向,同时超过峰值80%的局部峰值bin也被视为关键点方向。

对关键点周围像素计算梯度直方图,搜索半径比上一步骤大得多,同样用一个高斯加权函数用于为每个邻居的梯度值分配权重。

根据梯度方向将最终的梯度值累积到一个 360-bin 的圆形方向直方图。最后,直方图将被归一化、平滑并转换为 128D 描述符。

构建金字塔应该保持顺序,以保证尺度空间变化连续性。Acharya和Bjorkman为加快这一过程,牺牲准确性打破构建顺序。考虑到不能使准确性降低,构建顺序在HartSift中保留。

分离卷积核

对于 大小的卷积核处理 大小的图像需要进行 次运算,如果将2D卷积核拆解为两个1D的卷积核,计算量减少至 . 通过使用共享内存和向量化方法,更容易实现合并全局内存访问并减少一维卷积的冗余访问。

Uber 内核

Uber内核将多个不同任务放到一个物理内核中,在一个内核中并行处理任务,而不需要在内核之间切换。差分金字塔第 层由高斯金字塔第 和第 层决定。将高斯差分金字塔和高斯卷积核封装在单个核中,可以充分挖掘并行性。

线程不需要重复读取高斯金字塔第 层的值,这是由于第 层的值计算完后,结果会放在寄存器内而不是全局内存中。借助Uber内核的优势,我们可以节省 的空间和 的内核运行时间

异构并行

HartSift 采用异构并行方法来加速这一阶段。CPU 和 GPU 将并行协作,构建 DoG 金字塔。

由于GPU处理小图像没有优势,作者将 以下的图像放到CPU处理,大图像放到GPU处理。用户也可以自行设置分离点,确保CPU和GPU负载平衡。

存在两个问题:

负载均衡

Warp是GPU最小并行执行单元,即以锁步方式执行的 32 个线程的集合。若负载不均衡,则warp执行时间取决于最后一个线程完成的时间,warp负载不均衡会导致GPU效率降低。

由于候选关键点分布的随机性,几乎所有经线都包含不同数量的空闲线程。如果这些warp继续处理以下部分,就会出现两个级别的负载不平衡.

在去除无效的候选关键点部分时,线程将进行亚像素插值以获得准确的候选关键点信息,从而去除具有低对比度或不稳定边缘响应的关键点候选。换句话说,一些线程会比其他线程更早返回一次。负载不平衡会变得更加严重。

为了突破性能瓶颈,HartSift 引入了重新平衡工作负载和多粒度并行优化。

重新平衡工作负载

当检测到负载不平衡时,HartSift 将通过启动具有适当粒度的新内核并分派每个具有 32 个活动线程的新经线来重新平衡工作负载。

此外,启动三个内核分别处理这三个部分,不仅可以重新平衡工作量,还可以根据不同部分的并行特性提供多粒度的并行。

多粒度并行

重新平衡工作负载优化保证每个内核中的线程和经线被完全加载,多粒度并行优化保证工作负载将平均分配到线程和经线。此外,不同内核的并行粒度取决于工作负载的特性。

HartSift通过将一个线程映射到一个或多个像素,采用与关键点候选检测部分和无效关键点去除部分并行的线程粒度。然而,线程粒度并行会导致方向分配部分的负载不平衡,因为不同关键点的相邻区域半径不同。线程粒度并行会为单个线程分配过多的工作,这在某些情况下限制了硬件资源的利用率。所以在这部分应用混合粒度并行:扭曲粒度构建直方图,线程粒度找出并将主导方向分配给相应的关键点。

基于扭曲的直方图算法

作者针对每个关键点提出了一种基于扭曲粒度和原子操作的高性能直方图算法,以充分利用局部性。

该阶段关键点的邻域半径远大于前一阶段。需要为每个关键点累积数千个邻居到一个 360-bin 直方图。如果采用前一阶段的基于原子扭曲的直方图算法,会对这一阶段的性能产生不同的影响。

HartSift引入了一种atomic-free的直方图算法,进一步提升了这一阶段的性能。

该算法包含三个步骤:

为了消除线程间的负载不平衡,实现全局合并访问,HartSift 使用一个warp 来处理一个keypoint 的所有邻居。当线程计算出它们的方向 bin 时,它们需要根据bin变量的值将梯度值累加到局部直方图。考虑到有如此多的邻居并且一个经线的一些线程可能具有相同的 bin,算法1引入了一种无原子的多键约简方法来累积每个经线的部分和。这种方法可以利用warp级shuffle和vote指令完全消除原子操作和本地同步。它根据bin对经纱的线程进行分组并指定每组具有最低车道的线程作为队长线程。队长线程将保存他们自己的 bin 的部分总和,并将它们并行地累积到驻留在共享内存中的本地直方图,而不会发生 bank 冲突和同步。在遍历所有邻居后,HartSift 将最终的局部直方图复制到驻留在全局内存中的全局直方图。

本文提出了一种GPU上的并行SIFT,命名为Hart-Sift,它可以在单机内同时使用CPU和GPU来实现高精度和实时的特征提取。HartSift根据每个阶段的不同特点,通过适当采用不同的优化策略来提升性能,例如负载均衡、基于warp的直方图算法和不同尺度样本的atomic-free直方图算法等。在NVIDIA GTX TITAN Black GPU上,HartSift可以在3.14 ~ 10.57ms(94.61 ~ 318.47fps)内提取高精度特征,轻松满足高精度和实时性的苛刻要求。另外,与OpenCV-SIFT和SiftGPU相比,HartSift获得了59.34 ~ 75.96倍和4.01 ~ 6.49倍加速分别。同时,HartSift 和 CudaSIFT 的性能几乎相同,但 HartSift 远比 CudaSIFT 准确。

㈤ OpenCV+Python特征提取算法与图像描述符之SIFT / SURF / ORB

算法效果比较博文

用于表示和量化图像的数字列表,简单理解成将图片转化为一个数字列表表示。特征向量中用来描述图片的各种属性的向量称为特征矢量。

参考
是一种算法和方法,输入1个图像,返回多个特征向量(主要用来处理图像的局部,往往会把多个特征向量组成一个一维的向量)。主要用于图像匹配(视觉检测),匹配图像中的物品。

SIFT论文
原理
opencv官网解释
实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。

尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。
其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。

对现实中物体的描述一定要在一个十分重要的前提下进行,这个前提就是对自然界建模时的尺度。当用一个机器视觉系统分析未知场景时,计算机没有办法预先知道图像中物体的尺度,因此我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的最佳尺度。图像的尺度空间表达指的是图像的所有尺度下的描述。

KeyPoint数据结构解析

SURF论文
原理
opencv官网解释
SURF是SIFT的加速版,它善于处理具有模糊和旋转的图像,但是不善于处理视角变化和光照变化。在SIFT中使用DoG对LoG进行近似,而在SURF中使用盒子滤波器对LoG进行近似,这样就可以使用积分图像了(计算图像中某个窗口内所有像素和时,计算量的大小与窗口大小无关)。总之,SURF最大的特点在于采用了Haar特征以及积分图像的概念,大大加快了程序的运行效率。

因为专利原因,OpenCV3.3开始不再免费开放SIFT\SURF,需要免费的请使用ORB算法

ORB算法综合了FAST角点检测算法和BRIEFF描述符。

算法原理
opencv官方文档
FAST只是一种特征点检测算法,并不涉及特征点的特征描述。

论文
opencv官方文档
中文版
Brief是Binary Robust Independent Elementary Features的缩写。这个特征描述子是由EPFL的Calonder在ECCV2010上提出的。主要思路就是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个二进制串,并将这个二进制串作为该特征点的特征描述子。文章同样提到,在此之前,需要选取合适的gaussian kernel对图像做平滑处理。

1:不具备旋转不变性。
2:对噪声敏感
3:不具备尺度不变性。

ORB论文
OpenCV官方文档

ORB采用了FAST作为特征点检测算子,特征点的主方向是通过矩(moment)计算而来解决了BRIEF不具备旋转不变性的问题。
ORB还做了这样的改进,不再使用pixel-pair,而是使用9×9的patch-pair,也就是说,对比patch的像素值之和,解决了BRIEF对噪声敏感的问题。
关于计算速度:
ORB是sift的100倍,是surf的10倍。

对图片数据、特征分布的一种统计
对数据空间(bin)进行量化

Kmeans

边缘:尺度问题->不同的标准差 捕捉到不同尺度的边缘
斑点 Blob:二阶高斯导数滤波LoG

关键点(keypoint):不同视角图片之间的映射,图片配准、拼接、运动跟踪、物体识别、机器人导航、3D重建

SIFT\SURF

㈥ sift算法得到的特征点如何用坐标描述

在我写的关于sift算法的前俩篇文章里头,已经对sift算法有了初步的介绍:九、图像特征提取与匹配之SIFT算法,而后在:九(续)、sift算法的编译与实现里,我也简单记录下了如何利用opencv,gsl等库编译运行sift程序。
但据一朋友表示,是否能用c语言实现sift算法,同时,尽量不用到opencv,gsl等第三方库之类的东西。而且,Rob Hess维护的sift 库,也不好懂,有的人根本搞不懂是怎么一回事。
那么本文,就教你如何利用c语言一步一步实现sift算法,同时,你也就能真正明白sift算法到底是怎么一回事了。

热点内容
空调外机压缩机声音大 发布:2024-11-28 19:27:28 浏览:311
中国密码箱哪里的好 发布:2024-11-28 19:23:01 浏览:309
低配服务器如何搭建网站 发布:2024-11-28 19:08:46 浏览:923
zenly为什么不能下载安卓机 发布:2024-11-28 18:59:05 浏览:295
怎么把辅助放入服务器 发布:2024-11-28 18:53:06 浏览:598
渲染器服务器ip一定吗 发布:2024-11-28 18:44:38 浏览:648
光遇的服务器老是爆满怎么办 发布:2024-11-28 18:41:10 浏览:714
sql最大日期的记录 发布:2024-11-28 18:35:35 浏览:716
数据服务器和电脑如何连接 发布:2024-11-28 18:06:49 浏览:745
怎么让编译器输出的字符相隔单位 发布:2024-11-28 18:04:25 浏览:524