除了我们熟知的SIFT、SURF、ORB等特征点提取算法,OpenCV中还提供了十余种特征点提取算法。最近在整理以往的ppt和报告,看到其中一页ppt,发现已经忘得差不多了,就再写篇博客复习下好了,这篇博客注重对比,技术方面的内容不会太过细致,希望能有帮助。当然,文章末尾会提供这些算法OpenCV调用的实例代码。

首先,引发内容的就是下面这张ppt:(不要注意Why Surf了,当时根据具体应用场景所做的选择)左边一栏是特征点的数目,右边一栏是检测的速度,数据是在博主自己的测试集(大概四五百张图片)上测试的。

SIFT

SIFT的论文在谷歌学术上单片引用超过四万次,算得上那个年代特征提取技术的里程碑了。一改以往特征点提取不稳定,特征不足的弱点,SIFT可以稳定的提取出特征点,并且对旋转平移缩放是鲁棒的。可以说是SIFT开启了鲁棒特征提取研究,下面是SIFT特征提取的主要步骤:

特征点检测:

构建尺度空间

在Dog高斯差分空间计算极值点,二次曲线插值获得亚像素精度的特征点

去除低对比度点,通过计算Hessian矩阵去除边缘响应点

特征描述:

统计特征点周围16*16区域的直方图,并选取直方图峰值作为改关键点的主方向

将坐标轴旋转为关键点的方向,保证旋转不变性,根据梯度计算128维特征描述子

SIFT的鲁棒性是有特征点检测和特征描述两个部分决定的,在这页最开始的PPT中,都是只统计了特征点检测算法,没有考虑特征描述(因为有许多算法不具备描述能力)。

这里额外解释下Dog,对不同模糊度的高斯滤波图像相减,得到的Dog,事实上就是不同尺度边缘的Laplace边缘检测,Dog计算比逐个进行Laplace滤波要快。数学推导参见Paper,在高斯滤波sigma计算时需要一定条件,才能近似的得到拉普拉斯滤波图像。

SURF

SURF算法可以看做是对SIFT算法的重要改进,全称Speeded-Up Robust Features,解决了SIFT计算复杂度高、耗时长的确定。SURF算法在光照和形变方面的鲁棒性要逊色于SIFT,但是带来了三倍的速度提升。

特征点检测:

计算积分图(为了加速Box滤波Harr小波的计算)

改变Box滤波器的尺度来得到不同的尺度空间

使用Hessian矩阵行列式的特征值的符号来确定极值

特征点描述:

根据像素在x,y方向上的Haar小波响应值来确定极值点方向

采用扇形区域扫描来统计得到64维或128维的直方图特征

FAST:BRISK/ORB/KAZE…

FAST是今年来最成功的特征点提取算法之一,其思想非常精妙。ORB算法、KAZE算法等都是使用FAST作为特征点检测算法,区别在于特征描述部分。

在图像中任选一点p, 假定其像素(亮度)值为 Ip

以3为半径画圆,覆盖p点周围的16个像素,如下图所示

设定阈值t,如果这周围的16个像素中有连续的n个像素的像素值都小于 Ip−t 或者有连续的n个像素都大于

Ip+t, 那么这个点就被判断为角点。 在OpenCV的实现中n取值为12(16个像素周长的 3/4).

一种更加快的改进是: 首先检测p点周围的四个点,即1, 5, 9, 12四个点中是否有三个点满足超过Ip+t, 如果不满足,则直接跳过,如果满足,则继续使用前面的算法,全部判断16个点中是否有12个满足条件。

在OpenCV中提供了一个参数,可以选取三种FAST计算方法。

Brisk、ORB、KAZE等算法都采用了FAST做特征点检测,BRIEF做特征描述,它们的不同之处比较少。

速度大致为:SIFT

ORB

ORB速度极快,ORB是SIFT和SURF之外非常好的选择,因为SIFT和SURF是有专利的,在商业软件中使用需要付费(当然,但多数开发者选择无视,但是如果你是巨头,就要避免踩雷)。ORB是采用rBRIEF进行描述的,优点就是速度快。

BRISK

BRISK算法同样是免费的,也是规避SIFT和SURF专业的好选择,同样是采用FAST检测特征点,BRIEF描述。BRISK只是在尺度空间构建的参数和BRIEF描述方式上有所不同。在BRIEF描述时采用均匀采样模式,考虑512个短距离子集,形成64bit的描述符,采用汉明距离来度量相似性。

KAZE

日语“风”“かぜ”,KAZE是一种和SIFT很像的方法,今年来收到广泛关注,因为它是近年来效果最好的方法。在构建尺度空间方面,KAZE采用AOS算法来对高斯模糊的图像进行非线性扩散滤波,通过不同的进化时间t来构建非线性尺度空间(与SIFT相似,只不过sigma换成了t)。在特征点检测方面,也是采用和SIFT相似的的方式,26邻域极值点加上海森矩阵检测的方式来检测出特征点。在特征描述方面,和SURF比较相似,采用扇形区域扫描的方式确定主方向,然后对于周围区域划分成4*4的区域,然后每个区域计算4维特征向量,总共得到64维的特征向量。与前面的算法最重要的不同在于,使用了非线性扩散滤波,在滤除噪声的同时保留了边缘和特征点,不会像高斯滤波之类的算法一样无差别的模糊图像,使得特征点检测更为稳定和有效。该算法在尺度鲁棒性上要逊色与SIFT,但是在速度和稳定性方面要强于SIFT,是目前最常用的特征点提取算法。该算法和SIFT算法在时间消耗上是差不多的,可以通过精简KAZE算法来提高速度。

Dense SIFT

Dense SIFT算法没有特征点提取过程,通过稠密无差别的采集样本点,计算SIFT特征来形成整幅图片的特征描述,这种特征常常在早期目标识别使用,现在已经被淘汰。

GFTT

Good Feature To Track,正式名称是shi_tomasi角点检测算法,这种算法可以提取出大量的特征点。一般在需要大量特征点时,可以使用GFTT。

MSER

最大稳定极值区域(MSER:Maximally Stable Extremal Regions)常被用于提取图像中的斑点,是一种分水岭算法。通过阈值分割,不断提升分割阈值,连通域变化稳定的区域被称为最大稳定极值区域。

综合对比

特征点检测速度:FAST > SURF > SIFT

特征点检测数量:根据阈值调整,博主的结果是: FAST > SURF > SIFT

OpenCV Code

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

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

