当前位置: 首页 > article >正文

基于相机内参推导的透视投影矩阵

基于相机内参推导透视投影矩阵(splatam):

M c a m = [ 2 ⋅ f x w 0.0 ( w − 2 ⋅ c x ) w 0.0 0.0 2 ⋅ f y h ( h − 2 ⋅ c y ) h 0.0 0 0 f a r + n e a r n e a r − f a r 2 f a r ⋅ n e a r n e a r − f a r 0.0 0.0 − 1.0 0.0 ] M_{cam}= \begin{bmatrix} \frac{2 \cdot fx}{w} & 0.0 & \frac{(w - 2 \cdot cx)}{w} & 0.0 \\ 0.0 & \frac{2 \cdot fy}{h} & \frac{(h - 2 \cdot cy)}{h} & 0.0 \\ 0 & 0 & \frac{far + near}{near - far} & \frac{2far \cdot near}{near - far} \\ 0.0 & 0.0 & -1.0 & 0.0 \end{bmatrix} Mcam= w2fx0.000.00.0h2fy00.0w(w2cx)h(h2cy)nearfarfar+near1.00.00.0nearfar2farnear0.0

  • fx: 相机内参中的焦距在x方向上的分量。
  • fy: 相机内参中的焦距在y方向上的分量。
  • cx: 图像中心在x方向上的坐标。
  • cy: 图像中心在y方向上的坐标。
  • w: 图像宽度。
  • h: 图像高度。
  • near: 视锥体(frustum)的近裁剪平面距离。
  • far: 视锥体(frustum)的远裁剪平面距离。
    注:此处深度为负

参考透射投影矩阵的数学推导的推导得到透视投影矩阵另一种形式:
M p = [ 2 n r − l 0 r + l r − l 0 0 2 n t − b t + b t − b 0 0 0 f + n n − f 2 f n n − f 0 0 − 1 0 ] M_p = \begin{bmatrix} \frac{2n}{r - l} & 0 & \frac{r + l}{r - l} & 0 \\ 0 & \frac{2n}{t - b} & \frac{t + b}{t - b} & 0 \\ 0 & 0 & \frac{f + n}{n - f} & \frac{2fn}{n - f} \\ 0 & 0 & -1 & 0 \end{bmatrix} Mp= rl2n0000tb2n00rlr+ltbt+bnff+n100nf2fn0

  • n: 近裁剪平面距离。
  • f: 远裁剪平面距离。
  • r: 近裁剪平面的右边界。
  • l: 近裁剪平面的左边界。
  • t: 近裁剪平面的上边界。
  • b: 近裁剪平面的下边界。

可以先看这两个参考再往下看:
参考:
https://zhuanlan.zhihu.com/p/421962223
https://blog.csdn.net/qq_43758883/article/details/116503614

通过视场角来从 M p M_p Mp得到 M c a m M_{cam} Mcam:

在这里插入图片描述

上图,忽略y轴,上半部分是相机坐标系,下班部分是像素坐标系,可见相机坐标下的视场角和像素坐标下的视场角是一致的,
1、
在相机坐标系下:
t a n ( f o v x / 2 ) = r − l 2 n tan(fovx/2) = \frac{r-l}{2n} tan(fovx/2)=2nrl

在像素坐标系下:
t a n ( f o v x / 2 ) = f x w / 2 tan(fovx/2 )= \frac{fx}{w/2} tan(fovx/2)=w/2fx
将上式公式同时提取缩放因子:
t a n ( f o v x / 2 ) = α f α w ′ / 2 = f w ′ / 2 = r − l 2 n tan(fovx/2) = \frac{ \alpha f}{\alpha w'/2} = \frac{ f}{ w'/2} = \frac{r-l}{2n} tan(fovx/2)=αw/2αf=w/2f=2nrl

2、
α ( r − l ) = w α ( r + l ) = ( w − 2 c x ) \begin{align} \alpha (r-l) &= w \\ \alpha (r+l) &= (w - 2cx) \end{align} α(rl)α(r+l)=w=(w2cx)
所以,
r + l r − l = ( w − 2 c x ) w \frac {r+l}{r-l} = \frac {(w - 2cx)}{w} rlr+l=w(w2cx)

同理,透视投影矩阵y轴也是如此推导。

splatam非标准透视投影

