Sleep-Cycle Facial Gesture Tracking

I was keen this week to observe my sleep. I started off by taking time-lapse video of my sleep and was shocked to see how much I move throughout the night. I also noticed that I spend a long time sleeping on my back, while I tend to begin my side. I then played around with both the NeuroSky Brainwave sensor and the Zeo Sleep Monitor to see if I could learn something more about brain waves.

The NeuroSky is an interesting toy and perhaps a hint at where human computer interfaces could go one day. It pretty accurately sensed three things; a relaxed state of mind, an active state of mind and eye blinking but was hard to use and felt ambiguous as a controller. The Zeo returns a graph logging the night’s sleep in 5 minute increments, broken into one of four stages of sleep: Light sleep, deep sleep, REM sleep and awake. It is hard to judge how accurate the readings are and so I wanted to match their data with a more observational metric. Initially I wanted to match the Zeo data to a time-lapse video to see if movement during the night correlates to changes in each sleep cycle. But this would involve watching the video back every time. My second thought was to use an IR motion sensor to log movement and see if there was a correlation in the data. Finally, I decided to revive an application that I played around with last semester that tracks facial gestures for 3D animators. Faceshift streams data out on over 50 locations on the face that can indicate pretty well whether a certain gesture is being performed. With this I hope to be able to see the different sort of gestures the face makes during light sleep, REM sleep and deep sleep — and perhaps even sense the nature of my dreams using data on indicators like smiles, frowns and squints throughout the night.

This is my Processing script for reading in the OSC messages that come out of Faceshift piped through this little application, and parsed out for two indicators that worked pretty well for me (smile right and eyebrows center up). I still need a more solid way to timestamp each output:

import oscP5.*;
import netP5.*;
PrintWriter output;
OscP5 oscP5;

void setup() {
size(100,100);
frameRate(10);
output = createWriter(“data.txt”);
OscProperties myProperties = new OscProperties();
myProperties.setListeningPort(8338);
myProperties.setDatagramSize(9999999);
oscP5 = new OscP5(this,myProperties);
}

void draw() {
// int s = second(); // Values from 0 – 59
// int min = minute(); // Values from 0 – 59
// int h = hour(); // Values from 0 – 23
// output.print(h +”:” + min + “:” + s + “,”);
}

void oscEvent(OscMessage theOscMessage) {
if(theOscMessage.checkAddrPattern(“/gesture/mouth/smile/right”)==true) {
float smile = theOscMessage.get(0).floatValue();
print(“### received an osc message.”);
print(” addrpattern: “+theOscMessage.addrPattern());
println(” typetag: “+theOscMessage.typetag());
println(” smile value: ” + smile);
output.print(“smile: ” + smile + “,”);
}
if (theOscMessage.checkAddrPattern(“/gesture/brows/up/center”)==true) {
float brows = theOscMessage.get(0).floatValue();
print(“### received an osc message.”);
print(” addrpattern: “+theOscMessage.addrPattern());
println(” typetag: “+theOscMessage.typetag());
println(” brow value: ” + brows);
output.print(“brows: ” + brows + “\r\n”);
}
}

void keyPressed() {
output.flush(); // Writes the remaining data to the file
output.close(); // Finishes the file
exit(); // Stops the program
}

Comments are closed.