注意:本文含有一些数学公式,如果chrome不能看见公式的话请用IE打开网站
1.特征点提取
 
特征点提取有以下几个步骤:
a.尺度空间金字塔结构的构造
和SIFT类似,尺度空间金字塔是由不同的尺度构成,相互连续的两个尺度之间由Octave构成. 我们令t表示尺度,它们之间的计算关系如下:
图像的大小为(width, height),举个例子:
width,     height             scale1-octave1
(2/3)width, (2/3)height           scale1-octave2
(1/2)width, (1/2)height           scale2-octave1
(1/3)width, (1/3)height           scale2-octave2
(1/4)width, (1/4)height           scale3-octave1
(1/6)width, (1/6)height           scale3-octave2
 
其中下采样得到. 不同octave之间的采样关系为2/3,不同尺度之间的采样关系为1/2. 关于构造的代码:
  1. void BriskScaleSpace::constructPyramid(const cv::Mat& image){
  2.  
  3. // set correct size:
  4. pyramid_.clear();
  5.  
  6. // fill the pyramid:
  7. pyramid_.push_back(BriskLayer(image.clone()));
  8. if(layers_>){
  9. pyramid_.push_back(BriskLayer(pyramid_.back(),BriskLayer::CommonParams::TWOTHIRDSAMPLE));
  10. }
  11. const int octaves2=layers_;
  12.  
  13. for(uint8_t i=; i<octaves2; i+=){
  14. pyramid_.push_back(BriskLayer(pyramid_[i-],BriskLayer::CommonParams::HALFSAMPLE));
  15. pyramid_.push_back(BriskLayer(pyramid_[i-],BriskLayer::CommonParams::HALFSAMPLE));
  16. }
  17. }
b.通过阈值选取合适的关键点
关键点检测是通过FAST的算法进行的. FAST和AGAST在特征点检测中提供不同的模板。BRISK算法大部分使用FAST9-16提取特征点。首先,FAST9-16应用于每一个octave和每一层intra-octave,取相同的阈值T来分辨潜在的兴趣区域。然后,对兴趣区域中的点进行非极大值抑制:
1,问题点需要满足最大值条件,就是在同层中八邻域中的FAST score s最大。s定义为最大阈值是考虑到此点是图像角点。
2,同层和上下层的scores 应该都比此点的score s 小。检查等大小的方形patch内部:边长选择2像素。既然相邻层是不同离散化的,就需要在patch边缘进行插值。
3.由于确定一个特征点需要除本层以外的上下两层,但c0层是最底层,故需虚拟有一个d-1层,但这层不使用FAST9-16,而使用FAST5-8
非极大值抑制的代码:
  1. __inline__ bool BriskScaleSpace::isMax2D(const uint8_t layer,
  2. const int x_layer, const int y_layer){
  3. const cv::Mat& scores = pyramid_[layer].scores();
  4. const int scorescols = scores.cols;
  5. uchar* data=scores.data + y_layer*scorescols + x_layer;
  6. // decision tree:
  7. const uchar center = (*data);
  8. data--;
  9. const uchar s_10=*data; //
  10. if(center<s_10) return false;
  11. data+=;
  12. const uchar s10=*data; //
  13. if(center<s10) return false;
  14. data-=(scorescols+);
  15. const uchar s0_1=*data; //
  16. if(center<s0_1) return false;
  17. data+=*scorescols;
  18. const uchar s01=*data; //
  19. if(center<s01) return false;
  20. data--;
  21. const uchar s_11=*data; //
  22. if(center<s_11) return false;
  23. data+=;
  24. const uchar s11=*data; //
  25. if(center<s11) return false;
  26. data-=*scorescols;
  27. const uchar s1_1=*data; //
  28. if(center<s1_1) return false;
  29. data-=;
  30. const uchar s_1_1=*data;//
  31. if(center<s_1_1) return false;
  32.  
  33. /*8 3 7
  34. 1 0 2
  35. 5 4 6*/
  36.  
  37. // reject neighbor maxima
  38. std::vector<int> delta;
  39. // put together a list of 2d-offsets to where the maximum is also reached
  40. if(center==s_1_1) { //
  41. delta.push_back(-);
  42. delta.push_back(-);
  43. }
  44. if(center==s0_1) { //
  45. delta.push_back();
  46. delta.push_back(-);
  47. }
  48. if(center==s1_1) { //
  49. delta.push_back();
  50. delta.push_back(-);
  51. }
  52. if(center==s_10) { //
  53. delta.push_back(-);
  54. delta.push_back();
  55. }
  56. if(center==s10) { //
  57. delta.push_back();
  58. delta.push_back();
  59. }
  60. if(center==s_11) { //
  61. delta.push_back(-);
  62. delta.push_back();
  63. }
  64. if(center==s01) { //
  65. delta.push_back();
  66. delta.push_back();
  67. }
  68. if(center==s11) { //
  69. delta.push_back();
  70. delta.push_back();
  71. }
  72. const unsigned int deltasize=delta.size();
  73. if(deltasize!=){
  74. // in this case, we have to analyze the situation more carefully:
  75. // the values are gaussian blurred and then we really decide
  76. data=scores.data + y_layer*scorescols + x_layer;
  77. int smoothedcenter=*center+*(s_10+s10+s0_1+s01)+s_1_1+s1_1+s_11+s11;
  78. for(unsigned int i=; i<deltasize;i+=){
  79. //这里把左上角作为中心点进行平滑不知道是何意?
  80. data=scores.data + (y_layer-+delta[i+])*scorescols + x_layer+delta[i]-;
  81. int othercenter=*data;
  82. data++;
  83. othercenter+=*(*data);
  84. data++;
  85. othercenter+=*data;
  86. data+=scorescols;
  87. othercenter+=*(*data);
  88. data--;
  89. othercenter+=*(*data);
  90. data--;
  91. othercenter+=*(*data);
  92. data+=scorescols;
  93. othercenter+=*data;
  94. data++;
  95. othercenter+=*(*data);
  96. data++;
  97. othercenter+=*data;
  98. if(othercenter>smoothedcenter) return false;
  99. }
  100. }
  101. return true;
  102. }
 
