Head Distance Tracking (code c#)

Forum for C#/Windows development

Head Distance Tracking (code c#)

Postby kevin.cole » 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

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);
        }
    }
kevin.cole
 
Posts: 7
Joined: 14 Jan 2014, 03:57

Re: Head Distance Tracking (code c#)

Postby kevin.cole » 17 Jan 2014, 01:23

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;
        }
kevin.cole
 
Posts: 7
Joined: 14 Jan 2014, 03:57

Re: Head Distance Tracking (code c#)

Postby mashrufz » 20 Jul 2015, 18:00

Hi, Thanks for the post. How successful was it to detect head movement based on pupil. Could you please shed some more light?

Regards,
mashrufz
 
Posts: 7
Joined: 15 Jul 2015, 13:03

Re: Head Distance Tracking (code c#)

Postby Anders » 24 Jul 2015, 11:30

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.
Anders
 
Posts: 124
Joined: 29 Oct 2013, 16:23


Return to C#



cron