In this project, we experimented with manipulating images via their geometries: identifying key points, manipulating them, and then mapping the pixels onto the resulting new geometry. We used these techniques to generate smooth animations morphing one face into another, to calculate population means, to map one face onto the geometry of another, and to generate caricatures by extrapolating from the mean.
I chose points manually for the image of me and the image of George, in the same order each time. I focused on edges and important facial features: top of the forehead, eyes, nostrils, edges of the mouth, and bottom of the chin. I then used scipy's Delaunay implementation to generate triangles.
Generating the midway face required implementing a function morph
, which takes two images, their corresponding keypoints, a triangulation, and two fractions (one for warping, one for dissolving), and outputs a single image representing the combined image at the two fractions. I used RectBivariateSpline
(one spline for each channel) to interpolate pixels and settled on multiplying the destination triangle's vertex position matrix by the inverse of the source triangle's vertex position matrix - "fancier" techniques involving linear algebra solvers gave me nothing but trouble.
Choosing good points turns out to be a pain! George Clooney and I come from somewhat different genetic backgrounds. He's also much older - he has bags under his eyes that are more visible than mine, and it was hard to figure out a mapping that accounted for that.
Generating a morph sequence was a simple matter of calling morph
45 times with smoothly interpolated fractions and saving the result as a GIF with imageio.mimsave
.
I chose to work with the Danes for this part, since the dataset is annotated well, available freely, and almost a little tiny bit diverse (I think I've seen less diverse groups of Danish AI researchers, at least!). I did encounter some issues with the points that the researchers chose: they ignored the forehead completely, leading morph results to look a bit alien and rarely flattering.
Nevertheless, manually re-annotating the dataset was not within the time constraints of this project. I created keypoints for my own photo corresponding to those used in the Danish dataset.