| import os |
|
|
| from ..core import logger |
| from .plt_plotter import Matplotlib3DPlotter |
| from .skeleton_plotter_tasks import Draw3DSkeletonMotion, Draw3DSkeletonState |
|
|
|
|
| def plot_skeleton_state(skeleton_state, task_name=""): |
| """ |
| Visualize a skeleton state |
| |
| :param skeleton_state: |
| :param task_name: |
| :type skeleton_state: SkeletonState |
| :type task_name: string, optional |
| """ |
| logger.info("plotting {}".format(task_name)) |
| task = Draw3DSkeletonState(task_name=task_name, skeleton_state=skeleton_state) |
| plotter = Matplotlib3DPlotter(task) |
| plotter.show() |
|
|
|
|
| def plot_skeleton_states(skeleton_state, skip_n=1, task_name=""): |
| """ |
| Visualize a sequence of skeleton state. The dimension of the skeleton state must be 1 |
| |
| :param skeleton_state: |
| :param task_name: |
| :type skeleton_state: SkeletonState |
| :type task_name: string, optional |
| """ |
| logger.info("plotting {} motion".format(task_name)) |
| assert len(skeleton_state.shape) == 1, "the state must have only one dimension" |
| task = Draw3DSkeletonState(task_name=task_name, skeleton_state=skeleton_state[0]) |
| plotter = Matplotlib3DPlotter(task) |
| for frame_id in range(skeleton_state.shape[0]): |
| if frame_id % skip_n != 0: |
| continue |
| task.update(skeleton_state[frame_id]) |
| plotter.update() |
| plotter.show() |
|
|
|
|
| def plot_skeleton_motion(skeleton_motion, skip_n=1, task_name=""): |
| """ |
| Visualize a skeleton motion along its first dimension. |
| |
| :param skeleton_motion: |
| :param task_name: |
| :type skeleton_motion: SkeletonMotion |
| :type task_name: string, optional |
| """ |
| logger.info("plotting {} motion".format(task_name)) |
| task = Draw3DSkeletonMotion( |
| task_name=task_name, skeleton_motion=skeleton_motion, frame_index=0 |
| ) |
| plotter = Matplotlib3DPlotter(task) |
| for frame_id in range(len(skeleton_motion)): |
| if frame_id % skip_n != 0: |
| continue |
| task.update(frame_id) |
| plotter.update() |
| plotter.show() |
|
|
|
|
| def plot_skeleton_motion_interactive_base(skeleton_motion, task_name=""): |
| class PlotParams: |
| def __init__(self, total_num_frames): |
| self.current_frame = 0 |
| self.playing = False |
| self.looping = False |
| self.confirmed = False |
| self.playback_speed = 4 |
| self.total_num_frames = total_num_frames |
|
|
| def sync(self, other): |
| self.current_frame = other.current_frame |
| self.playing = other.playing |
| self.looping = other.current_frame |
| self.confirmed = other.confirmed |
| self.playback_speed = other.playback_speed |
| self.total_num_frames = other.total_num_frames |
|
|
| task = Draw3DSkeletonMotion( |
| task_name=task_name, skeleton_motion=skeleton_motion, frame_index=0 |
| ) |
| plotter = Matplotlib3DPlotter(task) |
|
|
| plot_params = PlotParams(total_num_frames=len(skeleton_motion)) |
| print("Entered interactive plot - press 'n' to quit, 'h' for a list of commands") |
|
|
| def press(event): |
| if event.key == "x": |
| plot_params.playing = not plot_params.playing |
| elif event.key == "z": |
| plot_params.current_frame = plot_params.current_frame - 1 |
| elif event.key == "c": |
| plot_params.current_frame = plot_params.current_frame + 1 |
| elif event.key == "a": |
| plot_params.current_frame = plot_params.current_frame - 20 |
| elif event.key == "d": |
| plot_params.current_frame = plot_params.current_frame + 20 |
| elif event.key == "w": |
| plot_params.looping = not plot_params.looping |
| print("Looping: {}".format(plot_params.looping)) |
| elif event.key == "v": |
| plot_params.playback_speed *= 2 |
| print("playback speed: {}".format(plot_params.playback_speed)) |
| elif event.key == "b": |
| if plot_params.playback_speed != 1: |
| plot_params.playback_speed //= 2 |
| print("playback speed: {}".format(plot_params.playback_speed)) |
| elif event.key == "n": |
| plot_params.confirmed = True |
| elif event.key == "h": |
| rows, columns = os.popen("stty size", "r").read().split() |
| columns = int(columns) |
| print("=" * columns) |
| print("x: play/pause") |
| print("z: previous frame") |
| print("c: next frame") |
| print("a: jump 10 frames back") |
| print("d: jump 10 frames forward") |
| print("w: looping/non-looping") |
| print("v: double speed (this can be applied multiple times)") |
| print("b: half speed (this can be applied multiple times)") |
| print("n: quit") |
| print("h: help") |
| print("=" * columns) |
|
|
| print( |
| 'current frame index: {}/{} (press "n" to quit)'.format( |
| plot_params.current_frame, plot_params.total_num_frames - 1 |
| ) |
| ) |
|
|
| plotter.fig.canvas.mpl_connect("key_press_event", press) |
| while True: |
| reset_trail = False |
| if plot_params.confirmed: |
| break |
| if plot_params.playing: |
| plot_params.current_frame += plot_params.playback_speed |
| if plot_params.current_frame >= plot_params.total_num_frames: |
| if plot_params.looping: |
| plot_params.current_frame %= plot_params.total_num_frames |
| reset_trail = True |
| else: |
| plot_params.current_frame = plot_params.total_num_frames - 1 |
| if plot_params.current_frame < 0: |
| if plot_params.looping: |
| plot_params.current_frame %= plot_params.total_num_frames |
| reset_trail = True |
| else: |
| plot_params.current_frame = 0 |
| yield plot_params |
| task.update(plot_params.current_frame, reset_trail) |
| plotter.update() |
|
|
|
|
| def plot_skeleton_motion_interactive(skeleton_motion, task_name=""): |
| """ |
| Visualize a skeleton motion along its first dimension interactively. |
| |
| :param skeleton_motion: |
| :param task_name: |
| :type skeleton_motion: SkeletonMotion |
| :type task_name: string, optional |
| """ |
| for _ in plot_skeleton_motion_interactive_base(skeleton_motion, task_name): |
| pass |
|
|
|
|
| def plot_skeleton_motion_interactive_multiple(*callables, sync=True): |
| for _ in zip(*callables): |
| if sync: |
| for p1, p2 in zip(_[:-1], _[1:]): |
| p2.sync(p1) |
|
|
|
|
| |
|
|
|
|