Face Morphing
Varun Saran
To define correspondences, I selected 56 points (including 4 corners) on each face image. These points represent features that are matched between 2 images. This picture shows the 56 points on an image of Steph Curry.
To calculate a triangulation, I used Delauney triangulation, as shown in this image.
I followed these steps to create the midway face: 1. Compute the “average shape” by averaging the key point locations of the 2 images. 2. Warp both faces into that average shape 3. Given the 2 warped images, average the colors together to get a morphed image. To warp 2 faces, I had to find an affine transformation to warp each triangle in one image, to the corresponding triangle in the other. Affine transformations have 6 variables, so 3 sets of (x,y) coordinates is enough to solve the system. Once we know how to warp one triangle into its corresponding shape, we just have to loop over all triangles, and warp them all to match the new shape.
Instead of doing this forward warping, however, I did inverse warping. Forward warping creates holes in the result image because not every point needs to be hit, like if a small triangle gets mapped to a much larger one. So instead of warping the source image’s triangles to the destination, I warped the destination’s triangles to the source.
For the average image, the features of the 2 images were averaged. To create a gif animation, however, we need a gradually changing set of features. I used 45 frames, so my features were gradually changed from image 1’s features to image 2’s features.
I used the Danes dataset found here: https://web.archive.org/web/20210305094647/http://www2.imm.dtu.dk/~aam/datasets/datasets.html It includes pre-selected key points, so I didn’t need to manually select points for each of the images. For my project, I only used image type 1, which is a full frontal face with a neutral expression. I also only used the male subpopulation because I thought a male/female midway mix could have weird translucent hair. 1. The average face shape was calculated by averaging the key points across all the images. 2. Each face was then morphed into the average shape.
here are some results of morphing a few Danes into the shape of the average Dane. The numbers I use are from the original numbering used in the dataset.
3. To compute the average face, I just averaged all the pixel values at each point. The results show a very smooth, symmetric face as shown here. Here are some results of Steph Curry morphed into the shape of an average Danish male: And here is the average Dane morphed into Steph Curry’s shape:
Caricatures are just images of people with overly exaggerated features. To make Steph Curry extra Danish, instead of doing a midway morph with the average Dane, we can take Steph’s features, and add a scaled vector of the difference between steph and the average dane New features = steph_features + alpha*(dane_features - steph_features) A positive alpha makes Steph look more Danish, and a negative alpha makes him look less Danish. Resulting images can be seen here:
I changed the age of my friend, using an average 10 year old male picture found online (source: http://faceresearch.org/demos/images/thumbs/avg_res/age/10_male), and separately using an average baby (source: http://faceresearch.org/demos/images/thumbs/avg_res/age/baby).
Chain of morphs with my friends. For this part, I asked my friends for pictures of themselves, and morphed one person to the next. The results vary. Going from someone with long hair to someone with short hair looks a little strange, and differences in background also take away from the morph. My favorite transition was between my 2 roommates, whose pictures had the same background, and they both have short hair. The result is extremeley smooth and honestly each of the middle frames could be an actual person.