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 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 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_
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_