缘起
今天实验室老赵学长问我对6DoF交互的全景图片/视频有没有兴趣,正处于放养阶段闲着无聊就接着老赵的介绍了解了起来。
其实老赵之前用Unity已经做了一个6DoF交互图片的Demo,但是由于时间上的原因没继续做下去,看让我接着完善6DoF交互视频的模块,以及再对原始的360度的深度图像做一些优化以便能更好的建模。
首先,6DoF指的是6 Degree of Freedom,分别是三个正交的旋转自由度与三个正交的平移自由度。
3DoF(三个正交的旋转自由度)交互的图像与视频目前十分普及,将拍摄的360度图像/视频放在材质球上,将摄像机(视点)置于球心,保持视点位置不变进行旋转即可获得伪3D全景的体验。
Fig.1 - 在材质球中做旋转变换
Fig.2 - 在材质球中做平移变换
显而易见,这种方法只要一平移就直接就原形毕露了,其并没有利用利用到图像的RGBD信息进行三维重构,Pseudoscience 介绍了利用深度数据进行重构的方法,利用深度数据生成点云,再将RGB信息渲染在各个点上,并将点云联结成片。
Fig.3 - 利用深度信息进行三维重构
添加了三个平移自由度的6DoF,由于360全景图像/视频中存在的视角盲区,图像信息的缺失使得平移后的视点观察到的图像是肯定会有问题的,但是轻微平移变换带来的图像缺失是可以接受的。
BTW, 今年的SIGGRAPH中Stanford的学生用共焦扫描解决了对遮挡物体的3D重建,也许可以完美处理这个问题。
Fig.4 - 共焦扫描对遮挡物进行三维重构
本来是想完成这个播放器,同时用一些机器学习的方法来补全这些图像缺失的,最后由于对Unity, Shader以及GPGPU不太熟悉,所以只完成了一个乞丐版(6fps)的且无补全机制的播放器…
其实所做的工作很少,希望以后对这些方面有更多经验后可以再拾起来继续完善它吧!
调优总结
CPU层面上
- Update()中不使用寻找物体的函数,如Find / FindObjectOfType / FindGameObjectWithTag 等。
- 将类字段的初始化与初始化工作放在Awake()或Start()中执行。
- 将函数中可以提取的运算放在shader中执行。
内存层面
- 主动回收垃圾,定时调用System.GC.Collect()。
- 减少不必要的局部变量使用,尽量重复利用变量,提高内存利用率。
数学层面
- 乘法运算代替除法运算。
- 运算公式最简化,包括三角函数化简,因式分解,矩阵变换等。
- 将运算开销较大,且需要多次使用到的运算式结果保存,空间换时间。
其他层面
- 如果可以,将需要在脚本中实例化的GameObject先在Unity中保存为Prefab,并将所有可以直接定义的静态参数设置好,再通过脚本Instantiate这个Prefab,进一步为该Object添加逻辑组件。
- 将静态GameObject设置为static。
…
经过尝试这些调优方法后,成功将1帧的画面提升到了6帧… 这次的经历就当是学习Unity以及代码优化方法了…
问题
- 在使用OpenCVSharp的VideoCapture对视频(.avi)进行读取时,无法读取视频文件。
Xvid编码的视频 需要 Xvid codec 解码器才能使用VideoCapture类打开,参考自here。
- 在使用Visual Studio进行Unity中的compute shader(.compute文件)编写时,没有支持的Highlighting\Linting。
查阅Manual过后,compute shader使用的是HLSL,安装对应的HLSL Tools for Visual Studio插件即可,插件在这里。
参考
- Fig.1,2,3 - Pseudoscience
- Fig.4 - SIGGRAPH
原文戳这里,转载请声明出处。