Message Boards Message Boards

2 Replies
23 Total Likes
View groups...
Share this post:

Face symmetry from computer perspective

Posted 10 years ago
Which one of the people on photos below you recognize? There is quite a bit of research on facial symmetry linking it to some psychological, genetic, biological, and other phenomena. There are some curious facts, for example. While speaking ~ 76% of people tend to express greater amplitude of movement on the right side of their mouth. There is a potential link to the 'big-five' personality traits: openness, conscientiousness, extraversion, agreeableness, and neuroticism. As we age accumulated progressive changes in the soft tissues of the face tend to increase asymmetry with time. 

There is an interesting test to visualize asymmetry: compose (via cut & reflection) left with left side and right with right side portraits and compare them. As you can see on the photos below.

But there is a question can we automate this process? To us it is easy to understand where the axis of symmetry passes, but can a computer understand this? Especially for more asymmetric faces? In Wolfram Language there are perhaps many approaches to the problem. Here is one with ImageDistance as a measure for an optimization problem. Given pretty symmetric portrait of Lincoln: 

Lets define a function that can compare left and right "unequal halves" of an image i that is split vertically at pixel column x. 

splitF[i_, x_] := ImageDistance[
  ImageTake[i, All, {1, x}],
  ImageReflect[ImageTake[i, All, {x, -1}],Left -> Right], 
  DistanceFunction -> "MeanReciprocalSquaredEuclideanDistance"]

Now lets run x for several values around the middle and see where the minimum is:

i = Import[""];
Out[] = {400, 555}

ListPlot[splitL = Table[{splitF[i, k], k}, {k, 175, 225}]]

split = %[[1, 2]]

Out[]= 195

Now lets cut at column 197 and assemble the left- and right-symmetric faces - you will get the double Lincoln portrait sown above.

ImageAssemble@{ImageAssemble[{ImageTake[i, All, {1, split}],
    ImageReflect[ImageTake[i, All, {1, split}], Left -> Right]}],
  ImageAssemble[{ImageReflect[ImageTake[i, All, {split + 1, -1}],
     Left -> Right], ImageTake[i, All, {split + 1, -1}]}]}

Lets do the same thing with John Lennon but using a different DistanceFunction:

 g = Import[""];
 splitF[i_, x_] := ImageDistance[
   ImageTake[i, All, {1, x}],
   ImageReflect[ImageTake[i, All, {x, -1}],Left -> Right],
   DistanceFunction -> "MeanPatternIntensity"];
 ListPlot[splitL = Table[{splitF[g, k], k}, {k, 175, 225}]]
split = Sort[splitL][[1, 2]];

ImageAssemble@{ImageAssemble[{ImageTake[g, {1, -1}, {1, split}],
    ImageReflect[ImageTake[g, {1, -1}, {1, split}], Left -> Right]}],
  ImageAssemble[{ImageReflect[ImageTake[g, {1, -1}, {split + 1, -1}],
     Left -> Right], ImageTake[g, {1, -1}, {split + 1, -1}]}]}

Again you will get the double portrait of Lennon show at the top. Note the graph is different. Also the split column of curse is different. Choosing different DistanceFunction may give a very different result.
POSTED BY: Vitaliy Kaurov
2 Replies
Try it out on yourself with CurrentImage[]:
 Mirror[image_] :=
  Block[{width = First[ImageDimensions[image]]},
    With[{leftHalf = ImageTake[image, All, {1, x}],
      rightHalf = ImageTake[image, All, {x, -1}]},
          ImageReflect[leftHalf, Left -> Right]}],
        ImageAssemble[{ImageReflect[rightHalf, Left -> Right],
       }, "  "], ImageSizeMultipliers -> {}]
   {{x, width/2, ""}, 1, width, 1}

Nifty app -- it's even more fun when turning one's head a bit! For example:

POSTED BY: Andre Kuzniarek
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract