Project 3

Face Morphing

Yuan-Hao Huang

yhhuang20@berkeley.edu

Overview

This project applies morphing techniques (including warping and cross-dissolving) to build visual effects. These tricks include face changing animation, extrapolation from the population, and changing identity and features of a person.

Part 1

I used the provided tool for labelling, and used scipy.spatial.Delunay to compute triangulation on the midway shape. Then I applied the triangulation on both images.

Me:
Wan-an Chiang (the mayor of Taipei City, Taiwan):
Me (labelled & triangulated):
Wan-an Chiang (labelled & triangulated):

Part 2

The most important part of this section is to derive the affine transformation matrix. Suppose \(T_i=\begin{bmatrix}a&b&c\\d&e&f\\0&0&1\end{bmatrix}\) is the matrix that maps the triangle \((0, 0), (0, 1), (1, 0)\) to \((A_x, A_y), (B_x, B_y), (C_x, C_y)\). Solving \[\begin{cases} \begin{bmatrix}a&b&c\\d&e&f\\0&0&1\end{bmatrix} \begin{bmatrix}0\\0\\1\end{bmatrix} = \begin{bmatrix}A_x\\A_y\\1\end{bmatrix}\\ \begin{bmatrix}a&b&c\\d&e&f\\0&0&1\end{bmatrix} \begin{bmatrix}0\\1\\1\end{bmatrix} = \begin{bmatrix}B_x\\B_y\\1\end{bmatrix}\\ \begin{bmatrix}a&b&c\\d&e&f\\0&0&1\end{bmatrix} \begin{bmatrix}1\\0\\1\end{bmatrix} = \begin{bmatrix}C_x\\C_y\\1\end{bmatrix} \end{cases}\] we get \[ T_i = \begin{bmatrix}C_x-A_x&B_x-A_x&A_x\\C_y-A_y&B_y-A_y&A_y\\0&0&1\end{bmatrix} \] and \[ {T_i}^{-1} = \frac{1}{\det{T_i}}\begin{bmatrix}B_y-A_y&A_x-B_x&B_xA_y-AxBy\\A_y-C_y&C_x-A_x&A_xC_y-A_yC_x\\0&0&(C_x-A_x)(B_y-A_y)-(B_x-A_x)(C_y-A_y)\end{bmatrix} \] Suppose we now want to map triangle 2 to triangle 1 using affine transformation \(T\). We can first map triangle 2 to \((0, 0), (0, 1), (1, 0)\) using \({T_2}^{-1}\), then map \((0, 0), (0, 1), (1, 0)\) to triangle 1 using \(T_1\). Thus, \[ T = T_1{T_2}^{-1} \] and its value can be easily obtained by above formulas and matrix multiplication.

scipy.ndimage.map_coordinates is used to find the pixel values in the origin image given the coordinates. Then skimage.draw.polygon is used as masks to identify the area of each triangle. Since all the masks do not align perfectly (because each triangle is built independently), there are some defects on the boundries in the output figures.

Me:
Wan-an Chiang:
Me (warped to midway shape):
Wan-an Chiang (warped to midway shape):
Averaged color:

Part 3

This part is basically the same as Part 2, except that the midway shape and color averaging are calculated as weighted average of the two figures. As for determining the weights, I found that for two images with similar colors (such as two human faces), using linearly increasing weights (i.e. w=0, 1/45, 2/45, 3/45, ..., 1 for 46 frames) for both shape and color would work well. However, if we are mixing two images that differ very much in colors, it would be better to change the shape more on the beginning and the end, while change the color more in the middle. We can use linear function for shape (warp_frac) and sigmoid function for color (dissolve_frac).

10 fps:
20 fps:
30 fps:

These are .gif so you'll need to view it on the website.

Part 4

I used the male faces in the Danes dataset. After calculating the average shape, I warped the faces into the average shape. Here are some examples.

Original:
Warped:
Original:
Warped:
Original:
Warped:
Original:
Warped:
The average face of the dataset (male only):
Me:
Me warped into the average shape:
Average face warped into my shape:

Part 5

A=Average Face, M=Me

My shape:

A*150%+M*(-50%)
A*100%+M*0%
A*50%+M*50%
A*0%+M*100%
A*(-50%)+M*150%

Average shape:

A*150%+M*(-50%)
A*100%+M*0%
A*50%+M*50%
A*0%+M*100%
A*(-50%)+M*150%

Bells and Whistles

I changed the gender of my face using the Average Taiwanese Female image found here.

Average Taiwanese Female:
Me:
Warp my face into the female's shape (change shape):
Warp the female face into my face, then cross-dissolve with me (change appearance):
Warp both my face and the females's face into our midway shape, then cross-dissolve (change both shapr and appearance):

References

numpy

numpy.matmul
numpy.ndarray.flatten
numpy.transpose
numpy.average
numpy.clip

scipy

spatial.Delaunay
ndimage.map_coordinates

scikit-image

skimage.draw.polygon

geeksforgeeks

Read JSON file using Python
Read a file line by line in Python

stackoverflow

How to display an image
When to use cla(), clf() or close() for clearing a plot
Save plot to image file instead of displaying it
Numpy matrix of coordinates
Programmatically generate video or animated GIF in Python?
How do I pad a string with zeros?
How can I check if a file exists in python? [duplicate]

w3schools

Python round() Function
Python Classes and Objects