SURF(Speeded-Up Robust Features) 是对 SIFT 得改进,相对于 SIFT,SURF 利用积分图像与盒函数模拟 DoG,提升了计算速度;同时,使用了一种不用于 SIFT 的特征描述方案。

在 SIFT 中,检测尺度空间极值使用了 DoG 响应,SURF 做了如下改进:

1)首先求原图像的积分图像,使用积分图像可以求任意尺度盒函数(Box Filter)响应;

2)使用 Box Fitler 代替 DoG,下图给出了垂直方向与xy方向的 Box Filter,使用积分图像求任意尺寸响应时间都是固定的;

3)在 空间寻找极值作为候选特征点,定义 Hessian 矩阵 ,其中,G 为高斯函数,I 为图像函数;

剔除 Det(H) 小于某固定值的候选特征点,得到较好的极值点;

4)使用小波函数计算特征点附近响应,该响应仍然可在积分图像上计算;然后以 60 度为步长在圆形上滑动,求每个窗口响应和并将响应和最大方向作为主方向;

5)将特征点区域分为 4 * 4 小区域,在小区域内再次应用小波函数,并分别求出响应和,可构成向量 ,最终构成 4 * 4 * 4 = 64 维特征向量;

一种扩展方式是区分 dx,dy 方向,分别统计 dy > 0 时对应的 dx 求和,dy < 0 时对应的 dx 求和...,这样将 v 扩展为 8 维向量,最终形成 4 * 4 * 8 = 128 维特征向量;

opencv 提供了 SURF 实现,其构造函数如下:

SURF(double hessianThreshold, int nOctaves=4, int nOctaveLayers=2, bool extended=true, bool upright=false);

hessianThreshold:当候选特征点的 Hessian 矩阵行列式值小于该值时,忽略该候选特征点;

nOctaves:表示高斯金字塔层数,当层数越多时,可检测到更粗的特征点;

nOctaveLayers:检测尺度空间上极值使用层数为 nOctaveLayers + 3;

extended:是否使用扩展特征描述,默认特征点描述向量为64维,扩展特征点描述向量为128维;

upright:当特征点方向不改变时,在描述特征点时可不计算特征点主方向;

SURF 特征匹配代码与 SIFT 基本一致,如下:

 1 cv::Mat img1 = cv::imread("a.jpg", cv::IMREAD_GRAYSCALE);
2 cv::Mat img2 = cv::imread("b.jpg", cv::IMREAD_GRAYSCALE);
3
4 cv::SurfFeatureDetector detector(2000);
5 std::vector<cv::KeyPoint> keypoints1, keypoints2;
6 cv::Mat descriptors1, descriptors2;
7 detector.operator()(img1, cv::noArray(), keypoints1, descriptors1);
8 detector.operator()(img2, cv::noArray(), keypoints2, descriptors2);
9
10 cv::BFMatcher matcher(cv::NORM_L2);
11 std::vector<DMatch> matches;
12 matcher.match(descriptors1, descriptors2, matches);
13
14 cv::Mat img_matches;
15 cv::drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
16 cv::imwrite("c.jpg", img_matches);
17
18 double min_dist = 100;
19
20 for (int i = 0; i < matches.size(); i++)
21 {
22 double dist = matches[i].distance;
23 if (dist < min_dist) min_dist = dist;
24 }
25
26
27 // Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
28 // or a small arbitary value ( 0.02 )
29 std::vector< DMatch > good_matches;
30 for (int i = 0; i < matches.size(); i++)
31 {
32 if (matches[i].distance <= max(2 * min_dist, 0.02))
33 {
34 good_matches.push_back(matches[i]);
35 }
36 }
37
38 cv::drawMatches(img1, keypoints1, img2, keypoints2, good_matches, img_matches);
39 cv::imwrite("d.jpg", img_matches);

参考资料 SURF: Speeded Up Robust Features Herbert Bay & Tinne Tuylelaars & Luc Van Gool

Learning OpenCV 3   Adrian Kaehler & Gary Bradski

最新文章

  1. [Unity游戏开发]向量在游戏开发中的应用(二)
  2. 浅谈 原生javaScript&amp;&amp;react 实现全局触摸按钮(附带对addeventlistener的了解)
  3. kali linux 、 windows、ubuntu三系统的引导问题
  4. python协程
  5. 不是语言之争--Go vs Erlang
  6. python中反射(__import__和getattr使用)
  7. MongoDB (九) MongoDB 投影
  8. HDU 4278 Faulty Odometer 8进制转10进制
  9. jQuery对下拉框、单选框、多选框的处理
  10. C# Winform中执行post操作并获取返回的XML类型的数据
  11. MVC4 学习笔记01
  12. js 第一天
  13. 201521123039 《java程序设计》第十一周学习总结
  14. Greetings
  15. Docker教程:docker machine的配置和命令
  16. 测试框架httpclent 4.HttpClient Post方法实现
  17. [C]排序并插入
  18. Notes : &lt;Hands-on ML with Sklearn &amp; TF&gt; Chapter 6
  19. 通过示例学习JavaScript闭包
  20. 剑指offer【02】- 替换空格(Java)

热门文章

  1. spring boot 启动警告 WARN 15684 --- [ restartedMain] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources. 解决
  2. 最新RabbitMQ安装指南2021.07
  3. MicroPython 8266 配置
  4. unittest测试框架
  5. 《剑指offer》面试题59 - II. 队列的最大值
  6. Natasha 4.0 探索之路系列(二) &quot;域&quot;与插件
  7. JUC之阻塞队列(BlockingQueue)基础
  8. .NET SourceGenerators 根据 HTTPAPI 接口自动生成实现类
  9. 沁恒CH32F103C8T6(二): Linux PlatformIO环境配置, 示例运行和烧录
  10. docker和K8s对应参数