Head Distance Tracking (code c#)
Posted: 16 Jan 2014, 22:45
Although moving your head around somewhat quickly causes the sensor to fail, slower movements can be made. Pupil Center coordinates may be used to extrapolate the head's distance from the sensor. This can be useful for creating effects there the user leans in or out. It can also be used as part of correcting the vertical offset error that occurs currently.
Some code to consider adding to GazeData on the TETCSharpClient
Or you can incorporate this as an extension method in your application without making changes to the provided CSharpClient by creating a static extension method class:
Some code to consider adding to GazeData on the TETCSharpClient
- Code: Select all
Usage:
var dist = data.HeadDistance;
if (dist != GazeData.PUPIL_DISTANCE_NOTACCURATE) LastUsableHeadDistance= dist;
Code added to GazeData in TETCSharpClient:
/// <summary>
/// Minimum distance from sensor is about 1 foot
/// </summary>
public const double PUPIL_DISTANCE_MAX = 0.35d;
/// <summary>
/// Max distance is about 3-4 feet
/// </summary>
public const double PUPIL_DISTANCE_MIN = 0.10d;
/// <summary>
/// Returned when no pupil distance is not accurate enough to compute
/// </summary>
public const double PUPIL_DISTANCE_NOTACCURATE = -100d;
/// <summary>
/// Computed pupil distance to return a value between 0 and 1 for z distance from sensor within 1-4 foot range.
/// </summary>
public double HeadDistance
{
get
{
if ((State & STATE_TRACKING_GAZE) == 0) return PUPIL_DISTANCE_NOTACCURATE;
if ((State & STATE_TRACKING_PRESENCE) == 0) return PUPIL_DISTANCE_NOTACCURATE;
if ((State & STATE_TRACKING_FAIL) != 0) return PUPIL_DISTANCE_NOTACCURATE;
if ((State & STATE_TRACKING_LOST) != 0) return PUPIL_DISTANCE_NOTACCURATE;
if (LeftEye == null || RightEye == null) return PUPIL_DISTANCE_NOTACCURATE;
var leftCenter = LeftEye.PupilCenterCoordinates;
var rightCenter = RightEye.PupilCenterCoordinates;
if (leftCenter == null || rightCenter == null) return PUPIL_DISTANCE_NOTACCURATE;
var xDist = (rightCenter.X - leftCenter.X);
var yDist = (rightCenter.Y - leftCenter.Y);
if (xDist == 0 && yDist == 0) return PUPIL_DISTANCE_NOTACCURATE; //Sensor returning wonky values
var dist = Math.Sqrt(xDist * xDist + yDist * yDist);
if (dist > PUPIL_DISTANCE_MAX) return PUPIL_DISTANCE_NOTACCURATE; //Sensor returning wonky values
dist -= PUPIL_DISTANCE_MIN;
return dist / (PUPIL_DISTANCE_MAX - PUPIL_DISTANCE_MIN);
}
}
Or you can incorporate this as an extension method in your application without making changes to the provided CSharpClient by creating a static extension method class:
- Code: Select all
Usage:
var dist = data.HeadDistance();
if (dist != EyeTribeExtensions.PUPIL_DISTANCE_NOTACCURATE) LastUsableHeadDistance= dist;
public static class EyeTribeExtensions
{
/// <summary>
/// Minimum distance from sensor is about 1 foot
/// </summary>
public const double PUPIL_DISTANCE_MAX = 0.35d;
/// <summary>
/// Max distance is about 3-4 feet
/// </summary>
public const double PUPIL_DISTANCE_MIN = 0.10d;
/// <summary>
/// Returned when no pupil distance is not accurate enough to compute
/// </summary>
public const double PUPIL_DISTANCE_NOTACCURATE = -100d;
/// <summary>
/// Computed using pupil distance to return a value between 0 and 1 for z distance from sensor within 1-4 foot range.
/// </summary>
public static double HeadDistance(this GazeData data)
{
if ((data.State & GazeData.STATE_TRACKING_GAZE) == 0) return PUPIL_DISTANCE_NOTACCURATE;
if ((data.State & GazeData.STATE_TRACKING_PRESENCE) == 0) return PUPIL_DISTANCE_NOTACCURATE;
if ((data.State & GazeData.STATE_TRACKING_FAIL) != 0) return PUPIL_DISTANCE_NOTACCURATE;
if ((data.State & GazeData.STATE_TRACKING_LOST) != 0) return PUPIL_DISTANCE_NOTACCURATE;
if (data.LeftEye == null || data.RightEye == null) return PUPIL_DISTANCE_NOTACCURATE;
var leftCenter = data.LeftEye.PupilCenterCoordinates;
var rightCenter = data.RightEye.PupilCenterCoordinates;
if (leftCenter == null || rightCenter == null) return PUPIL_DISTANCE_NOTACCURATE;
var xDist = (rightCenter.X - leftCenter.X);
var yDist = (rightCenter.Y - leftCenter.Y);
if (xDist == 0 && yDist == 0) return PUPIL_DISTANCE_NOTACCURATE; //Sensor returning wonky values
var dist = Math.Sqrt(xDist * xDist + yDist * yDist);
if (dist > PUPIL_DISTANCE_MAX) return PUPIL_DISTANCE_NOTACCURATE; //Sensor returning wonky values
dist -= PUPIL_DISTANCE_MIN;
return dist / (PUPIL_DISTANCE_MAX - PUPIL_DISTANCE_MIN);
}
}