openMVG原理、编译、源码理解、实践

  • 1、理论
  • 2、实践
    • 2.1、源码编译(重点)
    • 2.2、其他
  • 3、 Work1: 根据tutorial_demo.py理解SFM pipeline
    • (1)、运行tutorial_demo.py:
    • (2)、源码理解
      • 1) 、step1: main_SfMInit_ImageListing.cpp
      • 2) 、step2: main_ComputeFeatures.cpp
      • 3) 、step3: main_MatchingFeatures.cpp
      • 4) 、step4: main_GlobalSFM.cpp
      • 5)、datacolor\from known pose 暂未细看
      • 6)、其他
  • 4、Work2:sfm结果(sfm_data_bin)转换
    • 1)数据转换至openMVS格式(.mvs)
    • 2)转换至其他格式(JSON/XML)

1、理论

学习链接:
官方github-wiki链接
官方文档链接
其他链接1
其他链接2
其他链接3
其他链接4

2、实践

2.1、源码编译(重点)

  1. 源码下载
    github链接

  2. Cmake编译> (实质:将源码组织成本地可运行的vs解决方案,并没有对源码进行更改或者执行)
    配置过程参见
    教程1
    其中,可将opencv的编译一同进行,参见:
    教程(含opencv编译)-1
    教程(含opencv编译)-2

  3. Vs运行解决方案中不中的项目

  • ALL_BUILD:

执行所有的项目文件,运行结果为.lib文件,路径为:
xx\openMVG\build\Windows-AMD64-\
ps: 在debug和release模型下运行分别存储于上述路径的对应文件夹下

  • INSTALL:

执行相关项目,生成源码对应的dll\lib\head.h,无论是debug还是release模式下,生成的文件路径及文件名一致,因此为区分两种模式下不同的输出,在生成后将文件名添加’d’/'r’后缀
ps: 结果文件的路径为:CMAKE_PREFIX_PATH
(我的电脑对应于:C:\Program Files (x86)\openMVG)
参考教程

  • Samples\

文件夹下为官方示例代码
用于检验先前的步骤是否正确运行

  • Softwares\

文件夹下为部分pipeIine的实现,可以理解为是samples的组合

  1. 编译生成的dll、lib以及头文件.h配置(重要)可用于其他工程文件,用以调用dll\lib
    操作教程
  2. 遇到的问题
  • 报错:无法打开lemon/config.h(openMVG/src/third_party/lemon/lemon/下不存在该文件)
解决办法:下载源码重新编译lemon
并将config.h文件拷贝至上述目录(openMVG/src/third_party/lemon/lemon/)

lemon编译参考链接

2.2、其他

  • 动态库、静态库的理解 博客讲解

3、 Work1: 根据tutorial_demo.py理解SFM pipeline

(1)、运行tutorial_demo.py:

(2)、源码理解

sfmpipeline 总览(重要)参考链接

1) 、step1: main_SfMInit_ImageListing.cpp

input: image、sensor_width_camera_database.txt(相机型号所对应ccdw)
output:sfmdata.json
sfmdata.json: SFM算法所需要的相关数据的集合,在初始状态只含有有效的views和intrinsics数据
OpenMVG中 focal length的计算方法:

CCD:相机中镜头后的感光元件,CCD是受光元件(像素)的集合体,接收透过镜头的光并将其转换为电信号。在像素数一样的情况下,CCD尺寸越大单位像素就越大。这样,单位像素可以收集更多的光线,因此,理论上可以说有利于提高画质。参考链接
ccdw:ccd的对角线的长度(涉及英寸与mm的换算)


std::max(width,height)/ccdw 表示单位长度对应的像素数,采用max(…),使长度与对角线长度更接近
exifReader->getFocal() 影像元数据中包含的相机焦距参数——5.58mm

PS:
图像信息“1/400 秒 f/2.8 5.85毫米”,其中,f表示光圈大小

2) 、step2: main_ComputeFeatures.cpp

影像金字塔DOG:
num_octaves = 6,//影像金字塔的层数
num_scales = 3,//影像金字塔的每层的尺度(通过高斯滤波形成不同的尺度)
mask使用:

Region:

3) 、step3: main_MatchingFeatures.cpp

匹配方法:Putative match——Geometric filter(F\E\H) 几何滤波(涉及RANSAC)

采用基本矩阵F时所采用的方法:A New A Contrario Approach for the Robust Determination of the Fundamental Matrix




Tracks:(官方链接)

4) 、step4: main_GlobalSFM.cpp

参考另一篇博文:openMVG–GlobalSFM(原理及代码解读)

5)、datacolor\from known pose 暂未细看

6)、其他

  1. 关键数据及结构理解(官方文档)
  2. R、C、t理解(注意C与t的区别)
  3. kenrel理解与使用
  4. keypointSet
  5. 代码中常用math类(重定义)
•Vec2将单个2d点存储为列矩阵(x,y)
•Vec3将单个3d点存储为列矩阵(x,y,z)
•Vec2f,Vec3f浮点版本。
•Vec是一个值的向量(双精度)
•Vecf一个浮点值的向量
•Mat对于通用矩阵容器,
•Mat2X收集由2d列存储的列,
•Mat3X将3d点的集合存储为列。
// Create a set of 2D points store as column
//创建一组2D点存储为列
Mat2X A(2, 5);//2行5列
A << 1, 2, 3, 4, 5,
6, 7, 8, 9, 10;
A.col(); // return a column vector : (1,6)^T
A.row(); // return a row vector : (1,2,3,4,5)
  1. sfm结果查看(可视化)

