美文网首页Android开发Android开发Android开发经验谈
计算机视觉 OpenCV Android | 特征检测与匹配 之

计算机视觉 OpenCV Android | 特征检测与匹配 之

作者: 凌川江雪 | 来源:发表于2019-02-14 23:57 被阅读4次

    引言及特征点监测器

    前面提到的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本来是SIFTSURF的,但在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图像即可。
    当然我们也可以更改一下代码,使用别的图片进行测试或者把图片放在项目中进行测试。


    参考材料

    相关文章

      网友评论

        本文标题:计算机视觉 OpenCV Android | 特征检测与匹配 之

        本文链接:https://www.haomeiwen.com/subject/adeueqtx.html