Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Fixing Logical Errors and Removing "TODO REMOVE" code #201

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 41 additions & 42 deletions common/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#

import matplotlib

matplotlib.use('Agg')

import matplotlib.pyplot as plt
Expand All @@ -14,14 +15,16 @@
import numpy as np
import subprocess as sp


def get_resolution(filename):
command = ['ffprobe', '-v', 'error', '-select_streams', 'v:0',
'-show_entries', 'stream=width,height', '-of', 'csv=p=0', filename]
with sp.Popen(command, stdout=sp.PIPE, bufsize=-1) as pipe:
for line in pipe.stdout:
w, h = line.decode().strip().split(',')
return int(w), int(h)



def get_fps(filename):
command = ['ffprobe', '-v', 'error', '-select_streams', 'v:0',
'-show_entries', 'stream=r_frame_rate', '-of', 'csv=p=0', filename]
Expand All @@ -30,35 +33,35 @@ def get_fps(filename):
a, b = line.decode().strip().split('/')
return int(a) / int(b)


def read_video(filename, skip=0, limit=-1):
w, h = get_resolution(filename)

command = ['ffmpeg',
'-i', filename,
'-f', 'image2pipe',
'-pix_fmt', 'rgb24',
'-vsync', '0',
'-vcodec', 'rawvideo', '-']
'-i', filename,
'-f', 'image2pipe',
'-pix_fmt', 'rgb24',
'-vsync', '0',
'-vcodec', 'rawvideo', '-']

i = 0
with sp.Popen(command, stdout = sp.PIPE, bufsize=-1) as pipe:
with sp.Popen(command, stdout=sp.PIPE, bufsize=-1) as pipe:
while True:
data = pipe.stdout.read(w*h*3)
data = pipe.stdout.read(w * h * 3)
if not data:
break
i += 1
if i > limit and limit != -1:
if i < limit and limit != -1:
continue
if i > skip:
yield np.frombuffer(data, dtype='uint8').reshape((h, w, 3))






def downsample_tensor(X, factor):
length = X.shape[0]//factor * factor
length = X.shape[0] // factor * factor
return np.mean(X[:length].reshape(-1, factor, *X.shape[1:]), axis=1)


