Page 1 of 1

Head Distance Tracking (code c#)

PostPosted: 16 Jan 2014, 22:45
by kevin.cole
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

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);
        }
    }

Re: Head Distance Tracking (code c#)

PostPosted: 17 Jan 2014, 01:23
by kevin.cole
Here's an extension method to extrapolate head tracking info.

Why would you want head position information?
http://www.youtube.com/watch?v=Jd3-eiid-Uw

I intend on also looking into getting rotation using the pupil size difference... but I don't know how useful or accurate that will actually be.



Code: Select all
public class Point3D
    {
        public Point3D(double x, double y, double z)
        {
            X = x;
            Y = y;
            Z = z;
        }
        public double X;
        public double Y;
        public double Z;
    }

public static Point3D HeadPosition(this GazeData data)
        {
            if ((data.State & GazeData.STATE_TRACKING_GAZE) == 0) return null;
            if ((data.State & GazeData.STATE_TRACKING_PRESENCE) == 0) return null;
            if ((data.State & GazeData.STATE_TRACKING_FAIL) != 0) return null;
            if ((data.State & GazeData.STATE_TRACKING_LOST) != 0) return null;


            if (data.LeftEye == null || data.RightEye == null) return null;

            var leftCenter = data.LeftEye.PupilCenterCoordinates;
            var rightCenter = data.RightEye.PupilCenterCoordinates;
            if (leftCenter == null || rightCenter == null) return null;

            var xDist = (rightCenter.X - leftCenter.X);
            var yDist = (rightCenter.Y - leftCenter.Y);

            if (xDist == 0 && yDist == 0) return null; //Sensor returning wonky values

            var dist = Math.Sqrt(xDist * xDist + yDist * yDist);
            if (dist > PUPIL_DISTANCE_MAX) return null; //Sensor returning wonky values

            var result = new Point3D(
                (leftCenter.X + rightCenter.X)*0.5,
                (leftCenter.Y + rightCenter.Y)*0.5,
                dist);
            return result;
        }

Re: Head Distance Tracking (code c#)

PostPosted: 20 Jul 2015, 18:00
by mashrufz
Hi, Thanks for the post. How successful was it to detect head movement based on pupil. Could you please shed some more light?

Regards,

Re: Head Distance Tracking (code c#)

PostPosted: 24 Jul 2015, 11:30
by Anders
In the public Unity examples you can find helper classes that handle noise in the data stream while also tracking of the user in 3D based on pupil tracking. The class you are looking for is GazeDataValidator. Inspect the project to see how it can be used.