boolCVPointLayer::Fast(vector&images,vector&disp){

vectorpt;

FastFeatureDetectorfast(layerparam.fast_param().thresh(),layerparam.fast_param().isnms());

for(inti=0;i

pt.clear();

fast.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::FastX(vector&images,vector&disp){

vectorpt;

intxtype=0;

autoftype=layerparam.fast_param().ftype();

switch(ftype)

{

casesvaf::FastParamCP_FastType_T_9_16:

xtype=FastFeatureDetector::TYPE_9_16;

break;

casesvaf::FastParamCP_FastType_T_7_12:

xtype=FastFeatureDetector::TYPE_7_12;

break;

casesvaf::FastParamCP_FastType_T_5_8:

xtype=FastFeatureDetector::TYPE_5_8;

break;

default:

break;

}

for(inti=0;i

pt.clear();

cv::FASTX(images[i].image,pt,layerparam.fast_param().thresh(),

layerparam.fast_param().isnms(),xtype);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::MSER(vector&images,vector&disp){

vectorpt;

autoparam=layerparam.mser_param();

cv::MSERmser(param.delta(),param.min_area(),param.max_area(),

param.max_varia(),param.min_divers(),param.max_evolution(),

param.area_thresh(),param.min_margin(),param.edgeblur_size());

for(inti=0;i

pt.clear();

mser.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::ORB(vector&images,vector&disp){

vectorpt;

autoparam=layerparam.orb_param();

autoobrtype=param.scoretype();

intotype=0;

switch(obrtype)

{

casesvaf::ORBParamCP_OBRScoreType_HARRIS_SCORE:

otype=ORB::HARRIS_SCORE;

break;

casesvaf::ORBParamCP_OBRScoreType_FAST_SCORE:

otype=ORB::FAST_SCORE;

break;

default:

break;

}

cv::ORBorb(param.nfeatures(),param.scalefactor(),param.nlevels(),param.edgethresh(),

param.firstlevel(),param.wta_k(),otype,param.patchsize());

for(inti=0;i

pt.clear();

orb.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::Brisk(vector&images,vector&disp){

vectorpt;

autoparam=layerparam.brisk_param();

BRISKbrisk(param.thresh(),param.octaves(),param.ptscale());

for(inti=0;i

pt.clear();

brisk.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::Freak(vector&images,vector&disp){

vectorpt;

FREAKfreak;

LOG(FATAL)<

returnfalse;

}

boolCVPointLayer::Star(vector&images,vector&disp){

vectorpt;

autoparam=layerparam.star_param();

cv::StarDetectorstar(param.maxsize(),param.response_thresh(),param.projected_thresh(),

param.binarized_thresh(),param.nms_size());

for(inti=0;i

pt.clear();

star.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::Sift(vector&images,vector&disp){

vectorpt;

autoparam=layerparam.sift_param();

SIFTsift(param.nfeatures(),param.octaves(),param.contrast_thresh(),

param.edge_thresh(),param.sigma());

for(inti=0;i

pt.clear();

sift.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::Surf(vector&images,vector&disp){

vectorpt;

autoparam=layerparam.surf_param();

SURFsurf(param.hassian_thresh(),param.octaves(),param.intevals(),

param.extended(),param.upright());

for(inti=0;i

pt.clear();

surf.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::GFTT(vector&images,vector&disp){

vectorpt;

autoparam=layerparam.gftt_param();

GoodFeaturesToTrackDetectorgftt(param.maxcornners(),param.quality(),param.mindist(),

param.blocksize(),param.useharris(),param.k());

for(inti=0;i

pt.clear();

gftt.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::Harris(vector&images,vector&disp){

/*vector pt;

Ptr detector = FeatureDetector::create("HARRIS");

for (int i = 0; i < images.size(); ++i){

pt.clear();

detector->detect(images[i].image, pt);

for (int j = 0; j < pt.size(); ++j){

images[i].keypoint.insert(images[i].keypoint.begin(), pt.begin(), pt.end());

}

}

return true;*/

vectorpt;

autoparam=layerparam.gftt_param();

GoodFeaturesToTrackDetectorgftt(param.maxcornners(),param.quality(),param.mindist(),

param.blocksize(),true,param.k());

for(inti=0;i

pt.clear();

gftt.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::Dense(vector&images,vector&disp){

vectorpt;

autoparam=layerparam.dense_param();

DenseFeatureDetectordense(param.initfeatscale(),param.featscalelevel(),param.featscalemul(),

param.initxystep(),param.initbound(),param.varyxyscale(),param.varybdscale());

for(inti=0;i

pt.clear();

dense.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::SimpleBlob(vector&images,vector&disp){

vectorpt;

SimpleBlobDetectorsb;

for(inti=0;i

pt.clear();

sb.detect(images[i].image,pt);

images[i].keypoint.insert(images[i].keypoint.begin(),pt.begin(),pt.end());

LOG(INFO)< points";

}

returntrue;

}

boolCVPointLayer::Grid(vector&images,vector&disp){

Ptrdetector=FeatureDetector::create("Grid");

returnfalse;

}

boolCVPointLayer::Pyramid(vector&images,vector&disp){

Ptrdetector=FeatureDetector::create("Pyramid");

returnfalse;

}

opencv曝光算法_OpenCV特征点提取算法对比相关推荐

  1. 特征点提取算法 - 01 - 特征的定义基础

    前言:特征提取(feature extraction)是计算机视觉和图像处理中的一个概念.它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征.特征提取的结果是把图像上的点分为不同的子 ...

  2. 数字摄影测量之特征点提取算法

    数字摄影测量之特征点提取算法 1 一些基本概念与 什么是特征点? 特征点条件(具有什么性质才被称为特征点?) 什么是数字影像(图像)的导数 2.特征点提取算法之--Moravec算子 特征点检测算法之 ...

  3. SURF网格化特征点提取算法流程(一)

    SURF网格化特征点提取算法流程(一) 相关: SURF网格化特征点提取的算法流程(二) SURF网格化特征点提取的算法流程(三) SURF网格化算法主要包括下面三个阶段: 第一部分:特征点检测 1. ...

  4. lm opencv 算法_OpenCV进行图像相似度对比的几种办法

    // PSNR.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include // Console I/O #include // St ...

  5. 【MATLAB教程案例26】图像特征点提取算法matlab仿真与分析——sift,surf,kaze,corner,BRISK等

    FPGA教程目录 MATLAB教程目录 目录 1.软件版本 2.图像的sift特征提取和matlab仿真 2.1sift理论概述 2.2 matlab仿真

  6. 一起自学SLAM算法:3.4 图像特征点提取

    连载文章,长期更新,欢迎关注: 写在前面 第1章-ROS入门必备知识 第2章-C++编程范式 第3章-OpenCV图像处理 3.1 认识图像数据 3.2 图像滤波 3.3 图像变换 3.4 图像特征点 ...

  7. 【特征检测】FAST特征点检测算法

    简介 在局部特征点检测快速发展的时候,人们对于特征的认识也越来越深入,近几年来许多学者提出了许许多多的特征检测算法及其改进算法,在众多的特征提取算法中,不乏涌现出佼佼者. 从最早期的Moravec,到 ...

  8. FAST特征点检测算法

    一.FAST算法简介   如今,特征点检测的算法有很多,从最初的Moravec,到Harris,再到SIFT.SUSAN.GLOH.SURF算法,可以说特征点提取算法层出不穷.各种改进算法PCA-SI ...

  9. 图像检索:几种基于纹理特征的图像检索算法

    from:图像检索:几种基于纹理特征的图像检索算法 本文节选自<基于纹理的图像检索算法研究>.描述了几种基于纹理特征的图像检索算法. 第 3 章基于纹理特征的图像检索 3.2 基于灰度共生 ...

最新文章

  1. python调用cmd命令会弹出黑框_python 调用cmd,不显示cmd黑框
  2. SharePoint 2010 新体验5 - Office Web Applications
  3. SAP LSMW 导入Open PO时价格不对问题之对策
  4. 用java程序完成从kafka队列读取消息到sparkstreaming再从sparkstreaming里把数据导入mysql中
  5. Linux基础命令---ab测试apache性能
  6. Git学习文档之二 应用总结-svn迁移到git
  7. mongodb启动时报错ERROR: child process failed, exited with error number 1
  8. (转载)python re模块详解 正则表达式
  9. mysql远程连接error 1045_启用远程MySQL连接:错误1045(28000):用户被拒绝访问
  10. 【原创】1985-2021年《中国城市统计年鉴》900+全变量地级市面板数据 Python编程整理直接可用的城市面板数据
  11. python输出最大的素数_Python中的最大素数回文
  12. efs android 分区 img,选择别人efs文件包都是.img格式的,怎么添加你们的.efs文? 爱问知识人...
  13. mysql 推送微信公众号_10分钟完成微信公众号第三方平台全网发布
  14. bim学习—— 第7章 放置幕墙门窗
  15. 网易云信im 的聊天记录展示
  16. Convert的用法
  17. MOSS SDK学习(5)
  18. kaggle案例:广告点击率预估+LR
  19. buck dcm占空比计算_如何计算BOOST转换器的占空比
  20. 面试题 收集请求k千里马

热门文章

  1. 机械迷城android分辨率,Android
  2. 数字逻辑电路:一致性电路表决电路
  3. Java 按时间排序
  4. 名画166 唐寅《金昌送别图》
  5. cocos2d-x接入live2d3.0学习
  6. Matrix Derivative
  7. android-5.1编译配置(van)
  8. 利盟设备提示“没有将模拟电话线连接到调制解调器,传真被禁用。”解决办法
  9. JavaScript正反选
  10. 有限元学习-自己编程!