Home
Course Guidelines
About the course Prerequite Material References
Python
Jupyter Notebooks Python overview
Exercises
Before the semester start: Installation and exercise setup Week 1: Introduction to Python and libraries Week 2: Vector representations Week 3: Linear Algebra Week 4: Linear Transformations Week 5: Models and least squares Week 6: Assignment 1 - Gaze Estimation Week 7: Model selection and descriptive statistics Week 8: Filtering Week 9: Classification Week 10: Evaluation Week 11: Dimensionality reduction Week 12: Clustering and refresh on gradients Week 13: Neural Networks Week 14: Convolutional Neural Networks (CNN's)
Tutorials
Week 1: Data analysis, manipulation and plotting Week 2: Linear algebra Week 3: Transformations tutorial Week 4: Projection and Least Squares tutorial Week 7: Cross-validation and descriptive statistics tutorial Week 8: Filtering tutorial Week 11: Gradient Descent / Ascent
In-class Exercises
In-class 1 In-class 2 In-class 10 In-class 3 In-class 4 In-class 8
Explorer

Document

  • Overview
  • 1. Evaluating poses
  • 2. Pen and paper exercises

Content

  • Task 1 Visually inspect and compare poses
  • Task 2 Calculate pose distance
  • Task 3 Mandatory task
  • Task 4 Compare poses

Evaluating poses

Overview of tasks
  • Task 1: Visually inspect and compare poses
  • Task 2: Calculate pose distance
  • Task 3: Mandatory task
  • Task 4: Compare poses

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")
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])
# 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
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()
# 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()
Task 1: Visually inspect and compare poses

This task involves visual inspection of the poses.

  1. Choose the three pairs of poses that look most similar and note their indices.
  2. Choose the three pairs of poses that look least similar and note their indices.
Task 2: Calculate pose distance

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.

  1. In the cell below, calculate the Euclidean distance between each combination of poses and store the result in an $18\times 18$ matrix called 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
# 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)
import seaborn as sns
t = np.triu(np.ones_like(res))
sns.heatmap(res, annot=True, mask=t)
Task 3: Mandatory task

The mandatory part of the exercise has to be entered in Grasple and requires you to complete question 1.

  1. Determine the three most similar pose-pairs using the distances calculated in the distance matrix res and plot them using the plotting function plot_pair .
  2. Determine the three most dissimilar pose-pairs using the distances calculated in the distance matrix 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
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
Task 4: Compare poses
  1. Compare the pose-pairs you chose in Task 1 with the calculated pose-pairs. How well did your intuition match the calculated result?
# write your reflections here
# write your reflections here