In this exercise you will compare distances between high-dimensional vectors of human poses (from a dataset of badminton poses). The dataset contains 18 sample poses, each defined by 25 points $(x_i, y_i)$. Your task is to calculate the Euclidean distance ($L_2$-norm) between all poses.
The dataset is loaded and stored in an $18\times 50$-dimensional Numpy array:
import numpy as np
import matplotlib.pyplot as plt
poses = np.load("data/poses.npy")
Each row in poses
has the form $x_1, y_1, x_2, y_2, \dots, x_{25}, y_{25}$, i.e. it is a list of $50$ elements constituting $25$ points:
# Get the first pose and print it
print(poses[0])
[-27.99571178 -6.48683038 -0.11660905 -1.17064333 0.84333174 -1.17055863 1.40324612 -0.75536782 1.64424262 -0.39685233 -0.91658014 -1.19784466 -1.47706657 -0.75565014 -1.63809865 -0.67290277 -0.0346016 -0.2573026 0.52441385 -0.28487094 0.92472628 0.2406497 1.08637127 0.87586495 -0.35960773 -0.2296778 -0.75350502 0.46266449 -0.75767282 1.26336037 -27.99571178 -6.48683038 -27.99571178 -6.48683038 0.4412623 -1.52924351 -0.43720223 -1.53048571 -1.23831741 1.26319098 -1.39460965 1.34502082 -0.67480729 1.34740641 0.68458786 1.12472817 1.08424651 1.09708925 1.16224962 0.93142511]
Note that the output above is still a 1D array, it is simply printed over multiple lines
The following cell contains a set of functions for plotting the poses. You do not need to study these - simply skip to the next section:
def limb_number_plot(s_pose_x,s_pose_y,n1,n2,c="red",label=None,axis = None):
if label is not None:
if (s_pose_x[n1]>-10.0) and (s_pose_x[n2]>-10.0) and (s_pose_y[n1]>-10.0) and (s_pose_y[n2]>-10.0):
axis.plot([s_pose_x[n1],s_pose_x[n2]], [s_pose_y[n1], s_pose_y[n2]],color = c, linestyle="-",label=label)
else:
if (s_pose_x[n1]>-10.0) and (s_pose_x[n2]>-10.0) and (s_pose_y[n1]>-10.0) and (s_pose_y[n2]>-10.0):
axis.plot([s_pose_x[n1],s_pose_x[n2]], [s_pose_y[n1], s_pose_y[n2]],color = c, linestyle="-")
def plot_single_pose(s_pose, a, c = "darkgreen", label=None, head = True):
s_pose_x=s_pose[::2]
s_pose_y=s_pose[1::2]
limb_number_plot(s_pose_x,s_pose_y,2,5,c,axis=a)
if label is not None:
limb_number_plot(s_pose_x,s_pose_y,9,12,c,label,axis=a)
else:
limb_number_plot(s_pose_x,s_pose_y,9,12,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,2,9,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,5,12,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,2,3,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,3,4,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,5,6,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,6,7,c,axis=a)
#left leg / foot
limb_number_plot(s_pose_x,s_pose_y,9,10,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,10,11,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,11,22,c,axis=a)
#right leg / foot
limb_number_plot(s_pose_x,s_pose_y,12,13,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,13,14,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,14,19,c,axis=a)
# head
if head:
limb_number_plot(s_pose_x,s_pose_y,0,15,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,0,16,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,15,17,c,axis=a)
limb_number_plot(s_pose_x,s_pose_y,16,18,c,axis=a)
return True
The cell below visualises each pose in the dataset:
# Create a 6x3 grid of subplots
fig, ax = plt.subplots(3, 6, figsize=(14, 8))
for i, p in enumerate(poses):
axis = ax[i//6, i%6] # Select the appropriate subplot
plot_single_pose(p, axis)
axis.set_title(i)
axis.set_xlim(-5, 5)
axis.set_ylim(3,-3)
plt.tight_layout()
This task involves visual inspection of the poses.
In this task you will calculate the Euclidean distance ($L_2$ norm) between all the poses. Note that the distance is symmetric, such that the distance between pairs (a, b) and (b, a) are the same.
res
(the name is important as the variable is used below) such that the distance between poses[i]
and poses[j]
is in position $i, j$ in the matrix.# Write your solution here
The following cell creates an 18x18 distance matrix:
import seaborn as sns
t = np.triu(np.ones_like(res))
sns.heatmap(res, annot=True, mask=t)
The mandatory part of the exercise has to be entered in Grasple and requires you to complete question 1.
res
and plot them using the plotting function plot_pair
.res
and plot them.def plot_single(ax, i, p):
ax.scatter(p[:, 0], p[:, 1]) # Plot the pose coordinates
ax.set_title(i)
ax.set_xlim(-5, 5)
ax.set_ylim(3,-3)
def plot_pair(a, b):
"""Plot two poses side by side. a and b are indices.
"""
fig, ax = plt.subplots(1, 2)
ap = poses[a]
bp = poses[b]
plot_single_pose(ap, ax[0])
plot_single_pose(bp, ax[1])
#plot_single(ax[0], a, ap)
#plot_single(ax[1], b, bp)
# Write your solution here
Plot of min difference pose pairs
Plot of max difference pose pairs
Plot of random pose pairs
# write your reflections here