首页 > 其他分享 >bev_feature与真实坐标的关系

bev_feature与真实坐标的关系

时间:2024-07-05 15:43:29浏览次数:9  
标签:tensor idx occ feature occupancy 坐标 indices bev size

在生成 BEV feature 时的 scatter:

nx = int((point_cloud_range[3]-point_cloud_range[0])/voxel_size[0])

# Create the canvas for this sample
canvas = torch.zeros(
    self.in_channels,
    self.nx * self.ny,
    dtype=voxel_features.dtype,
    device=voxel_features.device)

# coors[:,2] 体素y坐标
# coors[:,3] 体素x坐标
indices = coors[:, 2] * self.nx + coors[:, 3]
indices = indices.long()
voxels = voxel_features.t()
# Now scatter the blob back to the canvas.
canvas[:, indices] = voxels
# Undo the column stacking to final 4-dim tensor
canvas = canvas.view(1, self.in_channels, self.ny, self.nx)

示例:
image-20240705104826677|500

nx = 8
ny = 4
indices = []

for y in range(ny):
    for x in range(nx):
        idx = x + y*nx
        indices.append(idx)

indices_tensor = torch.from_numpy(np.array([indices]))
print(indices_tensor)

indices_tensor = indices_tensor.view(ny, nx)
print(indices_tensor)

indices_tensor = indices_tensor.permute(1, 0)
print(indices_tensor)

result:

tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
         18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]])

tensor([[ 0,  1,  2,  3,  4,  5,  6,  7],
        [ 8,  9, 10, 11, 12, 13, 14, 15],
        [16, 17, 18, 19, 20, 21, 22, 23],
        [24, 25, 26, 27, 28, 29, 30, 31]])

tensor([[ 0,  8, 16, 24],
        [ 1,  9, 17, 25],
        [ 2, 10, 18, 26],
        [ 3, 11, 19, 27],
        [ 4, 12, 20, 28],
        [ 5, 13, 21, 29],
        [ 6, 14, 22, 30],
        [ 7, 15, 23, 31]])

可以看到是按照 x 轴方向,行优先排列的,模型后面所有的操作都是基于这个形状的 feature 做的

occupancy 的输出格式为 1,X,Y,C

# bev_feature: (B, C_i, Dy, Dx)
# (B, C_i, Dy, Dx) -> (B, C_o, Dy, Dx) -> (B, Dx, Dy, C_o)
occ_pred = self.final_conv(bev_feats).permute(0,3,2,1)
bs, Dx, Dy = occ_pred.shape[:3]
# (B, Dx, Dy, C_o) -> (B, Dx, Dy, 2*C_o) ->(B, Dx, Dy, n_cls*Dz)
if self.use_predictor:
    occ_pred = self.predictor(occ_pred)
# (B, Dx, Dy, n_cls*Dz) -> (B, Dx, Dy, Dz, n_cls)
occ_pred = occ_pred.view(bs, Dx, Dy, self.Dz, self.num_classes)

occ_score = occ_pred.softmax(-1)
# (B, Dx, Dy, Dz)
occ_res = occ_score.argmax(-1).float().contiguous()

cuda 得到 point 结果:

int y = coor_idx % occupancy_dim_size.y;
int x = coor_idx / occupancy_dim_size.y;
int occupied_idx = 0;
float lidar_x, lidar_y, lidar_z;
for (int z = 0; z < occupancy_dim_size.z; ++z) {
    int semantic = round(occ_out_deveice[coor_idx * occupancy_dim_size.z + z]);
    if(semantic > 0 && semantic != 2) {
        occupied_idx = atomicAdd(occupied_num_device, 1);
        lidar_x = (x + 0.5) * occupancy_voxel_size.x + range.min_x;
        lidar_y = (y + 0.5) * occupancy_voxel_size.y + range.min_y;
        lidar_z = (z + 0.5) * occupancy_voxel_size.z + range.min_z;

        occupied_out_device[4 * occupied_idx] = lidar_x;
        occupied_out_device[4 * occupied_idx + 1] = lidar_y;
        occupied_out_device[4 * occupied_idx + 2] = lidar_z;
        occupied_out_device[4 * occupied_idx + 3] = semantic;
    }
}

根据 Core Concepts — NVIDIA cuDNN v9.2.1 documentation 的解释

data:
image-20240704181218487

NHWC 排布的数据在内存中的顺序:

image-20240704181256275

回到 BEV feature map,在 permute(0,3,2,1) 后,2,3 维度是 X, Y 内存是行排列的

int y = coor_idx % occupancy_dim_size.y;
int x = coor_idx / occupancy_dim_size.y;

图示:

occ 中的 feature:
这里得到的 BEV feature 与上述一致:

# 真实坐标id
tensor([[ 0,  8, 16, 24], # 第一列在原始BEV中的索引, 映射为内存中的 0,1,2,3
		[ 1,  9, 17, 25],
		[ 2, 10, 18, 26],
		[ 3, 11, 19, 27],
		[ 4, 12, 20, 28],
		[ 5, 13, 21, 29],
		[ 6, 14, 22, 30],
		[ 7, 15, 23, 31]])
