Beispiel #1
0
    # >>>>>>>>>>>>>>>>>>>>>>>>>> 3D IoU & boundary computation <<<<<<<<<<<<<<<<<<<<<<<<<<< #
    with open(root_dset + "/pickle/{}.pkl".format(args.item), "rb") as f:
        all_factors = pickle.load(f)
    with open(root_dset + "/pickle/{}_corners.pkl".format(args.item),
              "rb") as fc:
        all_corners = pickle.load(fc)
    bbox3d_all = {}

    for instance in test_ins:
        if args.item in ['drawer']:
            target_order = infos.datasets[args.item].spec_map[instance]
            path_urdf = my_dir + '/dataset/sapien/urdf/' + args.item + '/' + instance
            urdf_ins = get_urdf_mobility(path_urdf, False)
            joint_rpy = urdf_ins['joint']['rpy'][target_order[0]]
            rot_mat = euler_matrix(joint_rpy[0], joint_rpy[1],
                                   joint_rpy[2])[:3, :3]

        norm_factors = all_factors[instance]
        norm_corners = all_corners[instance]
        bbox3d_per_part = [None] * num_parts
        for p in range(num_parts):
            norm_factor = norm_factors[p + 1]
            norm_corner = norm_corners[p + 1]
            nocs_corner = np.copy(norm_corner)
            nocs_corner[0] = np.array([0.5, 0.5, 0.5]).reshape(
                1, 3) - 0.5 * (norm_corner[1] - norm_corner[0]) * norm_factor
            nocs_corner[1] = np.array([0.5, 0.5, 0.5]).reshape(
                1, 3) + 0.5 * (norm_corner[1] - norm_corner[0]) * norm_factor
            if args.item in ['drawer']:
                nocs_corner[0] = np.dot(nocs_corner[0].reshape(1, 3) - 0.5,
                                        rot_mat.T) + 0.5
