【更新】我的新博客:www.ryuzhihao.cc,当然这个csdn博客也会更新
本文在新博客中的链接:点击打开链接
完成时间:2017年2月27日
博客时间:2017年4月26日
去年,我有幸了解到image-based modeling的相关知识。作为一个大三本科生,虽说自己此前也做过一些相关工作,但是要自己实现Structure from motion,确实是费尽了我的脑袋壳儿(3个月)。
哦对,顺带宣传一下此前自己尝试过的一个相关的内容:Shape from shading(点击打开我的另一篇博客)。
平台:Qt + OpenGL + OpenCV
功能:(我实现的SFM算法——稀疏点云的获取)
程序截图:
1. 学校首任校长的雕像
输入数据:
输出结果:
2. 紫薇树:
输入数据:
输出结果:
3. 矮灌木
输入数据:
输出结果:
前面给出了三组测试用例的执行结果: 我的SFM算法实现。整体看来还是不错的,程序是其实有些不足,比如:对图像的分辨率要求比较高、若图像抖动会影响重建效果、恢复速度慢等等缺点。相比起VisualSFM及CMVS还是缺少了不少东西的。
关于SFM和CMVS的关系:SFM是得到稀疏点云的方法,CMVS是日本Yasutaka Furukawa(Washington University的assitance professor)基于SFM提出的多幅图像密集点云的提取方法。当然了,如果想要自己实现密集点云的CMVS,首先要实现稀疏点云的SFM。
我实现的程序也算是能得到相对密集的三维信息,也有比较快的执行速度。限于自己的知识水平有限,暂时无法做到CMVS那样的密集点云的效果。
顺带说明一下:我采用的方法大抵是知网、IEEE、SIGGRAPH上能够找到的关于SFM的Papers。说实话,虽说实现了出来,也是博主照葫芦画瓢,对原理的认识还是挺模糊的。不过还是希望接下来的介绍能够对看到这篇文章的人有所帮助。欢迎讨论~~~
Structure from motion (SfM) is a photogrammetric range imaging technique for estimating three-dimensional structures from two-dimensional image sequences that may be coupled with local motion signals. It is studied in the fields of computer vision and visual perception.
Structure from motion(SFM)是由一系列包含着视觉运动信息(motion signals)的多幅二维图像序列(2D image sequences)估计三维结构(3D model)的技术。它属于计算机视觉及可视化的研究范围。
说明:paper里面的太多数学原理、公式啥了,看的心累。这里整理出来的是简单的步骤,数学部分几乎没有。当然能理解最好,不要像我这样子半吊子…… 其实很多东西opencv已经帮我们做好了,我们只需要通过其中的函数就能实现下面的几个关键步骤。
1. 相机坐标系
为了更好的表示相机的旋转、平移,需要先引入相机的参考系。Z轴沿镜头方向,如下图(几乎每篇关于SFM的paper必有的图片……)
2. 相机的内参矩阵和外参矩阵
熟悉OpenCV的同学应该知道这一点。在市面上大多数计算机视觉方面的教材对这个都有很详细的讲述。这里不详细说了,不清楚的娃儿可以翻翻教材或者看看下面的博客:
http://blog.csdn.net/liyuan123zhouhui/article/details/52043683(摄像机内参、外参矩阵)
这里需要提一下:
一般来讲,内参矩阵需要通过标定求出来,但是其实部分参数我们可以从图片的信息中获取,在图片上右键“属性”,可以找到部分需要的信息:
外参矩阵的话:[R T] 包含从世界坐标系到相机坐标系的旋转、平移关系。
三、特征点提取和特征点匹配
这里可以不用我们去实现,使用OpenCV中的SIFT或SURF都可以做到。不过需要OpenCV3.0,之前版本的OpenCV可以直接使用SIFT和SURF,但是3之后的版本有我们需要的功能,只是它的SIFT等等被移动到nonfree.hpp里去了。具体的配置可以参考下面的链接(亲测可行,Qt下配到吐血!!!!):
(OpenCV3.1.0+Contrib配置)http://blog.csdn.net/qq_25517467/article/details/52189057
四、计算本征矩阵,进一步求出R、T矩阵
在得到匹配筛选过的特征点后,就能够计算出图像间的本征矩阵了。使用OpenCV中的findEssentialMat()方法可以直接实现。之后对求得本征矩阵essentialMat进行分析,得出图像间的相对变换矩阵R和T(两幅图像间的变换关系)
五、利用已知的R、T和匹配的特征点还原三维坐标。
这一步,需要我们自己去实现了。但是建议先去了解一下“三角测距”。因为到现在,我们已经知道图像两两之间的旋转平移的变换矩阵R、T,以及图像两两间的特征点匹配信息。这个就和“三角测距”非常类似。
关于这一步的实现可以参考各个论文或者下面的链接:
http://blog.sina.com.cn/s/blog_662c78590100zqwd.html
六、补充:
1. 关于SIFT、SURF的选择:SIFT得到的结果相对比较稀疏且特征点的价值较高,但是OpenCV里的SIFT不太稳定,很多图片在提取过程中会出现莫名其妙的错误。SURT的话特征点会比较多但是质量不怎么好,但是OpenCV的SURF非常稳定。
2. 关于稀疏点云SFM得到密集点云CMVS。
可以查阅相关论文,关于“面片”的部分。(我没有往下接着琢磨……)
3. 使用我的方法实现的SFM,如果想要有较快的速度,建议使用OpenCV的GPU模块。
4. 大致的实现流程如下:
祝大家好运。