Project 3: Face Morphing


In this assignment I implemented the warping algrithm and created a video of morphing images together.

Defining Correspondences

In the first part of this project, I use ginput() to pick 50 points, in addition to the 4 corners, and save them into a txt file so that they can be loaded the next time I use them. The points are selected in the same order so that they correspond to each other. Then I used Delaunay triangulation to the midway of the two point sets with consistent labeling. This is completed with the Delaunay function.
My Face Another women's face

Computing the "Mid-way Face"

In the second part of the project, I used the two images to do a morph at the midway. I first find the average shape by taking the average of each correspondance in my point set. Then I implemented a computeAffine function that outputs a transformation matrix between pairs of triangles, and then inverse warp all the pixels using RectBivariateSpline (interpolation). Polygon only checks the pixels inside the polygon so that I do not need to loop over pixels.

The original A and B images and the mid-way face are shown here.

Original A Mid Original B

The Morph Sequence

In this part I implemented a morph function to generate a warp between 2 images. I used a loop to generate a sequence of morphed images with different fracs. Then I used to make the gif.

The sequence is generated by first setting both hyperparameters to 0, and then increase by 1/44 in every iteration. In the end both of them are 1.

The "Mean face" of a population

In this part, I used Danes dataset to generate an average face of females by first computing the average shape and then morph each faces into the average shape. This is the average face, my face warped into the average geometry, and the average face warped into my geometry. Both color and shape differ when I try to warp my face into average geometry versus the other way round. Since my face has an additional alpha channel, I tried another comparison with an image in the Danes dataset. This seems to be more vivid and fits better.

Average Face Me to Average Average to Me
Average Face Female to Average Average to Female

Caricatures: Extrapolating from the mean

In this part, I produced a caricature by taking the difference between the first female face and the mean female population face, and then multiply it by a factor and add back to the face of the first female. The reason that I did not use my own photo is because my own photo has an alpha channel causing the difference in the dimension of the images.

Difference Output = Original + different * 0.6

Bells and Whistles

I used the first male face in the Danes dataset and try to morph just the shape, just the appearance, and both. The algorithm I used is pretty much the same as in the previous parts, while the hyperparameters various to realize "only shape" and "only appearance". The output I get is as follows.

Shape Only Appearance Only Both