Beispiel #2
0
    def __preprocess_and_save__(self, index):
        obj_category = self.list_obj[index]
        ins = self.list_instance[index]
        obj = self.objnamelist.index(obj_category)
        art_status = self.list_status[index]
        frame_order = self.list_rank[index]
        label = self.list_label[index]
        h5_save_path = self.root_dir + '/hdf5/' + obj_category + '/' + ins + '/' + art_status
        if (not os.path.exists(h5_save_path)):
            os.makedirs(h5_save_path)
        h5_save_name = h5_save_path + '/{}.h5'.format(frame_order)
        num_parts = self.urdf_dict[obj_category][ins]['num_links']

        model_offsets = self.urdf_dict[obj_category][ins]['link']
        joint_offsets = self.urdf_dict[obj_category][ins]['joint']

        parts_model_point = [None] * num_parts
        parts_world_point = [None] * num_parts
        parts_target_point = [None] * num_parts

        parts_cloud_cam = [None] * num_parts
        parts_cloud_world = [None] * num_parts
        parts_cloud_canon = [None] * num_parts
        parts_cloud_urdf = [None] * num_parts
        parts_cloud_norm = [None] * num_parts

        parts_world_pos = [None] * num_parts
        parts_world_orn = [None] * num_parts
        parts_urdf_pos = [None] * num_parts
        parts_urdf_orn = [None] * num_parts
        parts_urdf_box = [None] * num_parts

        parts_model2world = [None] * num_parts
        parts_canon2urdf = [None] * num_parts
        parts_target_r = [None] * num_parts
        parts_target_t = [None] * num_parts

        parts_mask = [None] * num_parts
        choose_x = [None] * num_parts
        choose_y = [None] * num_parts
        choose_to_whole = [None] * num_parts

        # rgb/depth/label
        print('current image: ', self.list_rgb[index])
        img = Image.open(self.list_rgb[index])
        img = np.array(img)  #.astype(np.uint8)
        depth = np.array(h5py.File(self.list_depth[index], 'r')['data'])
        label = np.array(Image.open(self.list_label[index]))

        # pose infos
        pose_dict = self.meta_dict[obj_category][ins][art_status][
            'frame_{}'.format(frame_order)]
        urdf_dict = self.urdf_dict[obj_category][ins]
        viewMat = np.array(pose_dict['viewMat']).reshape(4, 4).T
        projMat = np.array(pose_dict['projMat']).reshape(4, 4).T

        parts_world_pos[0] = np.array([0, 0, 0])
        parts_world_orn[0] = np.array([0, 0, 0, 1])
        for link in range(0, num_parts):
            if link > 0:
                parts_world_pos[link] = np.array(
                    pose_dict['obj'][link - 1][4]).astype(np.float32)
                parts_world_orn[link] = np.array(
                    pose_dict['obj'][link - 1][5]).astype(np.float32)

        for link in range(num_parts):
            if link == 1 and num_parts == 2:
                parts_urdf_pos[link] = np.array(urdf_dict['joint']['xyz'][
                    link -
                    1])  # todo, accumulate joints pffsets != link offsets
            else:
                parts_urdf_pos[link] = -np.array(
                    urdf_dict['link']['xyz'][link])
            parts_urdf_orn[link] = np.array(urdf_dict['link']['rpy'][link])

        for k in range(num_parts):
            center_world_orn = parts_world_orn[k]
            center_world_orn = np.array([
                center_world_orn[3], center_world_orn[0], center_world_orn[1],
                center_world_orn[2]
            ])
            my_model2world_r = quaternion_matrix(
                center_world_orn)[:4, :4]  # [w, x, y, z]
            my_model2world_t = parts_world_pos[k]
            my_model2world_mat = np.copy(my_model2world_r)
            for m in range(3):
                my_model2world_mat[m, 3] = my_model2world_t[m]
            my_world2camera_mat = viewMat
            my_camera2clip_mat = projMat
            my_model2camera_mat = np.dot(my_world2camera_mat,
                                         my_model2world_mat)
            parts_model2world[k] = my_model2world_mat

        # depth to cloud data
        mask = np.array((label[:, :] < num_parts) & (label[:, :] > -1)).astype(
            np.uint8)
        mask_whole = np.copy(mask)
        for n in range(num_parts):
            parts_mask[n] = np.array((label[:, :] == (n))).astype(np.uint8)
            choose_to_whole[n] = np.where(parts_mask[n] > 0)

        #>>>>>>>>>>------- rendering target pcloud from depth image --------<<<<<<<<<#
        # first get projected map
        ymap = self.ymap
        xmap = self.xmap
        h = self.height
        w = self.width
        u_map = ymap * 2 / w - 1
        v_map = (512 - xmap) * 2 / h - 1
        v1_map = xmap * 2 / h - 1
        w_channel = -depth
        projected_map = np.stack(
            [u_map * w_channel, v_map * w_channel, depth,
             w_channel]).transpose([1, 2, 0])
        projected_map1 = np.stack(
            [u_map * w_channel, v1_map * w_channel, depth,
             w_channel]).transpose([1, 2, 0])
        for s in range(num_parts):
            x_set, y_set = choose_to_whole[s]
            if len(x_set) < 10:
                print('data is empty, skipping!!!')
                return None
            else:
                choose_x[s] = x_set
                choose_y[s] = y_set

            # ---------------> from projected map into target part_cloud
            # order: cam->world->canon)
            projected_points = projected_map[
                choose_x[s][:].astype(np.uint16),
                choose_y[s][:].astype(np.uint16), :]
            projected_points = np.reshape(projected_points, [-1, 4])
            depth_channel = -projected_points[:, 3:4]
            cloud_cam = np.dot(
                projected_points[:, 0:2] -
                np.dot(depth_channel, projMat[0:2, 2:3].T),
                np.linalg.pinv(projMat[:2, :2].T))

            projected_points1 = projected_map1[
                choose_x[s][:].astype(np.uint16),
                choose_y[s][:].astype(np.uint16), :]
            projected_points1 = np.reshape(projected_points1, [-1, 4])
            cloud_cam_real = np.dot(
                projected_points1[:, 0:2] -
                np.dot(depth_channel, projMat[0:2, 2:3].T),
                np.linalg.pinv(projMat[:2, :2].T))
            cloud_cam_real = np.concatenate((cloud_cam_real, depth_channel),
                                            axis=1)

            cloud_cam = np.concatenate((cloud_cam, depth_channel), axis=1)
            cloud_cam_full = np.concatenate(
                (cloud_cam, np.ones((cloud_cam.shape[0], 1))), axis=1)

            # modify, todo
            camera_pose_mat = np.linalg.pinv(viewMat.T)
            camera_pose_mat[:3, :] = -camera_pose_mat[:3, :]
            cloud_world = np.dot(cloud_cam_full, camera_pose_mat)
            cloud_canon = np.dot(cloud_world,
                                 np.linalg.pinv(parts_model2world[s].T))

            # canon points should be points coordinates centered in the inertial frame
            parts_cloud_cam[s] = cloud_cam_real[:, :3]
            parts_cloud_world[s] = cloud_world[:, :3]
            parts_cloud_canon[s] = cloud_canon[:, :3]

        for k in range(num_parts):
            center_joint_orn = parts_urdf_orn[k]
            my_canon2urdf_r = euler_matrix(
                center_joint_orn[0], center_joint_orn[1],
                center_joint_orn[2])[:4, :4]  # [w, x, y, z]
            my_canon2urdf_t = parts_urdf_pos[k]
            my_canon2urdf_mat = my_canon2urdf_r
            for m in range(3):
                my_canon2urdf_mat[m, 3] = my_canon2urdf_t[m]
            part_points_space = np.concatenate(
                (parts_cloud_canon[k],
                 np.ones((parts_cloud_canon[k].shape[0], 1))),
                axis=1)
            parts_cloud_urdf[k] = np.dot(part_points_space,
                                         my_canon2urdf_mat.T)

        #>>>>>>>>>>>>>>> go to PNCS space
        for link in range(num_parts):
            tight_w = max(parts_cloud_urdf[link][:, 0]) - min(
                parts_cloud_urdf[link][:, 0])
            tight_l = max(parts_cloud_urdf[link][:, 1]) - min(
                parts_cloud_urdf[link][:, 1])
            tight_h = max(parts_cloud_urdf[link][:, 2]) - min(
                parts_cloud_urdf[link][:, 2])
            norm_factor = np.sqrt(1) / np.sqrt(tight_w**2 + tight_l**2 +
                                               tight_h**2)
            base_p = np.array([
                min(parts_cloud_urdf[link][:, 0]),
                min(parts_cloud_urdf[link][:, 1]),
                min(parts_cloud_urdf[link][:, 2])
            ]).reshape(1, 3)
            extre_p = np.array([
                max(parts_cloud_urdf[link][:, 0]),
                max(parts_cloud_urdf[link][:, 1]),
                max(parts_cloud_urdf[link][:, 2])
            ]).reshape(1, 3)
            center_p = (extre_p - base_p) / 2 * norm_factor

            parts_cloud_norm[link] = (parts_cloud_urdf[link][:, :3] -
                                      base_p) * norm_factor + np.array(
                                          [0.5, 0.5, 0.5]).reshape(
                                              1, 3) - center_p.reshape(1, 3)

        x_set_pcloud = np.concatenate(choose_x, axis=0)
        y_set_pcloud = np.concatenate(choose_y, axis=0)

        # save into h5 for rgb_img, input_pts, mask, correpsonding urdf_points
        print('Writing to ', h5_save_name)
        hf = h5py.File(h5_save_name, 'w')
        hf.create_dataset('rgb', data=img)
        hf.create_dataset('mask', data=mask)
        cloud_cam = hf.create_group('gt_points')
        for part_i, points in enumerate(parts_cloud_cam):
            cloud_cam.create_dataset(str(part_i), data=points)
        coord_gt = hf.create_group('gt_coords')
        for part_i, points in enumerate(parts_cloud_urdf):
            coord_gt.create_dataset(str(part_i), data=points)
        hf.close()

        ################# for debug only, let me know if you have questions #################
        if self.is_debug:
            figure = plt.figure(dpi=200)
            ax = plt.subplot(121)
            plt.imshow(img)
            plt.title('RGB image')
            ax1 = plt.subplot(122)
            plt.imshow(depth)
            plt.title('depth image')
            plt.show()
            plot3d_pts(
                [parts_cloud_cam],
                [['part {}'.format(i) for i in range(len(parts_cloud_cam))]],
                s=5,
                title_name=['camera coords'])
            plot3d_pts(
                [parts_cloud_world],
                [['part {}'.format(i) for i in range(len(parts_cloud_world))]],
                s=5,
                title_name=['world coords'])
            plot3d_pts(
                [parts_cloud_canon],
                [['part {}'.format(i) for i in range(len(parts_cloud_canon))]],
                s=5,
                title_name=['canon coords'])
            plot3d_pts(
                [parts_cloud_urdf],
                [['part {}'.format(i) for i in range(len(parts_cloud_urdf))]],
                s=5,
                title_name=['urdf coords'])

        return None