splatam使用的非标准透视投影,与一般不同,splatam是把深度缩放到 [0,1]:
此处深度全取正数,因此第三、四列需要加个负号。
M s p l a t a m = [ 2 ⋅ f x w 0.0 − ( w − 2 ⋅ c x ) w 0.0 0.0 2 ⋅ f y h − ( h − 2 ⋅ c y ) h 0.0 0.0 0.0 f a r f a r − n e a r − ( f a r ⋅ n e a r ) f a r − n e a r 0.0 0.0 1.0 0.0 ] M_{splatam}= \begin{bmatrix} \frac{2 \cdot fx}{w} & 0.0 & \frac{-(w - 2 \cdot cx)}{w} & 0.0 \\ 0.0 & \frac{2 \cdot fy}{h} & \frac{-(h - 2 \cdot cy)}{h} & 0.0 \\ 0.0 & 0.0 & \frac{far}{far - near} & \frac{-(far \cdot near)}{far - near} \\ 0.0 & 0.0 & 1.0 & 0.0 \end{bmatrix} Msplatam= w2fx0.00.00.00.0h2fy0.00.0w(w2cx)h(h2cy)farnearfar1.00.00.0farnear(farnear)0.0
可以看到矩阵的第三行与之前的不同,它的作用是把深度最后归一化到 [0,1]。
设相机坐标下的点位置为 [ x c a m , y c a m , z c a m , 1 ] [x_{cam} , y_{cam} ,z_{cam},1] [xcam,ycam,zcam,1],对应裁剪空间坐标为 [ x c , y c , z c , w c ] [x_{c} , y_{c} ,z_{c},w_c] [xc,yc,zc,wc],对应NDC坐标 [ x n , y n , z n , 1 ] [x_{n} , y_{n} ,z_{n},1] [xn,yn,zn,1]
故:
[ x c y c z c w c ] = M s p l a t a m [ x c a m y c a m z c a m 1 ] \begin{bmatrix}x_{c} \\ y_{c} \\ z_{c} \\w_c \end{bmatrix} =M_{splatam} \begin{bmatrix}x_{cam} \\ y_{cam} \\ z_{cam} \\1 \end{bmatrix} xcyczcwc =Msplatam xcamycamzcam1
考虑深度,即z轴的变换有:
z c = f a r f a r − n e a r z c a m − ( f a r ⋅ n e a r ) f a r − n e a r w c = z c a m \begin{align} z_c &= \frac{far}{far - near} z_{cam} - \frac{(far \cdot near)}{far - near} \\ w_c &= z_{cam} \end{align} zcwc=farnearfarzcamfarnear(farnear)=zcam

归一化处理,得到NDC坐标
z n = z c w c = f a r f a r − n e a r z c a m − ( f a r ⋅ n e a r ) f a r − n e a r z c a m = f a r − ( f a r ⋅ n e a r ) z c a m f a r − n e a r \begin{align} z_n &= \frac {z_c}{w_c} = \frac{\frac{far}{far - near} z_{cam} - \frac{(far \cdot near)}{far - near}}{z_{cam}} \\ &= \frac{far - \frac{(far \cdot near)}{z_{cam}}}{far - near} \end{align} zn=wczc=zcamfarnearfarzcamfarnear(farnear)=farnearfarzcam(farnear)
故,当 z c a m = n e a r z_{cam} = near zcam=near时, z n = 0 z_n = 0 zn=0, 当 z c a m = f a r z_{cam} = far zcam=far时, z n = 1 z_n = 1 zn=1,所以深度最后是限制在 [0,1]。为什么要怎样设计呢,因为使用3DGS渲染时,只考虑深度大于0的。


http://www.kler.cn/a/516423.html

相关文章:

  • Docker 在Linux 系统中的使用说明
  • Linux探秘坊-------5.git
  • 寒假刷题Day12
  • RabbitMQ 在实际应用时要注意的问题
  • 蚁群算法 (Ant Colony Optimization) 算法详解及案例分析
  • C语言操作符(上)
  • 如何制作一个我的世界的光影包?(但Java版
  • docker: Device or resource busy
  • 基于java线程池和EasyExcel实现数据异步导入
  • 【Kong Gateway】全面解析Kong Gateway:服务、路由、upstream、插件的核心概念介绍
  • 【自然语言处理(NLP)】介绍、发展史
  • springboot 配置redis
  • 3b1b线性代数基础
  • 蓝桥杯lesson3---string的使用
  • RabbitMQ 匿名队列详解
  • Elasticsearch的经典面试题及详细解答
  • CrypTen项目实践
  • 人工智能学习(一)之python入门
  • STM32的ADC工作模式
  • Linux 主流桌面环境及其默认应用大横评
  • 面向对象和面向过程的区别
  • 从ChatGPT热潮看智算崛起
  • Unity3D 动态骨骼性能优化详解
  • 对grid布局有哪些了解【css】
  • el-dialog内容大于高度时可滑动
  • python自动生成pg数据库表对应的es索引