CS 194-26 Project 3: Face Morphing


In this project I learned how to smoothly morph one face into another face as well as how to average a set of faces and change "my face" using that average. For this project, I did not have a usable picture of myself available, so isntead I am using Stephen Curry as my face.

Note: The images on this site do not have captions, but they do have titles which are visible after hovering over the images.

Defining Correspondences

First I chose aligned pictures of Stephen Curry and Lebron James to morph together. I then used ginput to define correspondences between the two images. I ended up doing 50 points for each image as well as 4 extra points for the corners. Finally, I used scipy’s Delaunay function to compute the triangulations.

Computing the "Mid-way Face"

To compute the "mid-way face," I first found the average shape of the triangulations for each image. Then I inverse warped (using affine matrices and interpolation) the color and shape of the two original images together to get the result.

The Morph Sequence"

The final morph sequence was simply computing 45 different "mid-way faces." Instead of combining the average of each image, I used 45 weight from 0 to 1. Then, I combined the resulting frames into a gif.

The "Mean Face" of a Population

For this section, I used the dataset of Danish Computer Scientists. I used the labeled dataset to find the average shape of the Danish Computer Scientists and morphed all the faces into this average shape. Here are some examples:

To find the mean face, I simply averaged all of the morphed images together.

To morph "my face" (Curry's face) into the average face shape and vice versa, I first had to resize and label "my face" following the same ordering as the dataset. Then I was able to calculate Curry's face warped into the average geometry, and the average face warped into Curry's geometry, using the average shape as the points for the mean face. Here are the results:

Caricatures: Extrapolating from the Mean

To extrapolate from the mean, I used the formula: image1_pts + alpha*(image1_pts - image1_pts) to add more and subtract some of Curry's features. The first two caricature use alpha = -1 and alpha = -0.5, meaning I added more of Curry's features to his face. The third caricature uses alpha = 0.5, meaning I removed some of Curry's unique features, bringing his face closer to the average.

Bells and Whistles

For Bells and Whistles, I changed the gender of "my face". I first calculated the average female Danish Computer Scientist's face. Then I used that to morph Curry's face into the averge female face shape, morph the average female face into Curry's face shape, and compute a mid-way image between the average female Danish Computer Scientist's face and Curry's face.


Overall, this was a very interesting project, though it was quite difficult in my opinion. One piece of advice I would like to share to the course staff is: the ordering of points for the Danes Dataset should be provided. I was having a lot of trouble replicating the same ordering on "my face" until another student posted the ordering on Piazza.