Beispiel #3
0
    def __preprocess_and_save__(self, index):
        obj_category = self.list_obj[index]
        ins = self.list_instance[index]
        obj = self.objnamelist.index(obj_category)
        art_status = self.list_status[index]
        frame_order = self.list_rank[index]
        label = self.list_label[index]
        h5_save_path = (self.root_dir + "/hdf5/" + obj_category + "/" + ins +
                        "/" + art_status)
        if not os.path.exists(h5_save_path):
            os.makedirs(h5_save_path)
        h5_save_name = h5_save_path + "/{}.h5".format(frame_order)
        num_parts = self.urdf_dict[obj_category][ins]["num_links"]
        new_num_parts = num_parts - 1

        model_offsets = self.urdf_dict[obj_category][ins]["link"]
        joint_offsets = self.urdf_dict[obj_category][ins]["joint"]

        parts_model_point = [None] * new_num_parts
        parts_world_point = [None] * new_num_parts
        parts_target_point = [None] * new_num_parts

        parts_cloud_cam = [None] * new_num_parts
        parts_cloud_world = [None] * new_num_parts
        parts_cloud_canon = [None] * new_num_parts
        parts_cloud_urdf = [None] * new_num_parts
        parts_cloud_norm = [None] * new_num_parts

        parts_world_pos = [None] * new_num_parts
        parts_world_orn = [None] * new_num_parts
        parts_urdf_pos = [None] * new_num_parts
        parts_urdf_orn = [None] * new_num_parts
        parts_urdf_box = [None] * new_num_parts

        parts_model2world = [None] * new_num_parts
        parts_canon2urdf = [None] * new_num_parts
        parts_target_r = [None] * new_num_parts
        parts_target_t = [None] * new_num_parts

        parts_mask = [None] * new_num_parts
        choose_x = [None] * new_num_parts
        choose_y = [None] * new_num_parts
        choose_to_whole = [None] * new_num_parts

        # rgb/depth/label
        print("current image: ", self.list_rgb[index])
        img = Image.open(self.list_rgb[index])
        img = np.array(img)  # .astype(np.uint8)
        depth = np.array(h5py.File(self.list_depth[index], "r")["data"])
        label = np.array(Image.open(self.list_label[index]))

        # pose infos
        pose_dict = self.meta_dict[obj_category][ins][art_status][
            "frame_{}".format(frame_order)]
        urdf_dict = self.urdf_dict[obj_category][ins]
        viewMat = np.array(pose_dict["viewMat"]).reshape(4, 4).T
        projMat = np.array(pose_dict["projMat"]).reshape(4, 4).T

        parts_world_pos[0] = np.array([0, 0, 0])
        parts_world_orn[0] = np.array([0, 0, 0, 1])
        # SAPIEN: skip the virtual base part
        for link in range(1, num_parts):
            if link > 0:
                parts_world_pos[link - 1] = np.array(
                    pose_dict["obj"][link - 1][4]).astype(np.float32)
                parts_world_orn[link - 1] = np.array(
                    pose_dict["obj"][link - 1][5]).astype(np.float32)

        for link in range(1, num_parts):
            if link == 1 and num_parts == 2:
                parts_urdf_pos[link] = np.array(urdf_dict["joint"]["xyz"][
                    link -
                    1])  # todo, accumulate joints offsets != link offsets
            else:
                # Only change this branch for SAPIEN data
                parts_urdf_pos[link - 1] = -np.array(
                    urdf_dict["link"]["xyz"][link][0])
            parts_urdf_orn[link - 1] = np.array(
                urdf_dict["link"]["rpy"][link][0])

        for k in range(1, num_parts):
            center_world_orn = parts_world_orn[k - 1]
            center_world_orn = np.array([
                center_world_orn[3],
                center_world_orn[0],
                center_world_orn[1],
                center_world_orn[2],
            ])
            my_model2world_r = quaternion_matrix(
                center_world_orn)[:4, :4]  # [w, x, y, z]
            my_model2world_t = parts_world_pos[k - 1]
            my_model2world_mat = np.copy(my_model2world_r)
            for m in range(3):
                my_model2world_mat[m, 3] = my_model2world_t[m]
            my_world2camera_mat = viewMat
            my_camera2clip_mat = projMat
            my_model2camera_mat = np.dot(my_world2camera_mat,
                                         my_model2world_mat)
            parts_model2world[k - 1] = my_model2world_mat

        # depth to cloud data
        # SAPIEN, throw away the label 0 for virtual base link
        mask = np.array((label[:, :] < num_parts) & (label[:, :] > 0)).astype(
            np.uint8)
        mask_whole = np.copy(mask)
        for n in range(1, num_parts):
            parts_mask[n - 1] = np.array((label[:, :] == (n))).astype(np.uint8)
            choose_to_whole[n - 1] = np.where(parts_mask[n - 1] > 0)

        # >>>>>>>>>>------- rendering target pcloud from depth image --------<<<<<<<<<#
        # first get projected map
        # ymap = self.ymap
        # xmap = self.xmap
        # h = self.height
        # w = self.width
        # u_map = ymap * 2 / w - 1
        # v_map = (512 - xmap) * 2 / h - 1
        # v1_map = xmap * 2 / h - 1
        # w_channel = -depth
        # projected_map = np.stack(
        #     [u_map * w_channel, v_map * w_channel, depth, w_channel]
        # ).transpose([1, 2, 0])
        # projected_map1 = np.stack(
        #     [u_map * w_channel, v1_map * w_channel, depth, w_channel]
        # ).transpose([1, 2, 0])
        for s in range(1, num_parts):
            x_set, y_set = choose_to_whole[s - 1]
            if len(x_set) < 10:
                print(ins, art_status, frame_order)
                print(
                    "data is empty, skipping!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
                )
                return None
            else:
                choose_x[s - 1] = x_set
                choose_y[s - 1] = y_set

            # ---------------> from projected map into target part_cloud
            # order: cam->world->canon)

            # MotionNet Modification
            point_num = np.shape(choose_x[s - 1])[0]
            cloud_cam = []
            cloud_cam_real = []
            for i in range(point_num):
                x = choose_x[s - 1][i]
                y = choose_y[s - 1][i]
                y_real = 512 - y
                cloud_cam.append([
                    (y + projMat[0, 2]) * depth[x, y] / projMat[0, 0],
                    -(x + projMat[1, 2]) * depth[x, y] / (-projMat[1, 1]),
                    -depth[x, y],
                ])
                cloud_cam_real.append([
                    (y + projMat[0, 2]) * depth[x, y] / projMat[0, 0],
                    -(x + projMat[1, 2]) * depth[x, y] / (-projMat[1, 1]),
                    -depth[x, y],
                ])
                # cloud_cam.append(
                #     [
                #         (x + projMat[0, 2]) * depth[x, y_real] / projMat[0, 0],
                #         -(y_real + projMat[1, 2]) * depth[x, y_real] / (-projMat[1, 1]),
                #         -depth[x, y_real],
                #     ]
                # )
                # pdb.set_trace()
                # print(cloud_cam)
                # break
            cloud_cam = np.array(cloud_cam)
            cloud_cam_real = np.array(cloud_cam_real)

            # pdb.set_trace()
            # MotionNet Modification
            # projected_points = projected_map[choose_x[s-1][:].astype(np.uint16), choose_y[s-1][:].astype(np.uint16), :]
            # projected_points = np.reshape(projected_points, [-1, 4])
            # depth_channel    = - projected_points[:, 3:4]
            # cloud_cam        = np.dot(projected_points[:, 0:2] - np.dot(depth_channel, projMat[0:2, 2:3].T), np.linalg.pinv(projMat[:2, :2].T))

            # projected_points1 = projected_map1[choose_x[s-1][:].astype(np.uint16), choose_y[s-1][:].astype(np.uint16), :]
            # projected_points1 = np.reshape(projected_points1, [-1, 4])
            # cloud_cam_real    = np.dot(projected_points1[:, 0:2] - np.dot(depth_channel, projMat[0:2, 2:3].T), np.linalg.pinv(projMat[:2, :2].T))
            # cloud_cam_real    = np.concatenate((cloud_cam_real, depth_channel), axis=1)

            # cloud_cam      = np.concatenate((cloud_cam, depth_channel), axis=1)

            cloud_cam_full = np.concatenate(
                (cloud_cam, np.ones((cloud_cam.shape[0], 1))), axis=1)

            # modify, todo
            camera_pose_mat = np.linalg.pinv(viewMat.T)
            # MotionNet modification
            # camera_pose_mat[:3, :] = -camera_pose_mat[:3, :]
            cloud_world = np.dot(cloud_cam_full, camera_pose_mat)
            cloud_canon = np.dot(cloud_world,
                                 np.linalg.pinv(parts_model2world[s - 1].T))

            # canon points should be points coordinates centered in the inertial frame
            parts_cloud_cam[s - 1] = cloud_cam_real[:, :3]
            parts_cloud_world[s - 1] = cloud_world[:, :3]
            parts_cloud_canon[s - 1] = cloud_canon[:, :3]

        for k in range(1, num_parts):
            center_joint_orn = parts_urdf_orn[k - 1]
            my_canon2urdf_r = euler_matrix(
                center_joint_orn[0], center_joint_orn[1],
                center_joint_orn[2])[:4, :4]  # [w, x, y, z]
            my_canon2urdf_t = parts_urdf_pos[k - 1]
            my_canon2urdf_mat = my_canon2urdf_r
            for m in range(3):
                my_canon2urdf_mat[m, 3] = my_canon2urdf_t[m]
            part_points_space = np.concatenate(
                (
                    parts_cloud_canon[k - 1],
                    np.ones((parts_cloud_canon[k - 1].shape[0], 1)),
                ),
                axis=1,
            )
            parts_cloud_urdf[k - 1] = np.dot(part_points_space,
                                             my_canon2urdf_mat.T)

        # >>>>>>>>>>>>>>> go to NPCS space
        # NPCS here is not stored into hdf5
        for link in range(1, num_parts):
            tight_w = max(parts_cloud_urdf[link - 1][:, 0]) - min(
                parts_cloud_urdf[link - 1][:, 0])
            tight_l = max(parts_cloud_urdf[link - 1][:, 1]) - min(
                parts_cloud_urdf[link - 1][:, 1])
            tight_h = max(parts_cloud_urdf[link - 1][:, 2]) - min(
                parts_cloud_urdf[link - 1][:, 2])
            norm_factor = np.sqrt(1) / np.sqrt(tight_w**2 + tight_l**2 +
                                               tight_h**2)
            base_p = np.array([
                min(parts_cloud_urdf[link - 1][:, 0]),
                min(parts_cloud_urdf[link - 1][:, 1]),
                min(parts_cloud_urdf[link - 1][:, 2]),
            ]).reshape(1, 3)
            extre_p = np.array([
                max(parts_cloud_urdf[link - 1][:, 0]),
                max(parts_cloud_urdf[link - 1][:, 1]),
                max(parts_cloud_urdf[link - 1][:, 2]),
            ]).reshape(1, 3)
            center_p = (extre_p - base_p) / 2 * norm_factor

            parts_cloud_norm[link - 1] = (
                (parts_cloud_urdf[link - 1][:, :3] - base_p) * norm_factor +
                np.array([0.5, 0.5, 0.5]).reshape(1, 3) -
                center_p.reshape(1, 3))

        x_set_pcloud = np.concatenate(choose_x, axis=0)
        y_set_pcloud = np.concatenate(choose_y, axis=0)

        # save into h5 for rgb_img, input_pts, mask, correpsonding urdf_points
        print("Writing to ", h5_save_name)
        hf = h5py.File(h5_save_name, "w")
        hf.create_dataset("rgb", data=img)
        hf.create_dataset("mask", data=mask)
        cloud_cam = hf.create_group("gt_points")
        for part_i, points in enumerate(parts_cloud_cam):
            cloud_cam.create_dataset(str(part_i), data=points)
        coord_gt = hf.create_group("gt_coords")
        for part_i, points in enumerate(parts_cloud_urdf):
            coord_gt.create_dataset(str(part_i), data=points)
        hf.close()

        ################# for debug only, let me know if you have questions #################
        if self.is_debug:
            figure = plt.figure(dpi=200)
            ax = plt.subplot(121)
            plt.imshow(img)
            plt.title('RGB image')
            ax1 = plt.subplot(122)
            plt.imshow(depth)
            plt.title('depth image')
            plt.show()
            plot3d_pts(
                [parts_cloud_cam],
                [['part {}'.format(i) for i in range(len(parts_cloud_cam))]],
                s=5,
                title_name=['camera coords'])
            plot3d_pts(
                [parts_cloud_world],
                [['part {}'.format(i) for i in range(len(parts_cloud_world))]],
                s=5,
                title_name=['world coords'])
            plot3d_pts(
                [parts_cloud_canon],
                [['part {}'.format(i) for i in range(len(parts_cloud_canon))]],
                s=5,
                title_name=['canon coords'])
            plot3d_pts(
                [parts_cloud_urdf],
                [['part {}'.format(i) for i in range(len(parts_cloud_urdf))]],
                s=5,
                title_name=['urdf coords'])

        return None
