Voxel Grid Usage in Airsim
-
airsim 提供了c++和python下的构建环境的网格地图,并以binvox的格式储存。
-
c++下构建网格地图的函数在WorldSimApi.cpp → {\rightarrow} →creatVoxelGrid()实现,该文件在airsim文件夹下的Unreal/Plugins中。
-
python下:
-
输入的参数:
position:voxel grid 中心的世界坐标,栅格化空间的中心坐标。
x,y,z:即为构建网格个地图栅格的大小,即把多大(以米为单位)的空间栅格化。
res:分辨率,就是栅格对应的现实距离空间大小,比如每一个栅格代表一个现实边长为1m的正方体。
of:构建出来栅格地图保存的文件名。以binvox的格式保存。
- 关于binvox的文件使用:
官网链接:https://www.patrickmin.com/binvox/binvox.html
关于文件的header:
#binvox 1
指明是binvox文件,并且版本号为1
dim 200 200 200
整个大的地图栅格的depth,width,height,等于上述函数中的x,y,z除以分辨率
translate -50 -50 -50
scale 0.01
以上两行说明了normalization transformation
data
最后一行说明一下是数据
- 关于normalization transformation,是归一化与网格匹配,即transalte和scale的具体使用:
在对模型进行体素化,先将网格归一化,使得每一个点都可以生成一个标准体素点(1x1x1),这一步主要是通过平移和统一比例实现的。然后单位正方体被体素化。因此,体素模型中每一个体素点都调节定位在单位立方体内部。 - 关于binvox的可视化:使用 viewvox 【filename】(下载链接:viewvox 3D voxel model viewer (patrickmin.com))
- 关于坐标的索引,对于给定的一个索引 ( i , j , k ) {(i,j,k)} (i,j,k)的格子以及整个栅格化区域的维度d,先计算出
( x n , y n , z n ) = ( ( i + 0.5 ) / d , ( j + 0.5 ) / d , ( k + 0.5 ) / d ) {(x_n, y_n, z_n) = ((i + 0.5) / d, (j + 0.5) / d, (k + 0.5) / d)} (xn,yn,zn)=((i+0.5)/d,(j+0.5)/d,(k+0.5)/d);(0.5是用来转化到格子中心坐标)。然后有两种方法来计算真实坐标:
- 第一种,把 ( x n , y n , z n ) {(x_n,y_n,z_n)} (xn,yn,zn)用scale缩放,然后平移translate即可得到。
- 使用binvox命令输出的normalization transformation steps,然后按步骤操作即可。
(binvox命令输出如下:)
-
从三维坐标到索引只要进行以上操作的逆向操作即可。
-
在数据部分,虽然栅格是三维的,但是被拉成一维数组存储,变化最快的是y坐标,然后是z坐标,最后是x坐标,也就是说一维数组的索引和三维数组的索引存在以下关系: i n d e x = x ∗ d ∗ d + y ∗ d + z {index = x * d *d + y * d + z} index=x∗d∗d+y∗d+z,index表示一维数组的索引。
-
关于数据,二进制数据由成对的字节组成。每对的第一个字节是值字节,为 0 或 1(1 表示体素的存在)。第二个字节是计数字节,并指定前面的体素值应重复多少次(因此显然最小计数为1,最大值为255)。
-
关于读写操作binvox文件有人写好的代码:dimatura/binvox-rw-py: Python module to read and write .binvox files. (github.com)
-
参考文档