工作需求经常需要跟坐标系转换打交道,在学习过程中也接触到很多相机姿态相关知识,另外因为自己是摄影爱好者,对相机相关参数也比较有学习的兴趣,因此开坑在这里整理一些学习到的相机计算相关知识。
Fov、Focal Length和Sensor
首先是一个在对齐Relighting项目(里面主要用到了neural-renderer)和Blender的相机参数时发现的问题,在使用我自己的编写的从Blender导出calib数据,和从calib数据导入Blender代码时,发现同一个相机竟然在不同的Blender工程中视场不一样大(震惊),检查之后终于找到了问题点所在,再Blender的相机面板的Camera下面,可以选择拟合传感器的方式,Blender默认是Auto,而我之前的工程文件是Horizontal。



跑题了,说回Blender中的Sensor面板,关于Fov(视场),焦距,Sensor大小,有以下约束关系:
数值计算公式: $fov(度)= 2 * arctan(传感器尺寸/2/焦距)$
- 视场取决于传感器大小和焦距。
- 相同焦距下,传感器越大,视场越宽。
- 相同传感器下,焦距越长,视场越窄;焦距越短,视场越宽。
如下图,可以把相机简化为一个小孔模型,镜头的光学中心点到成像平面的距离就是焦距。当更换画幅时,传感器大小变化,焦距不变,因此fov变化;当更换镜头时,传感器大小不变,焦距变化,fov变小,因此在相同的对焦距离下,视场更小。而之所以焦距变化,是镜头带来的固有光学属性,这样看来应该是对于机身来说,像平面不同,不同镜头改变了光学中心的位置从而改变焦距,因此也就可以解释为什么长焦镜头都是瘦高个。
在影视飓风的视频里看到16mm镜头在全画幅下fov为108度,但我无论怎么计算都计算不到这个数字,后面查资料才发现在相机中如果只使用一个fov数值那一般是感光元件对角线长度除以焦距,而不是长或者宽。全画幅的对角线长度约为43MM。
想到一个之前参加社团笔试的题目,用广角和长焦对着同一个主体拍摄:1、在同一距离,将广角拍摄得到的画面进行裁切后,保证主体大小相同,得到画面与长焦是否完全相同;2、改变拍摄距离距离,保证两种镜头主体大小相同,拍到的画面是否有区别。答案是第一问没有区别,第二问有区别。我对该问题的理解是,可以直接去思考相机与主体和背景的相对位置关系,同一距离下,相对位置完全相同,只有fov不同,因此只需要裁切就可以完全一样,但是不同距离下,当主体大小相同时,其实拍摄点与背景的相对位置关系已经发生了变化,因此画面已经完全不同。
又跑题了,说回Blender中的Sensor面板,当Sensor fit为Auto时,Blender会用下面的数值去拟合画面中较长的一个边,比如画面是横幅的就会拟合宽,竖幅的画面则会将这个数值对应到高。而下面的Horizontal和Vertical则是制定了以某一个固定的数值去拟合画面,Horizontal就是以指定的Width去拟合画面的宽,而高度是会根据我们设置的画面分辨率比例进行动态的计算调整的,不参与计算,也不显示动态变化(这里我觉得应该动态变化比较合理),Vertical则相反。
至于Blender中的fov,我在观察实验后发现,在修改Sensor fit时,Blender是保持Focal Length不变,根据上面的计算规则去计算Fov的,但并不是使用的对角线fov,而只是单纯某个边的fov。