Beispiel #4
0
            my_t_final = np.array(
                [my_mat_final[0][3], my_mat_final[1][3], my_mat_final[2][3]])

            my_pred = np.append(my_r_final, my_t_final)
            my_result.append(my_pred.tolist())
        my_result_np = np.array(my_result)
        my_result_mean = np.mean(my_result, axis=0)
        my_r = my_result_mean[:4]
        my_t = my_result_mean[4:]

        my_euler_form_r = euler_from_quaternion(my_r)
        print("my_euler_form_r", my_euler_form_r)
        #my_euler_form_r <class 'tuple'>: (0.9198490563735781, -0.007832527911272334, -0.47081842893943104)
        my_euler_yaw = list(my_euler_form_r)[2]
        my_rotation_matrix_from_euler = euler_matrix(my_euler_form_r[0],
                                                     my_euler_form_r[1],
                                                     my_euler_form_r[2])
        my_rotation_matrix_from_q = quaternion_matrix(my_r)
        x = np.dot(my_rotation_matrix_from_euler,
                   np.array([[1, 0, 0, 1]]).transpose()).flatten()
        y = np.dot(my_rotation_matrix_from_euler,
                   np.array([[0, 1, 0, 1]]).transpose()).flatten()
        z = np.dot(my_rotation_matrix_from_euler,
                   np.array([[0, 0, 1, 1]]).transpose()).flatten()
        newvs = []

        grasp_vector = [math.cos(my_euler_yaw), math.sin(my_euler_yaw), 0]
        # newvs.append([0,0,0,grasp_vector[0],grasp_vector[1],grasp_vector[2]])

        mx = my_rotation_matrix_from_euler[0, 0:3]
        my = my_rotation_matrix_from_euler[1, 0:3]
