I used this correspondence tool from a previous semester’s student to find corresponding points between my two faces. I loaded in the points from the resulting JSON file and used scipy.spatial.Delaunay
to produce tri
for both images. Then I used plt.triplot
on tri.simplices
to view the resulting triangles.
Input Images | Correspondences | Triangulation |
---|---|---|
To create the midway image, I needed both images and their correspondence points, along with the warp amount and dissolve amount. The warp and dissolve amounts are both 0.5 for this part of the project. I computed the midway points by doing (1.0 - warp_amt) * im1_points + warp_amt * im2_points
. Then, I computed the Delunay triangles. For each of the N
corresponding triangles for both images, I computed the affine transformation for each and solved for the 6 unknowns.
Then, I used skimage.draw.polygon
to find all the points that were within the triangle. I multiplied these coordinates by the inverse affine matrix. I also clipped the resulting x and y values to ensure that they remained within the image. I didn’t select many correpondence points below shoulder level, so this explains why the midway face there is more overlapped.
Input Image 1 (Kavya) | Input Image 2 (Ramya) | Midway Face |
---|---|---|
As per the instructions, I computed a morph sequence with 45 frames (with 0 fully being image 1 and 45 fully being image 2). Each frame’s duration is around 1/30th of a second. The warp amount and dissolve amount is determined by i / x
, where i
is the current frame number and x
is the number of frames.
I also computed another morph sequence where I used 100 frames, with each having a duration of 1/20th of a second.
I used the FEI Face Database as my dataset. I downloaded the points from frontalshapes_manuallyannotated_46points
and the datasets from frontalimages_spatiallynormalized
. I combined both folders (parts 1 and 2) into one final folder. To generate the average correspondence points of the population, I averaged the coordinate values. The images marked with an a
had a neutral expression, while the images marked with a b
had a happy/smiling expression. Thus, I generated two mean images so we could have separate ones per expression. For the mean population image, I used the points from each image and the average image to create the warped image. I used a warp amount of 0.5 and a dissolve amount of 0.
Here are some images (both neutral and happy) from the dataset that were warped to fit the average face shape.
Original Neutral Image | Warped Neutral Image | Original Happy Image | Warped Happy Image |
---|---|---|---|
Here are the images of the mean faces, as well as me warped into the mean face shape and vice versa.
Mean Face Neutral | Mean Face Happy |
---|---|
Mean Face Neutral -> Ramya | Ramya -> Mean Face Neutral |
---|---|
To generate the caricature, I changed the warp amount to no longer be in between 0 and 1. The warp amount is factored into the midpoints as such: (1.0 - warp_amt) * im1_points + warp_amt * im2_points
. I warped my face based on the neutral mean image. I got the following results with larger warp values:
Warp Amount = 1.5 | Warp Amount = 2 |
---|---|
Two noticeable differences are that my eyes are larger/further apart, and my chin is smaller.
I chose an image of an average Indian man that I found online to try and change my gender.
Me | Average Indian Man |
---|---|
Change Appearance | Change Shape | Change Shape + Appearance |
---|---|---|