def test_read_label_file(self): label = KittiLabel('./unit-test/data/test_KittiLabel_000003.txt').read_label_file(no_dontcare=True) self.assertEqual(len(label.data), 1) self.assertEqual(len(list(filter(lambda obj: obj.type == "DontCare", label.data))), 0) label = KittiLabel('./unit-test/data/test_KittiLabel_000003.txt').read_label_file(no_dontcare=False) self.assertEqual(len(label.data), 3) self.assertEqual(len(list(filter(lambda obj: obj.type == "DontCare", label.data))), 2)
def ensemble_pseudo_anno_and_gt(gt_label_dir: str, detection_dir: str, old_classes: List[str], pseudo_anno_dir: str): ''' Ensemble detection results and ground-truth labels by 1. remove old-class annotations from gt_label 2. remove scores from detection result 3. merge this two together and save results to pseudo_anno_dir ''' gt_label_list = os.listdir(gt_label_dir) detection_list = os.listdir(detection_dir) from det3.dataloader.kittidata import KittiLabel from det3.utils.utils import write_str_to_file for label_name in detection_list: gt_label = KittiLabel(os.path.join( gt_label_dir, label_name)).read_label_file(no_dontcare=False) detection = KittiLabel(os.path.join(detection_dir, label_name)).read_label_file() new_label = KittiLabel() for obj in detection.data: obj.score = None new_label.add_obj(obj) for obj in gt_label.data: if obj.type in old_classes: continue new_label.add_obj(obj) write_str_to_file(str(new_label), os.path.join(pseudo_anno_dir, label_name)) return
def test_equal(self): label1 = KittiLabel('./unit-test/data/test_KittiLabel_000012.txt').read_label_file(no_dontcare=True) label2 = KittiLabel('./unit-test/data/test_KittiLabel_000012.txt').read_label_file(no_dontcare=True) self.assertTrue(label1.equal(label1, ['Car', 'Van'], rtol=1e-5)) self.assertTrue(label1.equal(label2, ['Car', 'Van'], rtol=1e-5)) self.assertTrue(label2.equal(label1, ['Car', 'Van'], rtol=1e-5)) self.assertTrue(label2.equal(label2, ['Car', 'Van'], rtol=1e-5)) label1 = KittiLabel('./unit-test/data/test_KittiLabel_000012.txt').read_label_file(no_dontcare=True) label2 = KittiLabel('./unit-test/data/test_KittiLabel_000003.txt').read_label_file(no_dontcare=True) self.assertTrue(not label1.equal(label2, ['Car', 'Van'], rtol=1e-5)) self.assertTrue(not label2.equal(label1, ['Car', 'Van'], rtol=1e-5))
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 filt_label_by_num_of_pts(pc, calib, label, min_num_pts): ''' @pc: np.ndarray ''' if min_num_pts < 0: return label is_iter = isinstance(calib, list) if istype(label, "CarlaLabel"): res = CarlaLabel() elif istype(label, "WaymoLabel"): res = WaymoLabel() elif istype(label, "KittiLabel"): res = KittiLabel() else: raise NotImplementedError res.data = [] # It is really important, # otherwise the "for obj in label.data" of the next stage will raise a problem. assert not isinstance(pc, dict) if not is_iter: for obj in label.data: num_pts = obj.get_pts_idx(pc, calib).sum() if num_pts > min_num_pts: res.add_obj(obj) else: for obj, calib_ in zip(label.data, calib): num_pts = obj.get_pts_idx(pc, calib_).sum() if num_pts > min_num_pts: res.add_obj(obj) res.current_frame = label.current_frame return res
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 filt_label_by_range(label, valid_range, calib=None): ''' @label: CarlaLabel @valid_range: [min_x, min_y, min_z, max_x, max_y, max_z] FIMU ''' min_x, min_y, min_z, max_x, max_y, max_z = valid_range is_iter = isinstance(calib, list) if istype(label, "CarlaLabel"): res = CarlaLabel() elif istype(label, "WaymoLabel"): res = WaymoLabel() elif istype(label, "KittiLabel"): res = KittiLabel() else: raise NotImplementedError res.data = [] # It is really important, # otherwise the "for obj in label.data" of the next stage will raise a problem. if not is_iter: for obj in label.data: if istype(label, "CarlaLabel") or istype(label, "WaymoLabel"): imu_pt = np.array([obj.x, obj.y, obj.z + obj.h / 2.0]).reshape(1, 3) if (min_x <= imu_pt[0, 0] <= max_x and min_y <= imu_pt[0, 1] <= max_y and min_z <= imu_pt[0, 2] <= max_z): res.add_obj(obj) elif istype(label, "KittiLabel"): bcenter_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, 3) bcenter_Flidar = calib.leftcam2lidar(bcenter_Fcam) center_Flidar = bcenter_Flidar + np.array([0, 0, obj.h / 2.0 ]).reshape(1, 3) if (min_x <= center_Flidar[0, 0] <= max_x and min_y <= center_Flidar[0, 1] <= max_y and min_z <= center_Flidar[0, 2] <= max_z): res.add_obj(obj) else: raise NotImplementedError else: for obj, calib_ in zip(label.data, calib): if istype(label, "CarlaLabel") or istype(label, "WaymoLabel"): imu_pt = np.array([obj.x, obj.y, obj.z + obj.h / 2.0]).reshape(1, 3) if (min_x <= imu_pt[0, 0] <= max_x and min_y <= imu_pt[0, 1] <= max_y and min_z <= imu_pt[0, 2] <= max_z): res.add_obj(obj) elif istype(label, "KittiLabel"): bcenter_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, 3) bcenter_Flidar = calib_.leftcam2lidar(bcenter_Fcam) center_Flidar = bcenter_Flidar + np.array([0, 0, obj.h / 2.0 ]).reshape(1, 3) if (min_x <= center_Flidar[0, 0] <= max_x and min_y <= center_Flidar[0, 1] <= max_y and min_z <= center_Flidar[0, 2] <= max_z): res.add_obj(obj) else: raise NotImplementedError res.current_frame = label.current_frame return res
def get_classes(label_dir:str, idx_list:list): ''' Get all the classes by going through all the label files. ''' res = [] for idx in idx_list: label = KittiLabel(label_path=f"{label_dir}/{idx}.txt").read_label_file() for cls in label.bboxes_name: if cls not in res: res.append(cls) return res
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 validate(data_dir: str, idx: str, label_Fcam: KittiLabel, save_dir: str): ''' To validate the function of this script inputs: data_dir: dir of Carla data idx: "000000.txt" label_Fcam: result after converting save_dir: dir for saving visulizaition figures Note: the following code is dangerous, and should not be used in other place. ''' from det3.dataloader.carladata import CarlaData from det3.visualizer.vis import FVImage, BEVImage from det3.dataloader.kittidata import KittiObj, KittiLabel, KittiCalib from PIL import Image tag = idx.split(".")[0] pc, label, calib = CarlaData(data_dir, tag).read_data() bevimg = BEVImage(x_range=(-100, 100), y_range=(-50, 50), grid_size=(0.05, 0.05)) bevimg.from_lidar(np.vstack([pc['velo_top']]), scale=1) fvimg = FVImage() fvimg.from_lidar(calib, np.vstack([pc['velo_top']])) for obj in label.read_label_file().data: if obj.type == 'Car': bevimg.draw_box(obj, calib, bool_gt=True) fvimg.draw_box(obj, calib, bool_gt=True) kittilabel = KittiLabel() kittilabel.data = [] kitticalib = KittiCalib(None) kitticalib.P2 = np.array([[450, 0., 600, 0.], [0., 450, 180, 0.], [0., 0., 1, 0.]]) kitticalib.R0_rect = np.eye(4) kitticalib.Tr_velo_to_cam = np.zeros((4, 4)) kitticalib.Tr_velo_to_cam[0, 1] = -1 kitticalib.Tr_velo_to_cam[1, 2] = -1 kitticalib.Tr_velo_to_cam[2, 0] = 1 kitticalib.Tr_velo_to_cam[3, 3] = 1 kitticalib.data = [] for obj in label_Fcam.data: kittilabel.data.append(KittiObj(str(obj))) for obj in kittilabel.data: if obj.type == 'Car': fvimg.draw_box(obj, kitticalib, bool_gt=False) bevimg.draw_box(obj, kitticalib, bool_gt=False) bevimg_img = Image.fromarray(bevimg.data) bevimg_img.save(os.path.join(save_dir, "{}_bev.png".format(tag))) fvimg_img = Image.fromarray(fvimg.data) fvimg_img.save(os.path.join(save_dir, "{}_fv.png".format(tag)))
def filt_label_by_cls(label, keep_classes): if istype(label, "CarlaLabel"): res = CarlaLabel() elif istype(label, "WaymoLabel"): res = WaymoLabel() elif istype(label, "KittiLabel"): res = KittiLabel() else: raise NotImplementedError res.data = [] # It is really important, # otherwise the "for obj in label.data" of the next stage will raise a problem. for obj in label.data: if obj.type in keep_classes: res.add_obj(obj) res.current_frame = label.current_frame return res
def get_classes(label_dir: str, idx_list: list, dataset: str): ''' Get all the classes by going through all the label files. ''' res = [] for idx in idx_list: if dataset == "carla": label = CarlaLabel( label_path=f"{label_dir}/{idx}.txt").read_label_file() elif dataset == "waymo": label = WaymoLabel( label_path=f"{label_dir}/{idx}.txt").read_label_file() elif dataset == "kitti": label = KittiLabel( label_path=f"{label_dir}/{idx}.txt").read_label_file() else: raise NotImplementedError for cls in label.bboxes_name: if cls not in res: res.append(cls) return res
def main(is_val, data_dir, vis_dir, result_path): dt_data = pickle.load(open(result_path, 'rb')) save_dir = vis_dir if is_val: for dt in tqdm(dt_data): idx = dt['metadata']['image_idx'] idx = "{:06d}".format(idx) calib, img, label, pc = KittiData(root_dir=data_dir, idx=idx).read_data() label_est = KittiLabel() label_est.data = [] num_dt = len(dt['name']) for i in range(num_dt): obj = KittiObj() obj.type = dt['name'][i] obj.truncated = dt['truncated'][i] obj.occluded = dt['occluded'][i] obj.alpha = dt['alpha'][i] obj.bbox_l, obj.bbox_t, obj.bbox_r, obj.bbox_b = dt['bbox'][i] obj.l, obj.h, obj.w = dt['dimensions'][i] obj.x, obj.y, obj.z = dt['location'][i] obj.ry = dt['rotation_y'][i] obj.score = dt['score'][i] label_est.data.append(obj) fvimg = FVImage() fvimg.from_image(img) for obj in label.data: if (obj.x > obj.z) or (-obj.x > obj.z): continue if obj.type in ['Car', 'Van']: fvimg.draw_3dbox(obj, calib, bool_gt=True, width=3) for obj in label_est.data: if (obj.x > obj.z) or (-obj.x > obj.z): continue fvimg.draw_3dbox(obj, calib, bool_gt=False, width=2, c=(255, 255, int(255 * obj.score), 255)) fvimg_img = Image.fromarray(fvimg.data) fvimg_img.save(os.path.join(save_dir, "fv_{}.png".format(idx))) else: pc_dir = os.path.join(data_dir, "velodyne_points", "data") img2_dir = os.path.join(data_dir, "image_02", "data") calib_dir = os.path.join(data_dir, "calib") calib = read_calib(calib_dir) for dt in tqdm(dt_data): idx = dt['metadata']['image_idx'] idx = "{:010d}".format(idx) pc = read_pc_from_bin(os.path.join(pc_dir, idx + ".bin")) img = read_image(os.path.join(img2_dir, idx + ".png")) label_est = KittiLabel() label_est.data = [] num_dt = len(dt['name']) for i in range(num_dt): obj = KittiObj() obj.type = dt['name'][i] obj.truncated = dt['truncated'][i] obj.occluded = dt['occluded'][i] obj.alpha = dt['alpha'][i] obj.bbox_l, obj.bbox_t, obj.bbox_r, obj.bbox_b = dt['bbox'][i] obj.l, obj.h, obj.w = dt['dimensions'][i] obj.x, obj.y, obj.z = dt['location'][i] obj.ry = dt['rotation_y'][i] obj.score = dt['score'][i] label_est.data.append(obj) fvimg = FVImage() fvimg.from_image(img) # for obj in label.data: # if obj.type in ['Car', 'Van']: # fvimg.draw_3dbox(obj, calib, bool_gt=True, width=3) for obj in label_est.data: if (obj.x > obj.z) or (-obj.x > obj.z): continue fvimg.draw_3dbox(obj, calib, bool_gt=False, width=2, c=(255, 255, int(obj.score * 255), 255)) fvimg_img = Image.fromarray(fvimg.data) fvimg_img.save(os.path.join(save_dir, "fv_{}.png".format(idx)))
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_
def test_init(self): kittilabel = KittiLabel('./unit-test/data/test_KittiLabel_000003.txt') self.assertEqual(kittilabel.data, None)
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 test_targets(self): def limit_period_torch(val, offset=0.5, period=np.pi): return val - torch.floor(val / period + offset) * period import torch import torch.nn as nn from det3.methods.second.ops.torch_ops import rotate_nms from det3.dataloader.kittidata import KittiCalib for i, data in enumerate(self.dataloader): if i == 2: break else: continue label = data["metadata"][0]["label"] tag = data["metadata"][0]["tag"] 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() # pred_dict = { # "cls_preds": cls_pred * 10, # "box_preds": box_pred # } # box_coder = self.box_coder # from det3.ops import write_pkl # write_pkl({"pred_dict": pred_dict, "box_coder": box_coder}, "test_model_est.pkl") box_pred = self.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, } from det3.dataloader.kittidata import KittiObj, KittiLabel label_gt = KittiLabel() label_est = KittiLabel() calib = KittiCalib(f"unit_tests/data/test_kittidata/training/calib/{tag}.txt").read_calib_file() for obj_str in label.split("\n"): if len(obj_str) == 0: continue obj = KittiObj(obj_str) if obj.type not in ["Car", "Pedestrian"]: continue bcenter_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(-1, 3) bcenter_Flidar = calib.leftcam2lidar(bcenter_Fcam) center_Flidar = bcenter_Flidar + np.array([0, 0, obj.h/2.0]).reshape(-1, 3) if (center_Flidar[0, 0] < 0 or center_Flidar[0, 0] > 52.8 or center_Flidar[0, 1] < -30 or center_Flidar[0, 1] > 30 or center_Flidar[0, 2] < -3 or center_Flidar[0, 2] > 1): continue 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_gt.add_obj(obj) 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) self.assertTrue(label_gt.equal(label_est, acc_cls=["Car", "Pedestrian"], rtol=1e-2))
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_