(本文作为课程作业记录)
本文描述如何通过只给出从图像确定的最小几何信息的单透视图来计算3D仿射量。其中有代表性的最小信息有基准平面的消失线和不平行于此平面的方向消失点。结果表明,即使没有相机校准的知识(例如焦距),也没有相机和环境的明确关系(例如姿势),依然可以从图像中确定仿射场景结构。
具体而言,本文展示如何(1)在带有一个公共的缩放系数下,计算基准面和与之平行的平面的距离;(2)计算基准面和任何与之平行的平面的长度与面积比;(3)确定相机位置。从这些成果中可以引申出一个简单的几何学。
在此基础上,本文用python复现了论文《Single View Metrology》1中的一些示例结果。
关键词:3D重建;视频测量;摄影测量法
在本文中,相机模型是一个中心投影。我们假设在场景中,基准面的消失线可以在图像上测量得出,另一个方向(不平行于此平面)的消失点也是如此。这些信息总体上可以容易地从有结构的场景的图片中获得。例如径向畸变(通常在安保摄像头上使用广角镜头会略微出现)等等会破坏中心投影的影响普遍可以被修复,因此对我们的方法无害。
虽然示意图会展示出相机中心处于一个有限的位置,我们推导的结果仍然对相机中心处于无穷远,或者说图像通过平行投影得出的情况有效。
关于平面的消失线和消失点的基础理论在图1中说明。基准面的消失线 l \mathbf{l} l是基准面上的直线的无穷远点在图像上的投影。消失点 v \mathbf{v}\mathbf{} v是基准方向上无穷远点在图像上的点。要注意到,虽然为了清晰直白,我们通常倾向于将消失点作为"竖直"消失点,这样图像上的消失点就是相机中心在基准面的竖直落脚点,但是基准方向不必是竖直的。同理,基准面通常但不是必须是地平面,这样消失线就是为人熟知的"地平线"。
图 1 基础理论:一个平面与基准面平行,穿过相机中心,平面的消失线 l \mathbf{l}\mathbf{} l是此平面与图像平面的相交线。消失点 v \mathbf{v}\mathbf{} v是经过相机中心、与基准方向平行的线和图像平面的相交点。
可以看到,消失线隔开了场景空间的所有点。任何投影在消失线上的点与基准面的距离和相机中心一样高。在其之上则比相机中心距离基准面更远,在其之下则比相机中心距离基准面更近。
我们希望通过图像上两个点 x \mathbf{x} x和 x ′ \mathbf{x'} x′测量两个平行平面在基准方向上的距离。图
2通过对应点 x \mathbf{x} x和 x ′ \mathbf{x'} x′展示了这个理论。我们用大写字母 X \mathbf{X} X表示在空间中的点,小写 x \mathbf{x} x表示图像上的点。
定义1.
如果穿过两点 X \mathbf{X}\mathbf{} X和 X ′ \mathbf{X'} X′的线与基准方向平行,那么分开平面上(都平行于基准面)的两点 X \mathbf{X}\mathbf{} X和 X ′ \mathbf{X'} X′相对应。
图 2 两个平面间的距离与相机中心到两者其中一个平面的距离有关:(a)实际(b)图像。在平面 π \mathbf{\pi} π上的点 x \mathbf{x} x与平面 π ′ \mathbf{\pi'} π′上的点 x ′ \mathbf{x'} x′对应,一条线上四个对齐的点 x , x ′ , v \mathbf{x,}\mathbf{x'}\mathbf{,v} x,x′,v与消失线交点 c \mathbf{c} c定义了交叉比。交叉比的值确定了平面间实际距离的比值。
因此对应点和消失点共线。例如如果方向是竖直的话,人的头顶和落脚点对应。如果这两点实际距离已知,那么就称为基准距离。
理论1.
给出基准面的消失线和基准方向的消失点,可以计算出带有公共缩放系数的消失线到消失点的距离。这个缩放系数可以通过已知基准长度确定。
证明:在图 2(b)中已标记的四点 x , x ′ , c , v \mathbf{x,}\mathbf{x'}\mathbf{,c,v} x,x′,c,v定义了交叉比。消失点是图像上的场景中的一个无穷远点。鉴于 c \mathbf{c} c点在消失线上, c \mathbf{c} c点是一个到平面 π \mathbf{\pi} π距离 Z c Z_{c} Zc的点,其中 Z c Z_{c} Zc是相机中心到平面 π \mathbf{\pi} π的距离。与 Z c Z_{c} Zc相关联的交叉比的值确定了穿过 X \mathbf{X}\mathbf{} X和 X ′ \mathbf{X'} X′的平面之间的距离 Z Z Z的仿射长度比(或者说 π ′ \mathbf{\pi'} π′取决于交叉比的次序)。要注意到,距离 Z Z Z也可以用线间单应变换来计算,来回避交叉比次序的歧义。
从图 2(b)我们可以得出
d ( x , c ) d ( x ′ , v ) d ( x ′ , c ) d ( x , v ) = d ( X , C ) d ( X ′ , V ) d ( X ′ , C ) d ( X , V ) # ( 1 ) \frac{d\left( \mathbf{x,c} \right)d\left( \mathbf{x'}\mathbf{,v} \right)}{d\left( \mathbf{x'}\mathbf{,c} \right)d\left( \mathbf{x,v} \right)} = \frac{d\left( \mathbf{X,C} \right)d\left( \mathbf{X'}\mathbf{,V} \right)}{d\left( \mathbf{X'}\mathbf{,C} \right)d\left( \mathbf{X,V} \right)}\#(1) d(x′,c)d(x,v)d(x,c)d(x′,v)=d(X′,C)d(X,V)d(X,C)d(X′,V)#(1)
其中 d ( x 1 , x 2 ) d\left( \mathbf{x}_{\mathbf{1}}\mathbf{,}\mathbf{x}_{\mathbf{2}} \right) d(x1,x2)是俩一般点 x 1 , x 2 \mathbf{x}_{\mathbf{1}}\mathbf{,}\mathbf{x}_{\mathbf{2}} x1,x2间的距离。鉴于点 v \mathbf{v} v
反向投影到无穷远点有 d ( X ′ , V ) / d ( X , V ) = 1 d(\mathbf{X'}\mathbf{,V})/d(\mathbf{X,V}) = 1 d(X′,V)/d(X,V)=1,所以(1)中右手边可以归约为 Z c / ( Z c − Z ) Z_{c}/(Z_{c} - Z) Zc/(Zc−Z)。简单的代数操作即可得出
Z Z c = 1 − d ( x , c ) d ( x ′ , v ) d ( x ′ , c ) d ( x , v ) # ( 2 ) \frac{Z}{Z_{c}} = 1 - \frac{d\left( \mathbf{x,c} \right)d\left( \mathbf{x'}\mathbf{,v} \right)}{d\left( \mathbf{x'}\mathbf{,c} \right)d\left( \mathbf{x,v} \right)}\#(2) ZcZ=1−d(x′,c)d(x,v)d(x,c)d(x′,v)#(2)
一旦相机距离 Z c Z_{c} Zc确定,距离 Z Z Z也一并可获得。
然而实践上更常见的是通过另外一种测量方法在图像上获得距离 Z Z Z,也就是基准长度。事实上,给出一个已知基准距离 Z r Z_{r} Zr,通过(2)我们可以计算出 Z c Z_{c} Zc从而将公式应用到新的一对端点并计算出 Z Z Z。
下面我们推广理论1。
定义2.
如果通过对应点的约束链可以从一个平面集合内一个平面到另一个任意平面,则这个集合内的平面是被链接的。
图 3
两个平面间距离与另外两个平面间距离有关系:(a)实际(b)图像。平面 π \mathbf{\pi} π上的点 x \mathbf{x} x对应平面 π ′ \mathbf{\pi'} π′上的点 x ′ \mathbf{x'} x′。点 s 1 \mathbf{s}_{\mathbf{1}} s1对应点 s 2 \mathbf{s}_{\mathbf{2}} s2。点 r 1 \mathbf{r}_{\mathbf{1}} r1对应点 r 2 \mathbf{r}_{\mathbf{2}} r2。 R 1 \mathbf{R}_{\mathbf{1}} R1和 R 2 \mathbf{R}_{\mathbf{2}} R2的实际距离 Z r Z_{r} Zr已知,且作为基准值计算 Z Z Z
理论2.
给出一个被链接的平面集合,任何一对平面间距离足以确定另一对任意平面间的绝对距离。链接的来源是对应点的约束链。
证明: 图3展示了四个平行的平面。注意它们共享了同一条消失线,同时也是多条轴的消失线。它们间距离 Z r Z_{r} Zr可以作为基准来计算另外两个的距离 Z Z Z。
从四个对齐点 v , c r , r 2 , r 1 \mathbf{v}\mathbf{,}\mathbf{c}_{\mathbf{r}}\mathbf{,}\mathbf{r}_{\mathbf{2}}\mathbf{,}\mathbf{r}_{\mathbf{1}} v,cr,r2,r1定义的交叉比和已知点 R 1 , R 2 \mathbf{R}_{\mathbf{1}}\mathbf{,}\mathbf{R}_{\mathbf{2}} R1,R2距离 Z r Z_{r} Zr可以计算出从平面 π r \mathbf{\pi}_{\mathbf{r}} πr到相机间的距离。
四个对齐点 v , c s , s 2 , s 1 \mathbf{v,}\mathbf{c}_{\mathbf{s}}\mathbf{,}\mathbf{s}_{\mathbf{2}}\mathbf{,}\mathbf{s}_{\mathbf{1}} v,cs,s2,s1定义的交叉比和相机距离确定了平面 π r \mathbf{\pi}_{\mathbf{r}} πr到 π \mathbf{\pi} π间距离。相机到平面 π \mathbf{\pi} π的距离 Z c Z_{c} Zc也因此确定。
现在可以在(2)中用 Z c Z_{c} Zc计算平面 π \mathbf{\pi} π到 π ′ \mathbf{\pi'} π′间距离 Z Z Z。
如果基准平面 π \pi π经过仿射校准(即已知它消失线),从图像度量值上我们可以计算:
另外,消失线被平行于基准面的一束平面共享,于是从束中其他任意平面都可以得出仿射度量值。然而,即使如面积比这样的仿射度量值可以在一个特定的平面得出,但是在不同平面上的区域面积不能直接比较。如果从一个平面到另一个平面平行投影一个区域,由于两个区域都在同一个平面,所以可以得出仿射度量值。平行投影不改变仿射属性。
两个平行平面实际上的映射关系诱导出在图像上两个平面内的点的投影映射关系。这个图像映射是平面同调关系。这个关系是带有五个自由度的投影变换。它具有一条线上的固定点,称为轴,和单独一个不在轴上的固定点,称为顶点。依据反映在图像上的三维空间透视,平面同调关系很自然就可以产生。
在这里,平面消失线和竖直消失点分别是轴和顶点。同调关系可以参数化为
H ~ = I + μ v l ⊤ v ⋅ l # ( 3 ) \widetilde{H} = I + \mu\frac{\mathbf{v}\mathbf{l}^{\top}}{\mathbf{v} \cdot \mathbf{l}}\#(3) H =I+μv⋅lvl⊤#(3)
其中 v \mathbf{v} v是消失点, l \mathbf{l} l是平面消失线, μ \mu μ是缩放系数。 v \mathbf{v} v和 l \mathbf{l} l确定了四个同调关系自由度。剩下的自由度 μ \mu μ是由任意一对对应点唯一确定。一旦矩阵 H ~ \widetilde{H} H 计算出来,平面上的每个点都可以被转换成对应点,即 x ′ = H ~ x \mathbf{x'} = \widetilde{H}\mathbf{x} x′=H x。
因此我们可以比较两个分开平面上的度量值。尤其是可以计算:
事实上我们可以用同调关系从一个平面上转换所有点到基准平面上。然后从已知的基准面消失线得出仿射度量值。
在2.1节中我们依据相机到基准面的距离计算出平面间距离比。反其道行之,我们可以从一个特定已知平面的单独的基准距离 Z r Z_{r} Zr计算出相机距离 Z c Z_{c} Zc。再者,考虑图1,相机位置对于基准面似乎是竖直消失点对于基准面的反投影。这个反投影已经被从图像到基准面的单应投影完成了(反之亦然)。即使实际场景的坐标框架选择有点随意,框架一固定,单应关系以及相机位置就立刻被定义。
前面的章节描述基于交叉比计算度量值。在这一节我们延伸出一个独特的代数方法。这对构建几何有几个好处。第一是它回避了交叉比次序的潜在问题。第二是它可以让我们处理极小值和普遍的过度约束设置。第三我们在一个表示形式上整合了不同类型的度量值。第四可以进行不确定性分析。
首先我们在空间内定义一个仿射坐标系 X Y Z XYZ XYZ。让原点位于基准面内,并在平面上生成 X X X和 Y Y Y轴。 Z Z Z轴是基准方向。图像坐标系就是通常的 x y xy xy仿射图像框架。空间上的一个点 X \mathbf{X} X通过一个 3 × 4 3 \times 4 3×4的投影矩阵 P P P投影到图像点 x \mathbf{x} x:
x = P X = [ p 1 p 2 p 3 p 4 ] X \mathbf{x} = P\mathbf{X} = \begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{2}} & \mathbf{p}_{\mathbf{3}} & \mathbf{p}_{\mathbf{4}} \\ \end{bmatrix}\mathbf{X} x=PX=[p1p2p3p4]X
其中 x \mathbf{x} x和 X \mathbf{X} X是形如 x = ( x , y , w ) ⊤ , X = ( X , Y , Z , W ) ⊤ \mathbf{x} = (x,y,w)^{\top},\mathbf{X} = (X,Y,Z,W)^{\top} x=(x,y,w)⊤,X=(X,Y,Z,W)⊤的齐次向量。" = = ="意思是带一个缩放系数下相等。
如果我们用消失点来分别指示出 X , Y , Z X,Y,Z X,Y,Z方向 v X , v Y , v \mathbf{v}_{X},\mathbf{v}_{Y},\mathbf{v} vX,vY,v,显然可以检验 P P P的前三列是消失点: v X = p 1 , v Y = p 2 , v = p 3 \mathbf{v}_{X} = \mathbf{p}_{\mathbf{1}},\mathbf{v}_{Y} = \mathbf{p}_{\mathbf{2}},\mathbf{v =}\mathbf{p}_{\mathbf{3}} vX=p1,vY=p2,v=p3,最后一列则是实际空间坐标系原点 o = p 4 \mathbf{o}\mathbf{=}\mathbf{p}_{\mathbf{4}} o=p4。由于我们选择的坐标框架在基准面上的 X , Y X,Y X,Y轴 p 1 = v X , p 2 = v Y \mathbf{p}_{\mathbf{1}}\mathbf{=}\mathbf{v}_{X},\mathbf{p}_{\mathbf{2}}\mathbf{=}\mathbf{v}_{Y} p1=vX,p2=vY是在消失线上的两个单独的点,选择这些点会固定 X , Y X,Y X,Y轴,我们将消失线表示为 l \mathbf{l} l,为了强调 v X , v Y \mathbf{v}_{X},\mathbf{v}_{Y} vX,vY在消失线上,我们将它们表示为 l 1 ⊥ , l 2 ⊥ \mathbf{l}_{\mathbf{1}}^{\mathbf{\bot}}\mathbf{,}\mathbf{l}_{\mathbf{2}}^{\mathbf{\bot}} l1⊥,l2⊥,并且 l i ⊥ ⋅ l = 0 \mathbf{l}_{i}^{\mathbf{\bot}}\mathbf{\cdot l} = 0 li⊥⋅l=0。
投影矩阵的1,2,4列是基准面到图像的单应矩阵的三列。单应矩阵必须要秩为3,不然从基准面到图像的映射会退化。另外,最后一列(坐标原点)不能在消失线上,不然三点共线,列之间不再线性无关。于是我们将其设为 p 4 = l / ∥ l ∥ = l ‾ \mathbf{p}_{\mathbf{4}}\mathbf{= l/\| l\| =}\overline{\mathbf{l}} p4=l/∥l∥=l。
因此投影矩阵 P P P的参数化形式为
P = [ l 1 ⊥ l 2 ⊥ α v l ‾ ] # ( 4 ) \begin{matrix} P = \begin{bmatrix} \mathbf{l}_{\mathbf{1}}^{\mathbf{\bot}} & \mathbf{l}_{\mathbf{2}}^{\mathbf{\bot}} & \alpha\mathbf{v} & \overline{\mathbf{l}} \\ \end{bmatrix}\#(4) \\ \end{matrix} P=[l1⊥l2⊥αvl]#(4)
其中 α \alpha α是缩放系数。
要注意到竖直消失点 v \mathbf{v} v对矩阵P附加了两个约束、 l \mathbf{l} l有两个、 α \alpha α有一个,总共五个约束。(目前前两列不完全已知,唯一约束仅仅只是垂直于 l \mathbf{l} l)。然而一般而言 P P P矩阵有十一个自由度,可以认为包括从基准面诱导的从实际场景到图像的单应矩阵的八个、消失点的两个、仿射参数 α \alpha α的一个自由度。这里消失线确定了单应矩阵的八个自由度中的两个。
我们希望通过场景中 X \mathbf{X} X和 X ′ \mathbf{X}\mathbf{'} X′测量两个平面的距离。两个点可以选择为 X = ( X , Y , 0 ) ⊤ , X ′ = ( X , Y , Z ) ⊤ \mathbf{X} = (X,Y,0)^{\top},\mathbf{X'} = (X,Y,Z)^{\top} X=(X,Y,0)⊤,X′=(X,Y,Z)⊤,它们的映射是 x \mathbf{x} x和 x ′ \mathbf{x'} x′。如果 P P P是投影矩阵,那么图像坐标为
x = P ( X Y 0 1 ) , x ′ = P ( X Y Z 1 ) \mathbf{x} = P\begin{pmatrix} X \\ Y \\ 0 \\ 1 \\ \end{pmatrix},\mathbf{x'} = P\begin{pmatrix} X \\ Y \\ Z \\ 1 \\ \end{pmatrix} x=P⎝ ⎛XY01⎠ ⎞,x′=P⎝ ⎛XYZ1⎠ ⎞
上面的等式可以写成
x = ρ ( X p 1 + Y p 2 + p 4 ) # ( 5 ) x ′ = ρ ′ ( X p 1 + Y p 2 + Z p 3 + p 4 ) # ( 6 ) \mathbf{x} = \rho\left( X\mathbf{p}_{\mathbf{1}} + Y\mathbf{p}_{\mathbf{2}} + \mathbf{p}_{\mathbf{4}} \right)\mathbf{\#}(5) \\ \mathbf{x'} = \rho'\left( X\mathbf{p}_{\mathbf{1}} + Y\mathbf{p}_{\mathbf{2}} + Z\mathbf{p}_{\mathbf{3}} + \mathbf{p}_{\mathbf{4}} \right)\mathbf{\#}(6) x=ρ(Xp1+Yp2+p4)#(5)x′=ρ′(Xp1+Yp2+Zp3+p4)#(6)
其中 ρ \rho ρ和 ρ ′ \rho' ρ′是未知放缩系数。 p i \mathbf{p}_{i} pi是矩阵 P P P的第 i i i列。
由于 p 1 ⋅ l ‾ = p 2 ⋅ l ‾ = 0 \mathbf{p}_{\mathbf{1}}\mathbf{\cdot}\overline{\mathbf{l}}\mathbf{=}\mathbf{p}_{\mathbf{2}}\mathbf{\cdot}\overline{\mathbf{l}} = 0 p1⋅l=p2⋅l=0, p 4 ⋅ l ‾ = 1 \mathbf{p}_{\mathbf{4}}\mathbf{\cdot}\overline{\mathbf{l}} = 1 p4⋅l=1,用 l ‾ \overline{\mathbf{l}}\mathbf{} l点乘(5)得到 ρ = l ‾ ⋅ x \rho = \overline{\mathbf{l}}\mathbf{\cdot}\mathbf{x} ρ=l⋅x,于是(6)可以写成
x ′ = ρ ′ ( x ρ + α Z v ) # ( 7 ) \mathbf{x'} = \rho'\left( \frac{\mathbf{x}}{\rho} + \alpha Z\mathbf{v} \right)\mathbf{\#}(7) x′=ρ′(ρx+αZv)#(7)
用 x ′ \mathbf{x}\mathbf{'} x′向量乘(7)中每一项得到
x × x ′ = − α Z ρ ( v × x ′ ) # ( 8 ) \mathbf{x}\mathbf{\times}\mathbf{x'} = - \alpha Z\rho\left( \mathbf{v \times}\mathbf{x'} \right)\mathbf{\#}(8) x×x′=−αZρ(v×x′)#(8)
最后,(8)两边取绝对值得到
α Z = − ∥ x × x ′ ∥ ( l ‾ ⋅ x ) ∥ v × x ′ ∥ # ( 9 ) \alpha Z = - \frac{\left\| \mathbf{x}\mathbf{\times}\mathbf{x'} \right\|}{\left( \overline{\mathbf{l}}\mathbf{\cdot}\mathbf{x} \right)\left\| \mathbf{v \times}\mathbf{x'} \right\|}\mathbf{}\#\left( \mathbf{}\mathbf{}9\mathbf{} \right) αZ=−(l⋅x)∥v×x′∥∥x×x′∥#(9)
由于 α Z \alpha Z αZ是 α \alpha α的线性放缩,仿射结构已经得出了。如果 α \alpha α已知, Z Z Z的度量值也可以立刻计算出:
Z = − ∥ x × x ′ ∥ ( p 4 ⋅ x ) ∥ p 3 × x ′ ∥ # ( 10 ) Z = - \frac{\left\| \mathbf{x}\mathbf{\times}\mathbf{x'} \right\|}{\left( \mathbf{p}_{\mathbf{4}}\mathbf{\cdot}\mathbf{x} \right)\left\| \mathbf{p}_{\mathbf{3}}\mathbf{\times}\mathbf{x'} \right\|}\mathbf{}\#\left( \mathbf{}\mathbf{}10\mathbf{} \right) Z=−(p4⋅x)∥p3×x′∥∥x×x′∥#(10)
反过来,如果 Z Z Z已知(例如它是一个基准距离),(9)也提供计算 α \alpha α的一个方法,并因此移除了仿射歧义。
从多基准值进行度量校准
如果不只一个基准距离已知, α \alpha α的估计值可以由一个误差最小化算法衍生。这里展示当从基准面出发的距离都被测量的情况并最小化代数误差。
对于第 i i i个以点 r i , r i ′ \mathbf{r}_{i}\mathbf{,}\mathbf{r}_{i'} ri,ri′为端点基准距离 Z i Z_{i} Zi,我们定义 β i = ∥ r i × r i ′ ∥ , ρ i = l ‾ ⋅ r i , γ i = ∥ v × r i ′ ∥ \beta_{i} = \left\| \mathbf{r}_{i}\mathbf{\times}\mathbf{r}_{i'} \right\|,\rho_{i} = \overline{\mathbf{l}}\mathbf{\cdot}\mathbf{r}_{i}\mathbf{,}\gamma_{i} = \left\| \mathbf{v \times}\mathbf{r}_{\mathbf{i}'} \right\| βi=∥ri×ri′∥,ρi=l⋅ri,γi=∥v×ri′∥,于是从(9)我们得到
α Z ρ i γ i = − β i # ( 11 ) \alpha Z\rho_{i}\gamma_{i} = - \beta_{i}\#(11) αZρiγi=−βi#(11)
现在定义 n × 2 n \times 2 n×2矩阵 A A A(对(11)重新组织得)
A = ( Z 1 ρ 1 γ 1 β 1 ⋮ ⋮ Z i ρ i γ i β i ⋮ ⋮ Z n ρ n γ n β n ) A = \begin{pmatrix} Z_{1}\rho_{1}\gamma_{1} & \beta_{1} \\ \vdots & \vdots \\ Z_{i}\rho_{i}\gamma_{i} & \beta_{i} \\ \vdots & \vdots \\ Z_{n}\rho_{n}\gamma_{n} & \beta_{n} \\ \end{pmatrix} A=⎝ ⎛Z1ρ1γ1⋮Ziρiγi⋮Znρnγnβ1⋮βi⋮βn⎠ ⎞
其中 n n n是基准距离的数量。如果没有测量误差,或者 n = 1 n = 1 n=1则有 A s = 0 A\mathbf{s}\mathbf{= 0} As=0,其中 s = ( s 1 s 2 ) ⊤ \mathbf{s} = \left( s_{1}s_{2} \right)^{\top} s=(s1s2)⊤是一个齐次2维向量,且
α = s 1 s 2 # ( 12 ) \alpha = \frac{s_{1}}{s_{2}}\#(12) α=s2s1#(12)
通常情况下 n > 1 n>1 n>1,且基准距离都有不确定性,在此情况下,我们找寻令 ∥ A s ∥ \mathbf{\|}A\mathbf{s}\| ∥As∥取最小值的解。那就是对应 2 × 2 2 \times 2 2×2的矩阵 M = A ⊤ A M = A^{\top}A M=A⊤A的最小特征值的特征向量。此时 α \alpha α仍然可以通过(12)计算。
投影矩阵 P P P只定义在基准面上。在这一节我们根据平行平面 π ′ \mathbf{\pi'} π′确定投影矩阵 P ′ P' P′,以及如何计算到平面 π ′ \mathbf{\pi'} π′的距离。
图 4 度量平行于基准面 π π π的任意两个平面 π ′ , π ′ ′ π',π'' π′,π′′间的距离
假设实际坐标通过基准方向上的 Z r Z_{r} Zr从平面 π \mathbf{\pi} π变换到 π ′ \mathbf{\pi'} π′(图 4),我们可以参数化新投影矩阵 P ′ P' P′为
P ′ = [ p 1 p 2 p 3 Z r p 3 + p 4 ] # ( 13 ) P' = \begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{2}} & \mathbf{p}_{\mathbf{3}} & Z_{r}\mathbf{p}_{\mathbf{3}}\mathbf{+}\mathbf{p}_{\mathbf{4}} \\ \end{bmatrix}\#(13) P′=[p1p2p3Zrp3+p4]#(13)
π ′ , π ′ ′ \mathbf{\pi'}\mathbf{,\pi}\mathbf{''} π′,π′′间的距离 Z ′ Z' Z′可以计算
Z ′ = − ∥ x ′ × x ′ ′ ∥ ρ ′ ∥ p 3 × x ′ ′ ∥ # ( 14 ) Z' = - \frac{\Vert \mathbf{x'}\mathbf{\times}\mathbf{x''} \Vert}{\rho'\left\| \mathbf{p}_{\mathbf{3}}\mathbf{\times}\mathbf{x}^{\mathbf{''}} \right\|}\mathbf{}\#\left( \mathbf{}\mathbf{}14\mathbf{} \right) Z′=−ρ′∥p3×x′′∥∥x′×x′′∥#(14)
其中
ρ ′ = x ′ ⋅ p 4 1 + Z r p 3 ⋅ p 4 \rho' = \frac{\mathbf{x'}\mathbf{\cdot}\mathbf{p}_{\mathbf{4}}}{1 + Z_{r}\mathbf{p}_{\mathbf{3}}\mathbf{\cdot}\mathbf{p}_{\mathbf{4}}} ρ′=1+Zrp3⋅p4x′⋅p4
正如在2.2节所描述的,给出平面 π \mathbf{\pi} π到 π ′ \mathbf{\pi'} π′同调矩阵我们就可以让一个平面上的所有点转换到另一个平面,从而在另一个平面上得出仿射度量值。同调矩阵可以直接从投影矩阵中得出。平面到图像的单应矩阵就是忽略第三列的投影矩阵
H = [ p 1 p 2 p 4 ] , H ′ = [ p 1 p 2 Z r p 3 + p 4 ] H = \begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{2}} & \mathbf{p}_{\mathbf{4}} \\ \end{bmatrix},H' = \begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{2}} & Z_{r}\mathbf{p}_{\mathbf{3}}\mathbf{+}\mathbf{p}_{\mathbf{4}} \\ \end{bmatrix} H=[p1p2p4],H′=[p1p2Zrp3+p4]
于是 H ~ = H ′ H − 1 \widetilde{H} = H'H^{- 1} H =H′H−1是图像上在平面 π \mathbf{\pi} π的点到 π ′ \mathbf{\pi'} π′的映射,而且定义了同调矩阵。通过检验,由于 p 1 ⋅ p 4 = p 2 ⋅ p 4 = 0 \mathbf{p}_{\mathbf{1}}\mathbf{\cdot}\mathbf{p}_{\mathbf{4}}\mathbf{=}\mathbf{p}_{\mathbf{2}}\mathbf{\cdot}\mathbf{p}_{\mathbf{4}} = 0 p1⋅p4=p2⋅p4=0,所以 ( I + Z r p 3 p 4 ⊤ ) H = H ′ \left( I + Z_{r}\mathbf{p}_{\mathbf{3}}\mathbf{p}_{\mathbf{4}}^{\mathbf{\top}} \right)H = H' (I+Zrp3p4⊤)H=H′,于是同调矩阵:
H ~ = I + Z r p 3 p 4 ⊤ # ( 15 ) \widetilde{H} = I{+ Z}_{r}\mathbf{p}_{\mathbf{3}}\mathbf{p}_{\mathbf{4}}^{\mathbf{\top}}\mathbf{}\#\left( \mathbf{}\mathbf{}15\mathbf{} \right) H =I+Zrp3p4⊤#(15)
另一方面,从(4)同调矩阵可写为
H ~ = I + ψ v l ‾ ⊤ # ( 16 ) \widetilde{H} = I + \psi\mathbf{v}{\overline{\mathbf{l}}}^{\mathbf{\top}}\mathbf{}\#\left( \mathbf{}\mathbf{}16\mathbf{} \right) H =I+ψvl⊤#(16)
其中 v \mathbf{v} v是竖直消失点, l ‾ \overline{\mathbf{l}} l是平面消失线的正则化, ψ = α Z r \psi = \alpha Z_{r} ψ=αZr(参考(3))。
如果 Z r Z_{r} Zr且矩阵 P P P后两列已知,同调矩阵就可以用(15)计算,如果只有 v \mathbf{v} v, l ‾ \overline{\mathbf{l}} l已知,对应点 r , r ′ \mathbf{r}\mathbf{,r'} r,r′可见,那么同调参数 ψ \psi ψ可以用(9)计算(因为 α Z r = ψ \alpha Z_{r} = \psi αZr=ψ)而不需要知道 α , Z r \alpha,Z_{r} α,Zr的值。
假设相机中心是 C = ( X c , Y c , Z c . W c ) ⊤ \mathbf{C} = \left( X_{c},Y_{c},Z_{c}.W_{c} \right)^{\top} C=(Xc,Yc,Zc.Wc)⊤,于是由于 P C = 0 P\mathbf{C = 0} PC=0,有
P C = p 1 X c + p 2 Y c + p 3 Z c + p 4 W c = 0 # ( 17 ) P\mathbf{C}\mathbf{=}\mathbf{p}_{\mathbf{1}}X_{c}\mathbf{+}\mathbf{p}_{\mathbf{2}}Y_{c}\mathbf{+}\mathbf{p}_{\mathbf{3}}Z_{c}\mathbf{+}\mathbf{p}_{\mathbf{4}}W_{c}\mathbf{= 0}\#\left( \mathbf{}\mathbf{}17\mathbf{} \right) PC=p1Xc+p2Yc+p3Zc+p4Wc=0#(17)
给出问题的解答(通过克莱姆法则)
X c = − det [ p 2 p 3 p 4 ] Y c = det [ p 1 p 3 p 4 ] Z c = − det [ p 1 p 2 p 4 ] W c = det [ p 1 p 2 p 3 ] # ( 18 ) \begin{matrix} X_{c} &=& - \det\begin{bmatrix} \mathbf{p}_{\mathbf{2}} & \mathbf{p}_{\mathbf{3}} & \mathbf{p}_{\mathbf{4}} \\ \end{bmatrix} \\ Y_{c} &=& \det\begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{3}} & \mathbf{p}_{\mathbf{4}} \\ \end{bmatrix} \\ Z_{c} &=& - \det\begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{2}} & \mathbf{p}_{\mathbf{4}} \\ \end{bmatrix} \\ W_{c} &=& \det\begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{2}} & \mathbf{p}_{\mathbf{3}} \\ \end{bmatrix} \\ \end{matrix}\#(18) XcYcZcWc====−det[p2p3p4]det[p1p3p4]−det[p1p2p4]det[p1p2p3]#(18)
于是相机中心也被定义了。如果 α \alpha α未知,我们可以
X c = − det [ p 2 v p 4 ] Y c = det [ p 1 v p 4 ] α Z c = − det [ p 1 p 2 p 4 ] W c = det [ p 1 p 2 v ] # ( 19 ) \begin{matrix} X_{c} &=& - \det\begin{bmatrix} \mathbf{p}_{\mathbf{2}} & \mathbf{v} & \mathbf{p}_{\mathbf{4}} \\ \end{bmatrix} \\ Y_{c} &=& \det\begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{v} & \mathbf{p}_{\mathbf{4}} \\ \end{bmatrix} \\ \alpha Z_{c} &=& - \det\begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{2}} & \mathbf{p}_{\mathbf{4}} \\ \end{bmatrix} \\ W_{c} &=& \det\begin{bmatrix} \mathbf{p}_{\mathbf{1}} & \mathbf{p}_{\mathbf{2}} & \mathbf{v} \\ \end{bmatrix} \\ \end{matrix}\#(19) XcYcαZcWc====−det[p2vp4]det[p1vp4]−det[p1p2p4]det[p1p2v]#(19)
来获得带有一个仿射放缩系数 α \alpha α的距离 Z c Z_{c} Zc。如果是以前,我们需要利用 α \alpha α的知识来更新 Z c Z_{c} Zc,或者需要相机高度的知识来计算 α \alpha α,从而更新仿射框架。
可以注意到,仿射观察条件(相机中心在无穷远点)在(18)(19)上没有问题。因为其实我们可以让 l ‾ = [ 0 0 ∗ ] ⊤ , v = [ ∗ ∗ 0 ] ⊤ \overline{\mathbf{l}} = \begin{bmatrix}0 & 0 & * \\ \end{bmatrix}^{\top},\mathbf{v} = \begin{bmatrix}* & * & 0 \\\end{bmatrix}^{\top} l=[00∗]⊤,v=[∗∗0]⊤。由于
W c = 0 W_{c} = 0 Wc=0,我们此时获得在平面无穷远点的相机中心。在 π ∞ \mathbf{\pi}_{\mathbf{\infty}} π∞的点代表平行投影的观察方向。
如果观察点是有限的(即不是仿射观察条件), α Z c \alpha Z_{c} αZc的公式可以更进一步,通过两边标量乘 l ‾ \overline{\mathbf{l}} l可以得到
α Z c = − 1 l ‾ ⋅ v # ( 20 ) \alpha Z_{c} = - \frac{1}{\overline{\mathbf{l}} \cdot \mathbf{v}}\#(20) αZc=−l⋅v1#(20)
在这一节中我们复现了论文《Single View Metrology》中的一些示例结果。
图 5展示了怎么在额外给出一个垂直基准距离下计算人的升高。图 6展示了如何测量水平线到地面的高度。图 6的流程如下:
所有与地面平行的线都交于地平线上的点,则
图 5
从单视图中测量人的身高:(a)原图(b)示例( c c c)复现结果。在示例中消失线以白色线表示,基准距离是右边的窗框高度。在复现结果中用于确定消失点 v x , v y , v \mathbf{v}_{x},\mathbf{v}_{y},\mathbf{v} vx,vy,v的平行线以蓝色线表示。消失线以红色线表示。基准距离是柱高度201cm以紫色线表示。身高以黄色线表示,结果为178.08cm。
图 6
利用平行线计算高度:(a)示例(b)复现结果。在上方的蓝色线是 l x ′ \mathbf{l}_{x'} lx′,在下方的是 l x \mathbf{l}_{x} lx。竖直的蓝色线经过竖直消失点。 x , x ′ \mathbf{x},\mathbf{x'} x,x′是一对对应点,分别与窗上边缘和地面在同一平面,计算结果297.25cm。
在这步骤中计算 α \alpha α的代码如下
def cal_alpha(Z: list, r1: list, r2: list, v, l):
alpha=0
beta_i = rou_i = gamma_i = 0
A = np.zeros([len(Z), 2])
for i in range(len(Z)):
beta_i = np.linalg.norm(np.cross(r1[i], r2[i]))
l_bar = l / np.linalg.norm(l) #l的正则化
rho_i = np.dot(l_bar, r1[i])
gamma_i = np.linalg.norm(np.cross(v, r2[i]))
A[i, 0] = Z[i] * rho_i * gamma_i
A[i, 1] = beta_i
if len(Z) == 1:#只有一个基准距离
alpha = (-1.0 * beta_i) / (Z[0] * rho_i * gamma_i)
else:
M = np.dot(A.T, A)
lam,xi = np.linalg.eig(M)#计算特征值和向量
s = xi[:,np.argmin(lam)]#取最小特征值的特征向量
alpha = s[0] / s[1]
return alpha
计算距离Z的代码为
'''
其他代码中已定义以下内容
P = np.zeros([3, 4])
p1 = P[:, 0]
p2 = P[:, 1]
p3 = P[:, 2]
p4 = P[:, 3]
'''
def cal_z(point1, point2):
return -np.linalg.norm(np.cross(point1, point2)) / (np.dot(p4, point1) * np.linalg.norm(np.cross(p3, point2)))
图 7反映了如何利用同调关系来计算一个点在平行平面上的对应点。图 8展示了如何在平行平面间比较线段长度。图 9展示如何在平行平面间比较面积大小。计算同调矩阵需要先计算参数 ψ \psi ψ。 ψ \psi ψ可以通过(9)计算。需要注意的是,由于python的OpenCV库默认图像坐标系左上角为原点,y轴正方向向下,与示例中设置的图像坐标系不同。所以 ψ \psi ψ的符号也要变动。在最后,由于矩阵 P P P需要带系数 ρ \rho ρ才能使等式 x = P X \mathbf{x} = P\mathbf{X} x=PX成立,所以由 P P P推导出的同调矩阵 H ~ \widetilde{H} H 也需要带缩放系数。
图 7
从平面到另一个平行平面的点的同调映射:(a)原图,柜子的上顶面和下底面是平行平面。(b)示例图,共同的消失线(同调轴,上方白色)©示例图,显示物体轮廓(d)复现结果,用于确定消失点 v x , v y , v \mathbf{v}_{x},\mathbf{v}_{y},\mathbf{v} vx,vy,v的平行线以蓝色线表示。消失线以红色线表示。利用相同消失点和消失线推导的同调关系,给出上方选取点 x \mathbf{x} x,就能计算出下方对应点 x ′ \mathbf{x'} x′。橙色线表现了这个关系。
图 8
在两个平面之间测量平行线段长度之比:(a)原图示例(b)复现结果。点 r , r ′ \mathbf{r,r'} r,r′与消失点、消失线定义了两面墙的同调关系,蓝色线是定义消失点和消失线的平行线。紫色线段是以 r , r ′ \mathbf{r,r'} r,r′为端点的线段。橙色线是左外墙的线段映射到右外墙的结果。
图 9
测量在两个不同平面上的面积之比:(a)原图,目标是测量两个窗户的面积(b)复现效果图。橙色框是A1映射到A2平面的结果。利用 r , r ′ \mathbf{r}\mathbf{,r'} r,r′计算同调关系,并转换A1点到A2所在平面上,获得两个窗户的面积比为 A 1 / A 2 = 1.2 A1/A2 = 1.2 A1/A2=1.2
下面是计算 ψ , H ~ \psi,\widetilde{H} ψ,H 、同调对应点、以及额外缩放系数 ρ ~ \widetilde{\rho} ρ 的代码
def cal_psi(point1, point2, v, l):
l_bar = l / np.linalg.norm(l)
# 使用公式(9)计算psi。没有负号是因为图像坐标系y轴与示例中y轴正方向相反
return np.linalg.norm(np.cross(point1, point2)) / ((np.dot(l_bar, point1)) * (np.linalg.norm(np.cross(v, point2))))
def cal_H_tilde(psi, v, l):
l_bar = l / np.linalg.norm(l)
return np.identity(3) + psi * (np.dot(np.mat(v).T, np.mat(l_bar)))
def correspond(H_tilde, point):
correspond_point = np.dot(H_tilde, point)
correspond_point = np.array(correspond_point)[0] # 由矩阵转为向量
correspond_point = correspond_point / correspond_point[-1]
return correspond_point # 返回结果之后还需要乘缩放系数rho_tilde
rho_tilde = np.linalg.norm(reference_bottom_point) / np.linalg.norm(correspond(reference_top_point))
图 10展示了如何计算在不同平行平面上物体的高度。地平面是基准面 π \mathbf{\pi} π,将桌子桌面作为平面 π ′ \mathbf{\pi'} π′。用(14)即可以算出高度。
下面是计算文件夹高度 Z ′ Z' Z′的代码
'''
其他代码中已定义以下内容
P = np.zeros([3, 4])
p1 = P[:, 0]
p2 = P[:, 1]
p3 = P[:, 2]
p4 = P[:, 3]
'''
def cal_z_prime(point2, point3):
rho_prime = np.dot(point2, p4) / (1 + reference_distance * np.dot(p3, p4))
return -np.linalg.norm(np.cross(point2, point3)) / (rho_prime * (np.linalg.norm(np.cross(p3, point3))))
图 10
在不同平面上计算物体高度:(a)原示例结果(b)复现结果。蓝色线是定义消失点和消失线的平行线。紫色线是基准距离,桌子 r , r ′ \mathbf{r}\mathbf{,r'} r,r′的高度设定为60cm,计算出文件夹高度31.41cm。
图 11
计算相机位置:(a)原示例图(b)附带标识了参考点的复现图。 w i w_{i} wi表示用于计算单应矩阵的走廊矩形四个点。 w 0 w_{0} w0与原点重合。紫色线是基准距离。坐标系表示将空间坐标系 X Y Z XYZ XYZ按照图示构造。设定走廊矩形长宽为 830 c m × 120 c m 830cm \times 120cm 830cm×120cm。计算出相机位置为 X c = − 385.36 c m , Y c = − 651.01 c m , Z c = 161.29 c m X_{c} = - 385.36cm,Y_{c} = - 651.01cm,Z_{c} = 161.29cm Xc=−385.36cm,Yc=−651.01cm,Zc=161.29cm
图11展示在确定空间坐标系时,如何计算相机位置。在这里,空间坐标原点不再被设定为 p 4 = l ‾ \mathbf{p}_{\mathbf{4}} = \overline{\mathbf{l}} p4=l,而是 p 4 = w 0 \mathbf{p}_{\mathbf{4}} = w_{0} p4=w0。这导致两个结果。一是需要修改 α \alpha α的计算方法,因为之前计算方法依赖于 p 4 = l ‾ \mathbf{p}_{\mathbf{4}} = \overline{\mathbf{l}} p4=l, l ‾ ⋅ p 4 = 1 \overline{\mathbf{l}}\mathbf{\cdot}\mathbf{p}_{\mathbf{4}}\mathbf{=}1 l⋅p4=1。二是需要另一种方法计算从实际到图像的单应矩阵 H H H,因为矩阵 P P P现在是未知的。计算单应矩阵 H H H可以利用图像点和空间坐标的点的关系联立方程用矩阵解法。(至少4对点,8个方程)。2
def cal_H(world_point:list,img_point:list):
A = np.zeros([2 * len(img_point), 9])
for i in range(len(img_point)):
ip = img_point[i]
wp = world_point[i]
A[i * 2] = [wp[0], wp[1], 1, 0, 0, 0, -wp[0] * ip[0], -wp[1] * ip[0], -ip[0]]
A[i * 2 + 1] = [0, 0, 0, wp[0], wp[1], 1, -wp[0] * ip[1], -wp[1] * ip[1], -ip[1]]
lam, xi = np.linalg.eig(np.dot(A.T, A))
H_vector = xi[:, np.argmin(lam)]
return np.array([H_vector[:3], H_vector[3:6], H_vector[6:9]])
由于前提发生变换 ( l ‾ ⋅ p 4 ≠ 1 ) (\overline{\mathbf{l}}\mathbf{\cdot}\mathbf{p}_{\mathbf{4}} \neq 1) (l⋅p4=1),所以 α \alpha α的计算方法也发生了变化
def cal_alpha2(z: list, r1: list, r2: list, v, l):
global alpha
beta_i = rho_i = gamma_i = 0
A = np.zeros([len(z), 2])
for i in range(len(z)):
beta_i = np.linalg.norm(np.cross(r1[i], r2[i]))
l_bar = l / np.linalg.norm(l)
# 这里更改了代码,因为np.dot(l_bar,p4)不等于1
rho_i = np.dot(l_bar, r1[i]) / (np.dot(l_bar, p4))
gamma_i = np.linalg.norm(np.cross(v, r2[i]))
A[i, 0] = z[i] * rou_i * gamma_i
A[i, 1] = beta_i
if len(z) == 1:
alpha = (-1.0 * beta_i) / (z[0] * rho_i * gamma_i)
else:
M = np.dot(A.T, A)
lam, xi = np.linalg.eig(M) # 计算特征值和向量
s = xi[:, np.argmin(lam)] # 取最小特征值的特征向量
alpha = s[0] / s[1]
在算出单应矩阵后就可以得到投影矩阵 P P P的1,2,4列。以下是获得矩阵 P P P的流程。
p1[:] = H[:, 0]
p2[:] = H[:, 1]
p4[:] = H[:, 2]
#cal_alpha2()函数需要p4。所以需要计算p4后才运行cal_alpha2()
alpha=cal_alpha2(reference_distances, reference_ground_points, reference_plane_points, v, l)
p3[:] = alpha * v[:]
算出矩阵 P P P后依据(18)算出相机位置(前面提到,由于坐标朝向问题, Z c Z_{c} Zc符号实际上是相反的。)
Xc = -np.linalg.det(np.array([p2, p3, p4]).T)
Yc = np.linalg.det(np.array([p1, p3, p4]).T)
Zc = -np.linalg.det(np.array([p1, p2, p4]).T)
Wc = np.linalg.det(np.array([p1, p2, p3]).T)
A. Criminisi, I. Reid, and A. Zisserman, “Single view metrology,”
International Journal of Computer Vision, vol. 40, no. 2, pp.
123–148, 2000. ↩︎
A. Criminisi, I. Reid, and A. Zisserman, “A plane measuring
device,” Image and Vision Computing, vol. 17, no. 8, pp. 625–634,1999. ↩︎