Project 4: Face Morphing

James Lin, CS194-26-abr

Morphs and Midways

The topic of this project was face morphing: warping triangulated faces from one image to another, while cross-dissolving the two at the same time. To start off, we computed the "average face" between two images. For instance, consider pictures of I (James Lin) and basketball player Jeremy Lin.


I created point pairs mapping features from my face to Jeremy's (i.e. nose to nose, eyes to eyes, etc.). From those points I created a triangulation, which separated the images into triangles. Computing affine warps for these triangles allowed me to warp either face to a different feature structure.

With this done, I warped both our faces to the average of the two point feature structures and averaged the pixel values to get the mid-way face.


After that, it was relatively trivial to create a smooth transition from my face to Jeremy's - I ran the script multiple times with increasing weights for the averages (both the warp weight, and the cross-dissolve weight) so that the results would go from my face to his.



Average Faces

After dealing with single image warps and morphs, I moved on to using larger datasets. Using the Danes image dataset, I computed an average face shape of a group of people. For comparison, I warped two of the original images (on the left) to the average face shape (on the right).



And here is the result of warping every face to the average face shape and averaging all them all.


The result is very smooth and symmetric. All the asymmetric portions got "averaged" away. I also warped my own face to that of the average geometry (left) and vice versa (right).


On the left, you'll notice my forehead has been enlongated. Since the labeled dataset only marks geometry around the face and not the head/hair, the algorithm doesn't know what to do with all my hair when it gets stretched downwards.

On the right, you can see that the right eye is warped. This is a result of me being bad at taking selfies - in the original image, the right side of my face is closer to the camera and tilted upward a little, causing the artifact you see.


Caricatures

Until now, all my interpolations were weighted between 0 and 1. What happens if we go outside that range? Doing so starts exaggerating the differences between one image and the other.

I took the image of myself and caricatured it by moving it away from the average. Here is the result of weighting my image by 2.2 (and thus the average image by -1.2).



Bells and Whistles

For my bells and whistles, I decided to morph myself with my cat, Sparky. By some miracle, I was able to get a picture of him sitting properly and looking at the camera.


And here is the morph result.


The biggest difficulty was in matching feature points around the cat's ears, which were a major feature difference that didn't exist on the image of me. You can see some artifacts on the left ear that are an effect of this issue. However, the general contour of the face seems to transition well considering how wildly different the two images are.