def split_bvh(filepath, time_window, output_folder): motion = bvh.load(filepath) frames_per_time_window = time_window * motion.fps for num, i in enumerate( range(0, motion.num_frames(), int(frames_per_time_window / 2))): motion_slice = motion_ops.cut(motion, i, i + frames_per_time_window) filepath_slice = os.path.join( output_folder, filepath.split(".")[-2].split("/")[-1] + "_" + str(num) + ".bvh", ) bvh.save(motion_slice, filepath_slice)
def save_seq(i, pred_seq, src_seq, tgt_seq, skel): # seq_T contains pred, src, tgt data in the same order motions = [ motion_class.Motion.from_matrix(seq, skel) for seq in [pred_seq, src_seq, tgt_seq] ] ref_motion = motion_ops.append(motions[1], motions[2]) pred_motion = motion_ops.append(motions[1], motions[0]) bvh.save( ref_motion, os.path.join(args.save_output_path, "ref", f"{i}.bvh"), ) bvh.save( pred_motion, os.path.join(args.save_output_path, "pred", f"{i}.bvh"), )
def test_save_motion(self): # Load file motion = bvh.load(file=TEST_SINUSOIDAL_FILE) with tempfile.NamedTemporaryFile() as fp: # Save loaded file bvh.save(motion, fp.name, rot_order="XYZ") # Reload saved file and test if it is same as reference file # Read pose data from all frames (in Euler angle) with open(TEST_SINUSOIDAL_FILE) as f: orig_file = f.readlines() with open(fp.name) as f: saved_file = f.readlines() for orig_line, saved_line in zip( orig_file[-motion.num_frames():], saved_file[-motion.num_frames():], ): # Skip first 3 entries that store translation data, and read # the Euler angle data of joints orig_data, saved_data = [ np.array(list(map(float, line.strip().split()))) for line in [orig_line, saved_line] ] np.testing.assert_almost_equal(orig_data, saved_data) # Reload saved file and test if it has the same data as original # motion object with open(TEST_SINUSOIDAL_FILE) as f: file_content = f.readlines() for frame_num, line in enumerate( file_content[-motion.num_frames():]): # Skip first 3 entries that store translation data, and read # the Euler angle data of joints angle_data = np.array( list(map(float, line.strip().split()))[3:]).reshape(-1, 3) for T, true_E in zip(motion.poses[frame_num].data, angle_data): R, _ = conversions.T2Rp(T) E = conversions.R2E(R, order="XYZ", degrees=True) np.testing.assert_almost_equal(E, true_E)
def viz_motion(motion, num_nodes=4, save=False, up_dir='y', r=100, lines=True, lines_color='navy', points=True, points_color='goldenrod', lines_color_2='green', interval=5): now = datetime.datetime.now().strftime('%Y%m%d%H%M%S%f') if type(motion) == str: fi = motion else: fi = f'intermediate/motion_{now}.bvh' bvh.save(motion, filename=fi, verbose=True) # hardcoded skeleton = { 'Hips': ['LeftUpLeg', 'RightUpLeg', 'Spine'], 'LeftUpLeg': ['LeftLeg'], 'LeftLeg': ['LeftFoot'], 'LeftFoot': ['LeftToe'], 'LeftToe': ['LeftToeEnd'], 'RightUpLeg': ['RightLeg'], 'RightLeg': ['RightFoot'], 'RightFoot': ['RightToe'], 'RightToe': ['RightToeEnd'], 'Spine': ['Spine1'], 'Spine1': ['Spine2'], 'Spine2': ['Neck', 'LeftShoulder', 'RightShoulder'], 'Neck': ['Head'], 'Head': ['HeadEnd'], 'LeftShoulder': ['LeftArm'], 'LeftArm': ['LeftForeArm'], 'LeftForeArm': ['LeftHand'], 'LeftHand': ['LeftHandEnd'], 'RightShoulder': ['RightArm'], 'RightArm': ['RightForeArm'], 'RightForeArm': ['RightHand'], 'RightHand': ['RightHandEnd'], } last_desc = "" skel = process_bvhfile(fi) motion = {} for frame in range(skel.frames): skel.create_edges_onet(frame, debug=0) for edge in skel.edges[frame]: for vert in (edge.wv1, edge.wv2): if vert.descr is not last_desc: if vert.descr not in motion: motion[vert.descr] = [] if frame >= len(motion[vert.descr]): motion[vert.descr].append(list(vert.tr[:3])) last_desc = vert.descr # Body parts with open(fi) as f: content = f.readlines() body = {} key = '' joint = 'Hips' for line in content: line = line.replace('\n', '').replace('\t', '') if line == 'MOTION\n': break else: if line.startswith('ROOT') or line.startswith('JOINT'): key = ' '.join(line.split()[1:]) joint = key elif line.startswith('OFFSET'): body[key] = [float(v) for v in line.split()[1:]] elif line.startswith('End'): key += 'End' # Viz fig = plt.figure(fi, dpi=150) ax = plt.gca(projection='3d') plots = {} joints = list(motion.keys()) for joint_1 in joints: if not joint_1.endswith('End'): start = motion[joint_1][frame] for joint_2 in skeleton[joint_1]: end = motion[joint_2][frame] x = np.array([start[0], end[0]]) y = np.array([start[1], end[1]]) z = np.array([start[2], end[2]]) if lines and f'{joint_1} {joint_2}' not in plots: plots[f'{joint_1} {joint_2}'] = ax.plot(x, y, z, lw=2, zdir=up_dir, color=lines_color) if points and f'{joint_1}' not in plots: plots[f'{joint_1}'] = ax.scatter(*start, s=10, zdir=up_dir, color=points_color) else: plots[f'{joint_1}'] = ax.scatter(*motion[joint_1][frame], s=2, zdir=up_dir, color='blue') frame = 1 xs = [] ys = [] zs = [] for frame in motion[joint]: xs.append(frame[0]) ys.append(frame[1]) zs.append(frame[2]) if up_dir == "x": ax.set_xlim3d([-r + min(ys), r + max(ys)]) ax.set_ylim3d([-r + min(xs), r + max(xs)]) ax.set_zlim3d([-r + min(zs), r + max(zs)]) elif up_dir == "y": ax.set_xlim3d([-r + min(xs), r + max(xs)]) ax.set_ylim3d([-r + min(zs), r + max(zs)]) ax.set_zlim3d([-r + min(ys), r + max(ys)]) elif up_dir == "z": ax.set_xlim3d([-r + min(xs), r + max(xs)]) ax.set_ylim3d([-r + min(ys), r + max(ys)]) ax.set_zlim3d([-r + min(zs), r + max(zs)]) node_len = skel.frames // num_nodes for frame in range(skel.frames): for joint_1 in joints: if not joint_1.endswith('End'): start = motion[joint_1][frame] for joint_2 in skeleton[joint_1]: end = motion[joint_2][frame] x = np.array([start[0], end[0]]) y = np.array([start[1], end[1]]) z = np.array([start[2], end[2]]) if lines: plots[f'{joint_1} {joint_2}'][0].set_xdata(x) plots[f'{joint_1} {joint_2}'][0].set_ydata(y) plots[f'{joint_1} {joint_2}'][0].set_3d_properties( z, zdir=up_dir) if int((frame - 1) // node_len) % 2 == 0: plots[f'{joint_1} {joint_2}'][0].set_color( lines_color_2) else: plots[f'{joint_1} {joint_2}'][0].set_color( lines_color) if points: plots[f'{joint_1}'].set_offsets(np.c_[start[0], start[1]]) plots[f'{joint_1}'].set_3d_properties(start[2], zdir=up_dir) plots[f'{joint_2}'].set_offsets(np.c_[end[0], end[1]]) plots[f'{joint_2}'].set_3d_properties(end[2], zdir=up_dir) if save and frame + 1 % interval == 0: # print(frame, skel.frames, f'./motion/motion_{frame-1}.png') plt.savefig(f'./motion/motion_{frame-1}.png') plt.pause(1 / 1200) plt.close()
logging.info(f"Loaded {len(motions_with_velocity)} files") # Construct Motion Graph mg = graph.MotionGraph( motions=motions_with_velocity, motion_files=args.motion_files, skel=skel, base_length=args.base_length, blend_length=args.blend_length, verbose=True, ) mg.construct( w_joints=None, w_joint_pos=args.w_joint_pos, w_joint_vel=args.w_joint_vel, w_root_pos=args.w_root_pos, w_root_vel=args.w_root_vel, w_ee_pos=args.w_ee_pos, w_ee_vel=args.w_ee_vel, w_trajectory=args.w_trajectory, diff_threshold=args.diff_threshold, num_workers=args.num_workers, ) mg.reduce(method="scc") # del motions[:] motion, _ = mg.create_random_motion(length=10.0, start_node=0) bvh.save(motion, filename=args.output_bvh)
start_pose=start_pose, end_pose=end_pose, start_node=args.start_node, end_node=args.end_node) else: motion, nodes = mg.create_random_motion( length=args.steps, start_node=args.start_node ) #Originally was length 10.0, start_node=0 if args.save_metrics: end = time.time() mode = 'a' filename = 'metrics.csv' rows = [] if not (os.path.exists(filename) and os.path.isfile(filename)): mode = 'w' header = ('Dataset', 'BVH', 'Wall-Clock Start Time', 'Wall-Clock End Time', 'Wall-Clock Elapsed Time (s)', 'Node Sequence', 'Steps', 'Start Node', 'End Node', 'Error') rows.append(header) run_data = (motion_files, args.output_bvh, start, end, end - start, nodes, args.steps, start_node, end_node, error) rows.append(run_data) with open(filename, mode, newline='') as csvfile: writer = csv.writer(csvfile) for row in rows: writer.writerow(row) if motion: bvh.save(motion, filename=args.output_bvh, verbose=True) logging.info(f'Saved BVH')