CS194-26 Project 4: Face Morphing

By Kaiwen Zhou

Overview

In this project, we implement a face morphing algorithm to morph from one face to another. We then compute the "average face" of a population of faces, morph our face into it, and create a caricature of ourselves by extrapolating from the population mean.

Morphing implementation

In order to morph between two faces, we must first select corresponding points of interest on their images to be morphed between. From these point sets, we create a Delaunay triangulation based on the average points of the two sets. We then define a warp fraction and dissolve fraction to determine the specific interpolation between the two images.

We have an interpolated triangulation that we wish to warp both images to. In order to do this, we solve for the affine matrix resulting from transforming the triangles of the original image to the triangulation we desire, and applying that affine matrix transformation to all the points within their matching triangles. We do this through an inverse warp, in which we take the points of the warped triangulation that we desire and use our affine matrix to determine the pixels of the original images that we wish to sample from. The resulting affine matrix was of the form:

[[a, b, tx]
[c, d, ty]
[0, 0, 1]]

with 6 degrees of freedom, as makes sense for an affine transformation. These corresponded to pre-transformation and pre-transformation column vectors of the form:

[[x1, x2, x3]
[y1, y2, y3]
[ 1, 1, 1]]

One of my speed optimizations in order to avoid multiple nested loops involved using a sparse dictionary of keys matrix when generating each triangle mask, because it allowed for fast storage and retrieval of coordinates. I also multiplied all of the points of a triangulation all at once with its corresponding affine matrix. The resulting image morph gifs are a combination of 45 frames dividing the morph. The final morphed image was a combination of a fraction of the first morphed image and the rest of the second morphed image.

Results

anne hathaway to taylor swift morph
original anne hathaway image
original taylor swift image
taylor-hathaway midway image

Mean face of a population

We use our morphing algorithm to compute the average face of a dataset of faces. In this project, we are using the Danes image set. Thankfully, all the images are pre-annotated for our use - we simply use take these points, take the average point set of all of our images of interest (the subpopulation I used was all males) and then triangulate based on the average points. Then, we morph all of the images of interest into our average point set in order to obtain the average face, as shown below.

Additionally, I played around by morphing my face into the shape of the average danish face, and vice versa. The results aren't the best looking.

Results

average face of danish male imageset
my face
morph from my face into the average danish face
morph from the average danish face into my face

Caricature

Caricatures of one's face can be obtained by taking the difference between one's face & the average face, and extrapolating based on that (essentially just adding that differential multiplied by a factor of 0.8 to the points of my face and morphing it to that). This essentially exaggerates the features of my face that make it unique compared to the average face.

caricature of my face

Bells and Whistles: Morphing from Male to Female

Here I attempt a failed example of a morph from my face to make it more feminine. I morphed my face into the average male Chinese Actor face, and then added the differential between male and female Chinese Actor/Actresses. The result looks unaesthetic, probably because my face is a lot more round than these averages, and morphing it into such a substantially different face shape just doesn't work out.

average of chinese actors
average of chinese actresses
my cropped face
morph into chinese actor
extrapolation from self-actor to female