Calculate face asymetry index

By Jerzy Dziewierz for AGH-UST Krakow, Poland

This script allows to explore properties of differient methods of calculating asymetry index. Note that all calculations are done on relative coordinates(range 0-1). They are converted to pixels on plotting, and to "face units" on indexes calculation.

Contents

Read image and setup constants used later

img=imread('duzy.jpg'); % read image
img2=img(1:1200,1:1200,:); % cut a subset of a image
xmax=1200; ymax=1200;
ftobj = fittype('p1+p2*x'); % prepare centerline fitting function
figure(1) % open figure
clf % clear it
image(img2); % display image
axis image % scale display to fit image
hold on % prepare to add aditional plots
clc % clear console output

Set reference points

Note: this part may be replaced with UI for point input

lx=[0.37 0.37 0.42 0.40];  % left points x
ly=[0.39 0.55 0.67 0.78];  % left points y
rx=[0.57 0.58 0.55 0.56];  % right points x
ry=[0.39 0.55 0.67 0.82];  % right points y
plot(lx*xmax,ly*ymax,'rx',rx*xmax,ry*ymax,'bx');

Calculate "Face Unit" scaling value

Let's use eye distance as a face unit

fu=sqrt((lx(2)-rx(2)).^2+(ly(2)-ry(2)).^2); % eye points are on position "2".

Calculate midpoints

mx=(lx+rx)./2; % average of x coordinates
my=(ly+ry)./2; % and average of y coordinates
plot(mx*xmax,my*ymax,'go');

Fit a centerline (symetry line) into midpoints

cfobj = fit(my',mx',ftobj,'Startpoint',[0.3 0.18]); % execute fitting
sy=[0.2 0.9]; sx=cfobj(sy); % calculate centerline endpoints
plot(sx*xmax,sy*ymax,'y:'); % plot result
disp(sprintf('Symetry line: x=%2.4f+%2.4f*y',cfobj.p1,cfobj.p2)); % feedback result to console
Symetry line: x=0.4596+0.0298*y

Plot horizontal support lines

xh=[0.3 0.7]; % x ranges for horizontal lines
d_vert=cfobj.p2; %% symetry line direction coeff.
p_vert=cfobj.p1; %% symetry line offset (note: this is in rotated coords. x<-->y
d_horiz=-cfobj.p2; % horizontal support lines direction coeff.
p_horiz=my-mx*d_horiz; %% support line offset
for i=1:length(lx)
    yh=xh*d_horiz+p_horiz(i); %% calculate support line endpoints
    plot(xh*xmax,yh*ymax,'g:');
end

Calculate distance from reference points to support lines

dist_vert=abs((d_horiz*lx-ly+p_horiz)./sqrt(d_horiz*d_horiz+1)); % real point distance from vertical support

Calculate distance deviation from reference points to centerline

dist_sym_l=abs((d_vert*ly-lx+p_vert)./sqrt(d_vert*d_vert+1)); % distances from symetry line
dist_sym_r=abs((d_vert*ry-rx+p_vert)./sqrt(d_vert*d_vert+1)); % line
dist_sym_m=(dist_sym_l+dist_sym_r)./2; % nominal, "ideal" distances
dist_sym_d=abs(dist_sym_m-dist_sym_l); % horizontal distances deviation

Calculate indexes

avgdist_h=(sum(dist_vert)./length(dist_vert))./fu;
maxdist_h=max(dist_vert)./fu;
avgdist_v=(sum(dist_sym_d)./length(dist_sym_d))./fu;
maxdist_v=(max(dist_sym_d))./fu;
disp(sprintf('Average vertical distance from support line: ........... %2.4f[FU]',avgdist_h));
disp(sprintf('Maximum vertical distance from support line: ........... %2.4f[FU]',maxdist_h));
disp(sprintf('Average horizontal distance deviation from symetry line: %2.4f[FU]',avgdist_v));
disp(sprintf('Maximum horizontal distance deviation from symetry line: %2.4f[FU]',maxdist_v));
Average vertical distance from support line: ........... 0.0362[FU]
Maximum vertical distance from support line: ........... 0.1065[FU]
Average horizontal distance deviation from symetry line: 0.0131[FU]
Maximum horizontal distance deviation from symetry line: 0.0261[FU]

Index for specific point

We may be interested in evauation of position of only one specyfic point relative to the rest. For example, consider mouth metrics:

disp(sprintf('Mouth horizontal deviation: ............................ %2.4f[FU]',dist_sym_d(4)./fu));
disp(sprintf('Mouth vertical deviation: .............................. %2.4f[FU]',dist_vert(4)./fu));
annotation('arrow',[0.763 0.5648],[0.1445 0.249],'HeadLength',15,...
    'HeadWidth',15,...
    'LineWidth',2);
Mouth horizontal deviation: ............................ 0.0161[FU]
Mouth vertical deviation: .............................. 0.1065[FU]

Final note

Please note that these indexes are in "face units" (FU), which is (the definition of unit) in dispute. It may change, so above results are not yet comparable.