c.去除不符合条件的关键点
 
 
2.特征点描述
和SIFT类似,尺度空间金字塔是由不同的尺度构成,相互连续的两个尺度之间由Octave构成. 我们令t表示尺度,它们之间的计算关系如下:
其中下采样得到. 不同octave之间的采样关系为2/3,不同尺度之间的采样关系为1/2.
 
 
b.通过阈值选取合适的关键点
关键点检测是通过FAST的算法进行的. FAST和AGAST在特征点检测中提供不同的模板。BRISK算法大部分使用FAST9-16提取特征点。首先,FAST9-16应用于每一个octave和每一层intra-octave,取相同的阈值T来分辨潜在的兴趣区域。然后,对兴趣区域中的点进行非极大值抑制:
1,问题点需要满足最大值条件,就是在同层中八邻域中的FAST score s最大。s定义为最大阈值是考虑到此点是图像角点。
2,同层和上下层的scores 应该都比此点的score s 小。检查等大小的方形patch内部:边长选择2像素。既然相邻层是不同离散化的,就需要在patch边缘进行插值。
3.由于确定一个特征点需要除本层以外的上下两层,但c0层是最底层,故需虚拟有一个d-1层,但这层不使用FAST9-16,而使用FAST5-8
 
c.去除不符合条件的关键点
 
2.特征点描述

BRISK算法在每个模式设置了60个点。
小的蓝色的圆表示在patch中的采样位置;大的红色虚线圆半径为  对应于用来平滑采样点亮度的高斯核的标准差。上图是尺度t=1的模式.
为了避免混叠效果,我们对在模式中的采样点Pi应用了高斯平滑. 标准差正比于每个采样点对应于各自中心的距离.
然后对60个点两两选取组成点对。一共是(60-1)*60/2个点对。 计算局部梯度:
所有点对的集合为:
 
 
 
阈值距离的选取:
迭代整个L上的点对,这样就可以估计出关键点k模式方向的整体特征:
长距离的点对都参与了运算,基于本地梯度互相抵消的假说,所以全局梯度的计算是不必要的。这一点同时也被距离变量阈值的实验确认了
 
3.创建描述子
对于旋转和尺度归一化的描述子的建立,BRISK使用了关键点周围的抽样点旋转角度作为模式。和BRIEF类似,BIRSK的描述子也是一个包含512个比特位的向量,每个描述子由短距离点对两两进行比较产生的,上标alpha表示旋转的模式。
 
 
 
与BRIEF不同的地方是,BRIEF只是进行亮度比较,除了预设尺度和预先对样本模式的旋转之外,BRISK和BRIEF有着根本的区别:

a.BRISK使用固定的样本模式点,而且是以R为半径围绕关键点周围的圆进行均匀取样。因此特定的高斯核平滑不会突然地扭曲亮度内容的信息(模糊邻近的两个采样点的亮度,从而保证亮度平滑过渡)
b.与两两组成的点对相比,BRISK显著的减少了采样点的数量(例如,单个的样本点参与了更多的比较),限制了亮度查找表的复杂度
c.这里的比较是受到空间的限制的,所以亮度的改变仅仅只是需要局部一致性就可以了。

 
 
程序中用到的算法:
 

1.利用least square进行曲线拟合中的参数计算

二次曲线的标准公式如下:
给定数据:
 
函数在的理论值,然后有:  
 
 
根据最小二乘定理,当下列偏导数等于0时使得S最小.
 
用方程组的形式表示出来:
 
 
 
 
这里有个比较疑惑的地方, refine1D, refine1D_1, refine1D_2这三个函数的矩阵是选取什么样的尺度初值算出来的?有知道朋友可以说说。
 
2.least square二次曲面拟合的参数计算
二次曲面的标准公式如下:
 
这里,选择C使得平方误差最小:
 