# 映射到内存中的id:
tensor([[ 0,  1,  2,  3],
		[ 4,  5,  6,  7],
		[ 8,  9, 10, 11],
		[12, 13, 14, 15],
		[16, 17, 18, 19],
		[20, 21, 22, 23],
		[24, 25, 26, 27],
		[28, 29, 30, 31]])

IMG_20240704_193250

在目标检测中,centerhead 导出的onnx 最后输出的 feature map 顺序是 1,X,Y,C, 与 occ 是翻转关系:

reg_res = reg_res.permute(0, 2, 3, 1).contiguous()
height_res = height_res.permute(0, 2, 3, 1).contiguous()
dim_res = dim_res.permute(0, 2, 3, 1).contiguous()
rot_res = rot_res.permute(0, 2, 3, 1).contiguous()

数据排布:

tensor([[ 0,  1,  2,  3,  4,  5,  6,  7],
		[ 8,  9, 10, 11, 12, 13, 14, 15],
		[16, 17, 18, 19, 20, 21, 22, 23],
		[24, 25, 26, 27, 28, 29, 30, 31]])
int x = coor_idx % occupancy_dim_size.x;
int y = coor_idx / occupancy_dim_size.x;

标签:tensor,idx,occ,feature,occupancy,坐标,indices,bev,size
From: https://www.cnblogs.com/swc-blog/p/18285955

相关文章

  • (高数)二重积分的计算——直角坐标系
    二重积分的含义:一重积分是把函数分为一小条一小条来近似求和计算出一个面积,而二重积分则是多了一个维度,原本每个小条的背后都是一个平面,这些面积则需要对另一个变量求积分得出了。既然要求两个积分,先后就是一个问题。先求的积分为内层积分,后者为外层积分。做题时我们要先固......
  • 计算3个经纬度坐标点之间的夹角
    原文地址:https://www.cnblogs.com/imgss/p/10707150.html火车地图搞了有半年了,在做火车地图的过程中,遇到了一个问题,就是由于火车站点的地理坐标是直接请求api拿到的,部分api返回的结果可能千差万别。所以我需要一个方法,来在地图显示的过程中,判断出某个站点的坐标有误,并上报到服......
  • unity 从list中获取最近的坐标 / 获取最接近的角度(数值)
    ///<summary>///从列表points中获取距离targetPoint最近的坐标///</summary>///<paramname="points"></param>///<paramname="targetPoint"></param>///<returns><......
  • WPF Prism PubSubEvent(订阅)
    Prism提供了事件聚合器(EventAggregator)来实现事件的订阅和发布,允许模块之间进行松耦合的通信。主要作用:解耦合:通过事件订阅和发布,模块之间可以实现解耦合,避免直接依赖于彼此的实现细节。示例用法:定义事件类:publicclassMessageEvent:PubSubEvent<string>{}订......
  • Qt/C++编写地图应用/离线地图下载/路径规划/轨迹回放/海量点/坐标转换
    一、前言说明这个地图组件写了很多年了,最初设计的比较粗糙,最开始只是为了满足项目需要,并没有考虑太多拓展性,比如最初都是按照百度地图写死在代码中,经过这几年大量的现场实际应用,以及大量的用户提出的改进意见,逐渐萌生了彻底重新编写对应地图相关的代码,比如基类子类的设计,各种功能......
  • 高德坐标转gps坐标
    vue3实现高德坐标和gps坐标互转:/** *高德地图坐标转GPS坐标算法 */constpi=3.1415926535897932384626;consta=6378245.0;//长半轴constee=0.00669342162296594323;//扁率//地球坐标系(WGS-84)转火星坐标系(GCJ)exportfunctionWgsToGcj02(wglng,wglat){......
  • 百度坐标转gps坐标
    vue3页面实现:利用百度api的jsapi中的 BMap.Convertor()此方法通过计算取巧算出gps坐标误差非常小;假设百度坐标:lng1:113.94620475687566 lat1:22.56028856475092把这个坐标当成GPS坐标,通过接口获得他的百度坐标:lng2=113.95764483473,lat2=22.562997980443通过计算就可以得到......
  • 火星坐标转换
     出处:火星坐标、百度坐标、WGS84坐标转换代码(JS版)/***CreatedbyWandergison2015/7/8.*提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换*///定义一些常量varx_PI=3.14159265358979324*3000.0/180.0;varPI=3.1415926535897932......
  • 【吴恩达机器学习-week2】可选实验:特征工程和多项式回归【Feature Engineering and Po
    支持我的工作......
  • BEV感知算法:LSS论文与代码详解
    BEV感知算法:LSS论文与代码详解0. 前言最近几年,BEV感知是自动驾驶领域中一个非常热门研究方向,其核心思想是把多路传感器的数据转换到统一的BEV空间中去提取特征,实现目标检测、地图构建等任务。如何把多路相机的数据从二维的图像视角转换到三维的BEV视角?LSS提出一种显示估......