| import time
|
| import h5py
|
| import os
|
| import glob
|
| import cv2
|
| import pickle
|
| import numpy as np
|
| from pygments.lexer import default
|
|
|
| from function_util import save_videos, mk_dir
|
| from pathlib import Path
|
| import tyro
|
| from dataclasses import dataclass
|
| import click
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| def deal_data(pos_list, top_list, left_list, right_list, tactile_dict_lists):
|
| """Check if data dimension is consistent. Remove the longer dimension data if it is not consistent."""
|
| if len(pos_list) < len(top_list):
|
| for i in range(len(top_list)):
|
| file_name = top_list[i].split("/")[-1].split(".")[0] + ".pkl"
|
| if not os.path.exists(os.path.dirname(pos_list[0])+f"/{file_name}"):
|
| print(top_list[i])
|
| os.remove(top_list[i])
|
| os.remove(left_list[i])
|
| os.remove(right_list[i])
|
| top_list.remove(top_list[i])
|
| left_list.remove(left_list[i])
|
| right_list.remove(right_list[i])
|
| for tactile_name in tactile_dict_lists:
|
| tactile_dict_lists[tactile_name].remove(tactile_dict_lists[tactile_name][i])
|
| elif len(pos_list) > len(top_list):
|
| for i in range(len(pos_list)):
|
|
|
| file_name = pos_list[i].split("/")[-1].split(".")[0] + ".jpg"
|
| if not os.path.exists(os.path.dirname(pos_list[0])+f"/{file_name}"):
|
| print(pos_list[i])
|
| os.remove(pos_list[i])
|
| pos_list.remove(pos_list[i])
|
| for tactile_name in tactile_dict_lists:
|
| tactile_dict_lists[tactile_name].remove(tactile_dict_lists[tactile_name][i])
|
| return pos_list, top_list, left_list, right_list, tactile_dict_lists
|
|
|
|
|
| def load_data(one_dataset_dir):
|
| camera_names = ['top', 'left_wrist', 'right_wrist']
|
| print(camera_names)
|
|
|
|
|
| tactile_names = []
|
| tactile_dirs = {'tactile1': 'leftTactile', 'tactile2': 'rightTactile'}
|
| available_tactile_dirs = {}
|
| for tactile_name, tactile_dir in tactile_dirs.items():
|
| tactile_path = one_dataset_dir + tactile_dir + '/'
|
| if os.path.exists(tactile_path) and len(glob.glob(tactile_path + '*.jpg')) > 0:
|
| tactile_names.append(tactile_name)
|
| available_tactile_dirs[tactile_name] = tactile_dir
|
| print(f"Available tactile sensors: {tactile_names}")
|
|
|
| data_pose_list = glob.glob(one_dataset_dir + 'observation/*.pkl')
|
|
|
|
|
|
|
| images_top_list = glob.glob(one_dataset_dir + 'topImg/*.jpg')
|
| images_left_list = glob.glob(one_dataset_dir + 'leftImg/*.jpg')
|
| images_right_list = glob.glob(one_dataset_dir + 'rightImg/*.jpg')
|
| data_pose_list.sort(key=lambda x: int(x.split("/")[-1].split(".")[0]))
|
| images_top_list.sort(key=lambda x: int(x.split("/")[-1].split(".")[0]))
|
| images_left_list.sort(key=lambda x: int(x.split("/")[-1].split(".")[0]))
|
| images_right_list.sort(key=lambda x: int(x.split("/")[-1].split(".")[0]))
|
|
|
|
|
|
|
| tactile_dict_lists = {}
|
| for tactile_name in tactile_names:
|
| tactile_list = glob.glob(one_dataset_dir + available_tactile_dirs[tactile_name] + '/*.jpg')
|
| tactile_list.sort(key=lambda x: int(x.split("/")[-1].split(".")[0]))
|
| tactile_dict_lists[tactile_name] = tactile_list
|
|
|
| data_pose_list, images_top_list, images_left_list, images_right_list, tactile_dict_lists = (
|
| deal_data(data_pose_list, images_top_list, images_left_list, images_right_list, tactile_dict_lists))
|
|
|
| is_sim = False
|
| qpos = []
|
| qvel = []
|
| action = []
|
| base_action = None
|
| image_dict = dict()
|
| tactile_dict = dict()
|
| image_li = [[], [], []]
|
|
|
|
|
| tactile_li = {tactile_name: [] for tactile_name in tactile_names}
|
|
|
| for cam_name in camera_names:
|
| image_dict[f'{cam_name}'] = []
|
| for tactile_name in tactile_names:
|
| tactile_dict[f'{tactile_name}'] = []
|
| for i in range(len(data_pose_list)):
|
| with open(data_pose_list[i], "rb") as f:
|
| data_single = pickle.load(f)
|
| qpos.append(data_single['joint_positions'])
|
| qvel.append(data_single['joint_velocities'])
|
| action.append(data_single['control'])
|
|
|
|
|
|
|
| image_top = cv2.imread(images_top_list[i])
|
| image_left = cv2.imread(images_left_list[i])
|
| image_right = cv2.imread(images_right_list[i])
|
|
|
|
|
| for tactile_name in tactile_names:
|
| tactile_img = cv2.imread(tactile_dict_lists[tactile_name][i])
|
| tactile_li[tactile_name].append(tactile_img)
|
|
|
|
|
|
|
| image_li[0].append(image_top)
|
| image_li[1].append(image_left)
|
| image_li[2].append(image_right)
|
|
|
| image_dict['top'] = image_li[0]
|
| image_dict['left_wrist'] = image_li[1]
|
| image_dict['right_wrist'] = image_li[2]
|
|
|
|
|
| for tactile_name in tactile_names:
|
| tactile_dict[tactile_name] = tactile_li[tactile_name]
|
|
|
| return np.array(qpos), np.array(qvel), np.array(action), base_action, image_dict, tactile_dict, is_sim
|
|
|
|
|
| @click.command()
|
| @click.option('-r', '--root_dir', required=True, default="./datasets/", help='')
|
| @click.option('-d', '--dataset_name', required=True, default="dataset_package_test", help='')
|
| @click.option('-t', '--date_collect', required=True, default="20241010", help='')
|
| @click.option('-n', '--idx', required=True, default="0", help='')
|
| def main(root_dir, dataset_name, date_collect, idx):
|
| dataset_dir = root_dir + "/" + dataset_name + "/collect_data/"
|
| mk_dir(dataset_dir)
|
| output_video_dir = root_dir + "/" + dataset_name + "/output_videos/"
|
| mk_dir(output_video_dir)
|
| output_train_data = root_dir + "/" + dataset_name + "/train_data/"
|
| mk_dir(output_train_data)
|
| MIRROR_STATE_MULTIPLY = np.array([1, 1, 1, 1, 1, 1, 1])
|
| MIRROR_BASE_MULTIPLY = np.array([1, 1])
|
|
|
|
|
| one_data_dir = dataset_dir+date_collect+"/"
|
| print(one_data_dir)
|
| qpos, qvel, action, base_action, image_dict, tactile_dict, is_sim = load_data(one_data_dir)
|
| qpos = np.concatenate([qpos[:, :7] * MIRROR_STATE_MULTIPLY, qpos[:, 7:] * MIRROR_STATE_MULTIPLY], axis=1)
|
| qvel = np.concatenate([qvel[:, :7] * MIRROR_STATE_MULTIPLY, qvel[:, 7:] * MIRROR_STATE_MULTIPLY], axis=1)
|
| action = np.concatenate([action[:, :7] * MIRROR_STATE_MULTIPLY, action[:, 7:] * MIRROR_STATE_MULTIPLY], axis=1)
|
|
|
| if base_action is not None:
|
| base_action = base_action * MIRROR_BASE_MULTIPLY
|
|
|
| if 'left_wrist' in image_dict.keys():
|
| image_dict['left_wrist'], image_dict['right_wrist'] = \
|
| image_dict['left_wrist'], image_dict['right_wrist']
|
| elif 'cam_left_wrist' in image_dict.keys():
|
| image_dict['cam_left_wrist'], image_dict['cam_right_wrist'] = \
|
| image_dict['cam_left_wrist'][:, :, ::-1], image_dict['cam_right_wrist'][:, :, ::-1]
|
| else:
|
| raise Exception('No left_wrist or cam_left_wrist in image_dict')
|
|
|
| if 'top' in image_dict.keys():
|
| image_dict['top'] = image_dict['top']
|
| elif 'cam_high' in image_dict.keys():
|
| image_dict['cam_high'] = image_dict['cam_high'][:, :, ::-1]
|
| else:
|
| raise Exception('No top or cam_high in image_dict')
|
|
|
|
|
| if len(tactile_dict) == 0:
|
| print("Warning: No tactile sensors found in the dataset")
|
| else:
|
| print(f"Found {len(tactile_dict)} tactile sensor(s): {list(tactile_dict.keys())}")
|
|
|
|
|
| data_dict = {
|
| '/observations/qpos': qpos,
|
| '/observations/qvel': qvel,
|
| '/action': action,
|
| '/base_action': base_action,
|
| } if base_action is not None else {
|
| '/observations/qpos': qpos,
|
| '/observations/qvel': qvel,
|
| '/action': action,
|
| }
|
| for cam_name in image_dict.keys():
|
| data_dict[f'/observations/images/{cam_name}'] = image_dict[cam_name]
|
| for tactile_name in tactile_dict.keys():
|
| data_dict[f'/observations/{tactile_name}'] = tactile_dict[tactile_name]
|
| max_timesteps = len(qpos)
|
|
|
| COMPRESS = True
|
|
|
| if COMPRESS:
|
|
|
| t0 = time.time()
|
| encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 50]
|
| compressed_len = []
|
| for cam_name in image_dict.keys():
|
| image_list = data_dict[f'/observations/images/{cam_name}']
|
| compressed_list = []
|
| compressed_len.append([])
|
| for image in image_list:
|
| result, encoded_image = cv2.imencode('.jpg', image,
|
| encode_param)
|
| compressed_list.append(encoded_image)
|
| compressed_len[-1].append(len(encoded_image))
|
| data_dict[f'/observations/images/{cam_name}'] = compressed_list
|
| print(f'compression: {time.time() - t0:.2f}s')
|
|
|
|
|
| t0 = time.time()
|
| compressed_len = np.array(compressed_len)
|
| padded_size = compressed_len.max()
|
| for cam_name in image_dict.keys():
|
| compressed_image_list = data_dict[f'/observations/images/{cam_name}']
|
| padded_compressed_image_list = []
|
| for compressed_image in compressed_image_list:
|
| padded_compressed_image = np.zeros(padded_size, dtype='uint8')
|
| image_len = len(compressed_image)
|
| padded_compressed_image[:image_len] = compressed_image
|
| padded_compressed_image_list.append(padded_compressed_image)
|
| data_dict[f'/observations/images/{cam_name}'] = padded_compressed_image_list
|
| print(f'padding: {time.time() - t0:.2f}s')
|
|
|
|
|
| t0 = time.time()
|
| tactile_compressed_len = []
|
| for tactile_name in tactile_dict.keys():
|
| tactile_list = data_dict[f'/observations/{tactile_name}']
|
| compressed_list = []
|
| tactile_compressed_len.append([])
|
| for tactile_image in tactile_list:
|
| result, encoded_image = cv2.imencode('.jpg', tactile_image, encode_param)
|
| compressed_list.append(encoded_image)
|
| tactile_compressed_len[-1].append(len(encoded_image))
|
| data_dict[f'/observations/{tactile_name}'] = compressed_list
|
| print(f'tactile compression: {time.time() - t0:.2f}s')
|
|
|
|
|
| t0 = time.time()
|
|
|
| all_compressed_len = np.concatenate([compressed_len, np.array(tactile_compressed_len)], axis=0)
|
| padded_size = all_compressed_len.max()
|
|
|
|
|
| for cam_name in image_dict.keys():
|
| compressed_image_list = data_dict[f'/observations/images/{cam_name}']
|
| padded_compressed_image_list = []
|
| for compressed_image in compressed_image_list:
|
| padded_compressed_image = np.zeros(padded_size, dtype='uint8')
|
| image_len = len(compressed_image)
|
| padded_compressed_image[:image_len] = compressed_image
|
| padded_compressed_image_list.append(padded_compressed_image)
|
| data_dict[f'/observations/images/{cam_name}'] = padded_compressed_image_list
|
|
|
|
|
| for tactile_name in tactile_dict.keys():
|
| compressed_tactile_list = data_dict[f'/observations/{tactile_name}']
|
| padded_compressed_tactile_list = []
|
| for compressed_tactile in compressed_tactile_list:
|
| padded_compressed_tactile = np.zeros(padded_size, dtype='uint8')
|
| tactile_len = len(compressed_tactile)
|
| padded_compressed_tactile[:tactile_len] = compressed_tactile
|
| padded_compressed_tactile_list.append(padded_compressed_tactile)
|
| data_dict[f'/observations/{tactile_name}'] = padded_compressed_tactile_list
|
| print(f'tactile padding: {time.time() - t0:.2f}s')
|
|
|
|
|
| t0 = time.time()
|
| dataset_path = os.path.join(output_train_data, f'episode_init_{idx}')
|
| with h5py.File(dataset_path + '.hdf5', 'w', rdcc_nbytes=1024 ** 2 * 2) as root:
|
| root.attrs['sim'] = is_sim
|
| root.attrs['compress'] = COMPRESS
|
| obs = root.create_group('observations')
|
| image = obs.create_group('images')
|
| for cam_name in image_dict.keys():
|
| if COMPRESS:
|
| _ = image.create_dataset(cam_name, (max_timesteps, padded_size), dtype='uint8',
|
| chunks=(1, padded_size), )
|
| else:
|
| _ = image.create_dataset(cam_name, (max_timesteps, 480, 640, 3), dtype='uint8',
|
| chunks=(1, 480, 640, 3), )
|
| for tactile_name in tactile_dict.keys():
|
| if COMPRESS:
|
| _ = obs.create_dataset(tactile_name, (max_timesteps, padded_size), dtype='uint8',
|
| chunks=(1, padded_size), )
|
| else:
|
| _ = obs.create_dataset(tactile_name, (max_timesteps, 480, 640, 3), dtype='uint8',
|
| chunks=(1, 480, 640, 3), )
|
| qpos = obs.create_dataset('qpos', (max_timesteps, 14))
|
| qvel = obs.create_dataset('qvel', (max_timesteps, 14))
|
| action = root.create_dataset('action', (max_timesteps, 14))
|
| if base_action is not None:
|
| base_action = root.create_dataset('base_action', (max_timesteps, 2))
|
|
|
| for name, array in data_dict.items():
|
| root[name][...] = array
|
|
|
| if COMPRESS:
|
| _ = root.create_dataset('compress_len', (len(image_dict.keys()) + len(tactile_dict.keys()), max_timesteps))
|
| root['/compress_len'][...] = all_compressed_len
|
|
|
| print(f'Saving {dataset_path}: {time.time() - t0:.1f} secs\n')
|
|
|
|
|
| save_videos(image_dict, 0.02, video_path=os.path.join(output_video_dir + date_collect + f'_video.mp4'))
|
|
|
|
|
| if __name__ == "__main__":
|
| main() |