引言及特征点监测器
前面提到的SURF与SIFT特征检测器与描述子
,
其实都是OpenCV扩展模块xfeature2d
中的内容,
而在OpenCV本身包含的feature2d模块中
也包含了几个非常有用的特征检测器与描述子
,
其所支持的特征点检测器(FeatureDetector)
如下:
FAST=1
STAR=2
ORB=5
MSER=6
GFTT=7
HARRIS=8
SIMPLEBLOB=9
DENSE=10
BRISK=11
AKAZE=12
其中,3、4
本来是SIFT
与SURF
的,但在OpenCV3.x
中,它们已经被移到扩展模块
中了。
如果使用OpenCV官方编译好的OpenCV4Android 3.x版本的SDK
,
则当声明与使用这两个类型的时候,它会告诉你不支持
。
描述子类型
feature2d
支持的特征点检测器
还支持以下的描述子类型
:
DescriptorExtractor.ORB=3
DescriptorExtractor.BRIEF=4
DescriptorExtractor.BRISK=5
DescriptorExtractor.FREAK=6
DescriptorExtractor.AKAZE=7
这里其实还有1与2
分别是SIFT与SURF
,
但其已经被移到扩展模块
了,所以如果声明使用会抛出不支持
的错误提示。
简单介绍几种特征提取方法
在feature2d模块
中同时具有特征点检测与描述子功能的方法
有ORB、BRISK、AKAZE
。
下面我们简单介绍一下这三种特征提取方法
。
1.ORB检测器与描述子
ORB(Oriented FAST and Rotated BRIEF)
是OpenCV实验室于2011年开发出来的一种新的特征提取算法
,相比较于SIFT与SURF
,
ORB的一大好处是没有专利限制
,
可以免费自由使用
,
同时具有旋转不变性与尺度不变性
。
OpenCV4Android中创建ORB检测器与描述子的代码:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB); DescriptorExtractor descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
2.BRISK检测器与描述子
BRISK(Binary Robust Invariant Scalable Keypoint)特征检测与描述子
是在2011年由几位作者联合提出的一种新的特征提取算法
,
OpenCV4Android中创建ORB检测器与描述子的代码如下:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.BRISK); DescriptorExtractor descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.BRISK);
3.AKAZE检测器与描述子
AKAZE算法是
SIFT算法之后
,
具有尺度不变性
与旋转不变性算法领域
的再一次突破
,
它是KAZE特征提取算法
的加速版本
;其
算法原理有别于前面提到的几种方法
,
其是通过正则化PM方程与AOS(加性算子分裂)方法
来求解非线性扩散
,
从而得到 尺度空间 的 每一层
;采样的方法与
SIFT
类似,
对每一层实现候选点的定位与过滤
以实现关键点的提取
;然后再使用与
SURF
求解方向角度类似的方法实现旋转不变性
特征,
最终生成AKAZE描述子
。
AKAZE算法的原理本身比较复杂,笔者所读的书中亦无详细解说,
感兴趣的小伙伴阅读相关论文去深入了解。
在OpenCV4Android中创建AKAZE特征检测器与描述子的代码如下:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.AKAZE); DescriptorExtractor descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.AKAZE);
4. OpenCV4Android中feature2d检测器与描述子的使用
基于feature2d中的检测器对象实现对象关键点检测的演示代码:
FeatureDetector detector = null;if(type == 1) { detector = FeatureDetector.create(FeatureDetector.ORB); } else if(type == 2) { detector = FeatureDetector.create(FeatureDetector.BRISK); } else if(type == 3) { detector = FeatureDetector.create(FeatureDetector.FAST); } else if(type == 4){ detector = FeatureDetector.create(FeatureDetector.AKAZE); } else {detector = FeatureDetector.create(FeatureDetector.HARRIS); } MatOfKeyPoint keyPoints = new MatOfKeyPoint(); detector.detect(src, keyPoints); Features2d.drawKeypoints(src, keyPoints, dst);
以AKAZE为例,在feature2d中实现图像特征检测、描述子计算、特征匹配的演示代码如下:
private void descriptorDemo(Mat src, Mat dst) { String boxFile = fileUri.getPath().replaceAll("box_in_scene", "box"); Mat boxImage = Imgcodecs.imread(boxFile); FeatureDetector detector = FeatureDetector.create(FeatureDetector.AKAZE); DescriptorExtractor descriptorExtractor = DescriptorExtractor.create (DescriptorExtractor.AKAZE); // 关键点检测 MatOfKeyPoint keyPoints_box = new MatOfKeyPoint(); MatOfKeyPoint keyPoints_scene = new MatOfKeyPoint(); detector.detect(boxImage, keyPoints_box); detector.detect(src, keyPoints_scene); // 描述子生成 Mat descriptor_box = new Mat(); Mat descriptor_scene = new Mat(); descriptorExtractor.compute(boxImage, keyPoints_box, descriptor_box); descriptorExtractor.compute(src, keyPoints_scene, descriptor_scene); // 特征匹配 MatOfDMatch matches = new MatOfDMatch(); DescriptorMatcher descriptorMatcher = DescriptorMatcher.create (DescriptorMatcher.BRUTEFORCE_HAMMING); descriptorMatcher.match(descriptor_box, descriptor_scene, matches); Features2d.drawMatches(boxImage, keyPoints_box, src, keyPoints_scene, matches, dst); // 释放内存 keyPoints_box.release(); keyPoints_scene.release(); descriptor_box.release(); descriptor_scene.release(); matches.release(); }
如果是作者本人的GitHub项目的话,
运行时,首先需要把drawable中的box.png与box_in_scene图像放到SD卡上的指定目录下,
在演示程序运行之后选择box_in_scene图像即可。
当然我们也可以更改一下代码,使用别的图片进行测试或者把图片放在项目中进行测试。
作者:凌川江雪
链接:https://www.jianshu.com/p/44c9a77191ca
共同学习,写下你的评论
评论加载中...
作者其他优质文章