说明
判断一堆3d点哪些在一堆3d框内,与主流3d目标检测算法一样,立方体只有水平方向上的旋转,没有高度方向上的旋转,就是拍到BEV图像上是一个旋转的矩形
代码优势
基于numpy完成,直接判断一堆点和一堆3d框的包含关系,不使用for循环
算法思路
整体思路说白了其实也挺简单的,就是分两步,首先判断点是否在旋转矩形内(本人直接使用凸多边形),然后判断是否在高度范围内
针对numpy核心的代码思路是:在加和过程中True为1、False为0,因此同时满足三个条件加和应该为3。以此进行重叠的逻辑判断,最后判断一次取出满足全部条件的索引
工程细节
定义随机点
lidar_points = np.random.randint(low=0, high=10, size=(10, 3), dtype='int')
定义旋转矩形
定义一个旋转矩形,输入的box为中心点坐标x、y,矩形宽高,和围绕中心点旋转角度
def get_corners(box): # 这里本人项目yaw [-pi/4, 3*pi/4),需要映射到[0, pi) # box = box.detach().cpu().numpy() x = box[0] y = box[1] w = box[2] l = box[3] yaw = box[4] if yaw < 0: # 用来映射 yaw = yaw + np.pi bev_corners = np.zeros((4, 2), dtype=np.float32) cos_yaw = np.cos(yaw) sin_yaw = np.sin(yaw) bev_corners[0, 0] = (w / 2) * cos_yaw - (l / 2) * sin_yaw + x bev_corners[0, 1] = (w / 2) * sin_yaw + (l / 2) * cos_yaw + y bev_corners[1, 0] = (l / 2) * sin_yaw + (w / 2) * cos_yaw + x bev_corners[1, 1] = (w / 2) * sin_yaw - (l / 2) * cos_yaw + y bev_corners[2, 0] = (-w / 2) * cos_yaw - (-l / 2) * sin_yaw + x bev_corners[2, 1] = (-w / 2) * sin_yaw + (-l / 2) * cos_yaw + y bev_corners[3, 0] = (-l / 2) * sin_yaw + (-w / 2) * cos_yaw + x bev_corners[3, 1] = (-w / 2) * sin_yaw - (-l / 2) * cos_yaw + y return bev_corners
定义空间3d立方体
首先定义旋转矩形,然后为旋转矩形在z轴上赋最大值和最小值,得到的结果就是空间3d的立方体,但是没有高度上的旋转
def get_3dbox(boxes): boxes_3d = [] for box in boxes: bev_corners = get_corners(box[:5]) down = np.hstack( [bev_corners, box[5] * np.ones((bev_corners.shape[0], 1))]) up = np.hstack( [bev_corners, box[6] * np.ones((b