写在前面
Open3D中的隐藏点去除算法(Hidden Point Removal)的作用是从给定视点渲染点云时,去除背景中未被其他点遮挡的点,从而提高点云的可视化效果。Open3D库中实现了[Katz2007]提出的一种基于点云可见性近似计算的隐藏点去除方法。该方法不需要进行曲面重构或法向量估计,直接利用点云数据计算点的可见性。
在使用Open3D库时我们只需要一行
_, pt_map = pcd.hidden_point_removal(camera, radius)
就可以从原始点云
得到隐藏点去除掉后的点云
但是这种算法是如何在几乎不存在点遮挡的点云中实现遮挡点去除的呢?
我找到了这篇文献Direct Visibility of Point Sets对代码的底层逻辑进行一些了解。后来有很多人在这篇文章的基础上进行了优化,但是万变不离其宗,下面就对文章的算法进行讲解。
文章解读
介绍
论文介绍了一种新的方法——直接从点云中提取可见性信息。点云是一个包含3D位置信息的采样点集,与传统的网格表示相比更加简单和灵活。通过提取点云中的可见性信息,可以实现点集的可视化、视角相关的快速重构和实时的阴影投射。本文提出的方法简单快速,不依赖于屏幕分辨率和网格拓扑结构,并且适用于各种维度的点云。另外还对算法进行了理论证明,并给出了实验结果和应用示例。
算法实现
给定一个点集 P = { p i ∣ 1 ≤ i ≤ n } ⊂ ℜ D P = \{p_{i}|1\le{i}\le{n}\}\sub{\Re^{D}} P={pi∣1≤i≤n}⊂ℜD,这些点是在一个连续的表面 S S S上采样得来的。以及一个视点 C C C。我们的目标就是去找到所有在视点 C C C上能看到的所有点集 P P P中的点。
这种问题因为点云的稀疏性导致几乎所有点都是可见的,所以简单的直线可见性判断无法适用所有情况。所以要有新的点云可见性定义方法。如果一个点在半径为 ρ \rho ρ的开放球
在数学中,一个点 p p p的 r r r半径开放球 B r ( p ) B_r(p) Br(p)是指以 p p p为球心, r r r为半径的球体,但不包含球体表面上的任何点。也就是说, B r ( p ) B_r(p) Br(p)包含所有距离 p p p小于 r r r的点,但不包括球体表面上的点。
内的任何位置发生微小扰动都不会被其他点遮挡,那么这个点就是可见的。
显然,可见性的合理标准必须与采样密度相关。假设
P
P
P是平面
S
S
S的一个
ρ
−
\rho-
ρ−采样,即如果我们用半径为
ρ
\rho
ρ的开放球来围住每一个采样点
p
i
p_i
pi那么表面
S
S
S将完全包含在这些球的并集内。如果在球的任何位置扰动
p
i
p_i
pi的位置其均不被其他点遮挡,那么
p
i
p_i
pi就是可见点。但是这种算法只在视线垂直于表面时有较好效果,当平面是斜面时表现不好。但是我们还要去避免计算表面法线。
为了解决这个问题,作者提出了一个名为隐藏点移除(HPR)的算子,它具有正确性、适用于倾斜曲面和合理的时间复杂度等特点。该运算符由两个步骤组成:反演(Inversion)和凸包构造(Convex Hull Construction)。
反演(点变换)
给出点集
P
P
P和
C
C
C,我们将
P
P
P和一个坐标系相关联,让
C
C
C置于原点。那么我们就需要找到一个函数将点
p
i
p_i
pi映射到沿着
C
C
C到
p
i
p_i
pi的射线上,并在
∥
p
i
∥
\|p_i\|
∥pi∥中单调递减。其中
∥
⋅
∥
\|{\cdot}\|
∥⋅∥是一种范数。本文介绍了名为Spherical Flipping的反演方法,它将D维球面于半径为
R
R
R圆心在
C
C
C的球体联系起来,这个球包含了
P
P
P的所有点。用下式将
p
i
p_i
pi进行镜像反射。
p
^
i
=
f
(
p
i
)
=
p
i
+
2
(
R
−
∥
p
i
∥
)
p
i
∥
p
i
∥
\hat{p}_{i}=f(p_i)=p_{i}+2(R-\|p_i\|)\frac{p_i}{\|p_i\|}
p^i=f(pi)=pi+2(R−∥pi∥)∥pi∥pi
镜像反射的示意图如下,该公式实现了对蓝色的猫猫从绿色的球面进行镜面反射到外圈红色猫猫。
作者提示了反演函数不止这一种,像是 f ~ ( p i ) = p i ∥ p i ∥ γ \tilde{f}(p_i)=\frac{p_i}{\|p_i\|\gamma} f~(pi)=∥pi∥γpi这种公式也可以实现类似的效果。
凸包构造
点云的凸包是包含所有点的最小凸集。Open3D 包含计算点云凸包的方法。该实现基于 Qhull。使用函数compute_convex_hull
就可以得到下图效果的可视化凸包:
但是这种凸包是如何构建的?
通过上一步的点变换我们可以得到变换后的点云
P
^
\hat{P}
P^,我们要计算的凸包是变换后的点云
P
^
\hat{P}
P^和中心点
C
C
C的并集的。
文章中的主要结果就是提取了位于
P
^
∪
{
C
}
\hat{P}\cup\{C\}
P^∪{C}凸包上的点来将其等价为可见点。这里球心
C
C
C的引入是有必要性的,因为如果C在点云的外部时物体背面的点就会在凸包上。
我们从而可以引出一个定义:
如果点 p i p_i pi的反射点 p i ^ \hat{p_i} pi^位于 P ^ ∪ { C } \hat{P}\cup\{C\} P^∪{C}的凸包上,那么点 p i p_i pi被标记为从 C C C可见。
HPR算子可以被应用于任何维度,在二维空间中更易于理解。当我们考虑一个二维点集
p
i
∈
P
p_i\in{P}
pi∈P。不失一般性,将
p
i
p_i
pi置于X轴上。使用极坐标系
(
r
,
θ
)
(r, \theta)
(r,θ),我们可以将
P
i
P_i
Pi写成
p
i
=
(
r
i
,
0
)
p_{i}=(r_i,0)
pi=(ri,0)。其中
r
i
r_i
ri是
p
i
p_i
pi到
C
C
C的距离,与X轴的夹角为0。考虑穿过
p
i
^
\hat{p_i}
pi^并与X轴形成角度
β
\beta
β的直线
L
^
\hat{L}
L^,如下图所示:
我们要找到
L
^
\hat{L}
L^球形翻转对应的线
L
=
(
r
(
α
)
,
α
)
L=(r(\alpha),\alpha)
L=(r(α),α),使用正弦定理我们可以得到:
2
R
−
r
i
sin
(
π
−
α
−
β
)
=
R
−
r
(
α
)
sin
β
\frac{2R-r_i}{\sin(\pi-\alpha-\beta)}=\frac{R-r(\alpha)}{\sin{\beta}}
sin(π−α−β)2R−ri=sinβR−r(α)
从而得到
L
=
(
r
(
α
)
,
α
)
=
(
2
R
+
(
r
i
−
2
R
)
sin
β
sin
(
α
+
β
)
,
α
)
L=(r(\alpha),\alpha)=(2R+\frac{(r_{i}-2R)\sin{\beta}}{\sin(\alpha+\beta)},\alpha)
L=(r(α),α)=(2R+sin(α+β)(ri−2R)sinβ,α)
曲线
L
L
L同时经过了
p
i
p_i
pi和
C
C
C,在笛卡尔坐标系中需要用x和y的四次多项式表示。
下图说明了
L
L
L的形状如何随着角度
β
\beta
β的变化而变化。
L
L
L和X轴定义了与点
p
i
p_i
pi相关的空白区域。
p
i
p_i
pi的可见性取决于该区域的大小。该区域越大则
p
i
p_i
pi就越可见。HPR的重要特性就在于这个大小是由
p
i
p_i
pi周围的点自适应确定的,如下所述:
对于所有给定点
p
i
p_i
pi,
P
P
P的两侧总存在两个特殊点
p
j
p_j
pj和
p
k
∈
P
p_k\in{P}
pk∈P,它们对应的曲线
L
j
=
(
r
j
(
α
j
)
,
α
j
)
L_j=(r_{j}(\alpha_j),\alpha_j)
Lj=(rj(αj),αj)和
L
k
=
(
r
k
(
α
k
)
,
α
k
)
L_k = (r_{k}(\alpha_k),\alpha_k)
Lk=(rk(αk),αk),它们之间的区域就是最大可能的空白区域,如图下图所示:
当
p
i
p_i
pi可见时
当
p
i
p_i
pi不可见时
从曲线的公式可以推断出最大区域对应最小的
β
\beta
β。这意味着对于
p
i
p_i
pi
而言,与最大可能空白区域相对应的
β
j
\beta_j
βj和
β
k
\beta_k
βk最小的。
β
j
\beta_j
βj和
β
k
\beta_k
βk可以从
L
L
L的方程里面提取出来。对于可见的
p
i
p_i
pi,
β
j
\beta_j
βj和
β
k
\beta_k
βk的和应满足
β
j
+
β
k
≤
c
o
n
s
t
\beta_j+\beta_k\le{const}
βj+βk≤const。
设置
c
o
n
s
t
=
π
const = \pi
const=π意味着在计算上不需要为每个点找到最大化空区域大小的相邻点
p
j
、
p
k
p_j 、p_k
pj、pk了。相反,计算
P
^
∪
{
C
}
\hat{P}\cup\{C\}
P^∪{C}的凸包就足够了。这是因为当且仅当
P
^
∪
{
C
}
\hat{P}\cup\{C\}
P^∪{C}所有点位于由
p
i
^
,
p
j
^
ˉ
\bar{\hat{p_i},\hat{p_j}}
pi^,pj^ˉ和
p
i
^
,
p
k
^
ˉ
\bar{\hat{p_i},\hat{p_k}}
pi^,pk^ˉ定义的半空间的一侧时,点
p
i
^
\hat{p_i}
pi^才位于
P
^
∪
{
C
}
\hat{P}\cup\{C\}
P^∪{C}的凸包上。在文中的情况下,由于
L
j
L_j
Lj和
L
k
L_k
Lk之间的区域是空的(图中的灰色区域),所以
L
j
^
\hat{L_j}
Lj^和
L
k
^
\hat{L_k}
Lk^远端的区域必须是空的。
这一观察结果在计算上很重要,也是HPR算子如此高效的原因,如果不计算凸包就必须找到
p
j
p_j
pj和
p
k
p_k
pk使算法成为二次型(在3D中甚至是三次型)。相反,如果需要做的就是计算凸包并考虑如果
p
i
^
\hat{p_i}
pi^在
P
^
\hat{P}
P^的凸包上时点
p
i
p_i
pi是可见的就可以了。因此HPR算子定义了空区域的形状和大小。
上述说明可以拓展到3D,在这种情况下空区域就不是由曲线而是由曲面定义的。此外,在3D中不是使用两个相邻点而是至少三个相邻点定义包围空体积的表面,但是这种凸包解决方法的思路是一致的。
值得注意的是,即使我们定义的
π
\pi
π是个恒定的阈值,能见度的阈值也可以通过改变球体的半径来间接修改,
R
R
R较大时有更大的可见范围,但在使用不同的反演函数时上述解释将保持不变但是
L
L
L的形状会发生变化。