Example #1
0
    def get_bbox3dcorners(self):
        '''
        get the 8 corners of the bbox3d in imu frame.
        1.--.2
         |  |
         |  |
        4.--.3 (bottom)

        5.--.6
         |  |
         |  |
        8.--.7 (top)

        IMU Frame:
                      ^x
                      |
                y<----.z
        '''
        # lwh <-> yxz (imu) # lwh <-> xyz
        #  (origin comment) # (new comment)
        l, w, h = self.l, self.w, self.h
        x, z, y = self.x, self.z, self.y
        bottom = np.array([
            [-l/2,  w/2, 0],
            [ l/2,  w/2, 0],
            [ l/2, -w/2, 0],
            [-l/2, -w/2, 0],
        ])
        bottom = utils.apply_R(bottom, utils.rotz(self.ry))
        bottom = utils.apply_tr(bottom, np.array([x, y, z]).reshape(-1, 3))
        top = utils.apply_tr(bottom, np.array([0, 0, h]))
        return np.vstack([bottom, top])
Example #2
0
def get_corner_box_2drot_np(boxes):
    '''
    get corners of 2d rotated boxes.
    @boxes: np.ndarray (M, 5)
        [[x, y, l, w, theta]...] (x, y) is the center coordinate;
        l and w are the scales along x- and y- axes.
        theta is the rotation angle along the z-axis (counter-clockwise).
        2.--.3
         |  |                  ^x
         |  |                  |
        1.--.4 (bottom) y<----.z
    -> corners: np.ndarray (M, 4, 2)
    Note: 35 ms for 100 times (30 boxes)
    '''
    M = boxes.shape[0]
    l = boxes[:, 2:3]
    w = boxes[:, 3:4]
    theta = boxes[:, 4:5]
    p1 = np.hstack((-l / 2.0, w / 2.0, np.zeros_like(l)))
    p2 = np.hstack((l / 2.0, w / 2.0, np.zeros_like(l)))
    p3 = np.hstack((l / 2.0, -w / 2.0, np.zeros_like(l)))
    p4 = np.hstack((-l / 2.0, -w / 2.0, np.zeros_like(l)))
    pts = np.stack((p1, p2, p3, p4), axis=0)
    pts = np.transpose(pts, (1, 0, 2))
    tr_vecs = boxes[:, :2]
    tr_vecs = np.hstack((tr_vecs, np.zeros((M, 1))))
    for i, (tr_, ry_) in enumerate(zip(tr_vecs, theta)):
        pts[i] = apply_R(pts[i], rotz(ry_))
        pts[i] = apply_tr(pts[i], tr_)
    return pts[:, :, :2]
Example #3
0
 def test_by_visualization(self):
     from det3.ops import read_bin
     from det3.visualizer.vis import BEVImage, FVImage
     from tqdm import tqdm
     import numpy as np
     from det3.utils.utils import roty, rotz
     label_path = f"./unit-test/data/ut_UdiLabel_21_bin.json"
     pc_path = f"./unit-test/data/ut_UdiLabel_21.bin"
     calib_path = f"./unit-test/data/ut_UdiLabel_21.txt"
     pc = read_bin(pc_path, dtype=np.float32).reshape(-1, 4)
     label = UdiLabel(label_path).read_label_file()
     calib = UdiCalib(calib_path).read_calib_file()
     bev_img = BEVImage(x_range=(-100, 100),
                        y_range=(-50, 50),
                        grid_size=(0.05, 0.05))
     bev_img.from_lidar(pc, scale=1)
     for obj in label:
         bev_img.draw_box(obj, None, bool_gt=True, text=obj.cls[0])
     bev_img.save(f"./unit-test/result/test_UdiLabel_21.png")
     fv_img = FVImage()
     vcam_T = np.eye(4)
     vcam_T[:3, 3] = np.array([-3, 0, 3])
     vcam_T[:3, :3] = rotz(0) @ roty(np.pi * 0.1)
     calib.vcam_T = vcam_T
     fv_img.from_lidar(calib, pc, scale=2)
     for obj in label:
         fv_img.draw_3dbox(obj, calib, bool_gt=True)
     fv_img.save(f"./unit-test/result/test_UdiLabel_21_fv.png")
     print("Please manually check ./unit-test/result/test_UdiLabel_21.png")
