OpenCV SIFT源码讲解——代码逻辑宏观窥探

  • 一、暴露在外的接口:SIFT
  • 二、隐藏在SIFT背后的本质:SIFT_Impl
  • 三、使用sift算法全流程

一、暴露在外的接口:SIFT

一般来说,我们在OpenCV中使用SIFT算法的方式为:

//该表达式涉及到多态,详解在第2节
cv::Ptr<SiftFeatureDetector>  sift = SIFT::create();

那么,SiftFeatureDetector是什么呢?在 features2d.hpp中清晰的写出来:

typedef SIFT SiftFeatureDetector;

同样在该文件中,可以看到:

class CV_EXPORTS_W SIFT : public Feature2D
{...
}

CV_EXPORTS_W 的本质如下,表明SIFT 是一个暴露给用户的接口。

define CV_EXPORTS_W  CV_EXPORTS
//下面一行宏定义只能在源码内看到,不对外暴露
//若在程序中使用编译好的OpenCV,只能追踪到上一行宏定义
define CV_EXPORTS __declspec(dllexport)

二、隐藏在SIFT背后的本质:SIFT_Impl

在编译好的OpenCV内,对于SIFT,只提供了features2d.hpp文件,我们无法看到任何有关与他的具体实现。因此,想要探究其本质,现在进入其源码内:sift.dispatch.cpp。

在该cpp文件中,定义了一个SIFT的派生类SIFT_Impl 。该派生类不对外暴露。

class SIFT_Impl : public SIFT{};

同时,在该CPP文件中,也定义了SIFT接口的create函数:

Ptr<SIFT> SIFT::create( int _nfeatures, int _nOctaveLayers,double _contrastThreshold, double _edgeThreshold, double _sigma, int _descriptorType )
{.../** 返回指针*/return makePtr<SIFT_Impl>(_nfeatures, _nOctaveLayers, _contrastThreshold, _edgeThreshold, _sigma, _descriptorType);
}

因此,到目前为止,已经知道了SIFT背后的逻辑:

//定义SIFT类型的指针
//在create函数内定义 派生类 SIFT_Impl对象
//SIFT_Impl指针向上转型,赋值给sift。(多态)
cv::Ptr<SiftFeatureDetector>  sift = SIFT::create();

之后,sift通过箭头描述符调用的任何函数,都将通过虚指针指向派生类的具体实现。也即SIFT_Impl才是sift的本质。

三、使用sift算法全流程

//1.读取图像
cv::Mat matL = cv::imread(imgL);
cv::Mat matR = cv::imread(imgR);//2.定义关键点和描述符
std::vector<cv::KeyPoint> kpL,kpR;
cv::Mat descriptorL,descriptorR;//3.创建SIFT对象
cv::Ptr<SiftFeatureDetector>  siftL = SIFT::create();
cv::Ptr<SiftFeatureDetector>  siftR = SIFT::create();//4.探测关键点
siftL->detect(matL, kpL);
siftR->detect(matR, kpR);//5.计算描述符
siftL->compute(matL, kpL, descriptorL);
siftR->compute(matR, kpR, descriptorR);//6.描述符匹配
...

对于第3步,创建SIFT对象,上两节已经讲过,那么现在只剩下detect和compute两个步骤了。这两个步骤是个重难点,我将分多篇文章细讲,争取能给大家讲明白。(描述符匹配属于特征匹配通用的部分,不属于SIFT专有,在这里就不讲了)

回到features2d.hpp,可以看SIFT接口内并没有声明detectcompute两个函数,这是因为这两个函数是继承其基类Feature2D的(可以在该hpp文件内找到)。
进入features2d.cpp内,可以找到detectcompute的定义:

void Feature2D::detect( InputArray image,std::vector<KeyPoint>& keypoints,InputArray mask )
{...detectAndCompute(image, mask, keypoints, noArray(), false);
}void Feature2D::compute( InputArray image,std::vector<KeyPoint>& keypoints,OutputArray descriptors )
{...detectAndCompute(image, noArray(), keypoints, descriptors, true);
}

可以看到,这两个函数最终都将调用detectAndCompute,该函数是被SIFT_Impl重写(detect和compute还有一个重载函数,但是最后都会调用detectAndCompute)。
我将单独写一篇文章介绍detectAndCompute函数

