点云压缩的八叉树算法
1. 八叉树编码
1.1. ref [1]
通过循环递归的方法对大小
2
n
×
2
n
×
2
n
2^n\times 2^n \times 2^n
2n×2n×2n的八叉树空间8等分划分,最多剖分
n
n
n次。
在完成逐层划分之后,对数据编码,编码方式为:假设点云坐标
P
(
x
,
y
,
z
)
P(x,y,z)
P(x,y,z)和树中节点
(
a
,
b
,
c
)
(a,b,c)
(a,b,c)相对应且树中任一个节点都与一个最小包围盒
C
u
b
e
m
i
n
Cube_{min}
Cubemin一一对应
o c t : ( a , b , c ) ↔ C u b e m i n (1) oct:(a,b,c)\leftrightarrow Cube_{min} \tag{1} oct:(a,b,c)↔Cubemin(1)
一个坐标点对应一个oct节点,而一个oct节点可能对应多个坐标点。利用该特性可以删除多余的点。
节点编码为 M = m n − 1 ⋯ m 2 m 1 m 0 M=m_{n-1}\cdots m_2m_1m_0 M=mn−1⋯m2m1m0为节点在 n n n层的节点序号。
首先利用空间坐标计算出节点索引值:
{
a
=
i
n
t
(
x
−
x
m
i
n
λ
x
)
b
=
i
n
t
(
y
−
y
m
i
n
λ
y
)
c
=
i
n
t
(
z
−
z
m
i
n
λ
z
)
(2)
\begin{cases} a=int\left( \frac{x-x_{min}}{\lambda_x}\right)\\ b=int\left( \frac{y-y_{min}}{\lambda_y}\right)\\ c=int\left( \frac{z-z_{min}}{\lambda_z}\right) \tag{2}\end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧a=int(λxx−xmin)b=int(λyy−ymin)c=int(λzz−zmin)(2)
使用无符号整数表示
a
,
b
,
c
a,b,c
a,b,c
{
a
=
a
n
−
1
a
n
−
2
⋯
a
0
b
=
b
n
−
1
b
n
−
2
⋯
b
0
c
=
c
n
−
1
c
n
−
2
⋯
c
0
(3)
\begin{cases} a=a_{n-1}a_{n-2}\cdots a_0\\ b=b_{n-1}b_{n-2}\cdots b_0\\ c=c_{n-1}c_{n-2}\cdots c_0 \tag{3}\end{cases}
⎩⎪⎨⎪⎧a=an−1an−2⋯a0b=bn−1bn−2⋯b0c=cn−1cn−2⋯c0(3)
节点序号
m
i
m_i
mi和
a
i
,
b
i
,
c
i
a_i,b_i,c_i
ai,bi,ci之间的关系可以表示为:
m
i
=
a
i
+
b
i
⋅
2
+
c
i
⋅
4
(4)
m_i=a_i+b_i\cdot 2+c_i \cdot 4 \tag{4}
mi=ai+bi⋅2+ci⋅4(4)
若知道八叉树某一节点序号
m
i
m_i
mi,利用
m
i
m_i
mi和
a
i
,
b
i
,
c
i
a_i,b_i,c_i
ai,bi,ci之间的关系得出:
a
i
=
(
m
i
m
o
d
2
)
,
b
i
=
[
(
m
i
/
2
)
m
o
d
2
]
,
c
i
=
[
(
m
i
/
4
)
m
o
d
2
]
(5)
ai=(m_i\ mod\ 2),b_i=[(m_i/2)\ mod\ 2],c_i=[(m_i/4)\ mod\ 2] \tag{5}
ai=(mi mod 2),bi=[(mi/2) mod 2],ci=[(mi/4) mod 2](5)
1.2. 编码
由(2)进行量化,去除重复坐标,然后直接编码为:
M
=
c
n
−
1
b
n
−
1
a
n
−
1
⋯
c
0
b
0
a
0
(6)
M=c_{n-1}b_{n-1}a_{n-1}\cdots c_0b_0a_0 \tag{6}
M=cn−1bn−1an−1⋯c0b0a0(6)
1.3. 去重怎么弄?
量化是按坐标点循环
整数排序
→
\rightarrow
→去除重复点
2. 解码
3. opencl算法
3.1. ref [2]
4. 算法实现
- 直接用C++写了
5. 参考文献
[1] 三维点云数据精简与压缩的研究_唐林
[2] Massively parallel KD-tree construction and nearest neighbor search algorithms