Example #4
0
 def _apply_dry(self, obj, objpc, calib, dry):
     if dry == 0:
         return
     bottom_Fcam = np.array([obj.x, obj.y, obj.z]).reshape(1, -1)
     bottom_Flidar = calib.leftcam2lidar(bottom_Fcam)
     objpc[:, :3] = apply_tr(objpc[:, :3], -bottom_Flidar)
     # obj.ry += dry is correspond to rotz(-dry)
     # since obj is in cam frame
     # pc_ is in LiDAR frame
     objpc[:, :3] = apply_R(objpc[:, :3], rotz(-dry))
     objpc[:, :3] = apply_tr(objpc[:, :3], bottom_Flidar)
     # modify obj
     obj.ry += dry
Example #5
0
 def get_pts_idx(self, pc, calib=None):
     '''
     get points from pc
     inputs:
         pc: (np.array) [#pts, 3]
             in imu frame
     '''
     bottom_Fimu = np.array([self.x, self.y, self.z]).reshape(1, 3)
     center_Fimu = bottom_Fimu + np.array([0, 0, self.h/2.0]).reshape(1, 3)
     pc_ = utils.apply_tr(pc, -center_Fimu)
     pc_ = utils.apply_R(pc_, utils.rotz(-self.ry))
     idx_x = np.logical_and(pc_[:, 0] <= self.l/2.0, pc_[:, 0] >= -self.l/2.0)
     idx_y = np.logical_and(pc_[:, 1] <= self.w/2.0, pc_[:, 1] >= -self.w/2.0)
     idx_z = np.logical_and(pc_[:, 2] <= self.h/2.0, pc_[:, 2] >= -self.h/2.0)
     idx = np.logical_and(idx_x, np.logical_and(idx_y, idx_z))
     return idx
Example #6
0
 def get_pts_idx(self, pc, calib):
     '''
     get points from pc
     inputs:
         pc: (np.array) [#pts, 3]
             point cloud in velodyne frame
         calib (KittiCalib)
     '''
     bottom_Fcam = np.array([self.x, self.y, self.z]).reshape(1, 3)
     center_Fcam = bottom_Fcam + np.array([0, -self.h/2.0, 0]).reshape(1, 3)
     center_Flidar = calib.leftcam2lidar(center_Fcam)
     pc_ = utils.apply_tr(pc, -center_Flidar)
     pc_ = utils.apply_R(pc_, utils.rotz(self.ry+np.pi/2))
     idx_x = np.logical_and(pc_[:, 0] <= self.l/2.0, pc_[:, 0] >= -self.l/2.0)
     idx_y = np.logical_and(pc_[:, 1] <= self.w/2.0, pc_[:, 1] >= -self.w/2.0)
     idx_z = np.logical_and(pc_[:, 2] <= self.h/2.0, pc_[:, 2] >= -self.h/2.0)
     idx = np.logical_and(idx_x, np.logical_and(idx_y, idx_z))
     return idx
Example #7
0
def vis_fn(idx):
    global dataset, data_dir, output_dir
    if dataset == "KITTI":
        from det3.dataloader.kittidata import KittiData
        calib, img, label, pc = KittiData(data_dir, idx).read_data()
    elif dataset == "CARLA":
        from det3.dataloader.carladata import CarlaData
        import numpy as np
        pc_dict, label, calib = CarlaData(data_dir, idx).read_data()
        pc = np.vstack([
            calib.lidar2imu(v, key="Tr_imu_to_{}".format(k))
            for k, v in pc_dict.items()
        ])
    elif dataset == "UDI":
        from det3.dataloader.udidata import UdiData, UdiFrame
        import numpy as np
        udidata = UdiData(data_dir, idx).read_data()
        calib = udidata["calib"]
        label = udidata["label"]
        pc_dict = udidata["lidar"]
        for k, v in pc_dict.items():
            pc_dict[k] = calib.transform(v[:, :3],
                                         source_frame=UdiFrame(
                                             UdiData.lidar_to_frame(k)),
                                         target_frame=UdiFrame("BASE"))
        pc_merge = np.vstack([v for k, v in pc_dict.items()])
        bevimg = BEVImage(x_range=(-70, 70),
                          y_range=(-40, 40),
                          grid_size=(0.05, 0.05))
        bevimg.from_lidar(pc_merge, scale=1)
        for obj in label:
            bevimg.draw_box(obj, calib, bool_gt=True)
        bevimg_img = Image.fromarray(bevimg.data)
        bevimg_img.save(os.path.join(output_dir, idx + '.png'))

        for k, v in pc_dict.items():
            bevimg = BEVImage(x_range=(-70, 70),
                              y_range=(-40, 40),
                              grid_size=(0.05, 0.05))
            bevimg.from_lidar(v, scale=1)
            for obj in label:
                bevimg.draw_box(obj, calib, bool_gt=True)
            bevimg_img = Image.fromarray(bevimg.data)
            bevimg_img.save(os.path.join(output_dir, idx + f'_{k}.png'))

        fv_img = FVImage()
        vcam_T = np.eye(4)
        vcam_T[:3, 3] = np.array([-3, 0, 3])
        vcam_T[:3, :3] = rotz(0) @ roty(np.pi * 0.1)
        calib.vcam_T = vcam_T
        fv_img.from_lidar(calib, pc_merge, scale=2)
        for obj in label:
            fv_img.draw_3dbox(obj, calib, bool_gt=True)
        fv_img.save(os.path.join(output_dir, idx + '_fv.png'))
        return

    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.read_label_file().data:
        bevimg.draw_box(obj, calib, bool_gt=True)
    bevimg_img = Image.fromarray(bevimg.data)
    bevimg_img.save(os.path.join(output_dir, idx + '.png'))
