基于相机内参推导的透视投影矩阵
基于相机内参推导透视投影矩阵(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= w2⋅fx0.000.00.0h2⋅fy00.0w(w−2⋅cx)h(h−2⋅cy)near−farfar+near−1.00.00.0near−far2far⋅near0.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=
r−l2n0000t−b2n00r−lr+lt−bt+bn−ff+n−100n−f2fn0
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)=2nr−l
在像素坐标系下:
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=2nr−l
2、
α
(
r
−
l
)
=
w
α
(
r
+
l
)
=
(
w
−
2
c
x
)
\begin{align} \alpha (r-l) &= w \\ \alpha (r+l) &= (w - 2cx) \end{align}
α(r−l)α(r+l)=w=(w−2cx)
所以,
r
+
l
r
−
l
=
(
w
−
2
c
x
)
w
\frac {r+l}{r-l} = \frac {(w - 2cx)}{w}
r−lr+l=w(w−2cx)
同理,透视投影矩阵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=
w2⋅fx0.00.00.00.0h2⋅fy0.00.0w−(w−2⋅cx)h−(h−2⋅cy)far−nearfar1.00.00.0far−near−(far⋅near)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=far−nearfarzcam−far−near(far⋅near)=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=zcamfar−nearfarzcam−far−near(far⋅near)=far−nearfar−zcam(far⋅near)
故,当
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的。