def render_animation(keypoints, keypoints_metadata, poses, skeleton, fps, bitrate, azim, output, viewport,
limit=-1, downsample=1, size=6, input_video_path=None, input_video_skip=0):
"""
Expand All @@ -71,7 +74,7 @@ def render_animation(keypoints, keypoints_metadata, poses, skeleton, fps, bitrat
-- 'filename.gif': render and export the animation a gif file (requires imagemagick).
"""
plt.ioff()
fig = plt.figure(figsize=(size*(1 + len(poses)), size))
fig = plt.figure(figsize=(size * (1 + len(poses)), size))
ax_in = fig.add_subplot(1, 1 + len(poses), 1)
ax_in.get_xaxis().set_visible(False)
ax_in.get_yaxis().set_visible(False)
Expand All @@ -83,11 +86,11 @@ def render_animation(keypoints, keypoints_metadata, poses, skeleton, fps, bitrat
trajectories = []
radius = 1.7
for index, (title, data) in enumerate(poses.items()):
ax = fig.add_subplot(1, 1 + len(poses), index+2, projection='3d')
ax = fig.add_subplot(1, 1 + len(poses), index + 2, projection='3d')
ax.view_init(elev=15., azim=azim)
ax.set_xlim3d([-radius/2, radius/2])
ax.set_xlim3d([-radius / 2, radius / 2])
ax.set_zlim3d([0, radius])
ax.set_ylim3d([-radius/2, radius/2])
ax.set_ylim3d([-radius / 2, radius / 2])
try:
ax.set_aspect('equal')
except NotImplementedError:
Expand All @@ -96,7 +99,7 @@ def render_animation(keypoints, keypoints_metadata, poses, skeleton, fps, bitrat
ax.set_yticklabels([])
ax.set_zticklabels([])
ax.dist = 7.5
ax.set_title(title) #, pad=35
ax.set_title(title) # , pad=35
ax_3d.append(ax)
lines_3d.append([])
trajectories.append(data[:, 0, [0, 1]])
Expand All @@ -113,14 +116,10 @@ def render_animation(keypoints, keypoints_metadata, poses, skeleton, fps, bitrat
all_frames.append(f)
effective_length = min(keypoints.shape[0], len(all_frames))
all_frames = all_frames[:effective_length]

keypoints = keypoints[input_video_skip:] # todo remove
for idx in range(len(poses)):
poses[idx] = poses[idx][input_video_skip:]


if fps is None:
fps = get_fps(input_video_path)

if downsample > 1:
keypoints = downsample_tensor(keypoints, downsample)
all_frames = downsample_tensor(np.array(all_frames), downsample).astype('uint8')
Expand All @@ -133,31 +132,32 @@ def render_animation(keypoints, keypoints_metadata, poses, skeleton, fps, bitrat
image = None
lines = []
points = None

if limit < 1:
limit = len(all_frames)
else:
limit = min(limit, len(all_frames))

parents = skeleton.parents()

def update_video(i):
nonlocal initialized, image, lines, points

for n, ax in enumerate(ax_3d):
ax.set_xlim3d([-radius/2 + trajectories[n][i, 0], radius/2 + trajectories[n][i, 0]])
ax.set_ylim3d([-radius/2 + trajectories[n][i, 1], radius/2 + trajectories[n][i, 1]])
ax.set_xlim3d([-radius / 2 + trajectories[n][i, 0], radius / 2 + trajectories[n][i, 0]])
ax.set_ylim3d([-radius / 2 + trajectories[n][i, 1], radius / 2 + trajectories[n][i, 1]])

# Update 2D poses
joints_right_2d = keypoints_metadata['keypoints_symmetry'][1]
colors_2d = np.full(keypoints.shape[1], 'black')
colors_2d[joints_right_2d] = 'red'
if not initialized:
image = ax_in.imshow(all_frames[i], aspect='equal')

for j, j_parent in enumerate(parents):
if j_parent == -1:
continue

if len(parents) == keypoints.shape[1] and keypoints_metadata['layout_name'] != 'coco':
# Draw skeleton only if keypoints match (otherwise we don't have the parents definition)
lines.append(ax_in.plot([keypoints[i, j, 0], keypoints[i, j_parent, 0]],
Expand All @@ -179,25 +179,24 @@ def update_video(i):
for j, j_parent in enumerate(parents):
if j_parent == -1:
continue

if len(parents) == keypoints.shape[1] and keypoints_metadata['layout_name'] != 'coco':
lines[j-1][0].set_data([keypoints[i, j, 0], keypoints[i, j_parent, 0]],
[keypoints[i, j, 1], keypoints[i, j_parent, 1]])
lines[j - 1][0].set_data([keypoints[i, j, 0], keypoints[i, j_parent, 0]],
[keypoints[i, j, 1], keypoints[i, j_parent, 1]])

for n, ax in enumerate(ax_3d):
pos = poses[n][i]
lines_3d[n][j-1][0].set_xdata(np.array([pos[j, 0], pos[j_parent, 0]]))
lines_3d[n][j-1][0].set_ydata(np.array([pos[j, 1], pos[j_parent, 1]]))
lines_3d[n][j-1][0].set_3d_properties(np.array([pos[j, 2], pos[j_parent, 2]]), zdir='z')
lines_3d[n][j - 1][0].set_xdata(np.array([pos[j, 0], pos[j_parent, 0]]))
lines_3d[n][j - 1][0].set_ydata(np.array([pos[j, 1], pos[j_parent, 1]]))
lines_3d[n][j - 1][0].set_3d_properties(np.array([pos[j, 2], pos[j_parent, 2]]), zdir='z')

points.set_offsets(keypoints[i])

print('{}/{} '.format(i, limit), end='\r')


fig.tight_layout()
anim = FuncAnimation(fig, update_video, frames=np.arange(0, limit), interval=1000/fps, repeat=False)

anim = FuncAnimation(fig, update_video, frames=np.arange(0, limit), interval=1000 / fps, repeat=False)
if output.endswith('.mp4'):
Writer = writers['ffmpeg']
writer = Writer(fps=fps, metadata={}, bitrate=bitrate)
Expand Down
2 changes: 1 addition & 1 deletion data/prepare_data_humaneva.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,4 @@

print('Saving...')
np.savez_compressed(output_prefix_2d + args.output, positions_2d=output, metadata=metadata)
print('Done.')
print('Done.')
2 changes: 1 addition & 1 deletion run.py
Original file line number Diff line number Diff line change
Expand Up @@ -859,4 +859,4 @@ def run_evaluation(actions, action_filter=None):
for subject in all_actions_by_subject.keys():
print('Evaluating on subject', subject)
run_evaluation(all_actions_by_subject[subject], action_filter)
print('')
print('')