def test_getpts(self): pc = read_pc_from_bin("./unit-test/data/test_KittiObj_000016.bin") kittiobj = KittiObj("Truck 0.00 2 2.11 125.12 91.71 474.04 253.26 4.02 2.60 16.79 -9.48 2.08 26.41 1.77") kitticalib = KittiCalib("./unit-test/data/test_KittiObj_000016.txt").read_calib_file() pts = kittiobj.get_pts(pc[:, :3], kitticalib) pts_gt = np.load("./unit-test/data/test_KittiObj_getpts_gt.npy") self.assertTrue(np.allclose(pts, pts_gt, rtol=1e-6))
def read_data(self, num_feature=4): ''' read data returns: calib(KittiCalib) image(np.array): [w, h, 3] label(KittiLabel) pc(np.array): [# of points, 4] point cloud in lidar frame. [x, y, z] ^x | y<----.z ''' calib = KittiCalib(self.calib_path).read_calib_file() if self.output_dict["calib"] else None image = utils.read_image(self.image2_path) if self.output_dict["image"] else None label = KittiLabel(self.label2_path).read_label_file() if self.output_dict["label"] else None pc = utils.read_pc_from_bin(self.velodyne_path, num_feature=num_feature) if self.output_dict["velodyne"] else None return calib, image, label, pc
def get_sensor_data(self, query): idx = query info = self._kitti_infos[idx] calib = info["calib"] label = info["label"] tag = info["tag"] pc_reduced = read_pc_from_bin(info["reduced_pc_path"]) res = { "lidar": { "points": pc_reduced, }, "metadata": { "tag": tag }, "calib": calib, "cam": { "label": label } } return res
def test_flip_pc(self): pc = read_pc_from_bin("./unit-test/data/test_KittiObj_000016.bin") calib = KittiCalib("./unit-test/data/test_KittiObj_000016.txt").read_calib_file() label = KittiLabel("./unit-test/data/test_KittiObj_000016_label.txt").read_label_file() bevimg = BEVImage(x_range=(0, 70), y_range=(-40, 40), grid_size=(0.05, 0.05)) bevimg.from_lidar(pc, scale=1) for obj in label.data: bevimg.draw_box(obj, calib, bool_gt=True) bevimg_img = Image.fromarray(bevimg.data) bevimg_img.save(os.path.join('./unit-test/result/', 'test_KittiAugmentor_flippc_origin.png')) kitti_agmtor = KittiAugmentor() label, pc = kitti_agmtor.flip_pc(label, pc, calib) bevimg = BEVImage(x_range=(0, 70), y_range=(-40, 40), grid_size=(0.05, 0.05)) bevimg.from_lidar(pc, scale=1) for obj in label.data: bevimg.draw_box(obj, calib, bool_gt=True) bevimg_img = Image.fromarray(bevimg.data) bevimg_img.save(os.path.join('./unit-test/result/', 'test_KittiAugmentor_flippc_result.png')) print(bcolors.WARNING + "Warning: TestKittiAugmentor:test_flip_pc: You should check the function manully.:)"+ bcolors.ENDC) print(bcolors.WARNING + os.path.join('Warning: TestKittiAugmentor:test_flip_pc: ./unit-test/result/', 'test_KittiAugmentor_flippc_origin.png') + bcolors.ENDC) print(bcolors.WARNING + os.path.join('Warning: TestKittiAugmentor:test_flip_pc: ./unit-test/result/', 'test_KittiAugmentor_flippc_result.png') + bcolors.ENDC)
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 generate(self, points, max_voxels=None): res = self.points_to_voxel(points, self._voxel_size, self._point_cloud_range, self._coor_to_voxelidx, self._max_num_points, max_voxels or self._max_voxels) for k, v in res.items(): if k != "voxel_num": res[k] = v[:res["voxel_num"]] return res if __name__ == "__main__": from det3.utils.utils import read_pc_from_bin from spconv.utils import VoxelGeneratorV2 pc = read_pc_from_bin('/usr/app/data/KITTI/dev/velodyne/000123.bin') voxel_size = [0.05, 0.05, 0.1] point_cloud_range = [0, -40, -3, 70.4, 40, 1] max_num_points = 5 max_voxels = 20000 voxelizer = VoxelizerV1(voxel_size=voxel_size, point_cloud_range=point_cloud_range, max_num_points=max_num_points, max_voxels=max_voxels) voxelizer_gt = VoxelGeneratorV2(voxel_size, point_cloud_range, max_num_points, max_voxels, full_mean=False, block_filtering=False, block_factor=8,
def main(tag, cfg_path, is_val: bool, rawdata_dir, vis_dir): root_dir = Path(__file__).parent log_dir = Path(vis_dir) log_dir.mkdir(parents=True, exist_ok=True) setup_logger(log_dir) cfg = load_config_file(cfg_path=cfg_path, log_dir=log_dir, backup=False) # build net voxelizer = voxelizer_builder.build(voxelizer_cfg=cfg.Voxelizer) anchor_generator = anchor_generator_builder.build(anchor_generator_cfg=cfg.AnchorGenerator) box_coder = box_coder_builder.build(box_coder_cfg=cfg.BoxCoder) similarity_calculator = similarity_calculator_builder.build(similarity_calculator_cfg=cfg.SimilarityCalculator) target_assigner = target_assigner_builder.build(target_assigner_cfg=cfg.TargetAssigner, box_coder=box_coder, anchor_generators=[anchor_generator], region_similarity_calculators=[similarity_calculator]) net = second_builder.build(cfg=cfg.Net, voxelizer=voxelizer, target_assigner=target_assigner).cuda() # build dataloader val_data = dataloader_builder.build(cfg.Net, cfg.ValDataLoader, voxelizer, target_assigner, training=False) val_dataloader = torch.utils.data.DataLoader( val_data, batch_size=cfg.TrainDataLoader["batch_size"], shuffle=False, num_workers=cfg.TrainDataLoader["num_workers"], pin_memory=False, collate_fn=merge_second_batch, worker_init_fn=_worker_init_fn, drop_last=False) if cfg.WeightManager["restore"] is not None: restore(cfg.WeightManager["restore"], net) logger = Logger() t = time.time() net.eval() if is_val: detections = [] result_path_step = Path(vis_dir) result_path_step.mkdir(parents=True, exist_ok=True) logger.log_txt("#################################") logger.log_txt("# EVAL") logger.log_txt("#################################") with torch.no_grad(): for val_example in tqdm(val_dataloader): val_example = example_convert_to_torch(val_example, torch.float32) detection = net(val_example) detections += detection result_dict = val_data.dataset.evaluation(detections, str(result_path_step)) for k, v in result_dict["results"].items(): logger.log_txt("Evaluation {}".format(k)) logger.log_txt(v) logger.log_metrics(result_dict["detail"], -1) detections = val_data.dataset.convert_detection_to_kitti_annos(detections) with open(result_path_step / "result.pkl", 'wb') as f: pickle.dump(detections, f) else: detections = [] # load raw data data_dir = rawdata_dir vis_dir = vis_dir os.makedirs(vis_dir, exist_ok=True) 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) idx_list = os.listdir(pc_dir) idx_list = [idx.split(".")[0] for idx in idx_list] idx_list.sort(key=int) # for item in all data with torch.no_grad(): for idx in tqdm(idx_list): # getitem pc = read_pc_from_bin(os.path.join(pc_dir, idx+".bin")) img = read_image(os.path.join(img2_dir, idx+".png")) input_dict = { "lidar": { "type": "lidar", "points": pc, }, "metadata": { "image_idx": int(idx), "image_shape": None, }, "calib": None, "cam": {} } calib_dict = { 'rect': calib.R0_rect, 'Trv2c': calib.Tr_velo_to_cam, 'P2': np.concatenate([calib.P2, np.array([[0, 0, 0, 1]])], axis=0), } input_dict['calib'] = calib_dict example = val_data.dataset._prep_func(input_dict) if "image_idx" in input_dict["metadata"]: example["metadata"] = input_dict["metadata"] if "anchors_mask" in example: example["anchors_mask"] = example["anchors_mask"].astype(np.uint8) example = merge_second_batch([example]) val_example = example_convert_to_torch(example, torch.float32) detection = net(val_example) detections += detection detections = val_data.dataset.convert_detection_to_kitti_annos(detections) # save results result_path_step = Path(vis_dir) with open(result_path_step / "result.pkl", 'wb') as f: pickle.dump(detections, f)
def sample(self, gt_label, gt_calib): ''' parameters: gt_label: KittiLabel of GT with current_frame == Cam2 gt_calib: KittiCalib of GT sample_dict: {cls: max_num_objs} (deprecated) e.g. { "Car": 15, # It will return the result containing maximum 15 cars (including GT) ... } returns: res_label: KITTI label with current_frame == Cam2 gt_mask : A mask corresponding to the res_label.data (If GT obj, true.) calib_list: a list of calib object corresponding to the res_label.data objpc_list: a list of object p.c. corresponding to the res_label.data Note that for the calib_list and objpc_list, the entries corresponding to GT obj will be None. ''' from det3.dataloader.kittidata import Frame assert gt_label.current_frame == Frame.Cam2 res_label = gt_label.copy() _sample_dict = self._sample_dict.copy() for cls in gt_label.bboxes_name: if cls in _sample_dict.keys(): _sample_dict[cls] = _sample_dict[cls] - 1 if _sample_dict[ cls] > 1 else 1 for k, v in _sample_dict.items(): _sample_dict[k] = np.random.randint(low=0, high=v, dtype=np.int16) gt_mask = [True] * len(gt_label.data) calib_list = [None] * len(gt_label.data) objpc_list = [None] * len(gt_label.data) for cls, num_sample in _sample_dict.items(): if num_sample == 0: continue assert num_sample > 0, "num_sample must be positive integers" cls_samples = self._sampler_dict[cls].sample(num_sample) for cls_sample in cls_samples: attmps = 0 # if origin mode (_set_location & _set_rotation), max_attmps should be 1 max_attemps = 1 if self._sample_param[ "mode"] == "origin" else 10 while attmps < max_attemps: obj = cls_sample["box3d_cam"].copy() calib = cls_sample["calib"] objpc = read_pc_from_bin(cls_sample["gtpc_path"]) self._set_location(obj, calib, objpc, self._sample_param) self._set_rotation(obj, calib, objpc, self._sample_param) if not self._have_collision(res_label, obj): res_label.add_obj(obj) gt_mask.append(False) calib_list.append(calib) objpc_list.append(objpc) break else: attmps += 1 # if attmps >= max_attemps: # Logger.log_txt(f"DataBaseSamplerV3:sample: exceed "+ # f"max_attemps: {max_attemps}.") res_dict = { "res_label": res_label, "gt_mask": gt_mask, "calib_list": calib_list, "objpc_list": objpc_list, "num_obj": len(objpc_list) } return res_dict
db_infos = load_pickle("/usr/app/data/MyKITTI/KITTI_dbinfos_train.pkl") train_infos = load_pickle("/usr/app/data/MyKITTI/KITTI_infos_train.pkl") sample_dict = cfg.TrainDataLoader["DBSampler"]["sample_dict"] sample_param = cfg.TrainDataLoader["DBSampler"]["sample_param"] dbsampler = DataBaseSamplerV3(db_infos, db_prepor=db_prepor, sample_dict=sample_dict, sample_param=sample_param) for j in range(len(train_infos)): train_info = train_infos[j] calib = train_info["calib"] label = train_info["label"] tag = train_info["tag"] print(tag) pc_reduced = read_pc_from_bin(train_info["reduced_pc_path"]) orgbev = BEVImage(x_range=(0, 70), y_range=(-40, 40), grid_size=(0.1, 0.1)) orgfv = FVImage() orgbev.from_lidar(pc_reduced) orgfv.from_lidar(calib, pc_reduced) for obj in label.data: orgbev.draw_box(obj, calib) orgfv.draw_3dbox(obj, calib) sample_res = dbsampler.sample(gt_label=label, gt_calib=calib) for i in range(sample_res["num_obj"]): obj = sample_res["res_label"].data[i] obj_calib = sample_res["calib_list"][i] objpc = sample_res["objpc_list"][i]