Back to start

Facegen SDK .FG file feature export to CSV

Facegen allows the exporting of feature values across a wide range of facial features, including sex, race, age, symmetry, averageness per race, and many many shape and pigment cues. These can be used for many things, such as analyzing their relations to behavior (e.g., Colleen Carpinella and Kerri Johnson found relations in gender cues to politician preferences, 2013). You can also build visual models of face similarity based on cues, or descriptively explore cues and associations of various faces. These faces can be ones you created, or ones you scanned into the FaceGen Modeller software (e.g., used by Carpinella & Johnson, 2013). Pretty cool.

Here's some easy code you can implement on your FaceGen files (.fg) to extract all of these features, and plop them into a CSV. 

Requirements:

Script mentioned below, with notes here.

To extract the .FG feature values, in the command line, from the unzipped SDK folder, navigate to /bin/win/vs10/64/release/ or your correct bits/vs version, which should have something like fg3.exe in it. Then, from command line, these commands each print out one txt file per parameter per fg file (assuming the FG files are in the same current folder you are in, so move them there, or change the filepaths appropriately):

First, in batch:


Shape:

for %F in (*.fg) do (for /L %G in (0,1,60) do fg3 controls %F sliderShape symm %G > %F%GShape.txt)

Pigment:

for %F in (*.fg) do (for /L %G in (0,1,35) do fg3 controls %F sliderColor %G > %F%GColor.txt)

Gender:

for %F in (*.fg) do fg3 controls %F gender shape > %Fgendershape.txt`
for %F in (*.fg) do fg3 controls %F gender color > %Fgendercolor.txt

Race:

for %F in (*.fg) do fg3 controls %F race all african > %FRaceAFA.txt
for %F in (*.fg) do fg3 controls %F race all european > %FRaceAE.txt
for %F in (*.fg) do fg3 controls %F race all eastAsian > %FRaceAEA.txt
for %F in (*.fg) do fg3 controls %F race all southAsian > %FRaceASA.txt
for %F in (*.fg) do fg3 controls %F race african european > %FRaceAFE.txt
for %F in (*.fg) do fg3 controls %F race african eastAsian > %FRaceAFEA.txt
for %F in (*.fg) do fg3 controls %F race african southAsian > %FRaceAFSA.txt
for %F in (*.fg) do fg3 controls %F race european eastAsian > %FRaceEEA.txt
for %F in (*.fg) do fg3 controls %F race european southAsian > %FRaceESA.txt
for %F in (*.fg) do fg3 controls %F race eastAsian southAsian > %FRaceEASA.txt

Age:

for %F in (*.fg) do fg3 controls %F age shape > %Fageshape.txt
for %F in (*.fg) do fg3 controls %F age color > %Fagecolor.txt

Symmetry:

for %F in (*.fg) do fg3 controls %F asymmetry > %Fasymmetry.txt

Caricature/averageness:

for %F in (*.fg) do fg3 controls %F caricature all shape > %Fallcarshape.txt
for %F in (*.fg) do fg3 controls %F caricature all color > %Fallcarcolor.txt
for %F in (*.fg) do fg3 controls %F caricature african shape > %Fafricancarshape.txt
for %F in (*.fg) do fg3 controls %F caricature african color > %Fafricancarcolor.txt
for %F in (*.fg) do fg3 controls %F caricature european shape > %Feuropeancarshape.txt
for %F in (*.fg) do fg3 controls %F caricature european color > %Feuropeancarcolor.txt
for %F in (*.fg) do fg3 controls %F caricature eastAsian shape > %FeastAsiancarshape.txt
for %F in (*.fg) do fg3 controls %F caricature eastAsian color > %FeastAsiancarcolor.txt
for %F in (*.fg) do fg3 controls %F caricature southAsian shape > %FsouthAsiancarshape.txt
for %F in (*.fg) do fg3 controls %F caricature southAsian color > %FsouthAsiancarcolor.txt

That is all you need, but for some bash & python to quick aggregate it into a CSV...

Second, in Bash, this concats all cues per face (.fg file) into a txt per face:


for f in *.fg; do cat ${f}*.txt > ${f:0:${#f}-3}_all.txt; done

Third, with all of the txts per fg file in one folder, run this python code to reorganize and clean each, then make a csv out of the txts:


import numpy
import glob as glob

paths = glob.glob("*.txt")
files = [paths[i].split('/')[-1] for i,path in enumerate(paths)]

for file_i,fname in enumerate(files):
    lines = open(fname).read().splitlines()
    lines = [i for i in lines if i != '']
    linesplit = [i.split(' ') for i in lines]
    for i,j in enumerate(linesplit):
        if j[-1] == 'years': linesplit[i] = linesplit[i][0:-1]
        elif j[-1][0] == '(': linesplit[i][-1] = linesplit[i][-1][1:-1]
    linesdata = [["".join(i[:-1]),float(i[-1])] for i in linesplit]
    linesfinal = [[fname.split(".")[0],i[0],i[1]] for i in linesdata]
    numpy.savetxt("%s.csv" % (fname.split(".")[0]), linesfinal, delimiter=",", fmt='%s')

Last, again in Bash, aggregate the CSVs into one:


cat *.csv > all_fgstats.csv

And voila, there you go.