BEV,即bird’s eye view,鸟瞰图
    BEV图为3D点云数据
    鸟瞰图的计算需要用到地面数据,即空间上的点投影到某个平面,需要知道该平面的平面方程,平面方程的表达式为:
    点云BEV图处理 - 图1
    空间上的点点云BEV图处理 - 图2到平面上的距离为:
    点云BEV图处理 - 图3
    读取KITTI数据集中的地面数据:

    1. # 000274.txt
    2. # Plane
    3. Width 4
    4. Height 1
    5. -2.143976e-03 -9.997554e-01 2.201096e-02 1.707479e+00
    6. # 分别表示a, b, c, d四个参数值

    点云数据转BEV时高度分辨率为0.5,根据点云数据可以得到x,y和z轴上的数据,即x_col,y_col,z_col,然后使用np.lexsort()对x轴进行排序:

    sorted_order = np.lexsort((y_col, z_col, x_col))
    # 对 x_col 进行排序
    # 如果 x_col 中的数值一样,则比较 z_col 中相应索引下的值的大小
    # 如果还相同,再比较 y_col 中的元素
    

    将 y_col 中的元素置为0,即只保留x和z轴上的数据,然后使用np.view()对数值类型进行变换:

    # 定义12字节的数据类型
    dt = np.dtype((np.void, 12))
    
    # 先使用np.ascontiguousarray将一个内存不连续存储的数组转换为内存连续存储的数组,使得运行速度更快
    # 再使用np.view按指定方式对内存区域进行切割,来完成数据类型的转换
    # discrete_pts(n, 3) --> contiguous_array(n, 1)
    # itemsize输出array元素的字节数
    contiguous_array = np.ascontiguousarray(discrete_pts).view(dtype=dt)
    

    :::info 离散点云数据discrete_pts的shape为(n,3),其数值类型为np.int32,4字节,总字节为n_3_4Byte,现将其转为12Byte的数据,即保持总字节数不变:n_1_12,转换完成后的shape为(n,1)。 ::: 对上述的数据进行去重:

    # 去除数组中的重复数字,并进行排序
    _, unique_indices = np.unique(contiguous_array, return_index=True)
    unique_indices.sort()
    # 得到不重复的数据
    # voxel 体素(三维) 
    # pixel 像素(二维)
    voxel_coords = discrete_pts[unique_indices]
    # 将索引值映射到原点
    voxel_coords -= -400
    

    计算每个体素中数据点的数量,即后一个索引值减去当前索引值:

    num_points_in_voxel = np.diff(unique_indices)
    num_points_in_voxel = np.append(num_points_in_voxel,
                                    discrete_pts_2d.shape[0] -
                                    unique_indices[-1])
    

    计算每个体素中数据点的高度,通过计算点到平面方程的距离:

    # voxel (x, y, z)
    # 平面方程: ax + by + cz + d = 0
    height_in_voxel = (a*x + b*y + c*z + d) / np.sqrt(a**2 + b**2 + c**2)
    

    对高度信息进行缩放,height_in_voxel = height_in_voxel / 0.5,根据二维索引值voxel_coords(去除y轴)与高度信息即可得到BEV数据,密度信息的计算:

    # N is num points in voxel 
    # x = 16
    density_map = min(1.0, log(N+1)/log(x))
    

    最终的BEV是由5个高度信息和1个密度信息组成,其shape为(700, 800, 6)。