4、Work2:sfm结果(sfm_data_bin)转换

1)数据转换至openMVS格式(.mvs)

运行编译好的openMVG_main_openMVG2openMVS.exe
xx/openMVG_main_openMVG2openMVS.exe -i sfm_data_bin -o xxx.mvsPS: 运行过程中自动生成undistorted_images文件夹(存放原始影像)
具体实现及路径设置,还未细看(后期更新)

2)转换至其他格式(JSON/XML)

openMVG原理、编译、源码理解、实践相关推荐

  1. 斯坦福和NLTK英语短语词组抽取工具原理及源码理解

    一.斯坦福短语抽取工具实现了四个方法来进行短语搭配抽取 (1)基于统计频率数的方法 该方法用于查找长度为2或者3并且连续的短语搭配.因此只处理bigrams和trigrams语料库.对于候选短语集,首 ...

  2. 深入理解Spark 2.1 Core (十二):TimSort 的原理与源码分析

    在博文<深入理解Spark 2.1 Core (十):Shuffle Map 端的原理与源码分析 >中我们提到了: 使用Sort等对数据进行排序,其中用到了TimSort 这篇博文我们就来 ...

  3. 深入理解Spark 2.1 Core (十一):Shuffle Reduce 端的原理与源码分析

    我们曾经在<深入理解Spark 2.1 Core (一):RDD的原理与源码分析 >讲解过: 为了有效地实现容错,RDD提供了一种高度受限的共享内存,即RDD是只读的,并且只能通过其他RD ...

  4. 深入理解Spark 2.1 Core (十):Shuffle Map 端的原理与源码分析

    在上一篇<深入理解Spark 2.1 Core (九):迭代计算和Shuffle的原理与源码分析>提到经过迭代计算后, SortShuffleWriter.write中: // 根据排序方 ...

  5. 深入理解Spark 2.1 Core (八):Standalone模式容错及HA的原理与源码分析

    第五.第六.第七篇博文,我们讲解了Standalone模式集群是如何启动的,一个App起来了后,集群是如何分配资源,Worker启动Executor的,Task来是如何执行它,执行得到的结果如何处理, ...

  6. 深入理解Spark 2.1 Core (七):Standalone模式任务执行的原理与源码分析

    这篇博文,我们就来讲讲Executor启动后,是如何在Executor上执行Task的,以及其后续处理. 执行Task 我们在<深入理解Spark 2.1 Core (三):任务调度器的原理与源 ...

  7. 深入理解Spark 2.1 Core (六):Standalone模式运行的原理与源码分析

    我们讲到了如何启动Master和Worker,还讲到了如何回收资源.但是,我们没有将AppClient是如何启动的,其实它们的启动也涉及到了资源是如何调度的.这篇博文,我们就来讲一下AppClient ...

  8. Dubbo 实现原理与源码解析系列 —— 精品合集

    摘要: 原创出处 http://www.iocoder.cn/Dubbo/good-collection/ 「芋道源码」欢迎转载,保留摘要,谢谢! 1.[芋艿]精尽 Dubbo 原理与源码专栏 2.[ ...

  9. CopyOnWriteArrayList实现原理及源码分析

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! CopyOnWriteArrayList是Java并发包中提供的一个并发容器,它是个线程安全且读操 ...

最新文章

  1. 【网络安全】反序列化漏洞底层扩展与制作WebShell
  2. 第一章 java多线程
  3. paylinks.php_毕业设计-基于PHP的网上购物网站系统设计
  4. Future和Promise
  5. JavaScript 你必须了解的主流趋势!
  6. linux cp{,bak},Linux中cp覆盖不提示
  7. windows 截屏快捷键x220_电脑截屏快捷键是什么啊
  8. Java学习之Servlet-doGet()与doPost()
  9. nxlog收集windows事件方案
  10. quick-cocos2dx 组件管理器
  11. MATLAB GUI中的handles
  12. 小程序父子组件间传值(微信/支付宝/钉钉)
  13. Ruiy classicsQuotations
  14. 全球首个身份验证保险 提供每笔交易100万美金保额
  15. 【68期分享】7款红色大气PPT模板免费下载
  16. cdrx8如何批量导出jpg_cdr x8批量导出插件
  17. import nose ImportError: No module named 'nose'
  18. 【深度学习理论】(5) 图卷积神经网络 GCN
  19. IP地址的划分-----A,B,C,D类地址
  20. 人听到坏消息的反应_如何应对坏消息,正确传达坏消息的七个方法

热门文章

  1. Flash芯片你都认识吗?
  2. 【微信小程序】使用npm并引入vant-weapp组件库
  3. docker部署服务,本地文件路径正常,linux服务器文件路径找不到的小坑
  4. 从浏览器输入网址(URL),到最终展示页面,都发生了什么?
  5. iOS--在应用内切换语言
  6. 使用postman进行并发测试
  7. 【游戏 AI】7 - AI 引擎
  8. 基于遗传算法无人机路径规划MATLAB,基于遗传算法的机器人路径规划MATLAB源码
  9. 30岁成不了技术专家就应该转做管理?希望通过本文给大家带来一点思考
  10. Redis 本身有持久化,为什么还要写进 MySQL?