根据针孔相机模型,一个在相机坐标系下的 三维点
(
X
,
Y
,
Z
)
(X,Y,Z)
(X,Y,Z)
投影到 uv 坐标的过程如下所示
{
u
=
f
x
X
Z
+
c
x
v
=
f
y
Y
Z
+
c
y
\left\{ \begin{aligned} u & = & f_x \frac{X}{Z}+c_x\\ v & = & f_y \frac{Y}{Z}+c_y \\ \end{aligned} \right.
⎩
⎨
⎧uv==fxZX+cxfyZY+cy
其中,
f
x
,
f
y
,
c
x
,
c
y
f_x,f_y,c_x,c_y
fx,fy,cx,cy的单位是像素
反投影
{
X
=
Z
u
−
c
x
f
x
Y
=
Z
v
−
c
y
f
y
\left\{ \begin{aligned} X & = & Z\frac{u-c_x}{f_x}\\ Y & = & Z\frac{v-c_y}{f_y}\\ \end{aligned} \right.
⎩
⎨
⎧XY==Zfxu−cxZfyv−cy
常见地,
f
x
=
f
y
=
f
f_x=f_y=f
fx=fy=f
c
x
=
W
2
c_x = \frac{W}{2}
cx=2W
c
y
=
H
2
c_y = \frac{H}{2}
cy=2H
则上式简化为
{
X
=
Z
u
−
W
/
2
f
Y
=
Z
v
−
H
/
2
f
\left\{ \begin{aligned} X & = & Z\frac{u-W/2}{f}\\ Y & = & Z\frac{v-H/2}{f}\\ \end{aligned} \right.
⎩
⎨
⎧XY==Zfu−W/2Zfv−H/2
注意:在实际编程中可能增加
Z
=
d
e
p
t
h
=
d
e
p
t
h
/
d
e
p
t
h
_
s
c
a
l
e
Z = depth = depth/depth\_scale
Z=depth=depth/depth_scale
d
e
p
t
h
=
1
depth=1
depth=1
还可能出现坐标轴不一样的情况。
比如在 NeRF 的代码中
dirs = np.stack([(i-W*.5)/focal, -(j-H*.5)/focal, -np.ones_like(i)], -1)
This is just a process of converting pixel coordinates to camera coordinates.
And notice that it needs to convert the camera coordinates to opengl coordinates
( x right y up z back),so y should add a “-” and also z = -1 rather than 1