Beispiel #5
0
    for name in group:
        image = proj.findImageByName(name)
        ned, ypr, quat = image.get_camera_pose(opt=True)
        src_list.append(ned)
        ned, ypr, quat = image.get_camera_pose()
        dst_list.append(ned)
    A = get_recenter_affine(src_list, dst_list)

    # extract the rotation matrix (R) from the affine transform
    scale, shear, angles, trans, persp = transformations.decompose_matrix(A)
    print('  scale:', scale)
    print('  shear:', shear)
    print('  angles:', angles)
    print('  translate:', trans)
    print('  perspective:', persp)
    R = transformations.euler_matrix(*angles)
    print("R:\n{}".format(R))

    # fixme (just group):

    # update the optimized camera locations based on best fit
    camera_list = []
    # load optimized poses
    for image in proj.image_list:
        if image.name in group:
            ned, ypr, quat = image.get_camera_pose(opt=True)
        else:
            # this is just fodder to match size/index of the lists
            ned, ypr, quat = image.get_camera_pose()
        camera_list.append(ned)
Beispiel #6
0
def optmizer(project_dir, optmize_options):

    group_id = optmize_options[0]
    refine = optmize_options[1]
    cam_calibration = optmize_options[2]

    d2r = math.pi / 180.0
    r2d = 180.0 / math.pi

    # return a 3d affine tranformation between current camera locations
    # and original camera locations.
    def get_recenter_affine(src_list, dst_list):
        print('get_recenter_affine():')
        src = [[], [], [], []]  # current camera locations
        dst = [[], [], [], []]  # original camera locations
        for i in range(len(src_list)):
            src_ned = src_list[i]
            src[0].append(src_ned[0])
            src[1].append(src_ned[1])
            src[2].append(src_ned[2])
            src[3].append(1.0)
            dst_ned = dst_list[i]
            dst[0].append(dst_ned[0])
            dst[1].append(dst_ned[1])
            dst[2].append(dst_ned[2])
            dst[3].append(1.0)
            # print("{} <-- {}".format(dst_ned, src_ned))
        A = transformations.superimposition_matrix(src, dst, scale=True)
        print("A:\n", A)
        return A

    # transform a point list given an affine transform matrix
    def transform_points(A, pts_list):
        src = [[], [], [], []]
        for p in pts_list:
            src[0].append(p[0])
            src[1].append(p[1])
            src[2].append(p[2])
            src[3].append(1.0)
        dst = A.dot(np.array(src))
        result = []
        for i in range(len(pts_list)):
            result.append(
                [float(dst[0][i]),
                 float(dst[1][i]),
                 float(dst[2][i])])
        return result

    proj = ProjectMgr.ProjectMgr(project_dir)
    proj.load_images_info()

    source_file = os.path.join(proj.analysis_dir, 'matches_grouped')
    print('Match file:', source_file)
    matches = pickle.load(open(source_file, "rb"))
    print('Match features:', len(matches))

    # load the group connections within the image set
    groups = Groups.load(proj.analysis_dir)
    # sort from smallest to largest: groups.sort(key=len)

    opt = Optimizer.Optimizer(project_dir)
    opt.setup(proj,
              groups,
              group_id,
              matches,
              optimized=refine,
              cam_calib=cam_calibration)
    cameras, features, cam_index_map, feat_index_map, fx_opt, fy_opt, cu_opt, cv_opt, distCoeffs_opt = opt.run(
    )

    # mark all the optimized poses as invalid
    for image in proj.image_list:
        opt_cam_node = image.node.getChild('camera_pose_opt', True)
        opt_cam_node.setBool('valid', False)

    for i, cam in enumerate(cameras):
        image_index = cam_index_map[i]
        image = proj.image_list[image_index]
        ned_orig, ypr_orig, quat_orig = image.get_camera_pose()
        print('optimized cam:', cam)
        rvec = cam[0:3]
        tvec = cam[3:6]
        Rned2cam, jac = cv2.Rodrigues(rvec)
        cam2body = image.get_cam2body()
        Rned2body = cam2body.dot(Rned2cam)
        Rbody2ned = np.matrix(Rned2body).T
        (yaw, pitch,
         roll) = transformations.euler_from_matrix(Rbody2ned, 'rzyx')
        #print "orig ypr =", image.camera_pose['ypr']
        #print "new ypr =", [yaw/d2r, pitch/d2r, roll/d2r]
        pos = -np.matrix(Rned2cam).T * np.matrix(tvec).T
        newned = pos.T[0].tolist()[0]
        print(image.name, ned_orig, '->', newned, 'dist:',
              np.linalg.norm(np.array(ned_orig) - np.array(newned)))
        image.set_camera_pose(newned,
                              yaw * r2d,
                              pitch * r2d,
                              roll * r2d,
                              opt=True)
        image.placed = True
    proj.save_images_info()
    print('Updated the optimized camera poses.')

    # update and save the optimized camera calibration
    proj.cam.set_K(fx_opt, fy_opt, cu_opt, cv_opt, optimized=True)
    proj.cam.set_dist_coeffs(distCoeffs_opt.tolist(), optimized=True)
    proj.save()

    # compare original camera locations with optimized camera locations and
    # derive a transform matrix to 'best fit' the new camera locations
    # over the original ... trusting the original group gps solution as
    # our best absolute truth for positioning the system in world
    # coordinates.
    #
    # each optimized group needs a separate/unique fit

    matches_opt = list(matches)  # shallow copy
    refit_group_orientations = True
    if refit_group_orientations:
        group = groups[group_id]
        print('refitting group size:', len(group))
        src_list = []
        dst_list = []
        # only consider images that are in the current   group
        for name in group:
            image = proj.findImageByName(name)
            ned, ypr, quat = image.get_camera_pose(opt=True)
            src_list.append(ned)
            ned, ypr, quat = image.get_camera_pose()
            dst_list.append(ned)
        A = get_recenter_affine(src_list, dst_list)

        # extract the rotation matrix (R) from the affine transform
        scale, shear, angles, trans, persp = transformations.decompose_matrix(
            A)
        print('  scale:', scale)
        print('  shear:', shear)
        print('  angles:', angles)
        print('  translate:', trans)
        print('  perspective:', persp)
        R = transformations.euler_matrix(*angles)
        print("R:\n{}".format(R))

        # fixme (just group):

        # update the optimized camera locations based on best fit
        camera_list = []
        # load optimized poses
        for image in proj.image_list:
            if image.name in group:
                ned, ypr, quat = image.get_camera_pose(opt=True)
            else:
                # this is just fodder to match size/index of the lists
                ned, ypr, quat = image.get_camera_pose()
            camera_list.append(ned)

        # refit
        new_cams = transform_points(A, camera_list)

        # update position
        for i, image in enumerate(proj.image_list):
            if not image.name in group:
                continue
            ned, [y, p, r], quat = image.get_camera_pose(opt=True)
            image.set_camera_pose(new_cams[i], y, p, r, opt=True)
        proj.save_images_info()

        if True:
            # update optimized pose orientation.
            dist_report = []
            for i, image in enumerate(proj.image_list):
                if not image.name in group:
                    continue
                ned_orig, ypr_orig, quat_orig = image.get_camera_pose()
                ned, ypr, quat = image.get_camera_pose(opt=True)
                Rbody2ned = image.get_body2ned(opt=True)
                # update the orientation with the same transform to keep
                # everything in proper consistent alignment

                newRbody2ned = R[:3, :3].dot(Rbody2ned)
                (yaw, pitch, roll) = transformations.euler_from_matrix(
                    newRbody2ned, 'rzyx')
                image.set_camera_pose(new_cams[i],
                                      yaw * r2d,
                                      pitch * r2d,
                                      roll * r2d,
                                      opt=True)
                dist = np.linalg.norm(
                    np.array(ned_orig) - np.array(new_cams[i]))
                print('image: {}'.format(image.name))
                print('  orig pos: {}'.format(ned_orig))
                print('  fit pos: {}'.format(new_cams[i]))
                print('  dist moved: {}'.format(dist))
                dist_report.append((dist, image.name))
            proj.save_images_info()

            dist_report = sorted(dist_report,
                                 key=lambda fields: fields[0],
                                 reverse=False)
            print('Image movement sorted lowest to highest:')
            for report in dist_report:
                print('{} dist: {}'.format(report[1], report[0]))

        # tranform the optimized point locations using the same best
        # fit transform for the camera locations.
        new_feats = transform_points(A, features)

        # update any of the transformed feature locations that have
        # membership in the currently processing group back to the
        # master match structure.  Note we process groups in order of
        # little to big so if a match is in more than one group it
        # follows the larger group.
        for i, feat in enumerate(new_feats):
            match_index = feat_index_map[i]
            match = matches_opt[match_index]
            in_group = False
            for m in match[2:]:
                if proj.image_list[m[0]].name in group:
                    in_group = True
                    break
            if in_group:
                #print(' before:', match)
                match[0] = feat
                #print(' after:', match)
    else:
        # not refitting group orientations, just copy over optimized
        # coordinates
        for i, feat in enumerate(features):
            match_index = feat_index_map[i]
            match = matches_opt[match_index]
            match[0] = feat

    # write out the updated match_dict
    print('Updating matches file:', len(matches_opt), 'features')
    pickle.dump(matches_opt, open(source_file, 'wb'))

    #proj.cam.set_K(fx_opt/scale[0], fy_opt/scale[0], cu_opt/scale[0], cv_opt/scale[0], optimized=True)
    #proj.save()

    # temp write out just the points so we can plot them with gnuplot
    f = open(os.path.join(proj.analysis_dir, 'opt-plot.txt'), 'w')
    for m in matches_opt:
        try:
            f.write('%.2f %.2f %.2f\n' % (m[0][0], m[0][1], m[0][2]))
        except:
            pass
    f.close()

    # temp write out direct and optimized camera positions
    f1 = open(os.path.join(proj.analysis_dir, 'cams-direct.txt'), 'w')
    f2 = open(os.path.join(proj.analysis_dir, 'cams-opt.txt'), 'w')
    for name in groups[group_id]:
        image = proj.findImageByName(name)
        ned1, ypr1, quat1 = image.get_camera_pose()
        ned2, ypr2, quat2 = image.get_camera_pose(opt=True)
        f1.write('%.2f %.2f %.2f\n' % (ned1[1], ned1[0], -ned1[2]))
        f2.write('%.2f %.2f %.2f\n' % (ned2[1], ned2[0], -ned2[2]))
    f1.close()
    f2.close()