Example #8
0
 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_
Example #9
0
 def rotate_obj(self, label: WaymoLabel, pc: np.array, calib: WaymoCalib,
                dry_range: List[float]) -> (WaymoLabel, np.array):
     '''
     rotate object along the z axis in the LiDAR frame
     inputs:
         label: gt
         pc: [#pts, >= 3] in IMU frame
         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, "WaymoLabel")
     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
         if isinstance(pc, dict):
             pc_ = {k: v.copy() for k, v in pc.items()}
         else:
             pc_ = pc.copy()
         label_ = WaymoLabel()
         label_.data = []
         for obj in label.data:
             label_.data.append(WaymoObj(str(obj)))
         if num_attemp > max_attemp:
             print(
                 "WaymoAugmentor.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:
                 dry = np.random.rand() * (dry_max - dry_min) + dry_min
                 # modify pc
                 bottom_Fimu = np.array([obj.x, obj.y,
                                         obj.z]).reshape(1, -1)
                 if isinstance(pc_, dict):
                     for velo in pc_.keys():
                         idx = obj.get_pts_idx(pc_[velo][:, :3], calib)
                         pc_[velo][idx, :3] = apply_tr(
                             pc_[velo][idx, :3], -bottom_Fimu)
                         pc_[velo][idx, :3] = apply_R(
                             pc_[velo][idx, :3], rotz(dry))
                         pc_[velo][idx, :3] = apply_tr(
                             pc_[velo][idx, :3], bottom_Fimu)
                 else:
                     idx = obj.get_pts_idx(pc_[:, :3], calib)
                     pc_[idx, :3] = apply_tr(pc_[idx, :3], -bottom_Fimu)
                     pc_[idx, :3] = apply_R(pc_[idx, :3], rotz(dry))
                     pc_[idx, :3] = apply_tr(pc_[idx, :3], bottom_Fimu)
                 # modify obj
                 obj.ry += dry
         else:
             for obj, calib_ in zip(label_.data, calib):
                 dry = np.random.rand() * (dry_max - dry_min) + dry_min
                 # modify pc
                 bottom_Fimu = np.array([obj.x, obj.y,
                                         obj.z]).reshape(1, -1)
                 if isinstance(pc_, dict):
                     for velo in pc_.keys():
                         idx = obj.get_pts_idx(pc_[velo][:, :3], calib_)
                         pc_[velo][idx, :3] = apply_tr(
                             pc_[velo][idx, :3], -bottom_Fimu)
                         pc_[velo][idx, :3] = apply_R(
                             pc_[velo][idx, :3], rotz(dry))
                         pc_[velo][idx, :3] = apply_tr(
                             pc_[velo][idx, :3], bottom_Fimu)
                 else:
                     idx = obj.get_pts_idx(pc_[:, :3], calib_)
                     pc_[idx, :3] = apply_tr(pc_[idx, :3], -bottom_Fimu)
                     pc_[idx, :3] = apply_R(pc_[idx, :3], rotz(dry))
                     pc_[idx, :3] = apply_tr(pc_[idx, :3], bottom_Fimu)
                 # modify obj
                 obj.ry += dry
         if self.check_overlap(label_):
             break
     res_label = WaymoLabel()
     for obj in label_.data:
         res_label.add_obj(obj)
     res_label.current_frame = "IMU"
     return res_label, pc_