CS 194-26: Computational Photography, Fall 2017

Project 4: Face Morphing

Tom Cheng, cs194-26-aev



The Morph

Below, I've briefly outlined the steps I took to morph two photos.

  1. Define Correspondences: In each image, pick the same number of corresponding points. I implemented this using matplotlib.pyplot.ginput.
  2. Computing the "Mid-Way" Face: Given any two images and their corresponding points, we have to compute essentially the "middle frame" of this morph. We can do this by computing a Delauney triangulation of our corresponding points and using that to compute an affine transformation. Using this affine transformation, we "warp" our "starting photo" to achieve the mid-way face.
  3. Creating the Sequence: With this warp function, we're able to generate a sequence to generate a gif. We can achieve this by calling on our warp function with various warp fractions from 0 to 1.

George
Pitt
Mid-Way
George to Pitt

The "Mean Face" of a Population

Now that we can morph between two photos given corresponding points, we move onto datasets to compute the average face of a population. For this, I've decided to use the Danes dataset. Like before, I've briefly outlined the steps I took to compute the average face.

  1. Create a file parser to obtain our points.
  2. Compute the averages of all the points from our photos.
  3. Warp all photos with the average points.
  4. Add all warped images together and take the average.

Average Face for Danes Dataset

Original Face
Face image warped to average geometry
Original Face
Face image warped to average geometry
My Geometry to Average Danish
Average Danish to my Geometry

The point selection here wasn't of the finest quality. I certainly do apologize in advance for any nightmares that I might have caused.

Caricatures: Extrapolating from the Mean

Lastly, we create caricatures to "exaggerate" certain characteristics. Like before, I've briefly outlined the steps below.

  1. Given two images and their corresponding points, we can compute the average between their geometries.
  2. Subtract our "beginning geometry" from our average. This will be our differences.
  3. By multiplying the differences calculated above by some number greater than 1, we can exaggerate those differences.
  4. Add the expaggerated differences to our "beginning geometry" and warp the beginning geometry with the sum (end) geometry.

Multiplied differences by 1.5

Bells and Whistles: Changing ethnicity

I used the previous code to make myself appear more German.

German Average
More German Me

Bells and Whistles: Tom to Pikachu

I wanted to explore how extreme angles might affect the morph. To do this, I employed the help of a long time idol, Pikachu. Pikachu has some pretty long ears popping out of it. How will this affect my morph? I experimented and realized that the ears have quite an impact on my morph in that it'll cause a "ghost" to form right above my head as the very angular ears morphed back into my head. It's quite hard to describe in text. However, if you look at the top of the image, there's very faint outline of my hair up at the top. Nonetheless, this was quite a cool experiment, and I enjoyed having Pikachu's company in my project.

Tom to Pikachu

Note: I regret so hard not getting a haircut before this assignment. My mushroom top hair of a head really messed up the results. I apologize. =(

The End.

Thanks so much for reading!