, 其中
 
当梯度E为0向量的时候上式取得最小值。
 
 
也可以写成含有6个未知变量的6个方程组的形式:
 
是6X1的矩阵和1X6的矩阵的乘积.
 
6x6的矩阵
6x1向量
 
所以AC=B.
 
单个元素的例子:

3.平滑函数
曲面拟合采用的是线性曲面拟合
注意,程序中的积分路线是45度角度路径进行积分的。

4.曲面插值
smoothedIntensity,BriskLayer::value这两个函数中使用了曲面插值算法。

 
5.重采样
重采样使用SSE指令对采样进行加速。
 
 
 
 
reference:
1.<Curve Fitting and Solution of Equation>
2.<Least Squares Fitting of Data>      David Eberly

3.<BRISK: Binary Robust Invariant Scalable Keypoints> Stefan Leutenegger, Margarita Chli and Roland Y. Siegwart

BRISK: Binary Robust Invariant Scalable Keypoints的更多相关文章

  1. 【特征匹配】BRISK原文翻译

    原文:Stefan Leutenegger, Margarita Chli et al.<BRISK: Binary Robust Invariant Scalable Keypoints> ...

  2. opencv::Brisk检测与匹配

    Brisk(Binary Robust Invariant Scalable Keypoints)特征介绍 构建尺度空间 特征点检测 FAST9-16寻找特征点 特征点定位 关键点描述子

  3. Computer Vision_33_SIFT:TILDE: A Temporally Invariant Learned DEtector——2014

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  4. 【特征检测】BRISK特征提取算法

    [特征检测]BRISK特征提取算法原创hujingshuang 发布于2015-07-24 22:59:21 阅读数 17840 收藏展开简介        BRISK算法是2011年ICCV上< ...

  5. opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较

    opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较 参考: http://wenku.baidu.com/link?url=1aDYAJBCrrK-uk2w3sSNai7h52x_ ...

  6. (1)RGB-D SLAM系列- 工具篇(硬件+关键技术)

    /*************************************************************************************************** ...

  7. OpenCV特征点提取----Fast特征

    1.FAST(featuresfrom accelerated segment test)算法 http://blog.csdn.net/yang_xian521/article/details/74 ...

  8. 图像局部显著性—点特征(SIFT为例)

    基于古老的Marr视觉理论,视觉识别和场景重建的基础即第一阶段为局部显著性探测.探测到的主要特征为直觉上可刺激底层视觉的局部显著性--特征点.特征线.特征块. SalientDetection 已经好 ...

  9. Computer Vision_33_SIFT:Remote Sensing Image Registration With Modified SIFT and Enhanced Feature Matching——2017

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

随机推荐

  1. Android Studio运行SlidingView报错 FloatMath函数

    1,错误信息时这样的(图片百度的,但是提醒的是一样的) 我们点击这个错误提示,就会跳到出错的地方 2,开始的时候觉得很蛋疼,因为这个SlidingView是从别处导过来的,没什么问题把...就很久就 ...

  2. JSP 甜点

    JSP cookies Cookies是存储在客户机的文本文件,它们保存了大量轨迹信息.在servlet技术基础上,JSP显然能够提供对HTTP cookies的支持. 通常有三个步骤来识别回头客: ...

  3. mybatis中的#{}和${}

    #{}:相当于预处理中的占位符?. #{}里面的参数表示接收java输入参数的名称. #{}可以接受HashMap.简单类型.POJO类型的参数. 当接受简单类型的参数时,#{}里面可以是value, ...

  4. Quartz Core框架之core animation

    1.时间功能 (1)CFTimeIntervalCACurrentMediaTime ( void ); :返回当前的绝对时间 2.转换功能 (1)bool CATransform3DIsIdenti ...

  5. 球形环境映射之angular与latlong格式互换

    这么做只是纯好奇,因为这种格式互换在实际中是没有意义的,下面映射方式互换的贴图说明了一切. 刚开始打算使用matlab进行贴图映射方式的转换,但许久不用很是生疏,而且生成图片要考虑很多事情,尤其是生成 ...

  6. web框架思考

    以前一直不明白web框架是怎样实现路由.orm.接受请求的.今天看了下廖雪峰的python 实现web框架博客才明白. 简单总结并记录: http请求->wsgi->处理请求->返回 ...

  7. Java高级规范之三

    三十一.如果变量名要加注释,说明命名不是很准确. 不规范示例:暂无 规范实例:暂无 解析:暂无 三十二.任何类字段除非必要,否则都要私有化 不规范示例: public class Person{ St ...

  8. Reconstruct Itinerary

    Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...

  9. KANO模型

    一.满意度的定义 消费者的满意度是取决于他们对企业所提供的产品和服务的事前期待,与实际(感知)效果之间的比较后,用户形成的开心或失望的感觉.就是说,如果购后在实际消费中的实际效果与事前期待相符合,则感 ...

  10. python 3 字符串转 json

    from json import *; JSONDecoder().decode('str')