OpenCV SIFT源码讲解——代码逻辑宏观窥探相关推荐

  1. OpenCV SIFT源码讲解——构建高斯金字塔

    目录 一.构建方法 二.函数重要点注释 一.构建方法 高斯金字塔每层图像的尺度为:.理论上金字塔每层图像可以从原图做的高斯滤波得到.但是实际操作中,每组的第一张影像(除第一组)是上一组倒数第三张影像降 ...

  2. OpenCV SIFT源码详解——总体概览

    OpenCV SIFT源码详解--总体概览 一.版本 二.章节系列 此系列文章源自本人硕士毕业论文,主要讲源码,对于SIFT理论知识默认大家有过了解.若文章中有不对之处还请读者指出. 一.版本 本系列 ...

  3. Oriented Fast神奇高效的代码实现方式——ORBSLAM2源码讲解(二)

    文章目录 前言 一.基础知识 二.灰度质心法原理 三.UMAX 四.IC_Angle如何做加速运算 总结 前言 本博客结合哔哩大学视频ORBSLAM2[ORBSLAM2源码讲解专题一]ORB特征点提取 ...

  4. 双目相机标定OpenCV源码讲解

    双目相机标定OpenCV源码讲解 背景介绍 所述内容 参考资料 摄像机标定部分代码 代码思路 代码中的其他函数 找角点&求内参 求外参 求矫正映射矩阵 后记 背景介绍 暑假接近两个月的时间做了 ...

  5. ORB特征点提取与均匀化——ORBSLAM2源码讲解(一)

    文章目录 前言 一.基础知识 二.ORB特征均匀化策略对性能的影响 三.ORB特征金字塔 四.ORB提取扩展图像 五.ORB特征均匀化 总结 前言 本博客结合哔哩大学视频ORBSLAM2[ORBSLA ...

  6. RobHess的SIFT源码分析:综述

    最初的目的是想做全景图像拼接,一开始找了OpenCV中自带的全景拼接的样例,用的是Stitcher类,可以很方便的实现全景拼接,而且效果很好,但是不利于做深入研究. Stitcher类使用方法请查Op ...

  7. 27.串口通信实验源码讲解

    串口通信实验源码讲解 笔记基于正点原子官方视频 视频连接https://www.bilibili.com/video/BV1Wx411d7wT?p=71&spm_id_from=333.100 ...

  8. 讲解java源码_Java学习之Java源码讲解

    关于Java中源码的学习,是不少同学头疼的知识点.本文整理了JAVA源码学习的八大要点,分别是基础知识.面向对象.异常处理.集合.综合类核心代码.JAVA8新特性.Input/Output和Java小 ...

  9. 读Zepto源码之代码结构

    虽然最近工作中没有怎么用 zepto ,但是据说 zepto 的源码比较简单,而且网上的资料也比较多,所以我就挑了 zepto 下手,希望能为以后阅读其他框架的源码打下基础吧. 源码版本 本文阅读的源 ...

最新文章

  1. python3编写简易统计服务器
  2. php人气代码,php – 人气算法
  3. 新鲜新奇事物_对各样新奇事物都有兴趣去了解的星座
  4. 20172305 2017-2018-2 《程序设计与数据结构》实验三报告
  5. eclipse--python开发环境搭建
  6. java笔试题_公司真题 | 用友2018秋招Java笔试题(四)
  7. 基于51单片机的密码锁
  8. Android 优化布局层次结构
  9. python从入门到精通pdf百度云-跟老齐学Python:从入门到精通 完整版PDF[7MB]
  10. jvisualvm监控java,配置 jvisualvm 监控Java虚拟机
  11. Win10重装系统后的lockdir解密失败
  12. 记录贴:学习Andorid开发
  13. 计算机毕业设计之java+springboot基于vue的网上图书商城系统
  14. python数据分析:会员数据化运营(中)——RMF分析
  15. 棚卸資産管理の用語一覧(Glossary of inventory control terms and phrases)
  16. PHP获取唯一标识UUID
  17. mxgraph进阶(三)Web绘图—mxGraph项目实战
  18. 推荐几个测试能接受邮件的临时邮箱
  19. python王者战斗_Python3 类与对象之王者荣耀对战小游戏
  20. android widget零基础,Android Widget详解(一)

热门文章

  1. Greenplum修改hostname
  2. Ubuntu16.04-grafana安装及插件配置
  3. 干货分享 | 如何写出清晰易懂的交互文档?
  4. 苹果cms10好看的模板_电脑手机自适应超简洁模板
  5. 家庭媒体中心解决方案(五、 群晖系列nas基本功能使用指南篇3-网络记事本和远程监控)
  6. android记事本程序需求分析文档,记事本程序的需求分析
  7. arduino判断是否连接串口_Arduino-串口函数Serial
  8. STM32F103xx之IO输入输出电流电压特性
  9. java零钱换整程序_JAVA微信企业付款到零钱(十分钟搞定),
  10. 【伯乐在线】100个高质量Java开发者博客