The Jackson Transformation

Project Overview

A morph is basically a simultaneous warp of an image's shape and the cross-dissolve of an image's colors with another image. In this project, I created a "morph" animation of my face into another image, computed the mean of a population of faces, and extrapolated from a population mean to create a caricature(s) of myself.

Project Details

  • Mid-Way Face
  • Morph Sequence
  • Mean Face of a Population
  • Caricatures
  • Bells and Whistles

Mid-Way Face

The goal of this part was to compute the midway face of two images by warping them and cross dissolving them at alpha=0.5. To do this, I first took two images, my image and Mindy Kaling's. Then I picked a set number of corresponding points to define key features of the two images using matplotlib.pyplot.ginput() . To generate the mid way face, I first found the mean of the corresponding points for both images and generated a Trianglulation of those "mean" pts using scipy.spatial.Delaunay() . Then, using the triangles generated, I calculated the affine transform of each triangle corresponding to A and the Mean. The triangulation created an ideal mapping between the mean pts triangulation and the source pts triangulation. In turn,allowing me to retrieve the inverse points using this T that corresponds to each triangle. For the inverse transformation, I first generated a mask of each triangle skimage.draw.polygon(). Then I simply multiplied the Affine Matrix with each pixel point to find and paste the inverse pixel. Once I did the above for all triangles, I averaged the two warped images to get a midway face that was cross-dissolved with alpha of 0.5. Here are my results (hover over to see triangulation):

Morph Sequence

The goal of this part of the project is to take to images, A and B and morph them. Instead of using a constant alpha of .5 like in part 1, I computed intermediate points between frames. To do this, I varied the alpha or "warp factor" between the frames using the equation by addjusting the "dissolve factor" as 1/N where N is the number of Frames. Then to get the warp_factor I simply multiply current frame alpha = i * (1/N): (A * alpha) + B * (1 - alpha).
Then I applied the same triangulation, inverse warp, and cross-dissolve algorithm for midface across all frames to genearte the sequence of images. To generate the final gif I used imageio.mimsave(). For my first MorphSequence, I morphed my face into Mindy Kaling's face. To test this approach with multiple images, I also morphed the four generations of women in my family - great grandma, grandma, mom, and me!!! Here are my result(s):

Mrina Mindy Morph

Four Generations Morph

Mean Face of a Population

The goal of the project is to compute the mean face given a set of faces and their corresponding points. I used the Danes Dataset from the class's project spec and computed the mean face of all the Danish scientists. The data set consisted of 37 RGB images and 37 asf files that had the corresponding points for each image. First, I used standard python file reader to parse the asf files for corresponding points. Then, I took the average of all the corresponding points for each image from the asf files and generated a triangulation. I applied this triangulation to the corresponding points of each image in the dataset and computed the affine transform matrix. Next, for each image, I used the same algorithm that I used to compute the midface and found to inverse warp between the image and the average triangulation. This also computed the face of each Dane warped into the average face's structure. Once I had all the faces warped into the average I simply cross-dissolved the images onto each other and got the Mena Face of all the Danish Scientists.

The Mean Face of Danish Scientists

Danish Scientists warped into the Mean Face (Hover to see warp)

My Face warped into the Mean Face and the Mean Face warped into mine (Hover to see warp)


The goal of this part was to create a caricature of my face using the mean face generated in the previous part. To do this, I first computed the corresponding points for my face and for the mean face of the danes database. Then I took the difference between the two and added a scalar multiple alpha to the difference back on to my original corressponding points. Then using these points I generated a triangulation, and warped my face to that structure using the same warping process from previous parts. Here is my face warped into different alphas (NOTE: a negative alpha of .75 is basically interpolation and looks very similar to my face warped into the mean above):

alpha = -0.75

alpha = 0.5

alpha = .75

alpha = 1.00

Bells and Whistles

Music Video - Michael Jackson Over The Years
Class Video Participation (Frame 14)


Hands down my favorite project in this class so far!!! Honestly, warping faces to other faces was really cool. I think it's pretty neat how simple 3x3 affine transformations can achieve pretty smooth results. The hardest part about this project was finding images that work well together as well as selecting corresponding points. Special Thanks to Professor Efros for this project, the TAs, and wonderful peers on Piazza :)