CS 194-26: Image Manipulation and Computational Photography

Morphing Faces

Florin Langer, Fall 2018

Defining Correspondences

I made a program that allows a user to select corresponding points between two images in order. This part was especially difficult because the correspondences kept getting corrupted, which I diagnosed the cause of by taking only one correspondence at a time and then replotting all previous correspondences each time I would take a new one to see when the points moved. It turned out to be an issue with my computer's trackpad sporadically double-clicking. After such a headache, I, of course, saved these correspondences to a file.

Correspondences Number of Correspondences
Florin Points 55
Dash Points 55
Both Points 55
Florin Points 56
Merkel Points 56
Both Points 56

Computing the Mid-Way Face

I calculated the average of every correspondence (pair of points between images) and computed a Delaunay triangulation for those average points. I used that same triangulation for the other two sets of points to ensure triangles would match up. I then interpolated over the R,G,B bands in images to have sensible values for intermediate pixels. I went on to iterate over the Delaunay triangles and compute an affine transformation between each of those and each triangle in each image. Within each iteration, I would compute all the points within that triangle and iterate over those to calculate the spatial transformation for that pixel and assign it the appropriate color values from the interpolation function.

Triangulations Number of Triangles
Average Triangulation 104
Florin Triangulation 104
Dash Triangulation 104
Average Triangulation 106
Florin Triangulation 106
Merkel Triangulation 106
Florin Warp to Mean
Dash Warp to Mean
Mid-Way Face
Florin Warp to Mean
Merkel Warp to Mean
Mid-Way Face

The Morph Sequence

I created a morph of 45 frames at 30 frames per second using much of the same technique from the previous section, only adding a morph fraction and dissolve fraction. The morph fraction is used to calculate the points to warp to in each iteration by multiplying the first image's points by 1 - warp fraction and the second image's by warp fraction and adding the results. The dissolve fraction is used in the same way to weight the interpolation values. I set both to be the current iteration divided by the total number of frames.

I encountered quite a challenge with my chin's morphing to Dash's because the triangles became too thin and would visibly splinter upon intermediate warps. This is simply because I could not include more of my body in the photo without vertically squishing it first since my head is taller than Dash's. Not including correspondences for the chin resolved this but made my chin stretch to about my neck's length. This was not an issue in the Flerkel morph.
Darin Morph via GIPHY
Flerkel Morph via GIPHY

The Mean Face of a Sample

I used 50 of the 200 images of non-smiling people from the FEI Face Database to compute the mean on. I used these photos because they most closely match my expression in my own photo and only these are prelabeled with correspondences. My code was essentially the same as before but now allowing the mean to be calculated over any number of images.

Person 2
Person 8
Person 46
Triangulations Number of Triangles
Average Triangulation 94
Person 1 Triangulation 94
Florin Triangulation 104
Mean Face of Sample
Person 2 Warp to Mean
Person 8 Warp to Mean
Person 46 Warp to Mean
Florin Warp to Mean
Mean Warp to Florin


I extrapolated from the mean face to accentuate my features.

Caricatures Warp Fraction

Morphing Dogs

For my bell and whistle, I morphed two dogs.

Dog 1
Dog 2
Dogg Morph via GIPHY