def filt_label_by_cls(label, keep_cls): label.data = list(filter(lambda obj: obj.type in keep_cls, label.data)) res = KittiLabel() for obj in label.data: res.add_obj(obj) res.current_frame = label.current_frame return res
def save_detections(self, detections, tags, calibs, save_dir): res_dir = save_dir if os.path.isdir(res_dir): shutil.rmtree(res_dir, ignore_errors=True) os.makedirs(res_dir) for det, tag, calib in zip(detections, tags, calibs): label = KittiLabel() label.current_frame = "Cam2" final_box_preds = det["box3d_lidar"].detach().cpu().numpy() label_preds = det["label_preds"].detach().cpu().numpy() scores = det["scores"].detach().cpu().numpy() for i in range(final_box_preds.shape[0]): obj_np = final_box_preds[i, :] bcenter_Flidar = obj_np[:3].reshape(1, 3) bcenter_Fcam = calib.lidar2leftcam(bcenter_Flidar) wlh = obj_np[3:6] ry = obj_np[-1] obj = KittiObj() obj.type = self._class_names[int(label_preds[i])] obj.score = scores[i] obj.x, obj.y, obj.z = bcenter_Fcam.flatten() obj.w, obj.l, obj.h = wlh.flatten() obj.ry = ry obj.from_corners(calib, obj.get_bbox3dcorners(), obj.type, obj.score) obj.truncated = 0 obj.occluded = 0 obj.alpha = -np.arctan2(-bcenter_Flidar[0, 1], bcenter_Flidar[0, 0]) + ry label.add_obj(obj) # save label write_str_to_file(str(label), os.path.join(res_dir, f"{tag}.txt"))
def keep(self, label: KittiLabel, pc: np.array, calib: KittiCalib) -> (KittiLabel, np.array): # copy pc & label pc_ = pc.copy() label_ = KittiLabel() label_.data = [] for obj in label.data: label_.data.append(KittiObj(str(obj))) res_label = KittiLabel() for obj in label_.data: res_label.add_obj(obj) res_label.current_frame = "Cam2" return res_label, pc_
def flip_pc(self, label: KittiLabel, pc: np.array, calib: KittiCalib) -> (KittiLabel, np.array): ''' flip point cloud along the y axis of the Kitti Lidar frame inputs: label: ground truth pc: point cloud calib: ''' assert istype(label, "KittiLabel") calib_is_iter = isinstance(calib, list) # copy pc & label pc_ = pc.copy() label_ = KittiLabel() label_.data = [] for obj in label.data: label_.data.append(KittiObj(str(obj))) # flip point cloud pc_[:, 1] *= -1 # modify gt if not calib_is_iter: for obj in label_.data: bottom_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, -1) bottom_Flidar = calib.leftcam2lidar(bottom_Fcam) bottom_Flidar[0, 1] *= -1 bottom_Fcam = calib.lidar2leftcam(bottom_Flidar) obj.x, obj.y, obj.z = bottom_Fcam.flatten() obj.ry *= -1 else: for obj, calib_ in zip(label_.data, calib): bottom_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, -1) bottom_Flidar = calib_.leftcam2lidar(bottom_Fcam) bottom_Flidar[0, 1] *= -1 bottom_Fcam = calib_.lidar2leftcam(bottom_Flidar) obj.x, obj.y, obj.z = bottom_Fcam.flatten() obj.ry *= -1 res_label = KittiLabel() for obj in label_.data: res_label.add_obj(obj) res_label.current_frame = "Cam2" return res_label, pc_
def test_filt_label_by_range(self): def limit_period_torch(val, offset=0.5, period=np.pi): return val - torch.floor(val / period + offset) * period data_cfg = Test_prep_infos.TRAINDATA_cfg voxelizer = voxelizer_builder.build(Test_exclude_classes.VOXELIZER_cfg) target_assigner = target_assigner_builder.build(Test_exclude_classes.TARGETASSIGNER_cfg) dataloader = build(data_cfg, ext_dict={ "voxelizer": voxelizer, "target_assigner": target_assigner, "feature_map_size": [1, 200, 176] }) box_coder = target_assigner.box_coder import torch import torch.nn as nn from det3.methods.second.ops.torch_ops import rotate_nms from det3.dataloader.carladata import CarlaObj, CarlaLabel from incdet3.utils.utils import filt_label_by_range for data in dataloader: tag = data["metadata"][0]["tag"] if tag != "000006": continue label = data["metadata"][0]["label"] cls_pred = torch.from_numpy(data["labels"]).cuda().float() cls_pred *= (cls_pred >= 0).float() cls_pred = cls_pred.long() cls_pred = nn.functional.one_hot(cls_pred, num_classes=2+1) cls_pred = cls_pred[..., 1:] anchors = torch.from_numpy(data["anchors"]).cuda().float() box_pred = torch.from_numpy(data["reg_targets"]).cuda().float() box_pred = box_coder.decode(box_pred, anchors) for box_preds, cls_preds in zip(box_pred, cls_pred): box_preds = box_preds.float() cls_preds = cls_preds.float() total_scores = cls_preds nms_func = rotate_nms top_scores, top_labels = torch.max( total_scores, dim=-1) top_scores_keep = top_scores >= 0.5 top_scores = top_scores.masked_select(top_scores_keep) box_preds = box_preds[top_scores_keep] top_labels = top_labels[top_scores_keep] boxes_for_nms = box_preds[:, [0, 1, 3, 4, 6]] selected = nms_func( boxes_for_nms, top_scores, pre_max_size=1000, post_max_size=1000, iou_threshold=0.3, ) selected_boxes = box_preds[selected] selected_labels = top_labels[selected] selected_scores = top_scores[selected] box_preds = selected_boxes scores = selected_scores label_preds = selected_labels final_box_preds = box_preds final_scores = scores final_labels = label_preds predictions_dict = { "box3d_lidar": final_box_preds, "scores": final_scores, "label_preds": label_preds, } label_est = KittiLabel() calib = KittiCalib(f"unit_tests/data/test_kittidata/training/calib/{tag}.txt").read_calib_file() for box3d_lidar, label_preds, score in zip( predictions_dict["box3d_lidar"], predictions_dict["label_preds"], predictions_dict["scores"]): obj = KittiObj() obj.type = "Car" if label_preds == 0 else "Pedestrian" xyzwlhry_Flidar = box3d_lidar.cpu().numpy().flatten() bcenter_Flidar = xyzwlhry_Flidar[:3].reshape(-1, 3) bcenter_Fcam = calib.lidar2leftcam(bcenter_Flidar) obj.x, obj.y, obj.z = bcenter_Fcam.flatten() obj.w, obj.l, obj.h, obj.ry = xyzwlhry_Flidar[3:] obj.truncated = 0 obj.occluded = 0 obj.alpha = 0 obj.bbox_l = 0 obj.bbox_t = 0 obj.bbox_r = 0 obj.bbox_b = 0 label_est.add_obj(obj) label_est.current_frame = "Cam2" label_filt = filt_label_by_range(label_est, valid_range=[20, -35.2, -3, 52.8, 12.85, -0.26], calib=calib) self.assertTrue(len(label_filt) == 1)
def rotate_obj(self, label: KittiLabel, pc: np.array, calib: KittiCalib, dry_range: List[float]) -> (KittiLabel, np.array): ''' rotate object along the z axis in the LiDAR frame inputs: label: gt pc: [#pts, >= 3] calib: dry_range: [dry_min, dry_max] in radius returns: label_rot pc_rot Note: If the attemp times is over max_attemp, it will return the original copy ''' assert istype(label, "KittiLabel") dry_min, dry_max = dry_range max_attemp = 10 num_attemp = 0 calib_is_iter = isinstance(calib, list) while True: num_attemp += 1 # copy pc & label pc_ = pc.copy() label_ = KittiLabel() label_.data = [] for obj in label.data: label_.data.append(KittiObj(str(obj))) if num_attemp > max_attemp: print( "KittiAugmentor.rotate_obj: Warning: the attemp times is over {} times," "will return the original copy".format(max_attemp)) break if not calib_is_iter: for obj in label_.data: # generate random number dry = np.random.rand() * (dry_max - dry_min) + dry_min # modify pc_ idx = obj.get_pts_idx(pc_[:, :3], calib) bottom_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, -1) bottom_Flidar = calib.leftcam2lidar(bottom_Fcam) pc_[idx, :3] = apply_tr(pc_[idx, :3], -bottom_Flidar) # obj.ry += dry is correspond to rotz(-dry) # since obj is in cam frame # pc_ is in LiDAR frame pc_[idx, :3] = apply_R(pc_[idx, :3], rotz(-dry)) pc_[idx, :3] = apply_tr(pc_[idx, :3], bottom_Flidar) # modify obj obj.ry += dry else: for obj, calib_ in zip(label_.data, calib): # generate random number dry = np.random.rand() * (dry_max - dry_min) + dry_min # modify pc_ idx = obj.get_pts_idx(pc_[:, :3], calib_) bottom_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, -1) bottom_Flidar = calib_.leftcam2lidar(bottom_Fcam) pc_[idx, :3] = apply_tr(pc_[idx, :3], -bottom_Flidar) # obj.ry += dry is correspond to rotz(-dry) # since obj is in cam frame # pc_ is in LiDAR frame pc_[idx, :3] = apply_R(pc_[idx, :3], rotz(-dry)) pc_[idx, :3] = apply_tr(pc_[idx, :3], bottom_Flidar) # modify obj obj.ry += dry if self.check_overlap(label_): break res_label = KittiLabel() for obj in label_.data: res_label.add_obj(obj) res_label.current_frame = "Cam2" return res_label, pc_
def tr_obj(self, label: KittiLabel, pc: np.array, calib: KittiCalib, dx_range: List[float], dy_range: List[float], dz_range: List[float]) -> (KittiLabel, np.array): ''' translate object in the LiDAR frame inputs: label: gt pc: [#pts, >= 3] calib: dx_range: [dx_min, dx_max] in LiDAR frame dy_range: [dy_min, dy_max] in LiDAR frame dz_range: [dz_min, dz_max] in LiDAR frame returns: label_tr pc_tr Note: If the attemp times is over max_attemp, it will return the original copy ''' assert istype(label, "KittiLabel") dx_min, dx_max = dx_range dy_min, dy_max = dy_range dz_min, dz_max = dz_range max_attemp = 10 num_attemp = 0 calib_is_iter = isinstance(calib, list) while True: num_attemp += 1 # copy pc & label pc_ = pc.copy() label_ = KittiLabel() label_.data = [] for obj in label.data: label_.data.append(KittiObj(str(obj))) if num_attemp > max_attemp: print( "KittiAugmentor.tr_obj: Warning: the attemp times is over {} times," "will return the original copy".format(max_attemp)) break if not calib_is_iter: for obj in label_.data: # gennerate ramdom number dx = np.random.rand() * (dx_max - dx_min) + dx_min dy = np.random.rand() * (dy_max - dy_min) + dy_min dz = np.random.rand() * (dz_max - dz_min) + dz_min # modify pc_ idx = obj.get_pts_idx(pc_[:, :3], calib) dtr = np.array([dx, dy, dz]).reshape(1, -1) pc_[idx, :3] = apply_tr(pc_[idx, :3], dtr) # modify obj bottom_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, -1) bottom_Flidar = calib.leftcam2lidar(bottom_Fcam) bottom_Flidar = apply_tr(bottom_Flidar, dtr) bottom_Fcam = calib.lidar2leftcam(bottom_Flidar) obj.x, obj.y, obj.z = bottom_Fcam.flatten() else: for obj, calib_ in zip(label_.data, calib): # gennerate ramdom number dx = np.random.rand() * (dx_max - dx_min) + dx_min dy = np.random.rand() * (dy_max - dy_min) + dy_min dz = np.random.rand() * (dz_max - dz_min) + dz_min # modify pc_ idx = obj.get_pts_idx(pc_[:, :3], calib_) dtr = np.array([dx, dy, dz]).reshape(1, -1) pc_[idx, :3] = apply_tr(pc_[idx, :3], dtr) # modify obj bottom_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, -1) bottom_Flidar = calib_.leftcam2lidar(bottom_Fcam) bottom_Flidar = apply_tr(bottom_Flidar, dtr) bottom_Fcam = calib_.lidar2leftcam(bottom_Flidar) obj.x, obj.y, obj.z = bottom_Fcam.flatten() if self.check_overlap(label_): break res_label = KittiLabel() for obj in label_.data: res_label.add_obj(obj) res_label.current_frame = "Cam2" return res_label, pc_