For Fa2024, I am taking an image processing class. One assignment is doing morphing WITHOUT NEURAL NETWORKS. So something like this:

0 0

(Morphing from my face to a girl)

There are some intermediate steps as well that I took. I do cariactures of myself as well as computing the mean face of a population.

This is a really cool video of super smooth facemorphing to music

Part 1 Link to heading

These are my source images:

0 0

First I need to compute features on both images. For that I used the dlib library to extract feature points for both images. Then I computed the half-way-point for each pair of points in the two images to get the half and half marph points. Then I calculated the delauney triangulization of the points so I can get a morphing triangle mesh.

You can see the triangulization and feature points are a bit smaller than the mans features and a bit bigger than the womans. 0

Part 2 Link to heading

Now I computed the mid-way face by calculating the affine transformation that gets one triangle on one image to when it should be in the midway point. This deformation is masked to the appropriate output triangle shape, and store in a triangle_array that stores all the deformed triangles with black outside the triangle.

To create the deformed face from the triangle_array, I just populate a black canvas with all the non-black parts of each image in the array.

Here is the woman and man morphed with weights 50/50 (so the half way point between the two)

0 0 0

Part 3 Link to heading

Now we will create a morph video. This is done by just changing the weighting from Part 2 from 50/50 to a dynamic weighting that goes from 100/0 to 0/100.

It is changing alpha = 0 -> 1 with output = image1 * alpha + image2 * (1 - alpha)

0 means completely image2 and 1 means completely image1.

0 0 0

Another one:

0 0 0

Part 4 Link to heading

Now we will compute the “average face” of some people.

I computed the average face shape of a danish face dataset by running the face landmark detector on all of them and taking the average position per point.

Here is the average face landmarks of a Dane on top of the average face of a dane:

0

The average dane look like this:

0

Here are some faces from the dataset morphed into the average danes shape:

0 0 0

Here is my face:

0

Here it is warped into the average dane shape:

0

Here is the average danes face warped to my face shape:

0

Part 5 Link to heading

I created a caricature of myself by extrapolating away from the average dane face shape. In other words, I set the weight to -1 instead of a number in the interval [0, 1] to exaggerate my features.

0

Extra credit Link to heading

Here is morphing synced to music of me from a kid to 21 years old

code