Overview

Given two images of faces, we want to produce a "morph" animation from one face to another face.

Approach

I used two images taken by Martin Schoeller; one of President Barak Obama, and another of Mark Zuckerberg.

Obama + Zuckerberg


First, we define the corresponding points between the two images using Python's ginput library.
Obama Points + Zuckerberg Points


Delaunay Triangulation: Obama (left), Zuckerberg (right)


Secondly, we compute the "mid-way" face between the two images. To do so, there are several steps.
  1. Compute the average triangulation of both images by taking the average of both image points, and computing Delaunay triangulation.
  2. Compute the affine projection for both points in the original images to the points in the average image.
  3. Define a mapping between a triangle and all of the pixels within its borders using skimage's draw_polygon function.
  4. For each pixel in each triangle, we get the corresponding original pixel by multipling by the inverse affine matrix for each image.
  5. Since these pixels may be "in-between" the original pixels, we use Python's interp2d function to give us the original image's pixel intensity.
  6. Finally, we take the average of these pixel intensities between the two images, and fill in our average image's color.
After computing the "mid-way" face, we set up a morph sequence to go from 0 to 1 with 45 frames in between. Each frame allows us to warp the (weighted) average image closer to the first or second image. Combining these frames gives us a gif that transforms one face to another face.

Conclusion

Being able to understand and implement the algorithms behind face warping made me appreciate more the work professionals do (see Michael Jackson's song "Black or White"). Although I was not able to fully implement the average between two faces, I enjoyed learning about Python's image procesing libraries and functions such as draw_polygon and Delaunay, as well as technqiues like cross-dissolve.