I thought today while watching England vs. Tunisia that soccer players look very much alike, especially within a team, and so I thought I could compute the average face by soccer team for this world cup.
Getting the data, in this case, images for each player in the current soccer world cup is arguably critical. The images need to have a plain background, similar illumination, and ideally, equal size. Luckily, the FIFA has done all of this, and the images are available online: https://www.fifa.com/worldcup/players/
If you inspect one of the player’s elements, you can access the URL for the player’s image, which can then be downloaded programmatically.
I extracted the page’s source code, and downloaded the 736 300 by 300 pixels images corresponding to all players in the world cup (32 teams by 23 player per team = 736).
Averaging a face
Average face is a loosely defined term; a naive implementation could be to treat the images as numerical matrices and use NumPy to average their value. This is only a few lines of code:
import numpy as np import imageio countries = ['argentina', 'belgium', 'colombia', 'croatia', ...] for country in countries: images_stacked = np.zeros((23, 300, 300, 3)) for i in range(0, 23): images_stacked[i] = imageio.imread('images-input/%s/%s_%s.jpg' % (country, country, i)) results = np.zeros((300, 300, 3)) for color in range(0, images_stacked.shape): for x_pos in range(0, images_stacked.shape): for y_pos in range(0, images_stacked.shape): results[x_pos, y_pos, color] = np.mean(images_stacked[:, x_pos, y_pos, color]) imageio.imwrite('images-output/%s_naive_averager.png' % country, results)
There is room for improving on this code, but I am not interested in that, rather on the actual results. And here is how they show:
Let’s look at another example:
Even though images are standard, averaging the pixel values doesn’t build a compelling picture; sure, we can distinguish some features such as color of the t-shirt or hair, but we can’t “put a face to it”. We need to think of something else…
Of course there is a better way, meet Face Morpher (FM from now own). FM works in a different way to find the average face, instead of averaging the pixel values, it builds a geometry of the face by identifying elements on it, such as the eyes or cheeks. It then proceeds to average those sections across images.
The results are much more compelling, and we are definitely able to put a face to this teams now.
Or in the case of Brazil:
It looks great! And yet, aren’t we missing important and distinctive elements, such as the hair, ears, or even team t-shirt?
I decided to them combine the two images: naive + FM for a more compelling result. I blended the images using Sketch, the naive average serves as background, and overlayed on top a semi-transparent FM face.
Quite happy with the result:
How does the average face look across all countries then?
Congratulations to France 🇫🇷 on this World Cup, and hope you had fun watching the games and reading through this visualization. Comment if you like!